]>
Commit | Line | Data |
---|---|---|
ed027b58 WB |
1 | package PVE::LXC::Setup::Gentoo; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | ||
6 | use File::Path 'make_path'; | |
7 | ||
8 | use PVE::LXC::Setup::Base; | |
9 | ||
10 | use base qw(PVE::LXC::Setup::Base); | |
11 | ||
12 | sub new { | |
13 | my ($class, $conf, $rootdir) = @_; | |
14 | ||
15 | my $version = PVE::Tools::file_read_firstline("$rootdir/etc/gentoo-release"); | |
16 | die "unable to read version info\n" if !defined($version); | |
17 | if ($version =~ /^gentoo base system release (.*)$/i) { | |
18 | $version = $1; | |
19 | } else { | |
20 | die "unrecognized gentoo version: $version\n"; | |
21 | } | |
22 | ||
23 | my $self = { conf => $conf, rootdir => $rootdir, version => 0 }; | |
24 | ||
25 | $conf->{ostype} = "gentoo"; | |
26 | ||
27 | return bless $self, $class; | |
28 | } | |
29 | ||
30 | sub template_fixup { | |
31 | my ($self, $conf) = @_; | |
32 | $self->setup_securetty($conf, qw(lxc/console lxc/tty1 lxc/tty2 lxc/tty3 lxc/tty4)); | |
33 | } | |
34 | ||
35 | sub setup_init { | |
36 | my ($self, $conf) = @_; | |
37 | ||
38 | my $filename = "/etc/inittab"; | |
39 | my $ttycount = PVE::LXC::Config->get_tty_count($conf); | |
40 | my $inittab = $self->ct_file_get_contents($filename); | |
41 | ||
42 | my @lines = grep { | |
43 | # remove getty lines | |
44 | !/^\s*c?\d+:\d*:[^:]*:.*getty/ | |
45 | } split(/\n/, $inittab); | |
46 | ||
47 | $inittab = join("\n", @lines) . "\n"; | |
48 | ||
49 | for (my $id = 1; $id <= $ttycount; $id++) { | |
50 | next if $id == 7; # reserved for X11 | |
51 | $inittab .= "$id\::respawn:/sbin/agetty 38400 tty$id\n"; | |
52 | } | |
53 | ||
54 | $self->ct_file_set_contents($filename, $inittab); | |
55 | } | |
56 | ||
57 | sub setup_network { | |
58 | my ($self, $conf) = @_; | |
59 | ||
60 | # Gentoo's /etc/conf.d/net is supposed to only contains variables, but is | |
61 | # in fact sourced by a shell, so reading out existing modules/config values | |
62 | # is pretty inconvenient. | |
63 | # We SHOULD check for whether iproute2 or ifconfig is already being used, | |
64 | # but for now we just assume ifconfig (since they also state iproute2 might | |
65 | # not be available in a default setup, though the templates usually do have | |
66 | # it installed - we might just get away with an if/else clause to insert | |
67 | # ifconfig/iproute2 syntax as needed, that way we don't need to parse this | |
68 | # file even to support both...) | |
69 | ||
70 | my %modules = (ifconfig => 1); | |
71 | ||
72 | my $data = ''; | |
73 | my %up; | |
74 | ||
75 | my $filename = "/etc/conf.d/net"; | |
76 | ||
77 | foreach my $k (keys %$conf) { | |
78 | next if $k !~ m/^net(\d+)$/; | |
79 | my $d = PVE::LXC::Config->parse_lxc_network($conf->{$k}); | |
80 | my $name = $d->{name}; | |
81 | next if !$name; | |
82 | ||
83 | my $has_ipv4 = 0; | |
84 | my $has_ipv6 = 0; | |
85 | ||
86 | my $config = ''; | |
87 | my $routes = ''; | |
88 | ||
89 | if (defined(my $ip = $d->{ip})) { | |
90 | if ($ip eq 'dhcp') { | |
91 | #$modules{dhclient} = 1; # Well, we could... | |
92 | $config .= "dhcp\n"; | |
93 | $up{$name} = 1; | |
94 | } elsif ($ip ne 'manual') { | |
95 | $has_ipv4 = 1; | |
96 | $config .= "$ip\n"; | |
97 | $up{$name} = 1; | |
98 | } | |
99 | } | |
100 | if (defined(my $gw = $d->{gw})) { | |
101 | if ($has_ipv4 && !PVE::Network::is_ip_in_cidr($gw, $d->{ip}, 4)) { | |
102 | $routes .= "-host $gw dev $name\n"; | |
103 | } | |
104 | $routes .= "default gw $gw\n"; | |
105 | $up{$name} = 1; | |
106 | } | |
107 | ||
108 | if (defined(my $ip = $d->{ip6})) { | |
109 | if ($ip eq 'dhcp') { | |
110 | # FIXME: The default templates seem to only ship busybox' udhcp | |
111 | # client which means we're in the same boat as alpine linux. | |
112 | # They also don't provide dhcpv6-only at all - for THAT however | |
113 | # there are patches from way back in 2013 (bug#450326 on | |
114 | # gentoo.org's netifrc)... but whatever, # that's only 10 years | |
115 | # after the RFC3315 release (DHCPv6). | |
116 | # | |
117 | # So no dhcpv6(-only) setups here for now. | |
118 | ||
119 | #$modules{dhclientv6} = 1; | |
120 | #$config .= "dhcpv6\n"; | |
121 | #$up{$name} = 1; | |
122 | } elsif ($ip ne 'manual') { | |
123 | $has_ipv6 = 1; | |
124 | $config .= "$ip\n"; | |
125 | $up{$name} = 1; | |
126 | } | |
127 | } | |
128 | if (defined(my $gw = $d->{gw6})) { | |
129 | if ($has_ipv6 && !PVE::Network::is_ip_in_cidr($gw, $d->{ip6}, 4)) { | |
130 | $routes .= "-6 -host $gw dev $name\n"; | |
131 | } | |
132 | $routes .= "-6 default gw $gw\n"; | |
133 | $up{$name} = 1; | |
134 | } | |
135 | ||
136 | chomp $config; | |
137 | chomp $routes; | |
138 | $data .= "config_$name=\"$config\"\n" if $config; | |
139 | $data .= "routes_$name=\"$routes\"\n" if $routes; | |
140 | } | |
141 | ||
142 | $data = "modules=\"\$modules " . join(' ', sort keys %modules) . "\"\n" . $data; | |
143 | ||
144 | # We replace the template's default file... | |
145 | $self->ct_modify_file($filename, $data, replace => 1); | |
146 | ||
147 | foreach my $iface (keys %up) { | |
148 | $self->ct_symlink("net.lo", "/etc/init.d/net.$iface"); | |
149 | } | |
150 | } | |
151 | ||
7dffc32a WB |
152 | sub set_hostname { |
153 | my ($self, $conf) = @_; | |
154 | ||
155 | my $hostname = $conf->{hostname} || 'localhost'; | |
156 | ||
157 | my $namepart = ($hostname =~ s/\..*$//r); | |
158 | ||
159 | my $hostname_fn = "/etc/conf.d/hostname"; | |
160 | ||
161 | my $oldname = 'localhost'; | |
162 | my $fh = $self->ct_open_file_read($hostname_fn); | |
163 | while (defined(my $line = <$fh>)) { | |
164 | chomp $line; | |
165 | next if $line =~ /^\s*(#.*)?$/; | |
166 | if ($line =~ /^\s*hostname=("[^"]*"|'[^']*'|\S*)\s*$/) { | |
167 | $oldname = $1; | |
168 | last; | |
169 | } | |
170 | } | |
171 | $fh->close(); | |
172 | ||
173 | my ($ipv4, $ipv6) = PVE::LXC::get_primary_ips($conf); | |
174 | my $hostip = $ipv4 || $ipv6; | |
175 | ||
176 | my ($searchdomains) = $self->lookup_dns_conf($conf); | |
177 | ||
178 | $self->update_etc_hosts($hostip, $oldname, $hostname, $searchdomains); | |
179 | ||
180 | # This is supposed to contain only the hostname, so we just replace the | |
181 | # file. | |
182 | $self->ct_file_set_contents($hostname_fn, "hostname=\"$namepart\"\n"); | |
183 | } | |
184 | ||
ed027b58 | 185 | 1; |