]> git.proxmox.com Git - pve-container.git/blob - src/PVE/LXCSetup/Base.pm
implement dns setup for containers
[pve-container.git] / src / PVE / LXCSetup / Base.pm
1 package PVE::LXCSetup::Base;
2
3 use strict;
4 use warnings;
5
6 use PVE::Tools;
7
8 my $update_etc_hosts = sub {
9 my ($etc_hosts_data, $hostip, $oldname, $newname, $searchdomains) = @_;
10
11 my $done = 0;
12
13 my @lines;
14
15 my $extra_names = '';
16 foreach my $domain (PVE::Tools::split_list($searchdomains)) {
17 $extra_names .= ' ' if $extra_names;
18 $extra_names .= "$newname.$domain";
19 }
20
21 foreach my $line (split(/\n/, $etc_hosts_data)) {
22 if ($line =~ m/^#/ || $line =~ m/^\s*$/) {
23 push @lines, $line;
24 next;
25 }
26
27 my ($ip, @names) = split(/\s+/, $line);
28 if (($ip eq '127.0.0.1') || ($ip eq '::1')) {
29 push @lines, $line;
30 next;
31 }
32
33 my $found = 0;
34 foreach my $name (@names) {
35 if ($name eq $oldname || $name eq $newname) {
36 $found = 1;
37 } else {
38 # fixme: record extra names?
39 }
40 }
41 $found = 1 if defined($hostip) && ($ip eq $hostip);
42
43 if ($found) {
44 if (!$done) {
45 if (defined($hostip)) {
46 push @lines, "$hostip $extra_names $newname";
47 } else {
48 push @lines, "127.0.1.1 $newname";
49 }
50 $done = 1;
51 }
52 next;
53 } else {
54 push @lines, $line;
55 }
56 }
57
58 if (!$done) {
59 if (defined($hostip)) {
60 push @lines, "$hostip $extra_names $newname";
61 } else {
62 push @lines, "127.0.1.1 $newname";
63 }
64 }
65
66 my $found_localhost = 0;
67 foreach my $line (@lines) {
68 if ($line =~ m/^127.0.0.1\s/) {
69 $found_localhost = 1;
70 last;
71 }
72 }
73
74 if (!$found_localhost) {
75 unshift @lines, "127.0.0.1 localhost.localnet localhost";
76 }
77
78 $etc_hosts_data = join("\n", @lines) . "\n";
79
80 return $etc_hosts_data;
81 };
82
83 sub set_dns {
84 my ($class, $conf) = @_;
85
86 my $nameserver = $conf->{'pve.nameserver'};
87 my $searchdomains = $conf->{'pve.searchdomain'};
88
89 my $host_resolv_conf = PVE::INotify::read_file('resolvconf');
90
91 if (!($nameserver && $searchdomains)) {
92 $searchdomains = $host_resolv_conf->{search};
93
94 my @list = ();
95 foreach my $k ("dns1", "dns2", "dns3") {
96 if (my $ns = $host_resolv_conf->{$k}) {
97 push @list, $ns;
98 }
99 }
100 $nameserver = join(' ', @list);
101 }
102
103 my $rootfs = $conf->{'lxc.rootfs'};
104
105 my $filename = "$rootfs/etc/resolv.conf";
106
107 my $data = '';
108
109 $data .= "search " . join(' ', PVE::Tools::split_list($searchdomains)) . "\n"
110 if $searchdomains;
111
112 foreach my $ns ( PVE::Tools::split_list($nameserver)) {
113 $data .= "nameserver $ns\n";
114 }
115
116 PVE::Tools::file_set_contents($filename, $data);
117 }
118
119 sub set_hostname {
120 my ($class, $conf) = @_;
121
122 my $hostname = $conf->{'lxc.utsname'} || 'localhost';
123
124 $hostname =~ s/\..*$//;
125
126 my $rootfs = $conf->{'lxc.rootfs'};
127
128 my $hostname_fn = "$rootfs/etc/hostname";
129
130 my $oldname = PVE::Tools::file_read_firstline($hostname_fn) || 'localhost';
131
132 my $hosts_fn = "$rootfs/etc/hosts";
133 my $etc_hosts_data = '';
134
135 if (-f $hosts_fn) {
136 $etc_hosts_data = PVE::Tools::file_get_contents($hosts_fn);
137 }
138
139 my ($ipv4, $ipv6) = PVE::LXC::get_primary_ips($conf);
140 my $hostip = $ipv4 || $ipv6;
141
142 $etc_hosts_data = &$update_etc_hosts($etc_hosts_data, $hostip, $oldname,
143 $hostname, $conf->{'pve.searchdomain'});
144
145 PVE::Tools::file_set_contents($hostname_fn, "$hostname\n");
146 PVE::Tools::file_set_contents($hosts_fn, $etc_hosts_data);
147 }
148
149 sub setup_network {
150 my ($class, $conf) = @_;
151
152 die "please implement this inside subclass"
153 }
154
155 sub setup_init {
156 my ($class, $conf) = @_;
157
158 die "please implement this inside subclass"
159 }
160
161 sub pre_start_hook {
162 my ($class, $conf) = @_;
163
164 $class->setup_init($conf);
165 $class->setup_network($conf);
166 $class->set_hostname($conf);
167 $class->set_dns($conf);
168
169 # fixme: what else ?
170 }
171
172 sub post_create_hook {
173 my ($class, $conf) = @_;
174
175 $class->setup_init($conf);
176 $class->setup_network($conf);
177 $class->set_hostname($conf);
178 $class->set_dns($conf);
179
180 # fixme: what else ?
181 }
182
183 1;