]>
Commit | Line | Data |
---|---|---|
81a6ec3f | 1 | package PVE::LXC::Setup::CentOS; |
c0eae401 DM |
2 | |
3 | use strict; | |
4 | use warnings; | |
179b842e | 5 | |
c0eae401 | 6 | use PVE::Tools; |
685d7b1c | 7 | use PVE::Network; |
c0eae401 | 8 | use PVE::LXC; |
c0eae401 | 9 | |
7af97ad5 | 10 | use PVE::LXC::Setup::Base; |
c0eae401 | 11 | |
7af97ad5 | 12 | use base qw(PVE::LXC::Setup::Base); |
c0eae401 DM |
13 | |
14 | sub new { | |
15 | my ($class, $conf, $rootdir) = @_; | |
16 | ||
17 | my $release = PVE::Tools::file_read_firstline("$rootdir/etc/redhat-release"); | |
18 | die "unable to read version info\n" if !defined($release); | |
19 | ||
20 | my $version; | |
21 | ||
fa099c21 | 22 | if ($release =~ m/release\s+(\d+\.\d+)(\.\d+)?/) { |
9b940fef | 23 | if ($1 >= 5 && $1 <= 8) { |
c0eae401 DM |
24 | $version = $1; |
25 | } | |
26 | } | |
27 | ||
81a6ec3f | 28 | die "unsupported centos release '$release'\n" if !$version; |
c0eae401 DM |
29 | |
30 | my $self = { conf => $conf, rootdir => $rootdir, version => $version }; | |
31 | ||
27916659 | 32 | $conf->{ostype} = "centos"; |
c0eae401 DM |
33 | |
34 | return bless $self, $class; | |
35 | } | |
36 | ||
142444d5 | 37 | my $tty_conf = <<__EOD__; |
c0eae401 DM |
38 | # tty - getty |
39 | # | |
40 | # This service maintains a getty on the specified device. | |
41 | # | |
42 | # Do not edit this file directly. If you want to change the behaviour, | |
43 | # please create a file tty.override and put your changes there. | |
44 | ||
45 | stop on runlevel [S016] | |
46 | ||
47 | respawn | |
48 | instance \$TTY | |
b9bc7cfa | 49 | exec /sbin/mingetty \$TTY |
c0eae401 DM |
50 | usage 'tty TTY=/dev/ttyX - where X is console id' |
51 | __EOD__ | |
142444d5 DM |
52 | |
53 | my $start_ttys_conf = <<__EOD__; | |
c0eae401 DM |
54 | # |
55 | # This service starts the configured number of gettys. | |
56 | # | |
57 | # Do not edit this file directly. If you want to change the behaviour, | |
58 | # please create a file start-ttys.override and put your changes there. | |
59 | ||
60 | start on stopped rc RUNLEVEL=[2345] | |
61 | ||
62 | env ACTIVE_CONSOLES=/dev/tty[1-6] | |
63 | env X_TTY=/dev/tty1 | |
64 | task | |
65 | script | |
66 | . /etc/sysconfig/init | |
67 | for tty in \$(echo \$ACTIVE_CONSOLES) ; do | |
68 | [ "\$RUNLEVEL" = "5" -a "\$tty" = "\$X_TTY" ] && continue | |
69 | initctl start tty TTY=\$tty | |
70 | done | |
71 | end script | |
72 | __EOD__ | |
73 | ||
57569b85 DM |
74 | my $power_status_changed_conf = <<__EOD__; |
75 | # power-status-changed - shutdown on SIGPWR | |
76 | # | |
77 | start on power-status-changed | |
78 | ||
79 | exec /sbin/shutdown -h now "SIGPWR received" | |
80 | __EOD__ | |
81 | ||
142444d5 DM |
82 | sub template_fixup { |
83 | my ($self, $conf) = @_; | |
84 | ||
142444d5 DM |
85 | if ($self->{version} < 7) { |
86 | # re-create emissing files for tty | |
87 | ||
f08b2779 | 88 | $self->ct_make_path('/etc/init'); |
142444d5 | 89 | |
2063d380 WB |
90 | my $filename = "/etc/init/tty.conf"; |
91 | $self->ct_file_set_contents($filename, $tty_conf) | |
92 | if ! $self->ct_file_exists($filename); | |
142444d5 | 93 | |
2063d380 WB |
94 | $filename = "/etc/init/start-ttys.conf"; |
95 | $self->ct_file_set_contents($filename, $start_ttys_conf) | |
96 | if ! $self->ct_file_exists($filename); | |
57569b85 | 97 | |
2063d380 WB |
98 | $filename = "/etc/init/power-status-changed.conf"; |
99 | $self->ct_file_set_contents($filename, $power_status_changed_conf) | |
100 | if ! $self->ct_file_exists($filename); | |
142444d5 DM |
101 | |
102 | # do not start udevd | |
2063d380 WB |
103 | $filename = "/etc/rc.d/rc.sysinit"; |
104 | my $data = $self->ct_file_get_contents($filename); | |
142444d5 | 105 | $data =~ s!^(/sbin/start_udev.*)$!#$1!gm; |
2063d380 | 106 | $self->ct_file_set_contents($filename, $data); |
142444d5 DM |
107 | |
108 | # edit /etc/securetty (enable login on console) | |
5e84bdc8 | 109 | $self->setup_securetty($conf); |
142444d5 DM |
110 | } |
111 | } | |
112 | ||
142444d5 DM |
113 | sub setup_init { |
114 | my ($self, $conf) = @_; | |
115 | ||
142444d5 DM |
116 | # edit/etc/securetty |
117 | ||
dd7a436b TL |
118 | $self->fixup_old_getty(); |
119 | ||
a4f1fab1 | 120 | $self->setup_container_getty_service($conf); |
c0eae401 DM |
121 | } |
122 | ||
123 | sub set_hostname { | |
124 | my ($self, $conf) = @_; | |
125 | ||
ead433af | 126 | # Redhat wants the fqdn in /etc/sysconfig/network's HOSTNAME |
27916659 | 127 | my $hostname = $conf->{hostname} || 'localhost'; |
c0eae401 | 128 | |
2063d380 WB |
129 | my $hostname_fn = "/etc/hostname"; |
130 | my $sysconfig_network = "/etc/sysconfig/network"; | |
c0eae401 DM |
131 | |
132 | my $oldname; | |
2063d380 WB |
133 | if ($self->ct_file_exists($hostname_fn)) { |
134 | $oldname = $self->ct_file_read_firstline($hostname_fn) || 'localhost'; | |
c0eae401 | 135 | } else { |
2063d380 | 136 | my $data = $self->ct_file_get_contents($sysconfig_network); |
c0eae401 DM |
137 | if ($data =~ m/^HOSTNAME=\s*(\S+)\s*$/m) { |
138 | $oldname = $1; | |
139 | } | |
140 | } | |
141 | ||
c0eae401 DM |
142 | my ($ipv4, $ipv6) = PVE::LXC::get_primary_ips($conf); |
143 | my $hostip = $ipv4 || $ipv6; | |
144 | ||
23d928a1 | 145 | my ($searchdomains) = $self->lookup_dns_conf($conf); |
c0eae401 | 146 | |
9096a91d | 147 | $self->update_etc_hosts($hostip, $oldname, $hostname, $searchdomains); |
c0eae401 | 148 | |
2063d380 WB |
149 | if ($self->ct_file_exists($hostname_fn)) { |
150 | $self->ct_file_set_contents($hostname_fn, "$hostname\n"); | |
f0f32274 WB |
151 | } |
152 | ||
153 | if ($self->ct_file_exists($sysconfig_network)) { | |
2063d380 | 154 | my $data = $self->ct_file_get_contents($sysconfig_network); |
f0f32274 | 155 | if ($data !~ s/^HOSTNAME=\h*(\S+)\h*$/HOSTNAME=$hostname/m) { |
c0eae401 DM |
156 | $data .= "HOSTNAME=$hostname\n"; |
157 | } | |
2063d380 | 158 | $self->ct_file_set_contents($sysconfig_network, $data); |
c0eae401 | 159 | } |
c0eae401 DM |
160 | } |
161 | ||
162 | sub setup_network { | |
163 | my ($self, $conf) = @_; | |
164 | ||
c0eae401 DM |
165 | my ($gw, $gw6); |
166 | ||
f08b2779 | 167 | $self->ct_make_path('/etc/sysconfig/network-scripts'); |
c0eae401 | 168 | |
f0f32274 WB |
169 | my ($has_ipv4, $has_ipv6); |
170 | ||
c0eae401 DM |
171 | foreach my $k (keys %$conf) { |
172 | next if $k !~ m/^net(\d+)$/; | |
1b4cf758 | 173 | my $d = PVE::LXC::Config->parse_lxc_network($conf->{$k}); |
fa13a37a | 174 | next if !$d->{name}; |
f0f32274 WB |
175 | $has_ipv4 = 1 if defined($d->{ip}); |
176 | $has_ipv6 = 1 if defined($d->{ip6}); | |
fa13a37a | 177 | |
2063d380 | 178 | my $filename = "/etc/sysconfig/network-scripts/ifcfg-$d->{name}"; |
685d7b1c | 179 | my $routefile = "/etc/sysconfig/network-scripts/route-$d->{name}"; |
85e4f0cd | 180 | my $route6file = "/etc/sysconfig/network-scripts/route6-$d->{name}"; |
685d7b1c | 181 | my $routes = ''; |
85e4f0cd | 182 | my $routes6 = ''; |
d5a932a5 WB |
183 | |
184 | my $header = "DEVICE=$d->{name}\nONBOOT=yes\n"; | |
185 | my $data = ''; | |
186 | my $bootproto = ''; | |
fa13a37a WB |
187 | |
188 | if ($d->{ip} && $d->{ip} ne 'manual') { | |
fa13a37a | 189 | if ($d->{ip} eq 'dhcp') { |
d5a932a5 | 190 | $bootproto = 'dhcp'; |
fa13a37a | 191 | } else { |
d5a932a5 | 192 | $bootproto = 'none'; |
c0eae401 DM |
193 | my $ipinfo = PVE::LXC::parse_ipv4_cidr($d->{ip}); |
194 | $data .= "IPADDR=$ipinfo->{address}\n"; | |
195 | $data .= "NETMASK=$ipinfo->{netmask}\n"; | |
196 | if (defined($d->{gw})) { | |
197 | $data .= "GATEWAY=$d->{gw}\n"; | |
9da070e2 WB |
198 | if (!PVE::Network::is_ip_in_cidr($d->{gw}, $d->{ip}, 4)) { |
199 | $routes .= "$d->{gw} dev $d->{name}\n"; | |
85e4f0cd | 200 | $routes .= "default via $d->{gw} dev $d->{name}\n"; |
9da070e2 | 201 | } |
c0eae401 DM |
202 | } |
203 | } | |
fa13a37a WB |
204 | } |
205 | ||
206 | if ($d->{ip6} && $d->{ip6} ne 'manual') { | |
d5a932a5 | 207 | $bootproto = 'none' if !$bootproto; |
fa13a37a | 208 | $data .= "IPV6INIT=yes\n"; |
c6b8740b WB |
209 | if ($d->{ip6} eq 'auto') { |
210 | $data .= "IPV6_AUTOCONF=yes\n"; | |
c6b8740b | 211 | } |
fa13a37a WB |
212 | if ($d->{ip6} eq 'dhcp') { |
213 | $data .= "DHCPV6C=yes\n"; | |
214 | } else { | |
da78375e | 215 | $data .= "IPV6ADDR=$d->{ip6}\n"; |
fa13a37a | 216 | if (defined($d->{gw6})) { |
d13fd23a WB |
217 | if (!PVE::Network::is_ip_in_cidr($d->{gw6}, $d->{ip6}, 6) && |
218 | !PVE::Network::is_ip_in_cidr($d->{gw6}, 'fe80::/10', 6)) { | |
85e4f0cd WB |
219 | $routes6 .= "$d->{gw6} dev $d->{name}\n"; |
220 | $routes6 .= "default via $d->{gw6} dev $d->{name}\n"; | |
221 | } else { | |
222 | $data .= "IPV6_DEFAULTGW=$d->{gw6}\n"; | |
9da070e2 | 223 | } |
fa13a37a | 224 | } |
c0eae401 | 225 | } |
685d7b1c WB |
226 | } |
227 | ||
1db21128 | 228 | next unless $data || $bootproto; |
d5a932a5 WB |
229 | $header .= "BOOTPROTO=$bootproto\n"; |
230 | $self->ct_file_set_contents($filename, $header . $data); | |
2edb50e5 | 231 | $self->ct_modify_file($routefile, $routes, delete => 1, prepend => 1); |
85e4f0cd | 232 | $self->ct_modify_file($route6file, $routes6, delete => 1, prepend => 1); |
c0eae401 | 233 | } |
f0f32274 WB |
234 | |
235 | my $sysconfig_network = "/etc/sysconfig/network"; | |
236 | if ($self->ct_file_exists($sysconfig_network)) { | |
237 | my $data = $self->ct_file_get_contents($sysconfig_network); | |
238 | if ($has_ipv4) { | |
239 | if ($data !~ s/(NETWORKING)=\S+/$1=yes/) { | |
240 | $data .= "NETWORKING=yes\n"; | |
241 | } | |
242 | } | |
243 | if ($has_ipv6) { | |
244 | if ($data !~ s/(NETWORKING_IPV6)=\S+/$1=yes/) { | |
245 | $data .= "NETWORKING_IPV6=yes\n"; | |
246 | } | |
247 | } | |
248 | $self->ct_file_set_contents($sysconfig_network, $data); | |
249 | } | |
c0eae401 DM |
250 | } |
251 | ||
252 | 1; |