]> git.proxmox.com Git - pve-container.git/blame - src/PVE/LXCSetup/Debian.pm
fix dns setup when using host dns configuration
[pve-container.git] / src / PVE / LXCSetup / Debian.pm
CommitLineData
1c7f4f65
DM
1package PVE::LXCSetup::Debian;
2
3use strict;
4use warnings;
55fa4e09 5use Data::Dumper;
1c7f4f65 6use PVE::Tools;
55fa4e09
DM
7use PVE::LXC;
8use File::Path;
1c7f4f65
DM
9
10use PVE::LXCSetup::Base;
11
12use base qw(PVE::LXCSetup::Base);
13
d66768a2
DM
14my $default_inittab = <<__EOD__;
15
16# The default runlevel.
17id:2:initdefault:
18
19# Boot-time system configuration/initialization script.
20# This is run first except when booting in emergency (-b) mode.
21si::sysinit:/etc/init.d/rcS
22
23# /etc/init.d executes the S and K scripts upon change
24# of runlevel.
25#
26# Runlevel 0 is halt.
27# Runlevel 1 is single-user.
28# Runlevels 2-5 are multi-user.
29# Runlevel 6 is reboot.
30
31l0:0:wait:/etc/init.d/rc 0
32l1:1:wait:/etc/init.d/rc 1
33l2:2:wait:/etc/init.d/rc 2
34l3:3:wait:/etc/init.d/rc 3
35l4:4:wait:/etc/init.d/rc 4
36l5:5:wait:/etc/init.d/rc 5
37l6:6:wait:/etc/init.d/rc 6
38# Normally not reached, but fallthrough in case of emergency.
39z6:6:respawn:/sbin/sulogin
40
41# What to do when CTRL-ALT-DEL is pressed.
42ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
43
44# What to do when the power fails/returns.
45p0::powerfail:/sbin/init 0
46
47# /sbin/getty invocations for the runlevels.
48#
49# The "id" field MUST be the same as the last
50# characters of the device (after "tty").
51#
52# Format:
53# <id>:<runlevels>:<action>:<process>
54#
55__EOD__
56
57sub setup_init {
58 my ($class, $conf) = @_;
59
60 my $rootfs = $conf->{'lxc.rootfs'};
61
62 my $filename = "$rootfs/etc/inittab";
63
64 if (-f $filename) {
65 my $inittab = $default_inittab;
66
67 my $ttycount = defined($conf->{'lxc.tty'}) ? $conf->{'lxc.tty'} : 4;
68 for (my $i = 1; $i <= $ttycount; $i++) {
69 next if $i == 7; # reserved for X11
70 my $levels = ($i == 1) ? '2345' : '23';
71 $inittab .= "$i:$levels:respawn:/sbin/getty --noclear 38400 tty$i\n";
72 }
73
74 PVE::Tools::file_set_contents($filename, $inittab);
75 }
76}
77
55fa4e09
DM
78sub setup_network {
79 my ($class, $conf) = @_;
80
81 my $rootfs = $conf->{'lxc.rootfs'};
82
83 my $networks = {};
84 foreach my $k (keys %$conf) {
85 next if $k !~ m/^net(\d+)$/;
93285df8 86 my $ind = $1;
55fa4e09
DM
87 my $d = $conf->{$k};
88 if ($d->{name}) {
89 my $net = {};
93285df8
DM
90 if (defined($d->{ip})) {
91 my $ipinfo = PVE::LXC::parse_ipv4_cidr($d->{ip});
55fa4e09
DM
92 $net->{v4address} = $ipinfo->{address};
93 $net->{v4netmask} = $ipinfo->{netmask};
94 }
93285df8
DM
95 if (defined($d->{'gw'})) {
96 $net->{v4gateway} = $d->{'gw'};
55fa4e09 97 }
93285df8 98 if (defined($d->{ip6})) {
55fa4e09
DM
99 die "implement me";
100 }
101 $networks->{$d->{name}} = $net;
102 }
103 }
104
93285df8 105 return if !scalar(keys %$networks);
55fa4e09
DM
106
107 my $filename = "$rootfs/etc/network/interfaces";
108 my $data = {};
109 my $order = [];
110 my $interfaces = "";
111
112 my $section;
113
114 my $done_v4_hash = {};
115 my $done_v6_hash = {};
116
117 my $print_section = sub {
118 my ($new) = @_;
119
120 return if !$section;
121
122 my $net = $networks->{$section->{ifname}};
123
124 if ($section->{type} eq 'ipv4') {
125 $done_v4_hash->{$section->{ifname}} = 1;
126
127 $interfaces .= "auto $section->{ifname}\n" if $new;
128
129 if ($net->{v4address}) {
130 $interfaces .= "iface $section->{ifname} inet static\n";
131 $interfaces .= "\taddress $net->{v4address}\n" if defined($net->{v4address});
132 $interfaces .= "\tnetmask $net->{v4netmask}\n" if defined($net->{v4netmask});
93285df8 133 $interfaces .= "\tgateway $net->{v4gateway}\n" if defined($net->{v4gateway});
55fa4e09
DM
134 foreach my $attr (@{$section->{attr}}) {
135 $interfaces .= "\t$attr\n";
136 }
137 } else {
138 $interfaces .= "iface $section->{ifname} inet manual\n";
139 }
140
141 $interfaces .= "\n";
142
143 } elsif ($section->{type} eq 'ipv6') {
144 $done_v6_hash->{$section->{ifname}} = 1;
145
146 if ($net->{v6address}) {
147 $interfaces .= "iface $section->{ifname} inet6 static\n";
148 $interfaces .= "\taddress $net->{v6address}\n" if defined($net->{v6address});
149 $interfaces .= "\tnetmask $net->{v6netmask}\n" if defined($net->{v6netmask});
93285df8 150 $interfaces .= "\tgateway $net->{v6gateway}\n" if defined($net->{v6gateway});
55fa4e09
DM
151 foreach my $attr (@{$section->{attr}}) {
152 $interfaces .= "\t$attr\n";
153 }
154 }
155
156 $interfaces .= "\n";
157 } else {
158 die "unknown section type '$section->{type}'";
159 }
160
161 $section = undef;
162 };
163
164 if (my $fh = IO::File->new($filename, "r")) {
165 while (defined (my $line = <$fh>)) {
166 chomp $line;
167 if ($line =~ m/^#/) {
168 $interfaces .= "$line\n";
169 next;
170 }
171 if ($line =~ m/^\s*$/) {
172 if ($section) {
173 &$print_section();
174 } else {
175 $interfaces .= "$line\n";
176 }
177 next;
178 }
179 if ($line =~ m/^iface\s+(\S+)\s+inet\s+(\S+)\s*$/) {
180 my $ifname = $1;
181 if (!$networks->{$ifname}) {
182 $interfaces .= "$line\n";
183 next;
184 }
185 $section = { type => 'ipv4', ifname => $ifname, attr => []};
186 next;
187 }
188 if ($line =~ m/^iface\s+(\S+)\s+inet6\s+(\S+)\s*$/) {
189 my $ifname = $1;
190 if (!$networks->{$ifname}) {
191 $interfaces .= "$line\n";
192 next;
193 }
194 $section = { type => 'ipv6', ifname => $ifname, attr => []};
195 next;
196 }
197 if ($section && $line =~ m/^\s*((\S+)\s(.*))$/) {
198 my ($adata, $aname) = ($1, $2);
199 if ($aname eq 'address' || $aname eq 'netmask' ||
200 $aname eq 'gateway' || $aname eq 'broadcast') {
201 # skip
202 } else {
203 push @{$section->{attr}}, $adata;
204 }
205 next;
206 }
207
208 $interfaces .= "$line\n";
209 }
210 &$print_section();
211
212 }
213
93285df8 214 my $need_separator = 1;
55fa4e09
DM
215 foreach my $ifname (sort keys %$networks) {
216 my $net = $networks->{$ifname};
93285df8 217
55fa4e09 218 if (!$done_v4_hash->{$ifname}) {
93285df8 219 if ($need_separator) { $interfaces .= "\n"; $need_separator = 0; };
55fa4e09
DM
220 $section = { type => 'ipv4', ifname => $ifname, attr => []};
221 &$print_section(1);
222 }
223 if (!$done_v6_hash->{$ifname} && defined($net->{v6address})) {
93285df8 224 if ($need_separator) { $interfaces .= "\n"; $need_separator = 0; };
55fa4e09
DM
225 $section = { type => 'ipv6', ifname => $ifname, attr => []};
226 &$print_section(1);
227 }
228 }
229
230 PVE::Tools::file_set_contents($filename, $interfaces);
231}
1c7f4f65
DM
232
2331;