]> git.proxmox.com Git - pve-container.git/commitdiff
Setup: add gentoo support
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Thu, 19 May 2016 13:21:43 +0000 (15:21 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Mon, 23 May 2016 05:04:29 +0000 (07:04 +0200)
With DHCPv6 we're in a similar boat as with Alpine: The
default templates only ship busybox' udhcpc which doesn't do
ipv6 at all, and if dhclient/dhcpcd are installed there'd
still be no way to configure ONLY dhcpv6 without including
dhcpv4. (We could just dump in a dhclientv6.sh script to
/lib64/netifrc/net/dhclientv6.sh if someone absolutely needs
it...)

Also the fact that the network configuration can in *theory*
be a full blown bash script is a bit inconvenient.

src/PVE/LXC.pm
src/PVE/LXC/Config.pm
src/PVE/LXC/Setup.pm
src/PVE/LXC/Setup/Gentoo.pm [new file with mode: 0644]
src/PVE/LXC/Setup/Makefile

index f7122620f149edf239162bbb7bfda28c56c817c2..759ab6d7ba9bbbe9040bf3f79d2d8b70e088de2a 100644 (file)
@@ -345,7 +345,7 @@ sub update_lxc_config {
     my $custom_idmap = grep { $_->[0] eq 'lxc.id_map' } @{$conf->{lxc}};
 
     my $ostype = $conf->{ostype} || die "missing 'ostype' - internal error";
-    if ($ostype =~ /^(?:debian | ubuntu | centos | fedora | opensuse | archlinux | alpine | unmanaged)$/x) {
+    if ($ostype =~ /^(?:debian | ubuntu | centos | fedora | opensuse | archlinux | alpine | gentoo | unmanaged)$/x) {
        my $inc ="/usr/share/lxc/config/$ostype.common.conf";
        $inc ="/usr/share/lxc/config/common.conf" if !-f $inc;
        $raw .= "lxc.include = $inc\n";
index 9d805fc0b8f2158b53e09133b8ac461cccadbbe1..83e5728877b0a69774925c15c0774bdf2a85fe57 100644 (file)
@@ -253,7 +253,7 @@ my $confdesc = {
     ostype => {
        optional => 1,
        type => 'string',
-       enum => ['debian', 'ubuntu', 'centos', 'fedora', 'opensuse', 'archlinux', 'alpine', 'unmanaged'],
+       enum => [qw(debian ubuntu centos fedora opensuse archlinux alpine gentoo unmanaged)],
        description => "OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/<ostype>.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.",
     },
     console => {
index 6568b90640249b533500e5c41ce63cd9ab215917..b9e112b48b3eddab452a3e9f2c56918f86cdc39f 100644 (file)
@@ -12,6 +12,7 @@ use PVE::LXC::Setup::Fedora;
 use PVE::LXC::Setup::SUSE;
 use PVE::LXC::Setup::ArchLinux;
 use PVE::LXC::Setup::Alpine;
+use PVE::LXC::Setup::Gentoo;
 
 my $plugins = {
     debian    => 'PVE::LXC::Setup::Debian',
@@ -21,6 +22,7 @@ my $plugins = {
     opensuse  => 'PVE::LXC::Setup::SUSE',
     archlinux => 'PVE::LXC::Setup::ArchLinux',
     alpine    => 'PVE::LXC::Setup::Alpine',
+    gentoo    => 'PVE::LXC::Setup::Gentoo',
 };
 
 my $autodetect_type = sub {
@@ -46,6 +48,8 @@ my $autodetect_type = sub {
        return "archlinux";
     } elsif (-f  "$rootdir/etc/alpine-release") {
        return "alpine";
+    } elsif (-f  "$rootdir/etc/gentoo-release") {
+       return "gentoo";
     }
     die "unable to detect OS distribution\n";
 };
diff --git a/src/PVE/LXC/Setup/Gentoo.pm b/src/PVE/LXC/Setup/Gentoo.pm
new file mode 100644 (file)
index 0000000..762cb74
--- /dev/null
@@ -0,0 +1,152 @@
+package PVE::LXC::Setup::Gentoo;
+
+use strict;
+use warnings;
+
+use File::Path 'make_path';
+
+use PVE::LXC::Setup::Base;
+
+use base qw(PVE::LXC::Setup::Base);
+
+sub new {
+    my ($class, $conf, $rootdir) = @_;
+
+    my $version = PVE::Tools::file_read_firstline("$rootdir/etc/gentoo-release");
+    die "unable to read version info\n" if !defined($version);
+    if ($version =~ /^gentoo base system release (.*)$/i) {
+       $version = $1;
+    } else {
+       die "unrecognized gentoo version: $version\n";
+    }
+
+    my $self = { conf => $conf, rootdir => $rootdir, version => 0 };
+
+    $conf->{ostype} = "gentoo";
+
+    return bless $self, $class;
+}
+
+sub template_fixup {
+    my ($self, $conf) = @_;
+    $self->setup_securetty($conf, qw(lxc/console lxc/tty1 lxc/tty2 lxc/tty3 lxc/tty4));
+}
+
+sub setup_init {
+    my ($self, $conf) = @_;
+
+    my $filename = "/etc/inittab";
+    my $ttycount =  PVE::LXC::Config->get_tty_count($conf);
+    my $inittab = $self->ct_file_get_contents($filename);
+
+    my @lines = grep {
+           # remove getty lines
+           !/^\s*c?\d+:\d*:[^:]*:.*getty/
+    } split(/\n/, $inittab);
+
+    $inittab = join("\n", @lines) . "\n";
+
+    for (my $id = 1; $id <= $ttycount; $id++) {
+       next if $id == 7; # reserved for X11
+       $inittab .= "$id\::respawn:/sbin/agetty 38400 tty$id\n";
+    }
+
+    $self->ct_file_set_contents($filename, $inittab);
+}
+
+sub setup_network {
+    my ($self, $conf) = @_;
+
+    # Gentoo's /etc/conf.d/net is supposed to only contains variables, but is
+    # in fact sourced by a shell, so reading out existing modules/config values
+    # is pretty inconvenient.
+    # We SHOULD check for whether iproute2 or ifconfig is already being used,
+    # but for now we just assume ifconfig (since they also state iproute2 might
+    # not be available in a default setup, though the templates usually do have
+    # it installed - we might just get away with an if/else clause to insert
+    # ifconfig/iproute2 syntax as needed, that way we don't need to parse this
+    # file even to support both...)
+
+    my %modules = (ifconfig => 1);
+
+    my $data = '';
+    my %up;
+
+    my $filename = "/etc/conf.d/net";
+
+    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};
+       next if !$name;
+
+       my $has_ipv4 = 0;
+       my $has_ipv6 = 0;
+
+       my $config = '';
+       my $routes = '';
+
+       if (defined(my $ip = $d->{ip})) {
+           if ($ip eq 'dhcp') {
+               #$modules{dhclient} = 1; # Well, we could...
+               $config .= "dhcp\n";
+               $up{$name} = 1;
+           } elsif ($ip ne 'manual') {
+               $has_ipv4 = 1;
+               $config .= "$ip\n";
+               $up{$name} = 1;
+           }
+       }
+       if (defined(my $gw = $d->{gw})) {
+           if ($has_ipv4 && !PVE::Network::is_ip_in_cidr($gw, $d->{ip}, 4)) {
+               $routes .= "-host $gw dev $name\n";
+           }
+           $routes .= "default gw $gw\n";
+           $up{$name} = 1;
+       }
+
+       if (defined(my $ip = $d->{ip6})) {
+           if ($ip eq 'dhcp') {
+               # FIXME: The default templates seem to only ship busybox' udhcp
+               # client which means we're in the same boat as alpine linux.
+               # They also don't provide dhcpv6-only at all - for THAT however
+               # there are patches from way back in 2013 (bug#450326 on
+               # gentoo.org's netifrc)... but whatever, # that's only 10 years
+               # after the RFC3315 release (DHCPv6).
+               #
+               # So no dhcpv6(-only) setups here for now.
+
+               #$modules{dhclientv6} = 1;
+               #$config .= "dhcpv6\n";
+               #$up{$name} = 1;
+           } elsif ($ip ne 'manual') {
+               $has_ipv6 = 1;
+               $config .= "$ip\n";
+               $up{$name} = 1;
+           }
+       }
+       if (defined(my $gw = $d->{gw6})) {
+           if ($has_ipv6 && !PVE::Network::is_ip_in_cidr($gw, $d->{ip6}, 4)) {
+               $routes .= "-6 -host $gw dev $name\n";
+           }
+           $routes .= "-6 default gw $gw\n";
+           $up{$name} = 1;
+       }
+
+       chomp $config;
+       chomp $routes;
+       $data .= "config_$name=\"$config\"\n" if $config;
+       $data .= "routes_$name=\"$routes\"\n" if $routes;
+    }
+
+    $data = "modules=\"\$modules " . join(' ', sort keys %modules) . "\"\n" . $data;
+
+    # 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");
+    }
+}
+
+1;
index f70c898d7203d86cd46ba03bde508e1b6ca29649..f971e0bfc8fe62fa60a0bf69e2f5d2693020e318 100644 (file)
@@ -1,4 +1,4 @@
-SOURCES=Base.pm Debian.pm Ubuntu.pm CentOS.pm Fedora.pm SUSE.pm ArchLinux.pm Alpine.pm
+SOURCES=Base.pm Debian.pm Ubuntu.pm CentOS.pm Fedora.pm SUSE.pm ArchLinux.pm Alpine.pm Gentoo.pm
 
 .PHONY: install
 install: