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

Dominik Csapak d.csapak at proxmox.com
Wed Jan 23 15:34:56 CET 2019


On 1/23/19 3:27 PM, Fabian Grünbichler wrote:
> 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.

any new config option is by default root at pam only
(see PVE/API2/Qemu.pm:335)

so this is already done?

> 
>> +
>> +	    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?

what exactly? i did not want the user to be able to set anything
(e.g. 'local:5' which is a valid volume-id but nonsense in this
context), but i did not want the user to be restricted
to first put the script in the storage and then set it

> 
>>   	}
>>       }
>>   
>> 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
> 
> _______________________________________________
> 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