From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id A8F351FF0DF for ; Fri, 28 Aug 2026 15:33:00 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id F297D21756; Fri, 28 Aug 2026 15:31:15 +0200 (CEST) From: Shannon Sterz To: pve-devel@lists.proxmox.com Subject: [PATCH docs 21/21] examples: add example hook script for host backup jobs Date: Fri, 28 Aug 2026 15:30:30 +0200 Message-ID: <20260828133030.351140-22-s.sterz@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260828133030.351140-1-s.sterz@proxmox.com> References: <20260828133030.351140-1-s.sterz@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1787923825323 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.845 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: KKCIM7LBQ46TD3MAZLXKERTQSQMAJCIB X-Message-ID-Hash: KKCIM7LBQ46TD3MAZLXKERTQSQMAJCIB X-MailFrom: s.sterz@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Signed-off-by: Shannon Sterz --- Makefile | 1 + examples/host-backup-example-hookscript.pl | 90 ++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100755 examples/host-backup-example-hookscript.pl diff --git a/Makefile b/Makefile index db07f2e..13ddb73 100644 --- a/Makefile +++ b/Makefile @@ -218,6 +218,7 @@ doc-install: index.html $(WIKI_IMPORTS) $(API_VIEWER_SOURCES) verify-images exam install -dm755 $(DESTDIR)/usr/share/doc/$(DOC_PACKAGE) install -dm755 $(DESTDIR)/usr/share/$(DOC_PACKAGE)/examples/ install -m 755 examples/guest-example-hookscript.pl $(DESTDIR)/usr/share/$(DOC_PACKAGE)/examples/ + install -m 755 examples/host-backup-example-hookscript.pl $(DESTDIR)/usr/share/$(DOC_PACKAGE)/examples/ install -m 0644 index.html $(INDEX_INCLUDES) $(DESTDIR)/usr/share/$(DOC_PACKAGE) install -m 0644 $(WIKI_IMPORTS) $(DESTDIR)/usr/share/$(DOC_PACKAGE) # install images diff --git a/examples/host-backup-example-hookscript.pl b/examples/host-backup-example-hookscript.pl new file mode 100755 index 0000000..9791814 --- /dev/null +++ b/examples/host-backup-example-hookscript.pl @@ -0,0 +1,90 @@ +#!/usr/bin/perl + +# Example host backup hook script. Currently these need to be added +# manually to a host backup job (or as an API parameter to a one off +# host backup). + +use v5.36; + +# First argument is the backup phase. + +my $phase = shift; + +# A payload is provided via `stdin` as JSON encoded. This will only +# exist for certain stages. Parameters may be added to the payload +# over time. Make sure a hook script can handle additional fields, +# for better compatibility. + +my @input = ; +my $payload = join('\n', @input); + +if ($phase eq 'job-start') { + + # A backup was started. Other than validating the parameters of + # the job, nothing has been done yet. + + # This stage has no payload: + die "Unknown payload: '$payload'\n" if $payload ne ''; + + # If the script returns only a valid JSON string that contains an + # object with a single string member called `base-path`, that + # string will be used as the base path of the backup. It needs to + # point to a directory. + # + # The default depends on the root file system. On XFS and ext-4 + # it is simply `/`. On ZFS and BTRFS it will be a path to a + # mounted snapshot of the root file system. + # + # This can be useful if the root file system supports extra + # consistency methods (such as, snapshot support), but the + # default backup mechanism cannot use it. For example, because + # the file system is not supported by Proxmox VE by default or + # taking snapshots comes with an overhead that needs to be + # evaluated by the operator. + print '{ "base-path": "/path/to/base/path" }'; + +} elsif ($phase eq 'backup-start') { + + # A backup has been prepared, but nothing has been backed up yet. + + # This stage has a payload that contains the name of the backup + # and the backup target. The target is a directory that should + # contain all files that should be included in the backup. It + # should be created but empty in this phase. + # + # The payload should be structured as following: + # ```js + # { + # "backup-name": "host-backup-1234567", + # "backup-target": "/path/to/tmp/backup/dir" + # } + # ``` + die "Paylod was undefined.\n" if !defined($payload); + + # Nothing can be communicated back to the job at this stage. + +} elsif ($phase eq 'backup-end') { + + # The backup has been completed and uploaded at this stage. + + # A payload should be provided, it will be identical to the + # previous stage's payload. + die "Paylod was undefined.\n" if !defined($payload); + + # Nothing can be communicated back to the job at this stage. + +} elsif ($phase eq 'job-end') { + + # The back up job has completed including cleaning up any + # snapshots or temporary files. + + # This stage receives no payload. + die "Unknown payload: '$payload'\n" if $payload ne ''; + + # Nothing can be communicated back to the job at this stage. + +} else { + die "Got unknown phase: '$phase'\n"; +} + +exit(0); -- 2.47.3