[pve-devel] [PATCH qemu-server 1/1] add hookscripts to vms

Fabian Grünbichler f.gruenbichler at proxmox.com
Wed Jan 23 15:27:58 CET 2019


On Mon, Jan 21, 2019 at 09:44:35AM +0100, Dominik Csapak wrote:
> this adds a new config option for it, and executes it on four
> points in time:
> 
> 'pre-start'
> 'post-start'
> 'pre-stop'
> 'post-stop'
> 
> on pre-start we abort if the script fails
> and pre-stop will not be called if the vm crashes or if
> the vm gets powered off from inside the guest
> 
> Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
> ---
>  PVE/API2/Qemu.pm  |  8 ++++++++
>  PVE/CLI/qm.pm     |  2 ++
>  PVE/QemuServer.pm | 12 ++++++++++++
>  3 files changed, 22 insertions(+)
> 
> diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
> index b55fd13..13aa021 100644
> --- a/PVE/API2/Qemu.pm
> +++ b/PVE/API2/Qemu.pm
> @@ -1101,6 +1101,14 @@ my $update_vm_api  = sub {
>  	    if ($param->{$opt} eq '1') {
>  		$param->{$opt} = PVE::QemuServer::generate_uuid();
>  	    }
> +	} elsif ($opt eq 'hookscript') {
> +	    my ($path, undef, $type) = PVE::Storage::path($storecfg, $param->{$opt});

IMHO this should be limited to root at pam here as well (just because an
admin put an executable in some scripts directory does not mean they
want every user that can modify their VM config to execute that script
as root - potentially that script then decides stuff based on VM config
content as well, etc. pp.). once we establish a ACL scheme for this
scripts we might relax this here, but for now let's keep it simple &
safe by default.

> +
> +	    raise_param_exc({ $opt => "is not in the scripts directory" })
> +		if $type ne 'scripts';
> +
> +	    warn "script '$path' not found, setting anyway\n"
> +		if ! -f $path;

does this make sense?

>  	}
>      }
>  
> diff --git a/PVE/CLI/qm.pm b/PVE/CLI/qm.pm
> index 26d4217..c85deb8 100755
> --- a/PVE/CLI/qm.pm
> +++ b/PVE/CLI/qm.pm
> @@ -19,6 +19,7 @@ use PVE::INotify;
>  use PVE::RPCEnvironment;
>  use PVE::Exception qw(raise_param_exc);
>  use PVE::Network;
> +use PVE::GuestHelpers;
>  use PVE::QemuServer;
>  use PVE::QemuServer::ImportDisk;
>  use PVE::QemuServer::OVF;
> @@ -778,6 +779,7 @@ __PACKAGE__->register_method({
>  		# vm was shutdown from inside the guest or crashed, doing api cleanup
>  		PVE::QemuServer::vm_stop_cleanup($storecfg, $vmid, $conf, 0, 0);
>  	    }
> +	    PVE::GuestHelpers::exec_hookscript($conf, $vmid, 'post-stop');
>  	});
>  
>  	warn "Finished cleanup for $vmid\n";
> diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
> index 1ccdccf..1132247 100644
> --- a/PVE/QemuServer.pm
> +++ b/PVE/QemuServer.pm
> @@ -30,6 +30,7 @@ use PVE::ProcFSTools;
>  use PVE::QemuConfig;
>  use PVE::QMPClient;
>  use PVE::RPCEnvironment;
> +use PVE::GuestHelpers;
>  use PVE::QemuServer::PCI qw(print_pci_addr print_pcie_addr);
>  use PVE::QemuServer::Memory;
>  use PVE::QemuServer::USB qw(parse_usb_device);
> @@ -607,6 +608,12 @@ EODESCR
>  	default => "1 (autogenerated)",
>  	optional => 1,
>      },
> +    hookscript => {
> +	type => 'string',
> +	format => 'pve-volume-id',
> +	optional => 1,
> +	description => "Script that will be executed during various steps in the vms lifetime.",
> +    },
>  };
>  
>  my $confdesc_cloudinit = {
> @@ -4587,6 +4594,7 @@ my $fast_plug_option = {
>      'description' => 1,
>      'protection' => 1,
>      'vmstatestorage' => 1,
> +    'hookscript' => 1,
>  };
>  
>  # hotplug changes in [PENDING]
> @@ -5105,6 +5113,8 @@ sub vm_start {
>  	    }
>  	}
>  
> +	PVE::GuestHelpers::exec_hookscript($conf, $vmid, 'pre-start', 1);
> +
>  	my ($cmd, $vollist, $spice_port) = config_to_command($storecfg, $vmid, $conf, $defaults, $forcemachine);
>  
>  	my $migrate_port = 0;
> @@ -5302,6 +5312,7 @@ sub vm_start {
>  		    property => "guest-stats-polling-interval",
>  		    value => 2) if (!defined($conf->{balloon}) || $conf->{balloon});
>  
> +	PVE::GuestHelpers::exec_hookscript($conf, $vmid, 'post-start');
>      });
>  }
>  
> @@ -5465,6 +5476,7 @@ sub vm_stop {
>  		my $opts = PVE::JSONSchema::pve_parse_startup_order($conf->{startup});
>  		$timeout = $opts->{down} if $opts->{down};
>  	    }
> +	    PVE::GuestHelpers::exec_hookscript($conf, $vmid, 'pre-stop');
>  	}
>  
>  	$timeout = 60 if !defined($timeout);
> -- 
> 2.11.0
> 
> 
> _______________________________________________
> pve-devel mailing list
> pve-devel at pve.proxmox.com
> https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel




More information about the pve-devel mailing list