[pve-devel] [PATCH container 2/4] Rework snapshot code, has_feature

Fabian Grünbichler f.gruenbichler at proxmox.com
Wed Mar 2 14:03:50 CET 2016


Move snapshot_create, snapshot_delete and snapshot_rollback
into abstract pve-common/src/PVE/AbstractConfig.pm,
splitting LXC-specific parts into __snapshot_XX methods in
src/PVE/LXC/Config.pm.

check_freeze_needed, snapshot_prepare and snapshot_commit
are downgraded to private __snapshot_XX methods (in
PVE::AbstractConfig and PVE::LXC::Config).

has_feature is made an implementation of the abstract
has_feature, and thus moves into src/PVE/LXC/Config.pm
---
 src/PVE/API2/LXC.pm          |   2 +-
 src/PVE/API2/LXC/Snapshot.pm |   6 +-
 src/PVE/LXC.pm               | 370 -------------------------------------------
 src/PVE/LXC/Config.pm        | 122 ++++++++++++++
 src/PVE/VZDump/LXC.pm        |   8 +-
 src/test/snapshot-test.pm    |  41 ++---
 6 files changed, 152 insertions(+), 397 deletions(-)

diff --git a/src/PVE/API2/LXC.pm b/src/PVE/API2/LXC.pm
index 5e98792..428f2c1 100644
--- a/src/PVE/API2/LXC.pm
+++ b/src/PVE/API2/LXC.pm
@@ -882,7 +882,7 @@ __PACKAGE__->register_method({
 	my $storage_cfg = PVE::Storage::config();
 	#Maybe include later
 	#my $nodelist = PVE::LXC::shared_nodes($conf, $storage_cfg);
-	my $hasFeature = PVE::LXC::has_feature($feature, $conf, $storage_cfg, $snapname);
+	my $hasFeature = PVE::LXC::Config->has_feature($feature, $conf, $storage_cfg, $snapname);
 
 	return {
 	    hasFeature => $hasFeature,
diff --git a/src/PVE/API2/LXC/Snapshot.pm b/src/PVE/API2/LXC/Snapshot.pm
index 90c187e..9537486 100644
--- a/src/PVE/API2/LXC/Snapshot.pm
+++ b/src/PVE/API2/LXC/Snapshot.pm
@@ -128,7 +128,7 @@ __PACKAGE__->register_method({
 
 	my $realcmd = sub {
 	    PVE::Cluster::log_msg('info', $authuser, "snapshot container $vmid: $snapname");
-	    PVE::LXC::snapshot_create($vmid, $snapname, 0, $param->{description});
+	    PVE::LXC::Config->snapshot_create($vmid, $snapname, 0, $param->{description});
 	};
 
 	return $rpcenv->fork_worker('pctsnapshot', $vmid, $authuser, $realcmd);
@@ -176,7 +176,7 @@ __PACKAGE__->register_method({
 
 	my $realcmd = sub {
 	    PVE::Cluster::log_msg('info', $authuser, "delete snapshot VM $vmid: $snapname");
-	    PVE::LXC::snapshot_delete($vmid, $snapname, $param->{force});
+	    PVE::LXC::Config->snapshot_delete($vmid, $snapname, $param->{force});
 	};
 
 	return $rpcenv->fork_worker('lxcdelsnapshot', $vmid, $authuser, $realcmd);
@@ -254,7 +254,7 @@ __PACKAGE__->register_method({
 
 	my $realcmd = sub {
 	    PVE::Cluster::log_msg('info', $authuser, "rollback snapshot LXC $vmid: $snapname");
-	    PVE::LXC::snapshot_rollback($vmid, $snapname);
+	    PVE::LXC::Config->snapshot_rollback($vmid, $snapname);
 	};
 
 	return $rpcenv->fork_worker('lxcrollback', $vmid, $authuser, $realcmd);
diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm
index 8f90bad..0144861 100644
--- a/src/PVE/LXC.pm
+++ b/src/PVE/LXC.pm
@@ -1661,140 +1661,6 @@ sub update_ipconfig {
 
 }
 
-# Internal snapshots
-
-# NOTE: Snapshot create/delete involves several non-atomic
-# actions, and can take a long time.
-# So we try to avoid locking the file and use the 'lock' variable
-# inside the config file instead.
-
-my $snapshot_copy_config = sub {
-    my ($source, $dest) = @_;
-
-    foreach my $k (keys %$source) {
-	next if $k eq 'snapshots';
-	next if $k eq 'snapstate';
-	next if $k eq 'snaptime';
-	next if $k eq 'vmstate';
-	next if $k eq 'lock';
-	next if $k eq 'digest';
-	next if $k eq 'description';
-	next if $k =~ m/^unused\d+$/;
-
-	$dest->{$k} = $source->{$k};
-    }
-};
-
-my $snapshot_apply_config = sub {
-    my ($conf, $snap) = @_;
-
-    # copy snapshot list
-    my $newconf = {
-	snapshots => $conf->{snapshots},
-    };
-
-    # keep description and list of unused disks
-    foreach my $k (keys %$conf) {
-	next if !($k =~ m/^unused\d+$/ || $k eq 'description');
-	$newconf->{$k} = $conf->{$k};
-    }
-
-    &$snapshot_copy_config($snap, $newconf);
-
-    return $newconf;
-};
-
-sub snapshot_save_vmstate {
-    die "implement me - snapshot_save_vmstate\n";
-}
-
-sub snapshot_prepare {
-    my ($vmid, $snapname, $save_vmstate, $comment) = @_;
-
-    my $snap;
-
-    my $updatefn =  sub {
-
-	my $conf = PVE::LXC::Config->load_config($vmid);
-
-	die "you can't take a snapshot if it's a template\n"
-	    if PVE::LXC::Config->is_template($conf);
-
-	PVE::LXC::Config->check_lock($conf);
-
-	$conf->{lock} = 'snapshot';
-
-	die "snapshot name '$snapname' already used\n"
-	    if defined($conf->{snapshots}->{$snapname});
-
-	my $storecfg = PVE::Storage::config();
-	die "snapshot feature is not available\n"
-	    if !has_feature('snapshot', $conf, $storecfg, undef, undef, $snapname eq 'vzdump');
-
-	$snap = $conf->{snapshots}->{$snapname} = {};
-
-	if ($save_vmstate && check_running($vmid)) {
-	    snapshot_save_vmstate($vmid, $conf, $snapname, $storecfg);
-	}
-
-	&$snapshot_copy_config($conf, $snap);
-
-	$snap->{snapstate} = "prepare";
-	$snap->{snaptime} = time();
-	$snap->{description} = $comment if $comment;
-
-	PVE::LXC::Config->write_config($vmid, $conf);
-    };
-
-    PVE::LXC::Config->lock_config($vmid, $updatefn);
-
-    return $snap;
-}
-
-sub snapshot_commit {
-    my ($vmid, $snapname) = @_;
-
-    my $updatefn = sub {
-
-	my $conf = PVE::LXC::Config->load_config($vmid);
-
-	die "missing snapshot lock\n"
-	    if !($conf->{lock} && $conf->{lock} eq 'snapshot');
-
-	my $snap = $conf->{snapshots}->{$snapname};
-	die "snapshot '$snapname' does not exist\n" if !defined($snap);
-
-	die "wrong snapshot state\n"
-	    if !($snap->{snapstate} && $snap->{snapstate} eq "prepare");
-
-	delete $snap->{snapstate};
-	delete $conf->{lock};
-
-	$conf->{parent} = $snapname;
-
-	PVE::LXC::Config->write_config($vmid, $conf);
-    };
-
-    PVE::LXC::Config->lock_config($vmid, $updatefn);
-}
-
-sub has_feature {
-    my ($feature, $conf, $storecfg, $snapname, $running, $backup_only) = @_;
-    
-    my $err;
-
-    foreach_mountpoint($conf, sub {
-	my ($ms, $mountpoint) = @_;
-
-	return if $err; # skip further test
-	return if $backup_only && $ms ne 'rootfs' && !$mountpoint->{backup};
-	
-	$err = 1 if !PVE::Storage::volume_has_feature($storecfg, $feature, $mountpoint->{volume}, $snapname, $running);
-    });
-
-    return $err ? 0 : 1;
-}
-
 my $enter_namespace = sub {
     my ($vmid, $pid, $which, $type) = @_;
     sysopen my $fd, "/proc/$pid/ns/$which", O_RDONLY
@@ -1864,242 +1730,6 @@ sub sync_container_namespace {
     die "failed to sync container namespace\n" if $? != 0;
 }
 
-sub check_freeze_needed {
-    my ($vmid, $config, $save_vmstate) = @_;
-
-    my $ret = check_running($vmid);
-    return ($ret, $ret);
-}
-
-sub snapshot_create {
-    my ($vmid, $snapname, $save_vmstate, $comment) = @_;
-
-    my $snap = snapshot_prepare($vmid, $snapname, $save_vmstate, $comment);
-
-    $save_vmstate = 0 if !$snap->{vmstate};
-
-    my $conf = PVE::LXC::Config->load_config($vmid);
-
-    my ($running, $freezefs) = check_freeze_needed($vmid, $conf, $snap->{vmstate});
-
-    my $drivehash = {};
-
-    eval {
-	if ($freezefs) {
-	    PVE::Tools::run_command(['/usr/bin/lxc-freeze', '-n', $vmid]);
-	    sync_container_namespace($vmid);
-	}
-
-	my $storecfg = PVE::Storage::config();
-	foreach_mountpoint($conf, sub {
-	    my ($ms, $mountpoint) = @_;
-
-	    return if $snapname eq 'vzdump' && $ms ne 'rootfs' && !$mountpoint->{backup};
-	    PVE::Storage::volume_snapshot($storecfg, $mountpoint->{volume}, $snapname);
-	    $drivehash->{$ms} = 1;
-	});
-    };
-    my $err = $@;
-    
-    if ($running) {
-	if ($freezefs) {
-	    eval { PVE::Tools::run_command(['/usr/bin/lxc-unfreeze', '-n', $vmid]); };
-	    warn $@ if $@;
-	}
-    }
-    
-    if ($err) {
-	warn "snapshot create failed: starting cleanup\n";
-	eval { snapshot_delete($vmid, $snapname, 1, $drivehash); };
-	warn "$@" if $@;
-	die "$err\n";
-    }
-
-    snapshot_commit($vmid, $snapname);
-}
-
-# Note: $drivehash is only set when called from snapshot_create.
-sub snapshot_delete {
-    my ($vmid, $snapname, $force, $drivehash) = @_;
-
-    my $prepare = 1;
-
-    my $snap;
-    my $unused = [];
-
-    my $unlink_parent = sub {
-	my ($confref, $new_parent) = @_;
-
-	if ($confref->{parent} && $confref->{parent} eq $snapname) {
-	    if ($new_parent) {
-		$confref->{parent} = $new_parent;
-	    } else {
-		delete $confref->{parent};
-	    }
-	}
-    };
-
-    my $updatefn =  sub {
-	my ($remove_drive) = @_;
-
-	my $conf = PVE::LXC::Config->load_config($vmid);
-
-	if (!$drivehash) {
-	    PVE::LXC::Config->check_lock($conf);
-	    die "you can't delete a snapshot if vm is a template\n"
-		if PVE::LXC::Config->is_template($conf);
-	}
-
-	$snap = $conf->{snapshots}->{$snapname};
-
-	die "snapshot '$snapname' does not exist\n" if !defined($snap);
-
-	# remove parent refs
-	if (!$prepare) {
-	    &$unlink_parent($conf, $snap->{parent});
-	    foreach my $sn (keys %{$conf->{snapshots}}) {
-		next if $sn eq $snapname;
-		&$unlink_parent($conf->{snapshots}->{$sn}, $snap->{parent});
-	    }
-	}
-
-	if ($remove_drive) {
-	    if ($remove_drive eq 'vmstate') {
-		die "implement me - saving vmstate\n";
-	    } else {
-		my $value = $snap->{$remove_drive};
-		my $mountpoint = $remove_drive eq 'rootfs' ? parse_ct_rootfs($value, 1) : parse_ct_mountpoint($value, 1);
-		delete $snap->{$remove_drive};
-		add_unused_volume($snap, $mountpoint->{volume});
-	    }
-	}
-
-	if ($prepare) {
-	    $snap->{snapstate} = 'delete';
-	} else {
-	    delete $conf->{snapshots}->{$snapname};
-	    delete $conf->{lock} if $drivehash;
-	    foreach my $volid (@$unused) {
-		add_unused_volume($conf, $volid);
-	    }
-	}
-
-	PVE::LXC::Config->write_config($vmid, $conf);
-    };
-
-    PVE::LXC::Config->lock_config($vmid, $updatefn);
-
-    # now remove vmstate file
-    # never set for LXC!
-    my $storecfg = PVE::Storage::config();
-
-    if ($snap->{vmstate}) {
-	die "implement me - saving vmstate\n";
-    };
-
-    # now remove all volume snapshots
-    foreach_mountpoint($snap, sub {
-	my ($ms, $mountpoint) = @_;
-
-	return if $snapname eq 'vzdump' && $ms ne 'rootfs' && !$mountpoint->{backup};
-	if (!$drivehash || $drivehash->{$ms}) {
-	    eval { PVE::Storage::volume_snapshot_delete($storecfg, $mountpoint->{volume}, $snapname); };
-	    if (my $err = $@) {
-		die $err if !$force;
-		warn $err;
-	    }
-	}
-
-	# save changes (remove mp from snapshot)
-	PVE::LXC::Config->lock_config($vmid, $updatefn, $ms) if !$force;
-	push @$unused, $mountpoint->{volume};
-    });
-
-    # now cleanup config
-    $prepare = 0;
-    PVE::LXC::Config->lock_config($vmid, $updatefn);
-}
-
-sub snapshot_rollback {
-    my ($vmid, $snapname) = @_;
-
-    my $prepare = 1;
-
-    my $storecfg = PVE::Storage::config();
-
-    my $conf = PVE::LXC::Config->load_config($vmid);
-
-    my $get_snapshot_config = sub {
-
-	die "you can't rollback if vm is a template\n" if PVE::LXC::Config->is_template($conf);
-
-	my $res = $conf->{snapshots}->{$snapname};
-
-	die "snapshot '$snapname' does not exist\n" if !defined($res);
-
-	return $res;
-    };
-
-    my $snap = &$get_snapshot_config();
-
-    foreach_mountpoint($snap, sub {
-	my ($ms, $mountpoint) = @_;
-
-	PVE::Storage::volume_rollback_is_possible($storecfg, $mountpoint->{volume}, $snapname);
-    });
-
-    my $updatefn = sub {
-
-	$conf = PVE::LXC::Config->load_config($vmid);
-
-	$snap = &$get_snapshot_config();
-
-	die "unable to rollback to incomplete snapshot (snapstate = $snap->{snapstate})\n"
-	    if $snap->{snapstate};
-
-	if ($prepare) {
-	    PVE::LXC::Config->check_lock($conf);
-	    PVE::Tools::run_command(['/usr/bin/lxc-stop', '-n', $vmid, '--kill'])
-		if check_running($vmid);
-	}
-
-	die "unable to rollback vm $vmid: vm is running\n"
-	    if check_running($vmid);
-
-	if ($prepare) {
-	    $conf->{lock} = 'rollback';
-	} else {
-	    die "got wrong lock\n" if !($conf->{lock} && $conf->{lock} eq 'rollback');
-	    delete $conf->{lock};
-	}
-
-	my $forcemachine;
-
-	if (!$prepare) {
-	    # copy snapshot config to current config
-	    $conf = &$snapshot_apply_config($conf, $snap);
-	    $conf->{parent} = $snapname;
-	}
-
-	PVE::LXC::Config->write_config($vmid, $conf);
-
-	if (!$prepare && $snap->{vmstate}) {
-	    die "implement me - save vmstate\n";
-	}
-    };
-
-    PVE::LXC::Config->lock_config($vmid, $updatefn);
-
-    foreach_mountpoint($snap, sub {
-	my ($ms, $mountpoint) = @_;
-
-	PVE::Storage::volume_snapshot_rollback($storecfg, $mountpoint->{volume}, $snapname);
-    });
-
-    $prepare = 0;
-    PVE::LXC::Config->lock_config($vmid, $updatefn);
-}
-
 sub template_create {
     my ($vmid, $conf) = @_;
 
diff --git a/src/PVE/LXC/Config.pm b/src/PVE/LXC/Config.pm
index f37586a..f041450 100644
--- a/src/PVE/LXC/Config.pm
+++ b/src/PVE/LXC/Config.pm
@@ -25,6 +25,12 @@ sub guest_type {
     return "CT";
 }
 
+sub __config_max_unused_disks {
+    my ($class) = @_;
+
+    return $MAX_UNUSED_DISKS;
+}
+
 sub config_file_lock {
     my ($class, $vmid) = @_;
 
@@ -38,6 +44,122 @@ sub cfs_config_path {
     return "nodes/$node/lxc/$vmid.conf";
 }
 
+sub has_feature {
+    my ($class, $feature, $conf, $storecfg, $snapname, $running, $backup_only) = @_;
+    my $err;
+
+    PVE::LXC::foreach_mountpoint($conf, sub {
+	my ($ms, $mountpoint) = @_;
+
+	return if $err; # skip further test
+	return if $backup_only && $ms ne 'rootfs' && !$mountpoint->{backup};
+
+	$err = 1
+	    if !PVE::Storage::volume_has_feature($storecfg, $feature,
+						 $mountpoint->{volume},
+						 $snapname, $running);
+    });
+
+    return $err ? 0 : 1;
+}
+
+sub __snapshot_save_vmstate {
+    my ($class, $vmid, $conf, $snapname, $storecfg) = @_;
+    die "implement me - snapshot_save_vmstate\n";
+}
+
+sub __snapshot_check_running {
+    my ($class, $vmid) = @_;
+    return PVE::LXC::check_running($vmid);
+}
+
+sub __snapshot_check_freeze_needed {
+    my ($class, $vmid, $config, $save_vmstate) = @_;
+
+    my $ret = $class->__snapshot_check_running($vmid);
+    return ($ret, $ret);
+}
+
+sub __snapshot_freeze {
+    my ($class, $vmid, $unfreeze) = @_;
+
+    if ($unfreeze) {
+	eval { PVE::Tools::run_command(['/usr/bin/lxc-unfreeze', '-n', $vmid]); };
+	warn $@ if $@;
+    } else {
+	PVE::Tools::run_command(['/usr/bin/lxc-freeze', '-n', $vmid]);
+	PVE::LXC::sync_container_namespace($vmid);
+    }
+}
+
+sub __snapshot_create_vol_snapshot {
+    my ($class, $vmid, $ms, $mountpoint, $snapname) = @_;
+
+    my $storecfg = PVE::Storage::config();
+
+    return if $snapname eq 'vzdump' && $ms ne 'rootfs' && !$mountpoint->{backup};
+    PVE::Storage::volume_snapshot($storecfg, $mountpoint->{volume}, $snapname);
+}
+
+sub __snapshot_delete_remove_drive {
+    my ($class, $snap, $remove_drive) = @_;
+
+    if ($remove_drive eq 'vmstate') {
+	die "implement me - saving vmstate\n";
+    } else {
+	my $value = $snap->{$remove_drive};
+	my $mountpoint = $remove_drive eq 'rootfs' ? PVE::LXC::parse_ct_rootfs($value, 1) : PVE::LXC::parse_ct_mountpoint($value, 1);
+	delete $snap->{$remove_drive};
+	$class->add_unused_volume($snap, $mountpoint->{volume});
+    }
+}
+
+sub __snapshot_delete_vmstate_file {
+    my ($class, $snap, $force) = @_;
+
+    die "implement me - saving vmstate\n";
+}
+
+sub __snapshot_delete_vol_snapshot {
+    my ($class, $vmid, $ms, $mountpoint, $snapname) = @_;
+
+    my $storecfg = PVE::Storage::config();
+    PVE::Storage::volume_snapshot_delete($storecfg, $mountpoint->{volume}, $snapname);
+}
+
+sub __snapshot_rollback_vol_possible {
+    my ($class, $mountpoint, $snapname) = @_;
+
+    my $storecfg = PVE::Storage::config();
+    PVE::Storage::volume_rollback_is_possible($storecfg, $mountpoint->{volume}, $snapname);
+}
+
+sub __snapshot_rollback_vol_rollback {
+    my ($class, $mountpoint, $snapname) = @_;
+
+    my $storecfg = PVE::Storage::config();
+    PVE::Storage::volume_snapshot_rollback($storecfg, $mountpoint->{volume}, $snapname);
+}
+
+sub __snapshot_rollback_vm_stop {
+    my ($class, $vmid) = @_;
+
+    PVE::Tools::run_command(['/usr/bin/lxc-stop', '-n', $vmid, '--kill'])
+	if $class->__snapshot_check_running($vmid);
+}
+
+sub __snapshot_rollback_vm_start {
+    my ($class, $vmid, $vmstate, $forcemachine);
+
+    die "implement me - save vmstate\n";
+}
+
+sub __snapshot_foreach_volume {
+    my ($class, $conf, $func) = @_;
+
+    PVE::LXC::foreach_mountpoint($conf, $func);
+}
+
 # END implemented abstract methods from PVE::AbstractConfig
 
 return 1;
diff --git a/src/PVE/VZDump/LXC.pm b/src/PVE/VZDump/LXC.pm
index 2e431f9..a91fabd 100644
--- a/src/PVE/VZDump/LXC.pm
+++ b/src/PVE/VZDump/LXC.pm
@@ -130,7 +130,7 @@ sub prepare {
     });
 
     if ($mode eq 'snapshot') {
-	if (!PVE::LXC::has_feature('snapshot', $conf, $storage_cfg, undef, undef, 1)) {
+	if (!PVE::LXC::Config->has_feature('snapshot', $conf, $storage_cfg, undef, undef, 1)) {
 	    die "mode failure - some volumes do not support snapshots\n";
 	}
 
@@ -138,7 +138,7 @@ sub prepare {
 
 	if ($conf->{snapshots} && $conf->{snapshots}->{vzdump}) {
 	    $self->loginfo("found old vzdump snapshot (force removal)");
-	    PVE::LXC::snapshot_delete($vmid, 'vzdump', 1);
+	    PVE::LXC::Config->snapshot_delete($vmid, 'vzdump', 1);
 	}
 
 	my $rootdir = $default_mount_point;
@@ -211,7 +211,7 @@ sub snapshot {
     $self->loginfo("create storage snapshot 'vzdump'");
 
     # todo: freeze/unfreeze if we have more than one volid
-    PVE::LXC::snapshot_create($vmid, 'vzdump', 0, "vzdump backup snapshot");
+    PVE::LXC::Config->snapshot_create($vmid, 'vzdump', 0, "vzdump backup snapshot");
     $task->{cleanup}->{remove_snapshot} = 1;
     
     # reload config
@@ -388,7 +388,7 @@ sub cleanup {
 
     if ($task->{cleanup}->{remove_snapshot}) {
 	$self->loginfo("remove vzdump snapshot");
-	PVE::LXC::snapshot_delete($vmid, 'vzdump', 0);
+	PVE::LXC::Config->snapshot_delete($vmid, 'vzdump', 0);
     }
 }
 
diff --git a/src/test/snapshot-test.pm b/src/test/snapshot-test.pm
index 60b63fb..95f3498 100644
--- a/src/test/snapshot-test.pm
+++ b/src/test/snapshot-test.pm
@@ -1,4 +1,4 @@
-package PVE::LXC;
+package PVE::LXC::Test;
 
 use strict;
 use warnings;
@@ -29,6 +29,15 @@ my $kill_possible;
 
 # Mocked methods
 
+sub mocked_has_feature {
+    my ($feature, $conf, $storecfg, $snapname) = @_;
+    return $snapshot_possible;
+}
+
+sub mocked_check_running {
+    return $running;
+}
+
 sub mocked_volume_snapshot {
     my ($storecfg, $volid, $snapname) = @_;
     die "Storage config not mocked! aborting\n"
@@ -141,7 +150,7 @@ sub testcase_prepare {
 	plan tests => 2;
 	$@ = undef;
 	eval {
-	    PVE::LXC::snapshot_prepare($vmid, $snapname, $save_vmstate, $comment);
+	    PVE::LXC::Config->__snapshot_prepare($vmid, $snapname, $save_vmstate, $comment);
 	};
 	is($@, $exp_err, "\$@ correct");
 	ok(test_file("snapshot-expected/prepare/lxc/$vmid.conf", "snapshot-working/prepare/lxc/$vmid.conf"), "config file correct");
@@ -154,7 +163,7 @@ sub testcase_commit {
 	plan tests => 2;
 	$@ = undef;
 	eval {
-	    PVE::LXC::snapshot_commit($vmid, $snapname);
+	    PVE::LXC::Config->__snapshot_commit($vmid, $snapname);
 	};
 	is($@, $exp_err, "\$@ correct");
 	ok(test_file("snapshot-expected/commit/lxc/$vmid.conf", "snapshot-working/commit/lxc/$vmid.conf"), "config file correct");
@@ -171,7 +180,7 @@ sub testcase_create {
 	$exp_vol_snap_delete = {} if !defined($exp_vol_snap_delete);
 	$@ = undef;
 	eval {
-	    PVE::LXC::snapshot_create($vmid, $snapname, $save_vmstate, $comment);
+	    PVE::LXC::Config->snapshot_create($vmid, $snapname, $save_vmstate, $comment);
 	};
 	is($@, $exp_err, "\$@ correct");
 	is_deeply($vol_snapshot, $exp_vol_snap, "created correct volume snapshots");
@@ -188,7 +197,7 @@ sub testcase_delete {
 	$exp_vol_snap_delete = {} if !defined($exp_vol_snap_delete);
 	$@ = undef;
 	eval {
-	    PVE::LXC::snapshot_delete($vmid, $snapname, $force);
+	    PVE::LXC::Config->snapshot_delete($vmid, $snapname, $force);
 	};
 	is($@, $exp_err, "\$@ correct");
 	is_deeply($vol_snapshot_delete, $exp_vol_snap_delete, "deleted correct volume snapshots");
@@ -205,7 +214,7 @@ sub testcase_rollback {
 	$exp_vol_snap_rollback = {} if !defined($exp_vol_snap_rollback);
 	$@ = undef;
 	eval {
-	    PVE::LXC::snapshot_rollback($vmid, $snapname);
+	    PVE::LXC::Config->snapshot_rollback($vmid, $snapname);
 	};
 	is($@, $exp_err, "\$@ correct");
 	is_deeply($vol_snapshot_rollback, $exp_vol_snap_rollback, "rolled back to correct volume snapshots");
@@ -253,30 +262,24 @@ sub mocked_write_config {
     PVE::Tools::file_set_contents($filename, $raw);
 }
 
-sub has_feature {
-    my ($feature, $conf, $storecfg, $snapname) = @_;
-    return $snapshot_possible;
-}
-
-sub check_running {
-    return $running;
-}
 # END mocked PVE::LXC methods
 
-sub sync_container_namespace {
-    return;
-}
-
-# END redefine PVE::LXC methods
 
 PVE::Tools::run_command("rm -rf snapshot-working");
 PVE::Tools::run_command("cp -a snapshot-input snapshot-working");
 
+printf("\n");
+printf("Setting up Mocking for PVE::LXC and PVE::LXC::Config\n");
+my $lxc_module = new Test::MockModule('PVE::LXC');
+$lxc_module->mock('sync_container_namespace', sub { return; });
+$lxc_module->mock('check_running', \&mocked_check_running);
+
 my $lxc_config_module = new Test::MockModule('PVE::LXC::Config');
 $lxc_config_module->mock('config_file_lock', sub { return "snapshot-working/pve-test.lock"; });
 $lxc_config_module->mock('cfs_config_path', \&mocked_cfs_config_path);
 $lxc_config_module->mock('load_config', \&mocked_load_config);
 $lxc_config_module->mock('write_config', \&mocked_write_config);
+$lxc_config_module->mock('has_feature', \&mocked_has_feature);
 
 $running = 1;
 $freeze_possible = 1;
-- 
2.1.4





More information about the pve-devel mailing list