[PATCH] pct gentoo plugin fix for systemd

Jorge Ventura jorge.araujo.ventura at gmail.com
Tue May 2 18:28:42 CEST 2023


From: Jorge Ventura <jv120257 at gmail.com>

Allow install gentoo rootfs based on systemd as container. Tested with
rootfs images from https://jenkins.linuxcontainers.org/.



---
 src/PVE/LXC/Setup/Gentoo.pm | 89 ++++++++++++++++++++++++++++---------
 1 file changed, 68 insertions(+), 21 deletions(-)

diff --git a/src/PVE/LXC/Setup/Gentoo.pm b/src/PVE/LXC/Setup/Gentoo.pm
index 6dc8e9f..6bf3d56 100644
--- a/src/PVE/LXC/Setup/Gentoo.pm
+++ b/src/PVE/LXC/Setup/Gentoo.pm
@@ -20,7 +20,7 @@ sub new {
 	die "unrecognized gentoo version: $version\n";
     }
 
-    my $self = { conf => $conf, rootdir => $rootdir, version => 0 };
+    my $self = { conf => $conf, rootdir => $rootdir, version => 0, _init => 'openrc' };
 
     $conf->{ostype} = "gentoo";
 
@@ -40,6 +40,13 @@ sub template_fixup {
 sub setup_init {
     my ($self, $conf) = @_;
 
+    my $systemd = $self->ct_readlink('/sbin/init');
+    if (defined($systemd) && $systemd =~ m@/systemd$@) {
+	$self->setup_container_getty_service($conf);
+	$self->{_init} = 'systemd';
+	return;
+    }
+
     my $filename = "/etc/inittab";
     my $ttycount =  PVE::LXC::Config->get_tty_count($conf);
     my $inittab = $self->ct_file_get_contents($filename);
@@ -77,12 +84,13 @@ sub setup_network {
     my $data = '';
     my %up;
 
-    my $filename = "/etc/conf.d/net";
+    my $filename = '';
+    my $name = '';
 
     foreach my $k (keys %$conf) {
 	next if $k !~ m/^net(\d+)$/;
 	my $d = PVE::LXC::Config->parse_lxc_network($conf->{$k});
-	my $name = $d->{name};
+	$name = $d->{name};
 	next if !$name;
 
 	my $has_ipv4 = 0;
@@ -140,17 +148,41 @@ sub setup_network {
 
 	chomp $config;
 	chomp $routes;
-	$data .= "config_$name=\"$config\"\n" if $config;
-	$data .= "routes_$name=\"$routes\"\n" if $routes;
+
+	if ($self->{_init} eq 'systemd') {
+	    $data .= "[Match]\nName=$name\n\n" if $config;
+	    if ($d->{ip} eq "dhcp") {
+               $data .= "[Network]\nDHCP=ipv4\n";
+   	    } else {
+               $data .= "[Netowrk]\nAddress=$d->{ip}\n";
+	       $data .= "Gateway=$d->{gw}";
+   	    }
+	} else {
+	    $data .= "config_$name=\"$config\"\n" if $config;
+	    $data .= "routes_$name=\"$routes\"\n" if $routes;
+	}
     }
 
-    $data = "modules=\"\$modules " . join(' ', sort keys %modules) . "\"\n" . $data;
+    if ($self->{_init} eq 'systemd') {
+        $filename = "/etc/systemd/network/$name.network";
+
+	if (!$self->ct_file_exists($filename)) {
+	    open(fd, '>', $filename) or die $!;
+	    close(fd);
+	}
+       
+	$self->ct_modify_file($filename, $data, replace => 1);
+    } else {
+        $filename = "/etc/conf.d/net";
+        
+	$data = "modules=\"\$modules " . join(' ', sort keys %modules) . "\"\n" . $data;
 
-    # We replace the template's default file...
-    $self->ct_modify_file($filename, $data, replace => 1);
+        # We replace the template's default file...
+        $self->ct_modify_file($filename, $data, replace => 1);
 
-    foreach my $iface (keys %up) {
-	$self->ct_symlink("net.lo", "/etc/init.d/net.$iface");
+        foreach my $iface (keys %up) {
+            $self->ct_symlink("net.lo", "/etc/init.d/net.$iface");
+        }
     }
 }
 
@@ -160,20 +192,31 @@ sub set_hostname {
     my $hostname = $conf->{hostname} || 'localhost';
 
     my $namepart = ($hostname =~ s/\..*$//r);
+    
+    my $hostname_fn = '';
 
-    my $hostname_fn = "/etc/conf.d/hostname";
+    if ($self->{_init} eq 'systemd') {
+	$hostname_fn = "/etc/hostname";
+	open(fd, '>', $hostname_fn) or die $!;
+	close(fd);
+    } else {
+        $hostname_fn = "/etc/conf.d/hostname";
+    }
 
     my $oldname = 'localhost';
-    my $fh = $self->ct_open_file_read($hostname_fn);
-    while (defined(my $line = <$fh>)) {
-	chomp $line;
-	next if $line =~ /^\s*(#.*)?$/;
-	if ($line =~ /^\s*hostname=("[^"]*"|'[^']*'|\S*)\s*$/) {
-	    $oldname = $1;
-	    last;
-	}
+
+    if ($self->{_init} eq 'openrc') {
+        my $fh = $self->ct_open_file_read($hostname_fn);
+        while (defined(my $line = <$fh>)) {
+            chomp $line;
+            next if $line =~ /^\s*(#.*)?$/;
+            if ($line =~ /^\s*hostname=("[^"]*"|'[^']*'|\S*)\s*$/) {
+                $oldname = $1;
+                last;
+            }
+        }
+        $fh->close();
     }
-    $fh->close();
 
     my ($ipv4, $ipv6) = PVE::LXC::get_primary_ips($conf);
     my $hostip = $ipv4 || $ipv6;
@@ -184,7 +227,11 @@ sub set_hostname {
 
     # This is supposed to contain only the hostname, so we just replace the
     # file.
-    $self->ct_file_set_contents($hostname_fn, "hostname=\"$namepart\"\n");
+    if ($self->{_init} eq 'systemd') {
+    	$self->ct_file_set_contents($hostname_fn, "$namepart\n");
+    } else {
+    	$self->ct_file_set_contents($hostname_fn, "hostname=\"$namepart\"\n");
+    }
 }
 
 1;
-- 
2.39.2





More information about the pve-devel mailing list