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