]> git.proxmox.com Git - pve-container.git/commitdiff
implement restore command
authorDietmar Maurer <dietmar@proxmox.com>
Wed, 29 Apr 2015 09:59:10 +0000 (11:59 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Wed, 29 Apr 2015 09:59:10 +0000 (11:59 +0200)
src/PVE/API2/LXC.pm
src/PVE/LXC.pm
src/PVE/LXCCreate.pm
src/PVE/VZDump/LXC.pm
src/pct

index b1aaf2213d9d276202ee4c99166bed492968f8b0..e22843c1d05bde27bea90581e499af5a4b39aaf1 100644 (file)
@@ -171,6 +171,11 @@ __PACKAGE__->register_method({
 
        my $restore = extract_param($param, 'restore');
 
+       if ($restore) {
+           # fixme: limit allowed parameters
+
+       }
+       
        my $force = extract_param($param, 'force');
 
        if (!($same_container_exists && $restore && $force)) {
@@ -217,8 +222,11 @@ __PACKAGE__->register_method({
        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);
@@ -246,16 +254,30 @@ __PACKAGE__->register_method({
        # 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);
 
     }});
@@ -566,21 +588,7 @@ __PACKAGE__->register_method({
        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);
        };
 
index 9f55803c8c29aafa703694fb0c8a47b2d79415a7..6afe69040add023d36d1d47dea1a3d02b2c32075 100644 (file)
@@ -1030,5 +1030,24 @@ sub get_primary_ips {
     
     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;
index 9b6d908935b4d1a8da598d5dfb33a6ded4196cf2..80786ab859a0c198da4afe5504e99e31d49480f7 100644 (file)
@@ -75,6 +75,7 @@ sub create_rootfs_dir {
     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";
@@ -90,6 +91,7 @@ sub create_rootfs_dir_loop {
     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;
 
@@ -142,6 +144,8 @@ sub create_rootfs_dir_qemu {
     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);
@@ -185,10 +189,34 @@ sub create_rootfs_dir_qemu {
 }
 
 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 {
index 1b909fa689dcb4b8403ab066e198bb103ded3a35..ceff32413604d7d1bc25f2f2c32f22c6ca5697a0 100644 (file)
@@ -262,7 +262,7 @@ sub archive {
     $cmd .= ")";
 
     if ($opts->{stdout}) {
-       $self->cmd ($cmd, output => ">&=" . fileno($opts->{stdout}));
+       $self->cmd ($cmd, output => ">&" . fileno($opts->{stdout}));
     } else {
        $self->cmd ("$cmd >$filename");
     }
diff --git a/src/pct b/src/pct
index 6307ce4c6be34b83991763cc6c3a4bca249291e8..5d5f9face6ba32bdbe689ffb4fcfe2c0e817a846 100755 (executable)
--- a/src/pct
+++ b/src/pct
@@ -5,6 +5,7 @@ use warnings;
 use lib qw(. ..);
 
 use PVE::SafeSyslog;
+use PVE::Tools qw(extract_param);
 use PVE::Cluster;
 use PVE::INotify;
 use PVE::RPCEnvironment;
@@ -81,7 +82,6 @@ __PACKAGE__->register_method ({
        exec('lxc-attach', '-n',  $param->{vmid});
     }});
 
-
 my $cmddef = {
     #test => [ __PACKAGE__, 'test', [], {}, sub {} ],
     list=> [ 'PVE::API2::LXC', 'vmlist', [], { node => $nodename }, sub {
@@ -108,6 +108,7 @@ my $cmddef = {
     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],