]>
git.proxmox.com Git - pve-container.git/blob - src/PVE/API2/LXC/Snapshot.pm
1 package PVE
::API2
::LXC
::Snapshot
;
7 use PVE
::Tools
qw(extract_param run_command);
8 use PVE
::Exception
qw(raise raise_param_exc);
10 use PVE
::Cluster
qw(cfs_read_file);
11 use PVE
::AccessControl
;
15 use PVE
::RPCEnvironment
;
18 use PVE
::JSONSchema
qw(get_standard_option);
19 use base
qw(PVE::RESTHandler);
21 __PACKAGE__-
>register_method({
25 description
=> "List all snapshots.",
27 check
=> ['perm', '/vms/{vmid}', [ 'VM.Audit' ]],
30 protected
=> 1, # lxc pid files are only readable by root
32 additionalProperties
=> 0,
34 vmid
=> get_standard_option
('pve-vmid', { completion
=> \
&PVE
::LXC
::complete_ctid
}),
35 node
=> get_standard_option
('pve-node'),
44 description
=> "Snapshot identifier. Value 'current' identifies the current VM.",
48 description
=> "Snapshot description.",
52 description
=> "Snapshot creation time",
54 renderer
=> 'timestamp',
58 description
=> "Parent snapshot identifier.",
64 links
=> [ { rel
=> 'child', href
=> "{name}" } ],
69 my $vmid = $param->{vmid
};
71 my $conf = PVE
::LXC
::Config-
>load_config($vmid);
72 my $snaphash = $conf->{snapshots
} || {};
76 foreach my $name (keys %$snaphash) {
77 my $d = $snaphash->{$name};
80 snaptime
=> $d->{snaptime
} || 0,
81 description
=> $d->{description
} || '',
83 $item->{parent
} = $d->{parent
} if defined($d->{parent
});
84 $item->{snapstate
} = $d->{snapstate
} if $d->{snapstate
};
88 my $running = PVE
::LXC
::check_running
($vmid) ?
1 : 0;
91 digest
=> $conf->{digest
},
93 description
=> "You are here!",
95 $current->{parent
} = $conf->{parent
} if defined($conf->{parent
});
102 __PACKAGE__-
>register_method({
108 description
=> "Snapshot a container.",
110 check
=> ['perm', '/vms/{vmid}', [ 'VM.Snapshot' ]],
113 additionalProperties
=> 0,
115 node
=> get_standard_option
('pve-node'),
116 vmid
=> get_standard_option
('pve-vmid', { completion
=> \
&PVE
::LXC
::complete_ctid
}),
117 snapname
=> get_standard_option
('pve-snapshot-name'),
121 # description => "Save the vmstate",
126 description
=> "A textual description or comment.",
132 description
=> "the task ID.",
137 my $rpcenv = PVE
::RPCEnvironment
::get
();
139 my $authuser = $rpcenv->get_user();
141 my $node = extract_param
($param, 'node');
143 my $vmid = extract_param
($param, 'vmid');
145 my $snapname = extract_param
($param, 'snapname');
147 die "unable to use snapshot name 'current' (reserved name)\n"
148 if $snapname eq 'current';
150 die "unable to use snapshot name 'vzdump' (reserved name)\n"
151 if $snapname eq 'vzdump';
154 PVE
::Cluster
::log_msg
('info', $authuser, "snapshot container $vmid: $snapname");
155 PVE
::LXC
::Config-
>snapshot_create($vmid, $snapname, 0, $param->{description
});
158 return $rpcenv->fork_worker('vzsnapshot', $vmid, $authuser, $realcmd);
161 __PACKAGE__-
>register_method({
162 name
=> 'delsnapshot',
163 path
=> '{snapname}',
167 description
=> "Delete a LXC snapshot.",
169 check
=> ['perm', '/vms/{vmid}', [ 'VM.Snapshot' ]],
172 additionalProperties
=> 0,
174 node
=> get_standard_option
('pve-node'),
175 vmid
=> get_standard_option
('pve-vmid'),
176 snapname
=> get_standard_option
('pve-snapshot-name'),
180 description
=> "For removal from config file, even if removing disk snapshots fails.",
186 description
=> "the task ID.",
191 my $rpcenv = PVE
::RPCEnvironment
::get
();
193 my $authuser = $rpcenv->get_user();
195 my $node = extract_param
($param, 'node');
197 my $vmid = extract_param
($param, 'vmid');
199 my $snapname = extract_param
($param, 'snapname');
202 PVE
::Cluster
::log_msg
('info', $authuser, "delete snapshot VM $vmid: $snapname");
203 PVE
::LXC
::Config-
>snapshot_delete($vmid, $snapname, $param->{force
});
206 return $rpcenv->fork_worker('vzdelsnapshot', $vmid, $authuser, $realcmd);
209 __PACKAGE__-
>register_method({
210 name
=> 'snapshot_cmd_idx',
211 path
=> '{snapname}',
218 additionalProperties
=> 0,
220 vmid
=> get_standard_option
('pve-vmid'),
221 node
=> get_standard_option
('pve-node'),
222 snapname
=> get_standard_option
('pve-snapshot-name'),
231 links
=> [ { rel
=> 'child', href
=> "{cmd}" } ],
238 push @$res, { cmd
=> 'rollback' };
239 push @$res, { cmd
=> 'config' };
244 __PACKAGE__-
>register_method({
246 path
=> '{snapname}/rollback',
250 description
=> "Rollback LXC state to specified snapshot.",
252 check
=> ['perm', '/vms/{vmid}', [ 'VM.Snapshot', 'VM.Snapshot.Rollback' ], any
=> 1],
255 additionalProperties
=> 0,
257 node
=> get_standard_option
('pve-node'),
258 vmid
=> get_standard_option
('pve-vmid'),
259 snapname
=> get_standard_option
('pve-snapshot-name'),
264 description
=> "the task ID.",
269 my $rpcenv = PVE
::RPCEnvironment
::get
();
271 my $authuser = $rpcenv->get_user();
273 my $node = extract_param
($param, 'node');
275 my $vmid = extract_param
($param, 'vmid');
277 my $snapname = extract_param
($param, 'snapname');
280 PVE
::Cluster
::log_msg
('info', $authuser, "rollback snapshot LXC $vmid: $snapname");
281 PVE
::LXC
::Config-
>snapshot_rollback($vmid, $snapname);
285 # hold migration lock, this makes sure that nobody create replication snapshots
286 return PVE
::GuestHelpers
::guest_migration_lock
($vmid, 10, $realcmd);
289 return $rpcenv->fork_worker('vzrollback', $vmid, $authuser, $worker);
292 __PACKAGE__-
>register_method({
293 name
=> 'update_snapshot_config',
294 path
=> '{snapname}/config',
298 description
=> "Update snapshot metadata.",
300 check
=> ['perm', '/vms/{vmid}', [ 'VM.Snapshot' ]],
303 additionalProperties
=> 0,
305 node
=> get_standard_option
('pve-node'),
306 vmid
=> get_standard_option
('pve-vmid'),
307 snapname
=> get_standard_option
('pve-snapshot-name'),
311 description
=> "A textual description or comment.",
315 returns
=> { type
=> 'null' },
319 my $rpcenv = PVE
::RPCEnvironment
::get
();
321 my $authuser = $rpcenv->get_user();
323 my $vmid = extract_param
($param, 'vmid');
325 my $snapname = extract_param
($param, 'snapname');
327 return undef if !defined($param->{description
});
331 my $conf = PVE
::LXC
::Config-
>load_config($vmid);
332 PVE
::LXC
::Config-
>check_lock($conf);
334 my $snap = $conf->{snapshots
}->{$snapname};
336 die "snapshot '$snapname' does not exist\n" if !defined($snap);
338 $snap->{description
} = $param->{description
} if defined($param->{description
});
340 PVE
::LXC
::Config-
>write_config($vmid, $conf, 1);
343 PVE
::LXC
::Config-
>lock_config($vmid, $updatefn);
348 __PACKAGE__-
>register_method({
349 name
=> 'get_snapshot_config',
350 path
=> '{snapname}/config',
353 description
=> "Get snapshot configuration",
355 check
=> ['perm', '/vms/{vmid}', [ 'VM.Snapshot', 'VM.Snapshot.Rollback' ], any
=> 1],
358 additionalProperties
=> 0,
360 node
=> get_standard_option
('pve-node'),
361 vmid
=> get_standard_option
('pve-vmid'),
362 snapname
=> get_standard_option
('pve-snapshot-name'),
365 returns
=> { type
=> "object" },
369 my $rpcenv = PVE
::RPCEnvironment
::get
();
371 my $authuser = $rpcenv->get_user();
373 my $vmid = extract_param
($param, 'vmid');
375 my $snapname = extract_param
($param, 'snapname');
377 my $conf = PVE
::LXC
::Config-
>load_config($vmid);
379 my $snap = $conf->{snapshots
}->{$snapname};
381 die "snapshot '$snapname' does not exist\n" if !defined($snap);