forked from xenserver/host-installer
-
Notifications
You must be signed in to change notification settings - Fork 2
/
init
executable file
·255 lines (217 loc) · 7.9 KB
/
init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#!/usr/bin/env python
# SPDX-License-Identifier: GPL-2.0-only
from __future__ import print_function
import sys
import os
import os.path
import signal
import subprocess
# user interface:
import tui
import tui.init
import tui.progress
import install
import init_constants
import netutil
import diskutil
import disktools
import util
from netinterface import *
from xcp import logger
from version import *
# Attempt to configure the network:
def configureNetworking(ui, device, config):
if ui:
ui.progress.showMessageDialog(
"Preparing for installation",
"Attempting to configure networking..."
)
if device == 'all':
config = 'dhcp'
mode, rest = config.split(":", 1) if config and ":" in config else (config, None)
config_dict = {'gateway': None, 'dns': None, 'domain': None, 'vlan': None}
if rest:
for el in rest.split(';'):
k, v = el.split('=', 1)
config_dict[k] = v
if mode == 'static':
if config_dict['dns'] is not None:
config_dict['dns'] = config_dict['dns'].split(',')
assert 'ip' in config_dict and 'netmask' in config_dict
if config_dict['vlan']:
if not netutil.valid_vlan(config_dict['vlan']):
raise RuntimeError("Invalid VLAN value for installer network")
config_dict['vlan'] = int(config_dict['vlan'])
nethw = netutil.scanConfiguration()
netcfg = {}
for i in nethw:
if (device == i or device == nethw[i].hwaddr) and mode == 'static':
netcfg[i] = NetInterface(NetInterface.Static, nethw[i].hwaddr,
config_dict['ip'], config_dict['netmask'],
config_dict['gateway'], config_dict['dns'],
config_dict['domain'], config_dict['vlan'])
else:
netcfg[i] = NetInterface(NetInterface.DHCP, nethw[i].hwaddr,
vlan=config_dict['vlan'])
netutil.writeNetInterfaceFiles(netcfg)
netutil.writeResolverFile(netcfg, '/etc/resolv.conf')
iface_to_start = []
if device == 'all':
iface_to_start.extend(list(netcfg.keys()))
elif device.startswith('eth'):
if device in nethw:
iface_to_start.append(device)
else:
# MAC address
matching_list = [x for x in nethw.values() if x.hwaddr == device]
if len(matching_list) == 1:
devname = matching_list[0].name
iface_to_start.append(devname)
for i in iface_to_start:
netutil.ifup(netcfg[i].getInterfaceName(i))
netcfg[i].waitUntilUp(i)
if ui:
ui.progress.clearModelessDialog()
def sig_term(x, y):
logger.log("Killed by another instance, terminating")
os.system('/usr/bin/clear')
sys.exit(0)
def main(args):
# log to tty3
logger.openLog('/dev/tty3')
logger.openLog('/tmp/install-log')
tty = None
signal.signal(signal.SIGTERM, sig_term)
try:
tty = os.path.basename(os.readlink('/proc/self/fd/0'))
pidfile = open('/var/run/installer-%s.pid' % tty, 'w')
print(os.getpid(), file=pidfile)
pidfile.close()
except:
pass
ui = tui
interactive = True
answer_device = 'all'
answer_config = 'dhcp'
init_network = False
reboot = False
answerfile_address = None
answerfile_script = None
mpath = False
use_ibft = False
netdev_map = []
try:
installer_version = subprocess.check_output(
['rpm', '-q', '--qf', '%{VERSION}-%{RELEASE}', 'host-installer'])
except Exception:
installer_version = 'unknown'
logger.log("%s Setup - Version %s" % (PRODUCT_BRAND or PLATFORM_NAME, PRODUCT_VERSION_TEXT))
logger.log("Installer Version %s" % (installer_version,))
logger.log("Command line args: %s" % str(args))
for (opt, val) in args.items():
if opt == "--answerfile":
answerfile_address = val
interactive = False
if not val.startswith('file://'):
init_network = True
elif opt == "--rt_answerfile":
answerfile_address = val
interactive = False
if not val.startswith('file://'):
init_network = True
ui = None
logger.openLog(sys.stdout)
elif opt == "--answerfile_generator":
answerfile_script = val
interactive = False
if not val.startswith('file://'):
init_network = True
elif opt in ['--answerfile_device', '--network_device']:
answer_device = val.lower()
init_network = True
elif opt == '--network_config':
answer_config = val.lower()
elif opt == "--reboot":
reboot = True
elif opt == "--device_mapper_multipath":
if val.lower() in [ "disabled", "false", "0", "no" ]:
mpath = False
elif val.lower() in [ "enabled", "true", "1", "yes", "force"]:
mpath = True
elif opt == "--use_ibft":
use_ibft = True
elif opt == "--map_netdev":
netdev_map = val
# start the user interface:
if ui:
# switch to ISO 8859-1 mode so line drawing characters work as expected on
# vt100 terminals.
print("\033%@")
logger.log("Starting 'init' user interface on %s" % tty)
ui.init_ui()
# let the user choose what they would like to do:
if interactive:
# choose keymap
kmap = ui.init.get_keymap()
if tty:
try:
# terminate any additional instances of the installer
for p in os.listdir('/var/run'):
if p != 'installer-%s.pid' % tty and p.startswith('installer-'):
f = open('/var/run/'+p)
pid = int(f.readline())
f.close()
logger.log("Killing installer with pid %d" % pid)
os.kill(pid, signal.SIGTERM)
except:
pass
args['--keymap'] = kmap
logger.log("Loading keymap %s" % kmap)
util.runCmd2(["/bin/loadkeys", kmap])
# Always sanitise netdevs - it generates
# data for later in the install
# CA-60620 - dont try and run remap_netdevs in the codepath where we are
# running several concurrent instances. It causes fun with competing
# /sbin/ip renames
netutil.remap_netdevs(netdev_map)
# Attaches iSCSI disks listed in iSCSI Boot Firmware Tables. This may
# reserve NICs and so should be called before netutil.scanConfiguration
if use_ibft:
try:
diskutil.process_ibft(ui, interactive)
except Exception as e:
logger.logException(e)
if ui:
ui.exn_error_dialog("install-log", False, interactive)
return reboot
raise
# ensure partitions/disks are not locked by LVM
# this should be done before attempting to enable multipath
lvm = disktools.LVMTool()
lvm.deactivateAll()
del lvm
# Ensure multipath devices are created unless installer is being
# run with the "--device_mapper_multipath=disabled" option
if mpath:
diskutil.mpath_enable()
if ui:
netutil.setAllLinksUp()
if init_network:
configureNetworking(ui, answer_device, answer_config)
logger.log("Starting installation/upgrade/restore")
rc = install.go(ui, args, answerfile_address, answerfile_script)
if ui:
ui.end_ui()
# Bring down multipath devices to ensure they're flushed
if mpath:
diskutil.mpath_disable()
# Log out of any iSCSI disks
if use_ibft:
diskutil.release_ibft_disks()
# stop logging to tty3:
logger.closeLogs()
return reboot
if __name__ == "__main__":
reboot = main(util.splitArgs(sys.argv[1:], ('--console', '--map_netdev', '--mount')))
if reboot:
os.system("reboot")