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