forked from JM1/bootstrap-fedora-coreos-with-redfish-bmc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bootstrap.sh
executable file
·202 lines (164 loc) · 7.95 KB
/
bootstrap.sh
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
#!/bin/bash
# vim:set tabstop=8 shiftwidth=4 expandtab:
# kate: space-indent on; indent-width 4;
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright (c) 2023 Jakob Meng, <[email protected]>
set -euxo pipefail
BMC_HOSTNAME_PORT=${BMC_HOSTNAME_PORT:-}
ENDPOINT=${ENDPOINT:-}
INSTALL_DEVICE=${INSTALL_DEVICE:?missing install device such as /dev/sda or /dev/nvme0n1}
error() {
echo "ERROR: $*" 1>&2
}
warn() {
echo "WARNING: $*" 1>&2
}
if command -v docker >/dev/null 2>&1; then
engine=docker
elif command -v podman >/dev/null 2>&1; then
engine=podman
else
error "Docker and Podman not found"
exit 125
fi
if [ "$(id -u)" -ne 0 ]; then
error "Please run as root"
exit 125
fi
cmd="$(readlink -f "$0")"
cd "$(dirname "$cmd")"
if ! "$engine" inspect "bootstrap-httpd:rawhide" >/dev/null 2>&1; then
"$engine" build -t "bootstrap-httpd:rawhide" .
fi
if [ -z "$("$engine" volume ls -q '--filter=name=^bootstrap-storage$')" ]; then
"$engine" volume create bootstrap-storage
fi
bootstrap_storage="$("$engine" volume inspect bootstrap-storage --format '{{ .Mountpoint }}')"
# always update to latest image
"$engine" pull quay.io/coreos/coreos-installer:release
"$engine" run --rm -v bootstrap-storage:/data -w /data \
quay.io/coreos/coreos-installer:release \
download -f iso --fetch-retries 3
rootfs_url=$(curl -s -L https://builds.coreos.fedoraproject.org/streams/stable.json \
| jq -r '.architectures.x86_64.artifacts.metal.formats.pxe.rootfs.location')
if [ ! -e "$bootstrap_storage/config.ign" ] || [ "config.bu" -nt "$bootstrap_storage/config.ign" ]; then
"$engine" run -i --rm quay.io/coreos/butane:release --pretty --strict \
< "config.bu" > "$bootstrap_storage/config.ign"
fi
last_coreos_iso=$(cd "$bootstrap_storage" && compgen -G "fedora-coreos-*-live.*.iso" | grep -v '.sig$' | sort | tail -n 1)
if [ ! -e "$bootstrap_storage/bootstrap-minimal.iso" ] \
|| [ "$cmd" -nt "$bootstrap_storage/bootstrap-minimal.iso" ] \
|| [ "$bootstrap_storage/$last_coreos_iso" -nt "$bootstrap_storage/bootstrap-minimal.iso" ] \
|| [ "$bootstrap_storage/config.ign" -nt "$bootstrap_storage/bootstrap-minimal.iso" ]; then
rm -f "$bootstrap_storage/bootstrap-minimal.iso"
# Do not use '--rootfs-url' option of 'coreos-installer iso extract minimal-iso' because it will
# be overwritten by any '--live-karg-append' option passed to 'coreos-installer iso customize'.
"$engine" run --rm -v bootstrap-storage:/data -w /data \
quay.io/coreos/coreos-installer:release \
iso extract minimal-iso \
"$last_coreos_iso" "bootstrap-minimal.iso"
chmod u=rw,g=r,o=r "$bootstrap_storage/bootstrap-minimal.iso"
# IPv6 is disabled because system might not provide internet connectivity with IPv6
"$engine" run --rm -v bootstrap-storage:/data -w /data \
quay.io/coreos/coreos-installer:release \
iso customize --force \
--dest-device "$INSTALL_DEVICE" \
--dest-ignition "config.ign" \
--live-karg-append "coreos.live.rootfs_url=$rootfs_url" \
--live-karg-append console=tty0 \
--live-karg-append console=ttyS0,115200 \
--live-karg-append earlyprintk=ttyS0,115200 \
--live-karg-append net.ifname-policy=mac \
--live-karg-append ipv6.disable=1 \
--dest-karg-append console=tty0 \
--dest-karg-append console=ttyS0,115200 \
--dest-karg-append earlyprintk=ttyS0,115200 \
--dest-karg-append net.ifname-policy=mac \
--dest-karg-append ipv6.disable=1 \
"bootstrap-minimal.iso"
fi
if [ -n "$("$engine" container ls -a -q '--filter=name=^bootstrap-httpd$')" ]; then
# Container exists
if [ -z "$("$engine" container ls -a -q '--filter=name=^bootstrap-httpd$' --filter=status=running)" ]; then
warn "Stopped container will be (re)started, but not rebuild. Remove container first to force rebuild."
"$engine" start bootstrap-httpd
fi
# Container is running
else
# Container does not exist
"$engine" run \
--detach \
--name bootstrap-httpd \
--cap-add=NET_ADMIN \
--security-opt no-new-privileges \
--security-opt label=disable \
--init \
--network=bridge \
-p 80:80 \
-p 443:443 \
-v "$PWD/etc/httpd/conf.d/coreos-installer.conf:/etc/httpd/conf.d/coreos-installer.conf:ro" \
-v "$PWD/etc/httpd/conf.d/welcome.conf:/etc/httpd/conf.d/welcome.conf:ro" \
-v 'bootstrap-storage:/var/www/coreos-installer/:ro' \
bootstrap-httpd:rawhide
# uid and gid of files and directories should be 0
fi
if [ -n "$BMC_HOSTNAME_PORT" ]; then
if [ -z "$ENDPOINT" ]; then
BMC_HOSTNAME=$(echo "$BMC_HOSTNAME_PORT" | cut -d ':' -f 1)
BMC_IP=$(getent hosts "$BMC_HOSTNAME" | head -n 1 | awk '{ print $1 }')
ENDPOINT=$(ip -j route get "$BMC_IP" | jq -r '.[0].prefsrc')
fi
read -r -s -p "Enter username and password for your BMC as 'username:password', e.g. 'root:secret':" bmc_user_pass
bmc_mgr0=$(curl --silent --insecure --user "$bmc_user_pass" "https://$BMC_HOSTNAME_PORT/redfish/v1/Managers/" | \
jq -r '.Members[0]."@odata.id"' | rev | cut -d '/' -f 1 | rev)
echo "Ejecting virtual media (ignore failures)"
curl --silent --insecure --user "$bmc_user_pass" -X POST \
"https://$BMC_HOSTNAME_PORT/redfish/v1/Managers/$bmc_mgr0/VirtualMedia/CD/Actions/VirtualMedia.EjectMedia" \
--header 'Content-Type: application/json' \
--data "{}"
echo "Inserting virtual media"
curl --silent --insecure --user "$bmc_user_pass" -X POST \
"https://$BMC_HOSTNAME_PORT/redfish/v1/Managers/$bmc_mgr0/VirtualMedia/CD/Actions/VirtualMedia.InsertMedia" \
--header 'Content-Type: application/json' \
--data "{\"Image\": \"http://$ENDPOINT/coreos-installer/bootstrap-minimal.iso\"}"
echo "Changing boot source to Utilities"
bmc_system0=$(curl --silent --insecure --user "$bmc_user_pass" "https://$BMC_HOSTNAME_PORT/redfish/v1/Systems/" | \
jq -r '.Members[0]."@odata.id"' | rev | cut -d '/' -f 1 | rev)
curl --silent --insecure --user "$bmc_user_pass" -X PATCH \
"https://$BMC_HOSTNAME_PORT/redfish/v1/Systems/$bmc_system0" \
--header 'Content-Type: application/json' \
--data '{"Boot": {"BootSourceOverrideTarget": "Utilities"}}'
echo "Powering off server"
curl --silent --insecure --user "$bmc_user_pass" -X POST \
"https://$BMC_HOSTNAME_PORT/redfish/v1/Systems/$bmc_system0/Actions/ComputerSystem.Reset" \
--header 'Content-Type: application/json' \
--data '{"ResetType":"ForceOff"}'
echo "Giving system time to power off"
sleep 15
echo "Powering on system"
curl --silent --insecure --user "$bmc_user_pass" -X POST \
"https://$BMC_HOSTNAME_PORT/redfish/v1/Systems/$bmc_system0/Actions/ComputerSystem.Reset" \
--header 'Content-Type: application/json' \
--data '{"ResetType":"On"}'
cat << ____EOF
Server is rebooting into BIOS setup. Choose booting from virtual media, e.g. Virtual Optical Drive. Wait until
installation of Fedora CoreOS has been completed and run
$engine stop bootstrap-httpd
to finish execution of this script.
____EOF
else
if [ -z "$ENDPOINT" ]; then
ENDPOINT=$(ip -j route get 1.1.1.1 | jq -r '.[0].prefsrc')
fi
cat << ____EOF
Point BMC of your bare-metal server to 'http://$ENDPOINT/coreos-installer/bootstrap-minimal.iso'. For example, use:
curl -v -k -X POST https://\$BMC_HOSTNAME_PORT/redfish/v1/Managers/iDRAC.Embedded.1/VirtualMedia/CD/Actions/VirtualMedia.InsertMedia \\
-u root \\
-H 'Content-Type: application/json' \\
-d '{"Image": "http://$ENDPOINT/coreos-installer/bootstrap-minimal.iso"}'
Next, reboot your server, wait until installation of Fedora CoreOS has been completed and run
$engine stop bootstrap-httpd
to finish execution of this script."
____EOF
fi
"$engine" wait bootstrap-httpd