summaryrefslogtreecommitdiff
path: root/create-boot-floppy
blob: 6178e76ac551dec02b304522e22d5ca94b200573 (plain)
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
#!/bin/bash
#
# proof of concept script to create a bootable 'deployment' floppy
#
# This one can run on a centos7, to generate a boot floppy for a centos7.
# 

Self=$(basename $0)

function print_usage {
  echo "usage: $Self <options>"
}

function print_help {
cat <<EOF
$Self <options>

Script to create a bootable 'install' floppy image.

The image uses ipxe to retrieve a kernel to boot, and sets URLs for the
'install' initrd and kickstart config the kernel should use.

The whole thing is pretty CentOS 7 -centric at this point.

Options given to this script will set values for the bootstrapping of the 
*install* stage only. All values may subsequently be overridden from the 
kickstart stage, once that is retrieved and control is handed over to it.

Options:
  -D, --domain		domain, to complete FQDN
  -G, --gateway 	Gateway of target system
  -H, --host		hostname of the target system
  -I, --ip		IP address of target system
  -K, --kserver		Kickstart server
  -M, --netmask		Netmask of target system
  -N, --nameserver	Nameserver of target system
  -S, --cosmos-hash	Hash used by cosmos to verify stuff
  -h, --help		this

If --cosmos-hash is set to 'disabled', the kickstart stage should skip cosmos
bootstrapping, and leave the system unmanaged.

If -N, -K, -S options are not given, default values are provided.

The script needs ipxe and syslinux to run, and 'sudo' to copy things onto the
floppy image

EOF
}

function parse_commadline {
  while [ "$#" -gt 0 ] ; do
    case "$1" in
    -h|--help)
      print_help
      exit 0
      ;;
    -H|--host)
      Host="$2"
      shift
      ;;
    -D|--domain)
      Domain="$2"
      shift
      ;;
    -I|--ip)
      IP="$2"
      shift
      ;;
    -M|--netmask)
      NM="$2"
      shift
      ;;
    -G|--gateway)
      GW="$2"
      shift
      ;;
    -N|--nameserver)
      NS="$2"
      shift
      ;;
    -K|--kserver)
      Kserver="$2"
      shift
      ;;
    -P|--publish-path)
      PublishPath="$2"
      shift
      ;;
    -S|--cosmos-hash)
      CosmosHash="$2"
      shift
      ;;
    -T|--tmp-dir)
      TmpDir="${2}"
      shift
      ;;
    *)
      echo "what do you mean \"$1\"?"
      exit 1
      ;;
    esac
    shift
  done
}

function check_options {
  if [ "x${Host}" = "x" ]
  then
    echo "${Self}: --host is mandatory"
    print_usage
    exit 1
  fi
  if [ "x${Domain}" = "x" ]
  then
    echo "${Self}: --domain is mandatory"
    print_usage
    exit 1
  fi
  if [ "x${IP}" = "x" ]
  then
    echo "${Self}: --ip is mandatory"
    print_usage
    exit 1
  fi
  if [ "x${NM}" = "x" ]
  then
    echo "${Self}: --netmask is mandatory"
    print_usage
    exit 1
  fi
  if [ "x${GW}" = "x" ]
  then
    echo "${Self}: --gateway is mandatory"
    print_usage
    exit 1
  fi
  if [ "x${NS}" = "x" ]
  then
    NS="109.105.96.141"
  fi
  if [ "x${Kserver}" = "x" ]
  then
    Kserver="109.105.122.84"
  fi
  if [ "x${CosmosHash}" = "x" ]
  then
    CosmosHash="2f15e1edb02f14607084f167929bc145ed47954d"
  fi
  if [ "x${TmpDir}" = "x" ]
    then
    TmpDir=$(mktemp -d)
  else
    mkdir -p "${TmpDir}"
  fi
}

# Host="kas-fiona-10-02"
# Domain="nordu.net"
# IP="109.105.122.135"
# NM="255.255.255.192"
# GW="109.105.122.129"
# NS="109.105.96.141"
# Kserver="109.105.122.84"
# CosmosHash="2f15e1edb02f14607084f167929bc145ed47954d"

parse_commadline $@
check_options

####
# In a bid to be clever, we're adding the 'cosmos hash' to the install
# kernel cmdline. This is the one place that cannot be forged, changed, get
# lost or 'go missing' from the initial invocation here, until the
# anaconda/kickstart process takes over...

WorkDir="${TmpDir}/${Host}.d"
mkdir -p ${WorkDir}/mnt

dd if=/dev/zero of=${WorkDir}/${Host}.img bs=2x80x18b count=1
mkfs.ext2 -F "${WorkDir}/${Host}.img"
sudo mount -o loop ${WorkDir}/${Host}.img ${WorkDir}/mnt

sudo sh -c "cat >${WorkDir}/mnt/extlinux.conf <<EOF
default ipxelabel
label ipxelabel
kernel /ipxe.lkrn
append initrd=/${Host}.ipxe
EOF"

# We want to use variables in the rendered *.ipxe
# We want to populate the variables in the *.ipxe with variables from this
# script.
# Redirection of output from the here-doc into a file needs root privs, because
# there's no real directory structure in the floppy filesystem, and mounting
# as a user is... also complicated.
# This all leads to the 'sudo sh -c "cat ..."' construct, which works well
# ...except:
# Quoting and escapes get complicated as a consequence. The upshot is that
# you *can* use your variables, and keep them too, but it has a price.

sudo sh -c "cat >${WorkDir}/mnt/${Host}.ipxe <<EOF
#!ipxe
echo ${Host}
ifopen net0
###
# Set some variables:
set ip ${IP}
set nm ${NM}
set gw ${GW}
set ns ${NS}
set hn ${Host}
set dn ${Domain}
set ks ${Kserver}

###
# Set up network:
set net0/ip \\$"{"ip"}"
set net0/netmask \\$"{"nm"}"
set net0/gateway \\$"{"gw"}"
set dns \\$"{"ns"}"
set hostname \\$"{"hn"}"
set domain \\$"{"dn"}"
###
# Print some things on screen
echo \"Configured IP Details:\"
show net0/ip
show net0/netmask
show net0/gateway
show dns
show hostname
show domain
route
###
# Set install parameters:
set base http://\\$"{"ks"}"/install/centos/7/os/x86_64
kernel \\$"{"base"}"/images/pxeboot/vmlinuz text console=tty1 console=ttyS1,115200n8 ip=\\$"{"ip"}" netmask=\\$"{"nm"}" gateway=\\$"{"gw"}" repo=\\$"{"base"}" ks=http://\\$"{"ks"}"/install/ks/\\$"{"hn"}".ks cosmoshash=${CosmosHash}
initrd \\$"{"base"}"/images/pxeboot/initrd.img
###
# Boot into install
boot
####
# We really never should be here, but if we are, start a shell
echo \"why are we here?\"
shell
EOF
"

#read

if [ -r /etc/redhat-release ]
then
  sudo cp -a /usr/share/ipxe/ipxe.lkrn ${WorkDir}/mnt/
elif [ -r /etc/debian_version ]
then
  sudo cp -a /boot/ipxe.lkrn ${WorkDir}/mnt/
else
  echo "neither redhat nor debian, I'm outta here..."
  exit 1
fi
sudo extlinux --install ${WorkDir}/mnt/
sudo umount ${WorkDir}/mnt/

if [ ! "x${PublishPath}" = "x" ]
then
  mkdir -p "${PublishPath}/${Host}.d/"
  mv "${WorkDir}/${Host}.img" "${PublishPath}/${Host}.d/"
  rm -rf ${WorkDir}
else
  echo "no PublishPath set, leaving everything in ${WorkDir}"
fi