use PVE::RPCEnvironment;
use PVE::LXC;
use PVE::LXC::Create;
+use PVE::LXC::Migrate;
use PVE::API2::LXC::Config;
use PVE::API2::LXC::Status;
use PVE::API2::LXC::Snapshot;
subclass => "PVE::API2::Firewall::CT",
path => '{vmid}/firewall',
});
-
-my $alloc_rootfs = sub {
- my ($storage_conf, $storage, $disk_size_gb, $vmid) = @_;
-
- my $volid;
-
- my $size = 4*1024*1024; # defaults to 4G
-
- $size = int($disk_size_gb*1024) * 1024 if defined($disk_size_gb);
-
- eval {
- my $scfg = PVE::Storage::storage_config($storage_conf, $storage);
- # fixme: use better naming ct-$vmid-disk-X.raw?
-
- if ($scfg->{type} eq 'dir' || $scfg->{type} eq 'nfs') {
- if ($size > 0) {
- $volid = PVE::Storage::vdisk_alloc($storage_conf, $storage, $vmid, 'raw',
- undef, $size);
- } else {
- $volid = PVE::Storage::vdisk_alloc($storage_conf, $storage, $vmid, 'subvol',
- undef, 0);
- }
- } elsif ($scfg->{type} eq 'zfspool') {
-
- $volid = PVE::Storage::vdisk_alloc($storage_conf, $storage, $vmid, 'subvol',
- undef, $size);
- } elsif ($scfg->{type} eq 'drbd') {
-
- $volid = PVE::Storage::vdisk_alloc($storage_conf, $storage, $vmid, 'raw', undef, $size);
-
- } elsif ($scfg->{type} eq 'rbd') {
-
- die "krbd option must be enabled on storage type '$scfg->{type}'\n" if !$scfg->{krbd};
- $volid = PVE::Storage::vdisk_alloc($storage_conf, $storage, $vmid, 'raw', undef, $size);
-
- } else {
- die "unable to create containers on storage type '$scfg->{type}'\n";
- }
- };
- if (my $err = $@) {
- # cleanup
- eval { PVE::Storage::vdisk_free($storage_conf, $volid) if $volid; };
- warn $@ if $@;
- die $err;
- }
-
- return $volid;
-};
__PACKAGE__->register_method({
name => 'vmlist',
proxyto => 'node',
parameters => {
additionalProperties => 0,
- properties => PVE::LXC::json_config_properties_no_rootfs({
+ properties => PVE::LXC::json_config_properties({
node => get_standard_option('pve-node'),
- vmid => get_standard_option('pve-vmid'),
+ vmid => get_standard_option('pve-vmid', { completion => \&PVE::Cluster::complete_next_vmid }),
ostemplate => {
description => "The OS template or backup file.",
type => 'string',
maxLength => 255,
+ completion => \&PVE::LXC::complete_os_templates,
},
password => {
optional => 1,
minLength => 5,
},
storage => get_standard_option('pve-storage-id', {
- description => "Target storage.",
+ description => "Default Storage.",
default => 'local',
optional => 1,
}),
- size => {
- optional => 1,
- type => 'number',
- description => "Amount of disk space for the VM in GB. A zero indicates no limits.",
- minimum => 0,
- default => 4,
- },
force => {
optional => 1,
type => 'boolean',
if (!($same_container_exists && $restore && $force)) {
PVE::Cluster::check_vmid_unused($vmid);
+ } else {
+ my $conf = PVE::LXC::load_config($vmid);
+ PVE::LXC::check_protection($conf, "unable to restore CT $vmid");
}
my $password = extract_param($param, 'password');
- my $disksize = extract_param($param, 'size');
-
my $storage = extract_param($param, 'storage') // 'local';
my $storage_cfg = cfs_read_file("storage.cfg");
if $rpcenv->{type} ne 'cli';
die "pipe can only be used with restore tasks\n"
if !$restore;
- die "pipe requires --size parameter\n"
- if !defined($disksize);
$archive = '-';
+ die "restore from pipe requires rootfs parameter\n" if !defined($param->{rootfs});
} else {
$rpcenv->check_volume_access($authuser, $storage_cfg, $vmid, $ostemplate);
$archive = PVE::Storage::abs_filesystem_path($storage_cfg, $ostemplate);
my $conf = {};
- PVE::LXC::update_pct_config($vmid, $conf, 0, $param);
+ my $no_disk_param = {};
+ foreach my $opt (keys %$param) {
+ my $value = $param->{$opt};
+ if ($opt eq 'rootfs' || $opt =~ m/^mp\d+$/) {
+ # allow to use simple numbers (add default storage in that case)
+ $param->{$opt} = "$storage:$value" if $value =~ m/^\d+(\.\d+)?$/;
+ } else {
+ $no_disk_param->{$opt} = $value;
+ }
+ }
+ PVE::LXC::update_pct_config($vmid, $conf, 0, $no_disk_param);
my $check_vmid_usage = sub {
if ($force) {
- die "cant overwrite running container\n"
+ die "can't overwrite running container\n"
if PVE::LXC::check_running($vmid);
} else {
PVE::Cluster::check_vmid_unused($vmid);
&$check_vmid_usage(); # final check after locking
PVE::Cluster::check_cfs_quorum();
-
- my $volid;
+ my $vollist = [];
eval {
- if (!defined($disksize)) {
+ if (!defined($param->{rootfs})) {
if ($restore) {
- (undef, $disksize) = PVE::LXC::Create::recover_config($archive);
- die "unable to detect disk size - please specify with --size\n"
+ my (undef, $disksize) = PVE::LXC::Create::recover_config($archive);
+ $disksize /= 1024 * 1024 * 1024; # create_disks expects GB as unit size
+ die "unable to detect disk size - please specify rootfs (size)\n"
if !$disksize;
+ $param->{rootfs} = "$storage:$disksize";
} else {
- $disksize = 4;
+ $param->{rootfs} = "$storage:4"; # defaults to 4GB
}
}
- $volid = &$alloc_rootfs($storage_cfg, $storage, $disksize, $vmid);
- PVE::LXC::Create::create_rootfs($storage_cfg, $storage, $volid, $vmid, $conf,
- $archive, $password, $restore);
-
- $conf->{rootfs} = PVE::LXC::print_ct_mountpoint({volume => $volid, size => $disksize });
+ $vollist = PVE::LXC::create_disks($storage_cfg, $vmid, $param, $conf);
+ PVE::LXC::Create::create_rootfs($storage_cfg, $vmid, $conf, $archive, $password, $restore);
# set some defaults
$conf->{hostname} ||= "CT$vmid";
$conf->{memory} ||= 512;
$conf->{swap} //= 512;
-
PVE::LXC::create_config($vmid, $conf);
};
if (my $err = $@) {
- eval { PVE::Storage::vdisk_free($storage_cfg, $volid) if $volid; };
- warn $@ if $@;
+ PVE::LXC::destroy_disks($storage_cfg, $vollist);
PVE::LXC::destroy_config($vmid);
die $err;
}
additionalProperties => 0,
properties => {
node => get_standard_option('pve-node'),
- vmid => get_standard_option('pve-vmid'),
+ vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid_stopped }),
},
},
returns => {
my $storage_cfg = cfs_read_file("storage.cfg");
+ PVE::LXC::check_protection($conf, "can't remove CT $vmid");
+
+ die "unable to remove CT $vmid - used in HA resources\n"
+ if PVE::HA::Config::vm_is_ha_managed($vmid);
+
my $code = sub {
# reload config after lock
$conf = PVE::LXC::load_config($vmid);
my $remcmd = $remip ?
['/usr/bin/ssh', '-t', $remip] : [];
- my $conf = PVE::LXC::load_config($vmid);
+ my $conf = PVE::LXC::load_config($vmid, $node);
my $concmd = PVE::LXC::get_console_command($vmid, $conf);
my $shcmd = [ '/usr/bin/dtach', '-A',
my $permissions = 'VM.Console';
my $conf = PVE::LXC::load_config($vmid);
+
+ die "CT $vmid not running\n" if !PVE::LXC::check_running($vmid);
+
my $concmd = PVE::LXC::get_console_command($vmid, $conf);
my $shcmd = ['/usr/bin/dtach', '-A',
additionalProperties => 0,
properties => {
node => get_standard_option('pve-node'),
- vmid => get_standard_option('pve-vmid'),
- target => get_standard_option('pve-node', { description => "Target node." }),
+ vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid }),
+ target => get_standard_option('pve-node', {
+ description => "Target node.",
+ completion => \&PVE::Cluster::complete_migration_target,
+ }),
online => {
type => 'boolean',
description => "Use online/live migration.",
# try to detect errors early
if (PVE::LXC::check_running($vmid)) {
- die "cant migrate running container without --online\n"
+ die "can't migrate running container without --online\n"
if !$param->{online};
}
my $realcmd = sub {
my $upid = shift;
- # fixme: implement lxc container migration
- die "lxc container migration not implemented\n";
+ PVE::LXC::Migrate->migrate($target, $targetip, $vmid, $param);
return;
};
additionalProperties => 0,
properties => {
node => get_standard_option('pve-node'),
- vmid => get_standard_option('pve-vmid'),
+ vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid_stopped }),
},
},
returns => { type => 'null'},