[pve-devel] [PATCH pve-container] add file access methods to LXCSetup::Base

Wolfgang Bumiller w.bumiller at proxmox.com
Wed Aug 19 07:57:56 CEST 2015


These should be used for all container file access as in the
future they'll support user-id mapping.
---
 src/PVE/LXCSetup/ArchLinux.pm | 12 ++++----
 src/PVE/LXCSetup/Base.pm      | 72 +++++++++++++++++++++++++++++++++++++++++++
 src/PVE/LXCSetup/Debian.pm    | 16 ++++------
 src/PVE/LXCSetup/Redhat.pm    | 71 +++++++++++++++++++-----------------------
 src/PVE/LXCSetup/Ubuntu.pm    | 14 ++++-----
 5 files changed, 121 insertions(+), 64 deletions(-)

diff --git a/src/PVE/LXCSetup/ArchLinux.pm b/src/PVE/LXCSetup/ArchLinux.pm
index 149558c..21da073 100644
--- a/src/PVE/LXCSetup/ArchLinux.pm
+++ b/src/PVE/LXCSetup/ArchLinux.pm
@@ -33,12 +33,12 @@ sub template_fixup {
     my $rootdir = $self->{rootdir};
 
     # systemctl enable systemd-networkd
-    make_path("$rootdir/etc/systemd/system/multi-user.target.wants");
-    make_path("$rootdir/etc/systemd/system/socket.target.wants");
-    symlink "/usr/lib/systemd/system/systemd-networkd.service",
-            "$rootdir/etc/systemd/system/multi-user.target.wants/systemd-networkd.service";
-    symlink "/usr/lib/systemd/system/systemd-networkd.socket",
-            "$rootdir/etc/systemd/system/socket.target.wants/systemd-networkd.socket";
+    $self->ct_mkdir('/etc/systemd/system/multi-user.target.wants');
+    $self->ct_mkdir('/etc/systemd/system/socket.target.wants');
+    $self->ct_symlink('/usr/lib/systemd/system/systemd-networkd.service',
+                      '/etc/systemd/system/multi-user.target.wants/systemd-networkd.service');
+    $self->ct_symlink('/usr/lib/systemd/system/systemd-networkd.socket',
+                      '/etc/systemd/system/socket.target.wants/systemd-networkd.socket');
 
     # edit /etc/securetty (enable login on console)
     $self->setup_securetty($conf, qw(pts/0));
diff --git a/src/PVE/LXCSetup/Base.pm b/src/PVE/LXCSetup/Base.pm
index 7c62979..e1a721b 100644
--- a/src/PVE/LXCSetup/Base.pm
+++ b/src/PVE/LXCSetup/Base.pm
@@ -7,6 +7,7 @@ use File::stat;
 use Digest::SHA;
 use IO::File;
 use Encode;
+use File::Path;
 
 use PVE::INotify;
 use PVE::Tools;
@@ -478,4 +479,75 @@ sub post_create_hook {
     # fixme: what else ?
 }
 
+sub ct_mkdir {
+    my ($self, $file, $mask) = @_;
+    my $root = $self->{rootdir};
+    $file //= $_; # emulate mkdir parameters
+    return CORE::mkdir("$root/$file", $mask) if defined ($mask);
+    return CORE::mkdir("$root/$file");
+}
+
+sub ct_unlink {
+    my $self = shift;
+    my $root = $self->{rootdir};
+    return CORE::unlink("$root/$_") if !@_; # emulate unlink parameters
+    return CORE::unlink(map { "$root/$_" } @_);
+}
+
+sub ct_open_file {
+    my $self = shift;
+    my $file = $self->{rootdir} . '/' . shift;
+    return IO::File->new($file, @_);
+}
+
+sub ct_make_path {
+    my $self = shift;
+    my $root = $self->{rootdir};
+    my $opt = pop;
+    $opt = "$root/$opt" if ref($opt) ne 'HASH';
+    return File::Path::make_path(map { "$root/$_" } @_, $opt);
+}
+
+sub ct_mkpath {
+    my $self = shift;
+    my $root = $self->{rootdir};
+
+    my $first = shift;
+    return File::Path::mkpath(map { "$root/$_" } @$first, @_) if ref($first) eq 'ARRAY';
+    unshift @_, $first;
+    my $last = pop;
+    return File::Path::mkpath(map { "$root/$_" } @_, $last) if ref($last) eq 'HASH';
+    return File::Path::mkpath(map { "$root/$_" } (@_, $last||()));
+}
+
+sub ct_symlink {
+    my ($self, $old, $new) = @_;
+    my $root = $self->{rootdir};
+    return CORE::symlink($old, "$root/$new");
+}
+
+sub ct_file_exists {
+    my ($self, $file) = @_;
+    my $root = $self->{rootdir};
+    return -f "$root/$file";
+}
+
+sub ct_file_read_firstline {
+    my ($self, $file) = @_;
+    my $root = $self->{rootdir};
+    return PVE::Tools::file_read_firstline("$root/$file");
+}
+
+sub ct_file_get_contents {
+    my ($self, $file) = @_;
+    my $root = $self->{rootdir};
+    return PVE::Tools::file_get_contents("$root/$file");
+}
+
+sub ct_file_set_contents {
+    my ($self, $file, $data) = @_;
+    my $root = $self->{rootdir};
+    return PVE::Tools::file_set_contents("$root/$file", $data);
+}
+
 1;
diff --git a/src/PVE/LXCSetup/Debian.pm b/src/PVE/LXCSetup/Debian.pm
index dbb5930..735f4f1 100644
--- a/src/PVE/LXCSetup/Debian.pm
+++ b/src/PVE/LXCSetup/Debian.pm
@@ -79,11 +79,9 @@ __EOD__
 sub setup_init {
     my ($self, $conf) = @_;
 
-    my $rootdir = $self->{rootdir};
+    my $filename = "/etc/inittab";
 
-    my $filename = "$rootdir/etc/inittab";
-
-    if (-f $filename) {
+    if ($self->ct_file_exists($filename)) {
 	my $inittab = $default_inittab;
 
 	my $ttycount =  PVE::LXC::get_tty_count($conf);
@@ -97,15 +95,13 @@ sub setup_init {
 	    }
 	}
 	
-	PVE::Tools::file_set_contents($filename, $inittab);
+	$self->ct_file_set_contents($filename, $inittab);
     }
 }
 
 sub setup_network {
     my ($self, $conf) = @_;
 
-    my $rootdir = $self->{rootdir};
-
     my $networks = {};
     foreach my $k (keys %$conf) {
 	next if $k !~ m/^net(\d+)$/;
@@ -144,7 +140,7 @@ sub setup_network {
 
     return if !scalar(keys %$networks);
 
-    my $filename = "$rootdir/etc/network/interfaces";
+    my $filename = "/etc/network/interfaces";
     my $interfaces = "";
 
     my $section;
@@ -201,7 +197,7 @@ sub setup_network {
 	$section = undef;
     };
 	
-    if (my $fh = IO::File->new($filename, "r")) {
+    if (my $fh = $self->ct_open_file($filename, "r")) {
 	while (defined (my $line = <$fh>)) {
 	    chomp $line;
 	    if ($line =~ m/^#/) {
@@ -280,7 +276,7 @@ sub setup_network {
 	}
     }
     
-    PVE::Tools::file_set_contents($filename, $interfaces);
+    $self->ct_file_set_contents($filename, $interfaces);
 }
 
 1;
diff --git a/src/PVE/LXCSetup/Redhat.pm b/src/PVE/LXCSetup/Redhat.pm
index 28a6c15..934e8ce 100644
--- a/src/PVE/LXCSetup/Redhat.pm
+++ b/src/PVE/LXCSetup/Redhat.pm
@@ -5,7 +5,6 @@ use warnings;
 use Data::Dumper;
 use PVE::Tools;
 use PVE::LXC;
-use File::Path;
 
 use PVE::LXCSetup::Base;
 
@@ -82,31 +81,28 @@ __EOD__
 sub template_fixup {
     my ($self, $conf) = @_;
 
-    my $rootdir = $self->{rootdir};
-    
     if ($self->{version} < 7) {
 	# re-create emissing files for tty
 
-	mkpath "$rootdir/etc/init";
-
-	my $filename = "$rootdir/etc/init/tty.conf";
-	PVE::Tools::file_set_contents($filename, $tty_conf)
-	    if ! -f $filename;
+	$self->ct_mkpath('/etc/init');
 
+	my $filename = "/etc/init/tty.conf";
+	$self->ct_file_set_contents($filename, $tty_conf)
+	    if ! $self->ct_file_exists($filename);
 
-	$filename = "$rootdir/etc/init/start-ttys.conf";
-	PVE::Tools::file_set_contents($filename, $start_ttys_conf)
-	    if ! -f $filename;
+	$filename = "/etc/init/start-ttys.conf";
+	$self->ct_file_set_contents($filename, $start_ttys_conf)
+	    if ! $self->ct_file_exists($filename);
 
-	$filename = "$rootdir/etc/init/power-status-changed.conf";
-	PVE::Tools::file_set_contents($filename, $power_status_changed_conf)
-	    if ! -f $filename;
+	$filename = "/etc/init/power-status-changed.conf";
+	$self->ct_file_set_contents($filename, $power_status_changed_conf)
+	    if ! $self->ct_file_exists($filename);
 
 	# do not start udevd
-	$filename = "$rootdir/etc/rc.d/rc.sysinit";
-	my $data = PVE::Tools::file_get_contents($filename);
+	$filename = "/etc/rc.d/rc.sysinit";
+	my $data = $self->ct_file_get_contents($filename);
 	$data =~ s!^(/sbin/start_udev.*)$!#$1!gm;
-	PVE::Tools::file_set_contents($filename, $data);
+	$self->ct_file_set_contents($filename, $data);
 	
 	# edit /etc/securetty (enable login on console)
 	$self->setup_securetty($conf, qw(lxc/console lxc/tty1 lxc/tty2 lxc/tty3 lxc/tty4));
@@ -116,8 +112,6 @@ sub template_fixup {
 sub setup_init {
     my ($self, $conf) = @_;
 
-    my $rootdir = $self->{rootdir};
-
      # edit/etc/securetty
 
     $self->setup_systemd_console($conf);
@@ -130,25 +124,23 @@ sub set_hostname {
 
     $hostname =~ s/\..*$//;
 
-    my $rootdir = $self->{rootdir};
-
-    my $hostname_fn = "$rootdir/etc/hostname";
-    my $sysconfig_network = "$rootdir/etc/sysconfig/network";
+    my $hostname_fn = "/etc/hostname";
+    my $sysconfig_network = "/etc/sysconfig/network";
 
     my $oldname;
-    if (-f $hostname_fn) {
-	$oldname = PVE::Tools::file_read_firstline($hostname_fn) || 'localhost';
+    if ($self->ct_file_exists($hostname_fn)) {
+	$oldname = $self->ct_file_read_firstline($hostname_fn) || 'localhost';
     } else {
-	my $data = PVE::Tools::file_get_contents($sysconfig_network);
+	my $data = $self->ct_file_get_contents($sysconfig_network);
 	if ($data =~ m/^HOSTNAME=\s*(\S+)\s*$/m) {
 	    $oldname = $1;
 	}
     }
 
-    my $hosts_fn = "$rootdir/etc/hosts";
+    my $hosts_fn = "/etc/hosts";
     my $etc_hosts_data = '';
-    if (-f $hosts_fn) {
-	$etc_hosts_data =  PVE::Tools::file_get_contents($hosts_fn);
+    if ($self->ct_file_exists($hosts_fn)) {
+	$etc_hosts_data =  $self->ct_file_get_contents($hosts_fn);
     }
 
     my ($ipv4, $ipv6) = PVE::LXC::get_primary_ips($conf);
@@ -159,10 +151,10 @@ sub set_hostname {
     $etc_hosts_data = PVE::LXCSetup::Base::update_etc_hosts($etc_hosts_data, $hostip, $oldname,
 							    $hostname, $searchdomains);
 
-    if (-f $hostname_fn) {
-	PVE::Tools::file_set_contents($hostname_fn, "$hostname\n");
+    if ($self->ct_file_exists($hostname_fn)) {
+	$self->ct_file_set_contents($hostname_fn, "$hostname\n");
     } else {
-	my $data = PVE::Tools::file_get_contents($sysconfig_network);
+	my $data = $self->ct_file_get_contents($sysconfig_network);
 	if ($data !~ s/^HOSTNAME=\s*(\S+)\s*$/HOSTNAME=$hostname/m) {
 	    $data .= "HOSTNAME=$hostname\n";
 	}
@@ -184,26 +176,25 @@ sub set_hostname {
 		$data .= "NETWORKING_IPV6=yes\n";
 	    }
 	}
-	PVE::Tools::file_set_contents($sysconfig_network, $data);
+	$self->ct_file_set_contents($sysconfig_network, $data);
     }
 
-    PVE::Tools::file_set_contents($hosts_fn, $etc_hosts_data);
+    $self->ct_file_set_contents($hosts_fn, $etc_hosts_data);
 }
 
 sub setup_network {
     my ($self, $conf) = @_;
 
-    my $rootdir = $self->{rootdir};
     my ($gw, $gw6);
 
-    mkpath "$rootdir/etc/sysconfig/network-scripts";
+    $self->ct_mkpath('/etc/sysconfig/network-scripts');
 
     foreach my $k (keys %$conf) {
 	next if $k !~ m/^net(\d+)$/;
 	my $d = PVE::LXC::parse_lxc_network($conf->{$k});
 	next if !$d->{name};
 
-	my $filename = "$rootdir/etc/sysconfig/network-scripts/ifcfg-$d->{name}";
+	my $filename = "/etc/sysconfig/network-scripts/ifcfg-$d->{name}";
 	my $had_v4 = 0;
 
 	if ($d->{ip} && $d->{ip} ne 'manual') {
@@ -220,7 +211,7 @@ sub setup_network {
 		    $data .= "GATEWAY=$d->{gw}\n";
 		}
 	    }
-	    PVE::Tools::file_set_contents($filename, $data);
+	    $self->ct_file_set_contents($filename, $data);
 	    # If we also have an IPv6 configuration it'll end up in an alias
 	    # interface becuase otherwise RH doesn't support mixing dhcpv4 with
 	    # a static ipv6 address.
@@ -230,7 +221,7 @@ sub setup_network {
 
 	if ($d->{ip6} && $d->{ip6} ne 'manual') {
 	    # If we're only on ipv6 delete the :0 alias
-	    unlink "$filename:0"if !$had_v4;
+	    $self->ct_unlink("$filename:0") if !$had_v4;
 
 	    my $data = "DEVICE=$d->{name}\n";
 	    $data .= "ONBOOT=yes\n";
@@ -249,7 +240,7 @@ sub setup_network {
 		    $data .= "IPV6_DEFAULTGW=$d->{gw6}\n";
 		}
 	    }
-	    PVE::Tools::file_set_contents($filename, $data);
+	    $self->ct_file_set_contents($filename, $data);
 	}
     }
 }
diff --git a/src/PVE/LXCSetup/Ubuntu.pm b/src/PVE/LXCSetup/Ubuntu.pm
index 9c9994a..d7b43f8 100644
--- a/src/PVE/LXCSetup/Ubuntu.pm
+++ b/src/PVE/LXCSetup/Ubuntu.pm
@@ -44,7 +44,6 @@ sub new {
 sub template_fixup {
     my ($self, $conf) = @_;
 
-    my $rootdir = $self->{rootdir};
     my $version = $self->{version};
     
     if ($version eq '15.04') {
@@ -54,23 +53,22 @@ sub template_fixup {
 
     if ($version eq '12.04') {
 	# suppress log level output for udev
-	my $filename = "$rootdir/etc/udev/udev.conf";
-	my $data = PVE::Tools::file_get_contents($filename);
+	my $filename = '/etc/udev/udev.conf';
+	my $data = $self->ct_file_get_contents($filename);
 	$data =~ s/=\"err\"/=0/m;
-	PVE::Tools::file_set_contents($filename, $data);
+	$self->ct_file_set_contents($filename, $data);
     }
 }
 
 sub setup_init {
     my ($self, $conf) = @_;
 
-    my $rootdir = $self->{rootdir};
     my $version = $self->{version};
 
     if ($version eq '12.04' || $version eq '14.04') {
 	my $ttycount =  PVE::LXC::get_tty_count($conf);
 	for (my $i = 1; $i < 7; $i++) {
-	    my $filename = "$rootdir/etc/init/tty$i.conf";
+	    my $filename = "/etc/init/tty$i.conf";
 	    if ($i <= $ttycount) {
 		my $tty_conf = <<__EOD__;
 # tty$i - getty
@@ -88,10 +86,10 @@ stop on runlevel [!2345]
 respawn
 exec /sbin/getty -8 38400 tty$i
 __EOD__
-                PVE::Tools::file_set_contents($filename, $tty_conf);
+                $self->ct_file_set_contents($filename, $tty_conf);
 	    } else {
 		for (my $i = $ttycount + 1; $i < 7; $i++) {
-		    unlink $filename;
+		    $self->ct_unlink($filename);
 		}
 	    }
 	}
-- 
2.1.4





More information about the pve-devel mailing list