use PVE::Cluster qw(cfs_read_file);
use PVE::AccessControl;
use PVE::Firewall;
+use PVE::GuestHelpers;
use PVE::Storage;
use PVE::RESTHandler;
use PVE::RPCEnvironment;
use PVE::LXC;
use PVE::LXC::Create;
-use PVE::HA::Config;
use PVE::JSONSchema qw(get_standard_option);
use base qw(PVE::RESTHandler);
parameters => {
additionalProperties => 0,
properties => {
- vmid => get_standard_option('pve-vmid'),
+ vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid }),
node => get_standard_option('pve-node'),
},
},
type => 'array',
items => {
type => "object",
- properties => {},
+ properties => {
+ name => {
+ description => "Snapshot identifier. Value 'current' identifies the current VM.",
+ type => 'string',
+ },
+ description => {
+ description => "Snapshot description.",
+ type => 'string',
+ },
+ snaptime => {
+ description => "Snapshot creation time",
+ type => 'integer',
+ renderer => 'timestamp',
+ optional => 1,
+ },
+ parent => {
+ description => "Parent snapshot identifier.",
+ type => 'string',
+ optional => 1,
+ },
+ },
},
links => [ { rel => 'child', href => "{name}" } ],
},
my $vmid = $param->{vmid};
- my $conf = PVE::LXC::load_config($vmid);
+ my $conf = PVE::LXC::Config->load_config($vmid);
my $snaphash = $conf->{snapshots} || {};
my $res = [];
}
my $running = PVE::LXC::check_running($vmid) ? 1 : 0;
- my $current = { name => 'current', digest => $conf->{digest}, running => $running };
+ my $current = {
+ name => 'current',
+ digest => $conf->{digest},
+ running => $running,
+ description => "You are here!",
+ };
$current->{parent} = $conf->{parent} if defined($conf->{parent});
push @$res, $current;
return $res;
}});
-use Data::Dumper; # fixme: remove
__PACKAGE__->register_method({
name => 'snapshot',
path => '',
additionalProperties => 0,
properties => {
node => get_standard_option('pve-node'),
- vmid => get_standard_option('pve-vmid'),
- snapname => get_standard_option('pve-lxc-snapshot-name'),
+ vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid }),
+ snapname => get_standard_option('pve-snapshot-name'),
# vmstate => {
# optional => 1,
# type => 'boolean',
die "unable to use snapshot name 'current' (reserved name)\n"
if $snapname eq 'current';
+ die "unable to use snapshot name 'vzdump' (reserved name)\n"
+ if $snapname eq 'vzdump';
+
my $realcmd = sub {
PVE::Cluster::log_msg('info', $authuser, "snapshot container $vmid: $snapname");
- PVE::LXC::snapshot_create($vmid, $snapname, $param->{description});
+ PVE::LXC::Config->snapshot_create($vmid, $snapname, 0, $param->{description});
};
- return $rpcenv->fork_worker('pctsnapshot', $vmid, $authuser, $realcmd);
+ return $rpcenv->fork_worker('vzsnapshot', $vmid, $authuser, $realcmd);
}});
__PACKAGE__->register_method({
properties => {
node => get_standard_option('pve-node'),
vmid => get_standard_option('pve-vmid'),
- snapname => get_standard_option('pve-lxc-snapshot-name'),
+ snapname => get_standard_option('pve-snapshot-name'),
force => {
optional => 1,
type => 'boolean',
my $snapname = extract_param($param, 'snapname');
- my $realcmd = sub {
+ my $do_delete = sub {
PVE::Cluster::log_msg('info', $authuser, "delete snapshot VM $vmid: $snapname");
- PVE::LXC::snapshot_delete($vmid, $snapname, $param->{force});
+ PVE::LXC::Config->snapshot_delete($vmid, $snapname, $param->{force});
};
- return $rpcenv->fork_worker('lxcdelsnapshot', $vmid, $authuser, $realcmd);
+ my $realcmd = sub {
+ if ($param->{force}) {
+ $do_delete->();
+ } else {
+ PVE::GuestHelpers::guest_migration_lock($vmid, 10, $do_delete);
+ }
+ };
+
+ return $rpcenv->fork_worker('vzdelsnapshot', $vmid, $authuser, $realcmd);
}});
__PACKAGE__->register_method({
properties => {
vmid => get_standard_option('pve-vmid'),
node => get_standard_option('pve-node'),
- snapname => get_standard_option('pve-lxc-snapshot-name'),
+ snapname => get_standard_option('pve-snapshot-name'),
},
},
returns => {
proxyto => 'node',
description => "Rollback LXC state to specified snapshot.",
permissions => {
- check => ['perm', '/vms/{vmid}', [ 'VM.Snapshot' ]],
+ check => ['perm', '/vms/{vmid}', [ 'VM.Snapshot', 'VM.Snapshot.Rollback' ], any => 1],
},
parameters => {
additionalProperties => 0,
properties => {
node => get_standard_option('pve-node'),
vmid => get_standard_option('pve-vmid'),
- snapname => get_standard_option('pve-lxc-snapshot-name'),
+ snapname => get_standard_option('pve-snapshot-name'),
},
},
returns => {
my $realcmd = sub {
PVE::Cluster::log_msg('info', $authuser, "rollback snapshot LXC $vmid: $snapname");
- PVE::LXC::snapshot_rollback($vmid, $snapname);
+ PVE::LXC::Config->snapshot_rollback($vmid, $snapname);
};
- return $rpcenv->fork_worker('lxcrollback', $vmid, $authuser, $realcmd);
+ my $worker = sub {
+ # hold migration lock, this makes sure that nobody create replication snapshots
+ return PVE::GuestHelpers::guest_migration_lock($vmid, 10, $realcmd);
+ };
+
+ return $rpcenv->fork_worker('vzrollback', $vmid, $authuser, $worker);
}});
__PACKAGE__->register_method({
properties => {
node => get_standard_option('pve-node'),
vmid => get_standard_option('pve-vmid'),
- snapname => get_standard_option('pve-lxc-snapshot-name'),
+ snapname => get_standard_option('pve-snapshot-name'),
description => {
optional => 1,
type => 'string',
my $updatefn = sub {
- my $conf = PVE::LXC::load_config($vmid);
- PVE::LXC::check_lock($conf);
+ my $conf = PVE::LXC::Config->load_config($vmid);
+ PVE::LXC::Config->check_lock($conf);
my $snap = $conf->{snapshots}->{$snapname};
$snap->{description} = $param->{description} if defined($param->{description});
- PVE::LXC::write_config($vmid, $conf, 1);
+ PVE::LXC::Config->write_config($vmid, $conf, 1);
};
- PVE::LXC::lock_container($vmid, 10, $updatefn);
+ PVE::LXC::Config->lock_config($vmid, $updatefn);
return undef;
}});
proxyto => 'node',
description => "Get snapshot configuration",
permissions => {
- check => ['perm', '/vms/{vmid}', [ 'VM.Snapshot' ]],
+ check => ['perm', '/vms/{vmid}', [ 'VM.Snapshot', 'VM.Snapshot.Rollback', 'VM.Audit' ], any => 1],
},
parameters => {
additionalProperties => 0,
properties => {
node => get_standard_option('pve-node'),
vmid => get_standard_option('pve-vmid'),
- snapname => get_standard_option('pve-lxc-snapshot-name'),
+ snapname => get_standard_option('pve-snapshot-name'),
},
},
returns => { type => "object" },
my $snapname = extract_param($param, 'snapname');
- my $conf = PVE::LXC::load_config($vmid);
+ my $conf = PVE::LXC::Config->load_config($vmid);
my $snap = $conf->{snapshots}->{$snapname};