From 0715179668327eea3b58ad5d8167f8bff842259f Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Tue, 4 Oct 2011 11:05:25 +0200 Subject: [PATCH] implement openvz start/stop --- PVE/API2/OpenVZ.pm | 207 ++++++++++++++++++++++++++++++++++++++++++++- PVE/OpenVZ.pm | 23 ++--- bin/pvectl | 9 ++ 3 files changed, 228 insertions(+), 11 deletions(-) diff --git a/PVE/API2/OpenVZ.pm b/PVE/API2/OpenVZ.pm index 4b94bff9..d4661184 100644 --- a/PVE/API2/OpenVZ.pm +++ b/PVE/API2/OpenVZ.pm @@ -126,7 +126,7 @@ __PACKAGE__->register_method({ my $code = sub { - my $basecfg_fn = PVE::OpenVZ::get_config_path($vmid); + my $basecfg_fn = PVE::OpenVZ::config_file($vmid); die "container $vmid already exists\n" if -f $basecfg_fn; @@ -237,6 +237,47 @@ __PACKAGE__->register_method({ return undef; }}); +__PACKAGE__->register_method({ + name => 'vmdiridx', + path => '{vmid}', + method => 'GET', + proxyto => 'node', + description => "Directory index", + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + vmid => get_standard_option('pve-vmid'), + }, + }, + returns => { + type => 'array', + items => { + type => "object", + properties => { + subdir => { type => 'string' }, + }, + }, + links => [ { rel => 'child', href => "{subdir}" } ], + }, + code => sub { + my ($param) = @_; + + # test if VM exists + my $conf = PVE::OpenVZ::load_config($param->{vmid}); + + my $res = [ + { subdir => 'config' }, + { subdir => 'status' }, + { subdir => 'vncproxy' }, + { subdir => 'migrate' }, + { subdir => 'rrd' }, + { subdir => 'rrddata' }, + ]; + + return $res; + }}); + __PACKAGE__->register_method({ name => 'vm_config', path => '{vmid}/config', @@ -313,6 +354,9 @@ __PACKAGE__->register_method({ my $vmid = $param->{vmid}; + # test if VM exists + my $conf = PVE::OpenVZ::load_config($param->{vmid}); + my $cmd = ['vzctl', 'destroy', $vmid ]; PVE::Tools::run_command($cmd); @@ -320,4 +364,165 @@ __PACKAGE__->register_method({ return undef; }}); +__PACKAGE__->register_method({ + name => 'vmcmdidx', + path => '{vmid}/status', + method => 'GET', + proxyto => 'node', + description => "Directory index", + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + vmid => get_standard_option('pve-vmid'), + }, + }, + returns => { + type => 'array', + items => { + type => "object", + properties => { + subdir => { type => 'string' }, + }, + }, + links => [ { rel => 'child', href => "{subdir}" } ], + }, + code => sub { + my ($param) = @_; + + # test if VM exists + my $conf = PVE::OpenVZ::load_config($param->{vmid}); + + my $res = [ + { subdir => 'current' }, + { subdir => 'start' }, + { subdir => 'stop' }, + ]; + + return $res; + }}); + +__PACKAGE__->register_method({ + name => 'vm_status', + path => '{vmid}/status/current', + method => 'GET', + proxyto => 'node', + protected => 1, # openvz /proc entries are only readable by root + description => "Get virtual machine status.", + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + vmid => get_standard_option('pve-vmid'), + }, + }, + returns => { type => 'object' }, + code => sub { + my ($param) = @_; + + # test if VM exists + my $conf = PVE::OpenVZ::load_config($param->{vmid}); + + my $vmstatus = PVE::OpenVZ::vmstatus($param->{vmid}); + + return $vmstatus->{$param->{vmid}}; + }}); + +__PACKAGE__->register_method({ + name => 'vm_start', + path => '{vmid}/status/start', + method => 'POST', + protected => 1, + proxyto => 'node', + description => "Start the container.", + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + vmid => get_standard_option('pve-vmid'), + }, + }, + returns => { + type => 'string', + }, + code => sub { + my ($param) = @_; + + my $rpcenv = PVE::RPCEnvironment::get(); + + my $user = $rpcenv->get_user(); + + my $node = extract_param($param, 'node'); + + my $vmid = extract_param($param, 'vmid'); + + my $realcmd = sub { + my $upid = shift; + + syslog('info', "starting container $vmid: $upid\n"); + + my $cmd = ['vzctl', 'start', $vmid]; + + PVE::Tools::run_command($cmd); + + return; + }; + + my $upid = $rpcenv->fork_worker('vzstart', $vmid, $user, $realcmd); + + return $upid; + }}); + +__PACKAGE__->register_method({ + name => 'vm_stop', + path => '{vmid}/status/stop', + method => 'POST', + protected => 1, + proxyto => 'node', + description => "Stop the container.", + parameters => { + additionalProperties => 0, + properties => { + node => get_standard_option('pve-node'), + vmid => get_standard_option('pve-vmid'), + fast => { + type => 'boolean', + description => "This is faster but can lead to unclean container shutdown.", + optional => 1, + } + }, + }, + returns => { + type => 'string', + }, + code => sub { + my ($param) = @_; + + my $rpcenv = PVE::RPCEnvironment::get(); + + my $user = $rpcenv->get_user(); + + my $node = extract_param($param, 'node'); + + my $vmid = extract_param($param, 'vmid'); + + my $realcmd = sub { + my $upid = shift; + + syslog('info', "stoping container $vmid: $upid\n"); + + my $cmd = ['vzctl', 'stop', $vmid]; + + push @$cmd, '--fast' if $param->{fast}; + + PVE::Tools::run_command($cmd); + + return; + }; + + my $upid = $rpcenv->fork_worker('vzstop', $vmid, $user, $realcmd); + + return $upid; + }}); + 1; diff --git a/PVE/OpenVZ.pm b/PVE/OpenVZ.pm index b9c39e13..4ae08440 100644 --- a/PVE/OpenVZ.pm +++ b/PVE/OpenVZ.pm @@ -39,31 +39,34 @@ sub cfs_config_path { return "nodes/$node/openvz/$vmid.conf"; } -sub get_config_path { - my $vmid = shift; - return "/etc/pve/openvz/${vmid}.conf"; -}; +sub config_file { + my ($vmid, $node) = @_; + + my $cfspath = cfs_config_path($vmid, $node); + return "/etc/pve/$cfspath"; +} sub load_config { my ($vmid) = @_; - my $basecfg_fn = get_config_path($vmid); + my $cfspath = cfs_config_path($vmid); - my $basecfg = PVE::Tools::file_get_contents($basecfg_fn); - die "container $vmid does not exists\n" if !$basecfg; + my $conf = PVE::Cluster::cfs_read_file($cfspath); + die "container $vmid does not exists\n" if !defined($conf); - my $conf = PVE::OpenVZ::parse_ovz_config($basecfg_fn, $basecfg); - - return wantarray ? ($conf, $basecfg) : $conf; + return $conf; } my $last_proc_vestat = {}; sub vmstatus { + my ($opt_vmid) = @_; my $list = config_list(); foreach my $vmid (keys %$list) { + next if $opt_vmid && ($vmid ne $opt_vmid); + my $d = $list->{$vmid}; $d->{status} = 'stopped'; diff --git a/bin/pvectl b/bin/pvectl index b9078d59..30ed30b9 100755 --- a/bin/pvectl +++ b/bin/pvectl @@ -29,6 +29,12 @@ $rpcenv->init_request(); $rpcenv->set_language($ENV{LANG}); $rpcenv->set_user('root@pam'); +my $upid_exit = sub { + my $upid = shift; + my $status = PVE::Tools::upid_read_status($upid); + exit($status eq 'OK' ? 0 : -1); +}; + my $cmddef = { list => [ "PVE::API2::OpenVZ", 'vmlist', [], @@ -66,6 +72,9 @@ my $cmddef = { } }], + start => [ 'PVE::API2::OpenVZ', 'vm_start', ['vmid'], { node => $nodename }, $upid_exit], + stop => [ 'PVE::API2::OpenVZ', 'vm_stop', ['vmid'], { node => $nodename }, $upid_exit], + }; my $cmd = shift;