-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathbecome_pandemic_master
executable file
·310 lines (285 loc) · 9.37 KB
/
become_pandemic_master
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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#!/bin/bash -x
# ---------------------------------
# become_pandemic_master
# makes the machine a pandemic master
#
# Usage:
# 1. boot pandemic master with Ubuntu Live CD
# (or a customized Live CD, made by
# make_customize_live.mk)
# 2. open shell and run this script by:
#
# ./become_pandemic_master
#
# What happens?
# the above command turns this machine into
# a pandemic master. see README for the basics,
# but here is what basically happens. it is based on
# the approach described in
# http://d.hatena.ne.jp/adsaria/20090206/1233905956
# the above page describes how to pxe-boot
# clients, as if the they booted from Live CD.
#
# 1. assign a static IP address to the network
# interface through which talk to its clients.
# the interface and static IP address can be
# specified below by setting 'pandemic_netif'
#
# 2. install DHCP server (isc-dhcp-server) and
# generate its config file /etc/dhcp/dhcpd.conf
# so that it serves any client connected to
# the same network. it specifies next-server to
# this machine, so that PXE-booted clients first
# obtains IP address from this machine and then
# try to get kernel from the TFTP server running
# on this machine.
#
# 3. install TFTP server (tftpd-hpa) and syslinux,
# and generate TFTP server's config file
# - generate
#
# /var/lib/tftpboot/pxelinux.cfg/default
#
# so that the tftp server sends a kernel and
# initrd image to any client that successfully
# contacted to the DHCP server.
#
# 4. install NFS server (nfs-kernel-server) and
# export an nfsroot, which is used as the root
# file system of any client who contacted to
# the TFTP server
#
# ---------------------------------
# variables you may want to customize
# ---------------------------------
# (0) media directory. the directory on which the Live CD
# is mounted. it is /cdrom when we boot up from CD.
# it should be something else I have not yet tested.
# you should set it so that you can find ${media}/casper
# directory
media=/cdrom
# (1) network interface through which this machine (master)
# is connected to clients. this script OVERWRITES its
# address and subnet.
#pandemic_netif=eth0
pandemic_netif=$(ls /sys/class/net | grep enp | head -1)
# (2) the first three octets of the subnet in which master
# and clients speak;
# TODO: currently, we assume the network is a /24 network
pandemic_subnet=10.0.3
# (3) the master's IP address
# if you ever want to customize this, make sure this does not
# overlap with the pandemic_client_range
pandemic_net_ipaddr=${pandemic_subnet}.15
pandemic_net_bcast=${pandemic_subnet}.255
pandemic_net_mask=255.255.255.0
# (4) IP address range for the clients
# this string is written into dhcpd.conf
pandemic_client_range="${pandemic_subnet}.100 ${pandemic_subnet}.199"
# (5) distribution name; it just names the nfsroot directory.
# otherwise it does not matter
# it must be "grub" when using UEFI (grubnetx64.efi)
distro=grub
# (6) name of the nfsroot directory.
# in my experience, it cannot not /var directory. NFS
# server complains saying it cannot be exported.
# stick with a directory under /tmp
#nfsroot=/tmp/`whoami`/${distro}
nfsroot=/rofs/client_root
# ---------------------------------
# install and configure DHCP server
# ---------------------------------
conf_net() {
conf=/etc/network/interfaces
bak=/tmp/interfaces
diff=/tmp/interfaces.diff
cat > ${diff} <<EOF
auto ${pandemic_netif}
iface ${pandemic_netif} inet static
address ${pandemic_net_ipaddr}
netmask ${pandemic_net_mask}
broadcast ${pandemic_net_bcast}
EOF
if ! test -e ${bak} ; then
cp ${conf} ${bak}
fi
# append it to the end of the original file
cat ${bak} ${diff} > ${conf}
# configure network
# don't do this: this will halt desktop
# service networking restart
# with eth0 statically configured in /etc/network/interfaces,
# network-manager does not bother to reconfigure it, as long
# as you restart it
service network-manager restart
# wait for the dynamic network connection to become up
if false ; then
for i in `seq 1 5`; do
if ping -w 1 -c 1 www.google.com ; then break; fi
sleep 1
done
if ! ping -w 1 -c 1 www.google.com ; then
echo "note: not connected to outside network"
fi
fi
# now bring up statically configured network interface
ifup ${pandemic_netif}
}
# ---------------------------------
# install and configure DHCP server
# ---------------------------------
conf_dhcp() {
# apt-get
apt-get -y install isc-dhcp-server
conf=/etc/dhcp/dhcpd.conf
bak=/tmp/dhcpd.bak
diff=/tmp/dhcpd.diff
default=/etc/default/isc-dhcp-server
# generate config file
# only importants are
# next-server, which says clients should contact
# tftp server.
# - filename, which says a bootloader the tftp server
# uses. it is relative to tftp server's root: /var/lib/tftpboot,
# so it means /var/lib/tftpboot/pxelinux.0
cat > ${diff} <<EOF
authoritative;
allow unknown-clients;
subnet ${pandemic_subnet}.0 netmask 255.255.255.0 {
range ${pandemic_client_range};
option broadcast-address ${pandemic_subnet}.255;
option domain-name-servers ${pandemic_net_ipaddr};
option domain-name "localnet"; # Domain name
option routers ${pandemic_net_ipaddr};
next-server ${pandemic_net_ipaddr}; # should be IP address
# filename "pxelinux.0";
# filename "BOOTx64.EFI";
# filename "grubx64.efi";
filename "grubnetx64.efi.signed";
}
EOF
# copy the original, if it is the first time
if ! test -e ${bak} ; then
cp ${conf} ${bak}
fi
# append it to the end of the original file
cat ${bak} ${diff} > ${conf}
# edit default file
sed --in-place=.bak -e s/INTERFACES=\"\"/INTERFACES=\"${pandemic_netif}\"/g ${default}
# (re)start the server
# initctl reload-configuration
service isc-dhcp-server restart
}
find_initrd() {
for initrd in initrd.lz initrd never_exist ; do
if [ -e ${media}/casper/${initrd} ]; then
echo ${initrd}
return 0
fi
done
echo "error: could not find initrd{.lz} in ${media}/casper/" 1>&2
exit 1
}
# ---------------------------------
# install tftp server
# ---------------------------------
conf_tftp() {
apt-get -y install tftpd-hpa
tftpboot=/var/lib/tftpboot
mkdir -p ${tftpboot}/pxelinux.cfg
# generate /var/lib/tftpboot/pxelinux.cfg/default;
# it uses a kernel (vmlinuz) and initrd image found in Live CD media.
# systemd.mask=tmp.mount is a workaround necessary to pxeboot
# clients based on 18.04. see
# https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1755863
initrd=$(find_initrd)
cat > ${tftpboot}/pxelinux.cfg/default <<EOF
default live
label live
kernel /${distro}/casper/vmlinuz
append initrd=/${distro}/casper/${initrd} boot=casper netboot=nfs nfsroot=${pandemic_net_ipaddr}:${nfsroot} systemd.mask=tmp.mount quiet splash --
EOF
# copy kernel and initrd image to tftp's directory
# (note: tftp server cannot see anywhere above /var/lib/tftpboot)
mkdir -p ${tftpboot}/${distro}/casper
cp -r ${media}/casper/vmlinuz ${media}/casper/${initrd} ${tftpboot}/${distro}/casper/
service tftpd-hpa restart
}
# ---------------------------------
# make nfsroot
# we use directory in Live CD
# ---------------------------------
conf_nfsroot() {
# install NFS server
apt-get -y install nfs-kernel-server
# export the nfsroot
cat > /etc/exports <<EOF
${nfsroot} *(fsid=0,ro,all_squash,no_subtree_check,crossmnt)
EOF
# (re)start servers
# initctl reload-configuration
service nfs-kernel-server restart
}
# ---------------------------------
# syslinux and tftp configuration
# ---------------------------------
conf_syslinux() {
# install syslinux
apt-get -y install syslinux
apt-get -y install pxelinux
# install bootloader (BIOS)
cp /usr/lib/PXELINUX/pxelinux.0 ${tftpboot}/ || cp /usr/lib/syslinux/pxelinux.0 ${tftpboot}/
cp /usr/lib/syslinux/modules/bios/ldlinux.c32 ${tftpboot}/
}
# ---------------------------------
# grub efi bootloader
# ---------------------------------
conf_grub_efi() {
apt-get -y install grub-efi-amd64-signed
apt-get -y install shim-signed
cp /usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed ${tftpboot}/
# cp /usr/lib/shim/shimx64.efi.signed ${tftpboot}/
initrd=$(find_initrd)
cat > ${tftpboot}/${distro}/grub.cfg <<EOF
set timeout=10
menuentry 'Live' {
net_ls_cards
net_ls_addr
linuxefi /${distro}/casper/vmlinuz ro systemd.mask=tmp.mount ip=dhcp boot=casper netboot=nfs nfsroot=10.0.3.15:/rofs/client_root quiet splash --
initrdefi /${distro}/casper/${initrd}
}
EOF
}
# ---------------------------------
# run additional customization
# ---------------------------------
conf_user() {
apt-get -y install make
for d in `ls -1d master_scripts/S*/` ; do
make -C $d -f `basename $d`.mk
done
}
# ---------------------------------
# restart all services again
# I don't know exactly why we need this.
# but unless we restart them again, pxeboot fails
# after DHCP (clients fail to contact tftp server)
# ---------------------------------
restart_services_again() {
service isc-dhcp-server restart
service tftpd-hpa restart
service nfs-kernel-server restart
}
main() {
set -e
export LANG=C
conf_net
conf_dhcp
conf_tftp
conf_nfsroot
conf_syslinux
conf_grub_efi
conf_user
restart_services_again
}
main