my $restore = extract_param($param, 'restore');
+ if ($restore) {
+ # fixme: limit allowed parameters
+
+ }
+
my $force = extract_param($param, 'force');
if (!($same_container_exists && $restore && $force)) {
my $archive;
if ($ostemplate eq '-') {
- die "archive pipe not implemented\n"
- # $archive = '-';
+ die "pipe requires cli environment\n"
+ if $rpcenv->{type} ne 'cli';
+ die "pipe can only be used with restore tasks\n"
+ if !$restore;
+ $archive = '-';
} else {
$rpcenv->check_volume_access($authuser, $storage_cfg, $vmid, $ostemplate);
$archive = PVE::Storage::abs_filesystem_path($storage_cfg, $ostemplate);
# disable for now, because kernel 3.10.0 does not support it
#$conf->{'lxc.id_map'} = ["u 0 100000 65536", "g 0 100000 65536"];
+ my $check_vmid_usage = sub {
+ if ($force) {
+ die "cant overwrite running container\n"
+ if PVE::LXC::check_running($vmid);
+ } else {
+ PVE::Cluster::check_vmid_unused($vmid);
+ }
+ };
+
my $code = sub {
- my $size = 4*1024*1024; # defaults to 4G
- $size = int($param->{disk}*1024) * 1024 if defined($param->{disk});
- PVE::LXCCreate::create_rootfs($storage_cfg, $storage, $size, $vmid, $conf, $archive, $password);
+ &$check_vmid_usage(); # final check after locking
+
+ PVE::Cluster::check_cfs_quorum();
+
+ PVE::LXCCreate::create_rootfs($storage_cfg, $storage, $param->{disk}, $vmid, $conf,
+ $archive, $password, $restore);
};
my $realcmd = sub { PVE::LXC::lock_container($vmid, 1, $code); };
- return $rpcenv->fork_worker($param->{restore} ? 'vzrestore' : 'vzcreate',
+ &$check_vmid_usage(); # first check before locking
+
+ return $rpcenv->fork_worker($restore ? 'vzrestore' : 'vzcreate',
$vmid, $authuser, $realcmd);
}});
my $storage_cfg = cfs_read_file("storage.cfg");
my $code = sub {
- if (my $volid = $conf->{'pve.volid'}) {
-
- my ($vtype, $name, $owner) = PVE::Storage::parse_volname($storage_cfg, $volid);
- die "got strange volid (containe is not owner!)\n" if $vmid != $owner;
-
- PVE::Storage::vdisk_free($storage_cfg, $volid);
-
- PVE::LXC::destroy_config($vmid);
-
- } else {
- my $cmd = ['lxc-destroy', '-n', $vmid ];
-
- run_command($cmd);
- }
-
+ PVE::LXC::destory_lxc_container($storage_cfg, $vmid, $conf);
PVE::AccessControl::remove_vm_from_pool($vmid);
};
return ($ipv4, $ipv6);
}
+
+sub destory_lxc_container {
+ my ($storage_cfg, $vmid, $conf) = @_;
+
+ if (my $volid = $conf->{'pve.volid'}) {
+
+ my ($vtype, $name, $owner) = PVE::Storage::parse_volname($storage_cfg, $volid);
+ die "got strange volid (containe is not owner!)\n" if $vmid != $owner;
+
+ PVE::Storage::vdisk_free($storage_cfg, $volid);
+
+ destroy_config($vmid);
+
+ } else {
+ my $cmd = ['lxc-destroy', '-n', $vmid ];
+
+ PVE::Tools::run_command($cmd);
+ }
+}
1;
my ($cleanup, $storage_conf, $storage, $vmid, $conf, $archive, $password) = @_;
# note: there is no size limit
+ $conf->{'pve.disksize'} = 0;
my $private = PVE::Storage::get_private_dir($storage_conf, $storage, $vmid);
mkdir($private) || die "unable to create container private dir '$private' - $!\n";
my ($cleanup, $storage_conf, $storage, $size, $vmid, $conf, $archive, $password) = @_;
my $volid = PVE::Storage::vdisk_alloc($storage_conf, $storage, $vmid, 'raw', "vm-$vmid-rootfs.raw", $size);
+ $conf->{'pve.disksize'} = $size/(1024*1024);
push @{$cleanup->{volids}}, $volid;
my $volid = PVE::Storage::vdisk_alloc($storage_conf, $storage, $vmid,
$format, "vm-$vmid-rootfs.$format", $size);
+ $conf->{'pve.disksize'} = $size/(1024*1024);
+
push @{$cleanup->{volids}}, $volid;
my $image_path = PVE::Storage::path($storage_conf, $volid);
}
sub create_rootfs {
- my ($storage_conf, $storage, $size, $vmid, $conf, $archive, $password) = @_;
+ my ($storage_conf, $storage, $disk_size_gb, $vmid, $conf, $archive, $password, $restore) = @_;
+
+ my $config_fn = PVE::LXC::config_file($vmid);
+ if (-f $config_fn) {
+ die "container exists" if !$restore; # just to be sure
+
+ my $old_conf = PVE::LXC::load_config($vmid);
+
+ if (!defined($disk_size_gb) && defined($old_conf->{'pve.disksize'})) {
+ $disk_size_gb = $old_conf->{'pve.disksize'};
+ }
+
+ # destroy old container
+ PVE::LXC::destory_lxc_container($storage_conf, $vmid, $old_conf);
- PVE::LXC::create_config($vmid, $conf);
+ # merge old config?
+
+ PVE::LXC::create_config($vmid, $conf);
+ } else {
+
+ PVE::LXC::create_config($vmid, $conf);
+ }
+
+ my $size = 4*1024*1024; # defaults to 4G
+
+ $size = int($disk_size_gb*1024) * 1024 if defined($disk_size_gb);
+
my $cleanup = { files => [], volids => [] };
eval {
$cmd .= ")";
if ($opts->{stdout}) {
- $self->cmd ($cmd, output => ">&=" . fileno($opts->{stdout}));
+ $self->cmd ($cmd, output => ">&" . fileno($opts->{stdout}));
} else {
$self->cmd ("$cmd >$filename");
}
use lib qw(. ..);
use PVE::SafeSyslog;
+use PVE::Tools qw(extract_param);
use PVE::Cluster;
use PVE::INotify;
use PVE::RPCEnvironment;
exec('lxc-attach', '-n', $param->{vmid});
}});
-
my $cmddef = {
#test => [ __PACKAGE__, 'test', [], {}, sub {} ],
list=> [ 'PVE::API2::LXC', 'vmlist', [], { node => $nodename }, sub {
set => [ 'PVE::API2::LXC', 'update_vm', ['vmid'], { node => $nodename }],
create => [ 'PVE::API2::LXC', 'create_vm', ['vmid', 'ostemplate'], { node => $nodename }, $upid_exit ],
+ restore => [ 'PVE::API2::LXC', 'create_vm', ['vmid', 'ostemplate'], { node => $nodename, restore => 1 }, $upid_exit ],
start => [ 'PVE::API2::LXC', 'vm_start', ['vmid'], { node => $nodename }, $upid_exit],
suspend => [ 'PVE::API2::LXC', 'vm_suspend', ['vmid'], { node => $nodename }, $upid_exit],