]> git.proxmox.com Git - pve-container.git/blobdiff - src/PVE/LXC/Setup/Debian.pm
remove Data::Dumper usages
[pve-container.git] / src / PVE / LXC / Setup / Debian.pm
index c6b299816d1396ab8058b2e4e76a8c499ffabc8f..50398892e512f695c79df4245c303caac618fe2b 100644 (file)
@@ -2,7 +2,7 @@ package PVE::LXC::Setup::Debian;
 
 use strict;
 use warnings;
-use Data::Dumper;
+
 use PVE::Tools qw($IPV6RE);
 use PVE::LXC;
 use PVE::Network;
@@ -19,8 +19,9 @@ sub new {
 
     die "unable to read version info\n" if !defined($version);
 
-    # translate stretch/sid => 9.0 (used on debian testing repository)
-    $version = 9.0 if $version eq 'stretch/sid';
+    # translate testing version names
+    $version = 9.1 if $version eq 'stretch/sid';
+    $version = 10 if $version eq 'buster/sid';
 
     die "unable to parse version info '$version'\n"
        if $version !~ m/^(\d+(\.\d+)?)(\.\d+)?/;
@@ -28,7 +29,7 @@ sub new {
     $version = $1;
 
     die "unsupported debian version '$version'\n"
-       if !($version >= 4 && $version <= 9);
+       if !($version >= 4 && $version <= 10);
 
     my $self = { conf => $conf, rootdir => $rootdir, version => $version };
 
@@ -37,12 +38,17 @@ sub new {
     return bless $self, $class;
 }
 
+# Debian doesn't support the /dev/lxc/ subdirectory.
+sub devttydir {
+    return '';
+}
+
 sub setup_init {
     my ($self, $conf) = @_;
 
     my $systemd = $self->ct_readlink('/sbin/init');
     if (defined($systemd) && $systemd =~ m@/systemd$@) {
-       $self->setup_container_getty_service(1);
+       $self->setup_container_getty_service($conf);
     }
 
     my $filename = "/etc/inittab";
@@ -53,7 +59,7 @@ sub setup_init {
 
     my @lines = grep {
            # remove getty lines
-           !/^\s*\d+:\d+:[^:]*:.*getty/ &&
+           !/^\s*\d+:\d*:[^:]*:.*getty/ &&
            # remove power lines
            !/^\s*p[fno0]:/
        } split(/\n/, $inittab);
@@ -79,32 +85,43 @@ sub setup_init {
 sub remove_gateway_scripts {
     my ($attr) = @_;
     my $length = scalar(@$attr);
-    for (my $i = 0; $i < $length; ++$i) {
-       my $a = $attr->[$i];
-       if ($a =~ m@^\s*post-up\s+.*route.*add.*default.*(?:gw|via)\s+(\S+)@) {
-           my $gw = $1;
-           if ($i > 0 && $attr->[$i-1] =~ m@^\s*post-up\s+.*route.*add.*\Q$1\E@) {
-               --$i;
-               splice @$attr, $i, 2;
-               $length -= 2;
-           } else {
-               splice @$attr, $i, 1;
-               $length -= 1;
-           }
-           --$i;
-           next;
+
+    my $found_section = 0;
+    my $keep = 1;
+    @$attr = grep {
+       if ($_ eq '# --- BEGIN PVE ---') {
+           $found_section = 1;
+           $keep = 0;
+           0; # remove this line
+       } elsif ($_ eq '# --- END PVE ---') {
+           $found_section = 1;
+           $keep = 1;
+           0; # remove this line
+       } else {
+           $keep;
        }
-       if ($a =~ m@^\s*pre-down\s+.*route.*del.*default.*(?:gw|via)\s+(\S+)@) {
-           my $gw = $1;
-           if ($attr->[$i+1] =~ m@^\s*pre-down\s+.*route.*del.*\Q$1\E@) {
-               splice @$attr, $i, 2;
-               $length -= 2;
-           } else {
-               splice @$attr, $i, 1;
-               $length -= 1;
-           }
+    } @$attr;
+
+    return if $found_section;
+    # XXX: To deal with existing setups we perform two types of removal for
+    # now. Newly started containers have their routing sections marked with
+    # begin/end comments. For older containers we perform a strict matching on
+    # the routing rules we added. We can probably remove this part at some point
+    # when it is unlikely that old debian setups are still around.
+
+    for (my $i = 0; $i < $length-3; ++$i) {
+       next if $attr->[$i+0] !~ m@^\s*post-up\s+ip\s+route\s+add\s+(\S+)\s+dev\s+(\S+)$@;
+       my ($ip, $dev) = ($1, $2);
+       if ($attr->[$i+1] =~ m@^\s*post-up\s+ip\s+route\s+add\s+default\s+via\s+(\S+)\s+dev\s+(\S+)$@ &&
+           ($ip eq $1 && $dev eq $2) &&
+           $attr->[$i+2] =~ m@^\s*pre-down\s+ip\s+route\s+del\s+default\s+via\s+(\S+)\s+dev\s+(\S+)$@ &&
+           ($ip eq $1 && $dev eq $2) &&
+           $attr->[$i+3] =~ m@^\s*pre-down\s+ip\s+route\s+del\s+(\S+)\s+dev\s+(\S+)$@ &&
+           ($ip eq $1 && $dev eq $2))
+       {
+           splice @$attr, $i, 4;
+           $length -= 4;
            --$i;
-           next;
        }
     }
 }
@@ -112,10 +129,12 @@ sub remove_gateway_scripts {
 sub make_gateway_scripts {
     my ($ifname, $gw) = @_;
     return <<"SCRIPTS";
+# --- BEGIN PVE ---
 \tpost-up ip route add $gw dev $ifname
 \tpost-up ip route add default via $gw dev $ifname
 \tpre-down ip route del default via $gw dev $ifname
 \tpre-down ip route del $gw dev $ifname
+# --- END PVE ---
 SCRIPTS
 }
 
@@ -196,8 +215,10 @@ sub setup_network {
        if ($section->{type} eq 'ipv4') {
            $done_v4_hash->{$ifname} = 1;
 
-           if (defined($net->{address}) && $net->{address} =~ /^(dhcp|manual)$/) {
-               $interfaces .= "iface $ifname inet $1\n";
+           if (!defined($net->{address})) {
+               # no address => no iface line
+           } elsif ($net->{address} =~ /^(dhcp|manual)$/) {
+               $interfaces .= "iface $ifname inet $1\n\n";
            } else {
                $interfaces .= "iface $ifname inet static\n";
                $interfaces .= "\taddress $net->{address}\n" if defined($net->{address});
@@ -214,15 +235,15 @@ sub setup_network {
                foreach my $attr (@{$section->{attr}}) {
                    $interfaces .= "\t$attr\n";
                }
+               $interfaces .= "\n";
            }
-
-           $interfaces .= "\n";
-
        } elsif ($section->{type} eq 'ipv6') {
            $done_v6_hash->{$ifname} = 1;
 
-           if (defined($net->{address6}) && $net->{address6} =~ /^(auto|dhcp|manual)$/) {
-               $interfaces .= "iface $ifname inet6 $1\n";
+           if (!defined($net->{address6})) {
+               # no address => no iface line
+           } elsif ($net->{address6} =~ /^(auto|dhcp|manual)$/) {
+               $interfaces .= "iface $ifname inet6 $1\n\n";
            } else {
                $interfaces .= "iface $ifname inet6 static\n";
                $interfaces .= "\taddress $net->{address6}\n" if defined($net->{address6});
@@ -238,9 +259,8 @@ sub setup_network {
                foreach my $attr (@{$section->{attr}}) {
                    $interfaces .= "\t$attr\n";
                }
+               $interfaces .= "\n";
            }
-
-           $interfaces .= "\n";
        } else {
            die "unknown section type '$section->{type}'";
        }
@@ -251,6 +271,12 @@ sub setup_network {
     if (my $fh = $self->ct_open_file_read($filename)) {
        while (defined (my $line = <$fh>)) {
            chomp $line;
+           if ($line =~ m/^# --- (?:BEGIN|END) PVE ---/) {
+               # Include markers in the attribute section so
+               # remove_gateway_scripts() can find them.
+               push @{$section->{attr}}, $line if $section;
+               next;
+           }
            if ($line =~ m/^#/) {
                $interfaces .= "$line\n";
                next;
@@ -334,6 +360,14 @@ sub setup_network {
        }
     }
 
+    # older templates (< Debian 8) do not configure the loopback interface
+    # if not explicitly told to do so
+    if (!$done_auto->{lo}) {
+       $interfaces = "auto lo\niface lo inet loopback\n" .
+                     "iface lo inet6 loopback\n\n" .
+                     $interfaces;
+    }
+
     $self->ct_file_set_contents($filename, $interfaces);
 }