]>
Commit | Line | Data |
---|---|---|
1c7f4f65 DM |
1 | package PVE::LXCSetup::Debian; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
55fa4e09 | 5 | use Data::Dumper; |
1c7f4f65 | 6 | use PVE::Tools; |
55fa4e09 DM |
7 | use PVE::LXC; |
8 | use File::Path; | |
1c7f4f65 DM |
9 | |
10 | use PVE::LXCSetup::Base; | |
11 | ||
12 | use base qw(PVE::LXCSetup::Base); | |
13 | ||
55fa4e09 DM |
14 | sub setup_network { |
15 | my ($class, $conf) = @_; | |
16 | ||
17 | my $rootfs = $conf->{'lxc.rootfs'}; | |
18 | ||
19 | my $networks = {}; | |
20 | foreach my $k (keys %$conf) { | |
21 | next if $k !~ m/^net(\d+)$/; | |
22 | my $d = $conf->{$k}; | |
23 | if ($d->{name}) { | |
24 | my $net = {}; | |
25 | if (defined($d->{ipv4})) { | |
26 | my $ipinfo = PVE::LXC::parse_ipv4_cidr($d->{ipv4}); | |
27 | $net->{v4address} = $ipinfo->{address}; | |
28 | $net->{v4netmask} = $ipinfo->{netmask}; | |
29 | } | |
30 | if (defined($d->{'ipv4.gateway'})) { | |
31 | $net->{v4gateway} = $d->{'ipv4.gateway'}; | |
32 | } | |
33 | if (defined($d->{ipv6})) { | |
34 | die "implement me"; | |
35 | } | |
36 | $networks->{$d->{name}} = $net; | |
37 | } | |
38 | } | |
39 | ||
40 | return if !scalar(keys %$networks); | |
41 | ||
42 | my $filename = "$rootfs/etc/network/interfaces"; | |
43 | my $data = {}; | |
44 | my $order = []; | |
45 | my $interfaces = ""; | |
46 | ||
47 | my $section; | |
48 | ||
49 | my $done_v4_hash = {}; | |
50 | my $done_v6_hash = {}; | |
51 | ||
52 | my $print_section = sub { | |
53 | my ($new) = @_; | |
54 | ||
55 | return if !$section; | |
56 | ||
57 | my $net = $networks->{$section->{ifname}}; | |
58 | ||
59 | if ($section->{type} eq 'ipv4') { | |
60 | $done_v4_hash->{$section->{ifname}} = 1; | |
61 | ||
62 | $interfaces .= "auto $section->{ifname}\n" if $new; | |
63 | ||
64 | if ($net->{v4address}) { | |
65 | $interfaces .= "iface $section->{ifname} inet static\n"; | |
66 | $interfaces .= "\taddress $net->{v4address}\n" if defined($net->{v4address}); | |
67 | $interfaces .= "\tnetmask $net->{v4netmask}\n" if defined($net->{v4netmask}); | |
68 | $interfaces .= "\taddress $net->{v4gateway}\n" if defined($net->{v4gateway}); | |
69 | foreach my $attr (@{$section->{attr}}) { | |
70 | $interfaces .= "\t$attr\n"; | |
71 | } | |
72 | } else { | |
73 | $interfaces .= "iface $section->{ifname} inet manual\n"; | |
74 | } | |
75 | ||
76 | $interfaces .= "\n"; | |
77 | ||
78 | } elsif ($section->{type} eq 'ipv6') { | |
79 | $done_v6_hash->{$section->{ifname}} = 1; | |
80 | ||
81 | if ($net->{v6address}) { | |
82 | $interfaces .= "iface $section->{ifname} inet6 static\n"; | |
83 | $interfaces .= "\taddress $net->{v6address}\n" if defined($net->{v6address}); | |
84 | $interfaces .= "\tnetmask $net->{v6netmask}\n" if defined($net->{v6netmask}); | |
85 | $interfaces .= "\taddress $net->{v6gateway}\n" if defined($net->{v6gateway}); | |
86 | foreach my $attr (@{$section->{attr}}) { | |
87 | $interfaces .= "\t$attr\n"; | |
88 | } | |
89 | } | |
90 | ||
91 | $interfaces .= "\n"; | |
92 | } else { | |
93 | die "unknown section type '$section->{type}'"; | |
94 | } | |
95 | ||
96 | $section = undef; | |
97 | }; | |
98 | ||
99 | if (my $fh = IO::File->new($filename, "r")) { | |
100 | while (defined (my $line = <$fh>)) { | |
101 | chomp $line; | |
102 | if ($line =~ m/^#/) { | |
103 | $interfaces .= "$line\n"; | |
104 | next; | |
105 | } | |
106 | if ($line =~ m/^\s*$/) { | |
107 | if ($section) { | |
108 | &$print_section(); | |
109 | } else { | |
110 | $interfaces .= "$line\n"; | |
111 | } | |
112 | next; | |
113 | } | |
114 | if ($line =~ m/^iface\s+(\S+)\s+inet\s+(\S+)\s*$/) { | |
115 | my $ifname = $1; | |
116 | if (!$networks->{$ifname}) { | |
117 | $interfaces .= "$line\n"; | |
118 | next; | |
119 | } | |
120 | $section = { type => 'ipv4', ifname => $ifname, attr => []}; | |
121 | next; | |
122 | } | |
123 | if ($line =~ m/^iface\s+(\S+)\s+inet6\s+(\S+)\s*$/) { | |
124 | my $ifname = $1; | |
125 | if (!$networks->{$ifname}) { | |
126 | $interfaces .= "$line\n"; | |
127 | next; | |
128 | } | |
129 | $section = { type => 'ipv6', ifname => $ifname, attr => []}; | |
130 | next; | |
131 | } | |
132 | if ($section && $line =~ m/^\s*((\S+)\s(.*))$/) { | |
133 | my ($adata, $aname) = ($1, $2); | |
134 | if ($aname eq 'address' || $aname eq 'netmask' || | |
135 | $aname eq 'gateway' || $aname eq 'broadcast') { | |
136 | # skip | |
137 | } else { | |
138 | push @{$section->{attr}}, $adata; | |
139 | } | |
140 | next; | |
141 | } | |
142 | ||
143 | $interfaces .= "$line\n"; | |
144 | } | |
145 | &$print_section(); | |
146 | ||
147 | } | |
148 | ||
149 | foreach my $ifname (sort keys %$networks) { | |
150 | my $net = $networks->{$ifname}; | |
151 | if (!$done_v4_hash->{$ifname}) { | |
152 | $section = { type => 'ipv4', ifname => $ifname, attr => []}; | |
153 | &$print_section(1); | |
154 | } | |
155 | if (!$done_v6_hash->{$ifname} && defined($net->{v6address})) { | |
156 | $section = { type => 'ipv6', ifname => $ifname, attr => []}; | |
157 | &$print_section(1); | |
158 | } | |
159 | } | |
160 | ||
161 | PVE::Tools::file_set_contents($filename, $interfaces); | |
162 | } | |
1c7f4f65 DM |
163 | |
164 | 1; |