]> git.proxmox.com Git - pve-container.git/commitdiff
fix: #1075: Correctly restore CT templates form backup
authorChristian Ebner <c.ebner@proxmox.com>
Wed, 17 Apr 2019 14:38:28 +0000 (16:38 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Thu, 25 Apr 2019 06:41:21 +0000 (06:41 +0000)
Restoring a backup from a CT template wrongly resulted in a CT with the template
flag set in the config.
This makes sure the CT template backup gets restored to a CT and only if the
storage supports templates, the resulting CT is converted to a template.
Otherwise the backup restores simply to a CT.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
src/PVE/API2/LXC.pm
src/PVE/LXC/Create.pm

index 5a8a9c9686389f4c018af761f87e2f74106565a9..cf14d75d93355137ae6672d94566389dca1567f2 100644 (file)
@@ -335,6 +335,7 @@ __PACKAGE__->register_method({
 
        my $code = sub {
            my $old_conf = PVE::LXC::Config->load_config($vmid);
+           my $was_template;
 
            my $vollist = [];
            eval {
@@ -344,6 +345,7 @@ __PACKAGE__->register_method({
                    if ($is_root && $archive ne '-') {
                        my $orig_conf;
                        ($orig_conf, $orig_mp_param) = PVE::LXC::Create::recover_config($archive);
+                       $was_template = delete $orig_conf->{template};
                        # When we're root call 'restore_configuration' with ristricted=0,
                        # causing it to restore the raw lxc entries, among which there may be
                        # 'lxc.idmap' entries. We need to make sure that the extracted contents
@@ -423,6 +425,17 @@ __PACKAGE__->register_method({
                foreach my $mp (keys %$delayed_mp_param) {
                    $conf->{$mp} = $delayed_mp_param->{$mp};
                }
+               # If the template flag was set, we try to convert again to template after restore
+               if ($was_template) {
+                   print STDERR "Convert restored container to template...\n";
+                   if (my $err = check_storage_supports_templates($conf)) {
+                       warn $err;
+                       warn "Leave restored backup as container instead of converting to template.\n"
+                   } else {
+                       PVE::LXC::template_create($vmid, $conf);
+                       $conf->{template} = 1;
+                   }
+               }
                PVE::LXC::Config->write_config($vmid, $conf);
            };
            if (my $err = $@) {
@@ -443,6 +456,22 @@ __PACKAGE__->register_method({
        return $rpcenv->fork_worker($workername, $vmid, $authuser, $realcmd);
     }});
 
+sub check_storage_supports_templates {
+    my ($conf) = @_;
+
+    my $scfg = PVE::Storage::config();
+    eval {
+       PVE::LXC::Config->foreach_mountpoint($conf, sub {
+           my ($ms, $mp) = @_;
+
+           my ($sid) = PVE::Storage::parse_volume_id($mp->{volume}, 0);
+           die "Warning: Directory storage '$sid' does not support container templates!\n"
+               if $scfg->{ids}->{$sid}->{path};
+       });
+    };
+    return $@
+}
+
 __PACKAGE__->register_method({
     name => 'vmdiridx',
     path => '{vmid}',
@@ -1177,14 +1206,9 @@ __PACKAGE__->register_method({
            die "you can't convert a CT to template if the CT is running\n"
                if PVE::LXC::check_running($vmid);
 
-           my $scfg = PVE::Storage::config();
-           PVE::LXC::Config->foreach_mountpoint($conf, sub {
-               my ($ms, $mp) = @_;
-
-               my ($sid) =PVE::Storage::parse_volume_id($mp->{volume}, 0);
-               die "Directory storage '$sid' does not support container templates!\n"
-                   if $scfg->{ids}->{$sid}->{path};
-           });
+           if (my $err = check_storage_supports_templates($conf)) {
+               die $err;
+           }
 
            my $realcmd = sub {
                PVE::LXC::template_create($vmid, $conf);
index c0ef1d7c78b64aa847f63bb846ff1e2ca7fcdb05..ed79611eef2d808773f76b2d86e4334f8d5be0f9 100644 (file)
@@ -139,7 +139,6 @@ sub recover_config {
        $conf = PVE::LXC::Config::parse_pct_config("/lxc/0.conf" , $raw);
 
        delete $conf->{snapshots};
-       delete $conf->{template}; # restored CT is never a template
 
        PVE::LXC::Config->foreach_mountpoint($conf, sub {
            my ($ms, $mountpoint) = @_;
@@ -174,6 +173,9 @@ sub restore_configuration {
            next if $key eq 'digest' || $key eq 'rootfs' || $key eq 'snapshots' || $key eq 'unprivileged' || $key eq 'parent';
            next if $key =~ /^mp\d+$/; # don't recover mountpoints
            next if $key =~ /^unused\d+$/; # don't recover unused disks
+           # we know if it was a template in the restore API call and check if the target
+           # storage supports creating a template there
+           next if $key =~ /^template$/;
            if ($restricted && $key eq 'lxc') {
                warn "skipping custom lxc options, restore manually as root:\n";
                warn "--------------------------------\n";