forked from Bitmessage/sysdeploy
Refactor to install and chainload IPXE
This commit is contained in:
parent
8c58dcbd70
commit
6cb980775b
69
install.inc
69
install.inc
|
@ -1,69 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
. maas-images.inc
|
|
||||||
. syslinux-menu.inc
|
|
||||||
|
|
||||||
function download_version()
|
|
||||||
{
|
|
||||||
local release_version="$1"
|
|
||||||
local drive="$2"
|
|
||||||
local downloads=~/Downloads
|
|
||||||
|
|
||||||
mkdir -p "$downloads"
|
|
||||||
pushd "$downloads"
|
|
||||||
|
|
||||||
download_and_verify "$release_version" boot-kernel
|
|
||||||
if [ $? -eq 1 ]; then
|
|
||||||
popd
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
download_and_verify "$release_version" boot-initrd
|
|
||||||
if [ $? -eq 1 ]; then
|
|
||||||
popd
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
download_and_verify "$release_version" squashfs
|
|
||||||
if [ $? -eq 1 ]; then
|
|
||||||
popd
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
popd
|
|
||||||
}
|
|
||||||
|
|
||||||
function install_version()
|
|
||||||
{
|
|
||||||
local drive="$2"
|
|
||||||
local target
|
|
||||||
local downloads=~/Downloads
|
|
||||||
|
|
||||||
mkdir -p "$downloads"
|
|
||||||
|
|
||||||
find_unused "$drive"
|
|
||||||
target="$unused"
|
|
||||||
if [ -z "$unused" ]; then
|
|
||||||
find_oldest "$drive"
|
|
||||||
target="$unused"
|
|
||||||
fi
|
|
||||||
if [ -z "$target" ]; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
pushd "$downloads"
|
|
||||||
mount_efi "$drive"
|
|
||||||
mkdir -p "$mnt""$imagepath"
|
|
||||||
[ -f "$mnt""$imagepath"/boot-initrd."$release_version" ] || \
|
|
||||||
cp boot-initrd "$mnt""$imagepath"/boot-initrd."$release_version"
|
|
||||||
[ -f "$mnt""$imagepath"/boot-kernel."$release_version" ] || \
|
|
||||||
cp boot-kernel "$mnt""$imagepath"/boot-kernel."$release_version"
|
|
||||||
umount_efi
|
|
||||||
|
|
||||||
dev_from_partnum "$drive" "$target"
|
|
||||||
dd if=squashfs of="$partition" bs=1M
|
|
||||||
rename_partition "$drive" "$target" root_"$release_version"
|
|
||||||
popd
|
|
||||||
update_syslinux_menu "$drive"
|
|
||||||
}
|
|
||||||
|
|
||||||
#function cleanup_version()
|
|
||||||
|
|
||||||
# vim: set ft=sh:
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
. install.inc
|
|
||||||
. drive.inc
|
. drive.inc
|
||||||
|
. syslinux.inc
|
||||||
|
|
||||||
declare -a drives
|
declare -a drives
|
||||||
|
|
||||||
|
@ -12,14 +12,7 @@ if [ ${#drives[@]} -eq 0 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
get_streams
|
|
||||||
get_latest_maas_id
|
|
||||||
|
|
||||||
for drive in "${drives[@]}"; do
|
for drive in "${drives[@]}"; do
|
||||||
setup_drive "$drive"
|
setup_drive "$drive"
|
||||||
install_syslinux "$drive"
|
install_syslinux "$drive"
|
||||||
download_version "$release_version" "$drive"
|
|
||||||
install_version "$release_version" "$drive"
|
|
||||||
update_syslinux_menu "$drive"
|
|
||||||
done
|
done
|
||||||
cleanup_temp
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
function download_and_verify_ipxe()
|
||||||
|
{
|
||||||
|
local ipxe_path="$1"
|
||||||
|
local ipxeshasum1='a'
|
||||||
|
local ipxeshasum2='b'
|
||||||
|
|
||||||
|
which wget || /bin/false
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
apt update -yq && apt -yq install wget
|
||||||
|
fi
|
||||||
|
|
||||||
|
# This will actually be a Gitea release download for the lastest master
|
||||||
|
wget https://images.sysdeploy.org/path/to/buildbot/latest/ipxe.lkrn -O "$ipxe_path" || echo "download failed" > "$ipxe_path"
|
||||||
|
wget https://images.sysdeploy.org/path/to/buildbot/latest/SHA256SUMS -O "${ipxe_path}.sha256sums" || echo "z ipxe.lkrn" > "${ipxe_path}.sha256sums"
|
||||||
|
|
||||||
|
ipxeshasum1=$(cat "${ipxe_path}.sha256sums" | grep "ipxe.lkrn" | awk '{print $1}' | tr -d '\n')
|
||||||
|
ipxeshasum2=$(sha256sum "$ipxe_path" | awk '{print $1}' | tr -d '\n')
|
||||||
|
|
||||||
|
rm -f "${ipxe_path}.sha256sums"
|
||||||
|
|
||||||
|
if [ "${ipxeshasum1}" != "${ipxeshasum1}" ]; then
|
||||||
|
ipxe_dl_verify=1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function install_ipxe()
|
||||||
|
{
|
||||||
|
local ipxe_install_path="$1"
|
||||||
|
local temp_dir="$(mktemp -d)"
|
||||||
|
local ipxe_path="${temp_dir}/ipxe.lkrn"
|
||||||
|
|
||||||
|
ipxe_dl_verify=0
|
||||||
|
download_and_verify_ipxe "$ipxe_path"
|
||||||
|
|
||||||
|
if (( ipxe_dl_verify > 0 )); then
|
||||||
|
>&2 echo ""
|
||||||
|
>&2 echo "Failed to download and verify IPXE kernel binary."
|
||||||
|
>&2 echo "In order to avoid disk partition issues, the syslinux install process"
|
||||||
|
>&2 echo "will continue. But you must manually download and copy the ipxe x86"
|
||||||
|
>&2 echo "lkrn file to ${ipxe_install_path}. If a file currently exists at that"
|
||||||
|
>&2 echo "path, it has not been touched."
|
||||||
|
>&2 echo ""
|
||||||
|
else
|
||||||
|
rm -f "${ipxe_install_path}"
|
||||||
|
cp "${ipxe_path}" "${ipxe_install_path}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
unset ipxe_dl_verify
|
||||||
|
|
||||||
|
rm -f "$ipxe_path"
|
||||||
|
rm -rf "$temp_dir"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# vim: set ft=sh:
|
|
@ -1,96 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
OS_CODENAME=focal
|
|
||||||
OS_VERSION=20.04
|
|
||||||
|
|
||||||
|
|
||||||
function get_streams()
|
|
||||||
{
|
|
||||||
if [ -e "$streams" ]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
streams="$(mktemp)"
|
|
||||||
wget -qO "$streams" https://images.maas.io/ephemeral-v3/stable/streams/v1/com.ubuntu.maas:stable:v3:download.json
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_latest_maas_id()
|
|
||||||
{
|
|
||||||
if [ ! -f "$streams" ]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
release_version=$(jq -r '.products[]|select(.version=="'"$OS_VERSION"'" and .arch=="amd64" and .kflavor=="generic" and .subarch=="ga-'"$OS_VERSION"'")|.versions|keys|max' \
|
|
||||||
"$streams")
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_checksum()
|
|
||||||
{
|
|
||||||
local release_version="$1"
|
|
||||||
local filename="$2"
|
|
||||||
if [ ! -f "$streams" ]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
checksum=$(jq -r '.products[]|select(.version=="'"$OS_VERSION"'" and .arch=="amd64" and .kflavor=="generic" and .subarch=="ga-'"$OS_VERSION"'").versions."'"$release_version"'".items."'"$filename"'".sha256' \
|
|
||||||
"$streams")
|
|
||||||
}
|
|
||||||
|
|
||||||
function file_url()
|
|
||||||
{
|
|
||||||
local release_version="$1"
|
|
||||||
local filename="$2"
|
|
||||||
local baseurl="https://images.maas.io/ephemeral-v3/stable"
|
|
||||||
|
|
||||||
if [ ! -f "$streams" ]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
url=$(jq -r '.products[]|select(.version=="'"$OS_VERSION"'" and .arch=="amd64" and .kflavor=="generic" and .subarch=="ga-'"$OS_VERSION"'").versions."'"$release_version"'".items."'"$filename"'".path' \
|
|
||||||
"$streams")
|
|
||||||
if [ -n "$MAAS_DOWNLOAD_URL" ]; then
|
|
||||||
baseurl="$MAAS_DOWNLOAD_URL"
|
|
||||||
fi
|
|
||||||
url="$baseurl/$url"
|
|
||||||
}
|
|
||||||
|
|
||||||
function verify_only()
|
|
||||||
{
|
|
||||||
local release_version="$1"
|
|
||||||
local fname="$2"
|
|
||||||
get_checksum "$release_version" "$fname"
|
|
||||||
sha256sum=$(sha256sum "$fname"|cut -d\ -f1)
|
|
||||||
if [ "$sha256sum" == "$checksum" ]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
function download_and_verify()
|
|
||||||
{
|
|
||||||
local release_version="$1"
|
|
||||||
local fname="$2"
|
|
||||||
|
|
||||||
file_url "$release_version" "$fname"
|
|
||||||
|
|
||||||
if [ -f "$fname" ]; then
|
|
||||||
if verify_only "$release_version" "$fname"; then
|
|
||||||
echo "$fname already downloaded, skipping"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
echo "Deleting $fname"
|
|
||||||
rm -f "$fname"
|
|
||||||
fi
|
|
||||||
wget "$url" -O "$fname"
|
|
||||||
if verify_only "$release_version" "$fname"; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
echo "Checksum fail"
|
|
||||||
rm -f "$fname"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
function cleanup_temp()
|
|
||||||
{
|
|
||||||
if [ -f "$streams" ]; then
|
|
||||||
rm -f "$streams"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# vim: set ft=sh:
|
|
|
@ -1,63 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
. syslinux.inc
|
|
||||||
. drive.inc
|
|
||||||
imagepath='/os/focal-maas'
|
|
||||||
|
|
||||||
function update_syslinux_menu()
|
|
||||||
{
|
|
||||||
local drive="$1"
|
|
||||||
declare -A versions
|
|
||||||
declare -a files
|
|
||||||
|
|
||||||
files=('boot-kernel.' 'boot-initrd.')
|
|
||||||
|
|
||||||
mount_efi "$drive"
|
|
||||||
|
|
||||||
find_newest "$drive"
|
|
||||||
|
|
||||||
> "$mnt"/syslinux/items.cfg
|
|
||||||
if [ -n "$newest" ]; then
|
|
||||||
version_from_partnum "$drive" "$newest"
|
|
||||||
echo "DEFAULT cloud-init-$version" >> "$mnt"/syslinux/items.cfg
|
|
||||||
fi
|
|
||||||
|
|
||||||
partition_list "$drive"
|
|
||||||
for part in $partitions; do
|
|
||||||
version_from_partnum "$drive" "$part"
|
|
||||||
if [ -z "$version" ]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
versions["$version"]=1
|
|
||||||
missing=""
|
|
||||||
for f in "${files[@]}"; do
|
|
||||||
if [ ! -e "$mnt""$imagepath"/"$f""$version" ]; then
|
|
||||||
missing="1"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [ -n "$missing" ]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
cat >> "$mnt"/syslinux/items.cfg << _EOL_
|
|
||||||
|
|
||||||
LABEL cloud-init-$version
|
|
||||||
MENU LABEL Ubuntu focal (MAAS $version)
|
|
||||||
KERNEL $imagepath/boot-kernel.$version
|
|
||||||
APPEND initrd=$imagepath/boot-initrd.$version root=PARTLABEL="root_$version" ip=dhcp overlayroot=tmpfs:recurse=0 ds=nocloud-net;s=https://box.sysdeploy.org/cloud-init/
|
|
||||||
_EOL_
|
|
||||||
done
|
|
||||||
|
|
||||||
# find expired
|
|
||||||
for f in "${files[@]}"; do
|
|
||||||
for i in "$mnt""$imagepath"/"$f"*; do
|
|
||||||
version="$(basename "$i"|cut -d. -f2-)"
|
|
||||||
if [ -z "${versions[$version]}" ]; then
|
|
||||||
rm -f $i
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
umount_efi
|
|
||||||
}
|
|
||||||
|
|
||||||
# vim: set ft=sh:
|
|
17
syslinux.inc
17
syslinux.inc
|
@ -1,5 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
. ipxe.inc
|
||||||
|
|
||||||
|
|
||||||
function dev_from_partnum()
|
function dev_from_partnum()
|
||||||
{
|
{
|
||||||
local drive="$1"
|
local drive="$1"
|
||||||
|
@ -30,7 +33,7 @@ function mount_efi()
|
||||||
mkfs.vfat "$partition"
|
mkfs.vfat "$partition"
|
||||||
if ! mount "$partition" "$mnt"; then
|
if ! mount "$partition" "$mnt"; then
|
||||||
echo "Can't mount \"$partition\""
|
echo "Can't mount \"$partition\""
|
||||||
cleanup_mnt
|
#cleanup_mnt # Commented out by Max because it's not defined anywhere.
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -43,6 +46,7 @@ function umount_efi()
|
||||||
rmdir "$mnt"
|
rmdir "$mnt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function install_syslinux()
|
function install_syslinux()
|
||||||
{
|
{
|
||||||
local drive="$1"
|
local drive="$1"
|
||||||
|
@ -67,6 +71,17 @@ function install_syslinux()
|
||||||
cp syslinux/{mainmenu,syslinux}.cfg "$mnt"/syslinux
|
cp syslinux/{mainmenu,syslinux}.cfg "$mnt"/syslinux
|
||||||
cp syslinux/syslx64.cfg "$mnt"/EFI/BOOT
|
cp syslinux/syslx64.cfg "$mnt"/EFI/BOOT
|
||||||
|
|
||||||
|
# These two are called here, because I was unsure if they needed to be
|
||||||
|
# set before the syslinux installer ran below. If not, they can be
|
||||||
|
# moved elsewhere to make this section cleaner and more readable.
|
||||||
|
install_ipxe "${mnt}/syslinux/ipxe.lkrn"
|
||||||
|
cat > "$mnt"/syslinux/items.cfg << _EOL_
|
||||||
|
DEFAULT Syslinux IPXE Chainloader
|
||||||
|
LABEL Syslinux IPXE Chainloader
|
||||||
|
MENU LABEL Chainload IPXE Network Boot
|
||||||
|
LINUX $mnt/syslinux/ipxe.lkrn
|
||||||
|
_EOL_
|
||||||
|
|
||||||
umount_efi
|
umount_efi
|
||||||
|
|
||||||
dev_from_partnum "$drive" 1
|
dev_from_partnum "$drive" 1
|
||||||
|
|
6
test.sh
6
test.sh
|
@ -1,4 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
tests/maas.sh
|
|
||||||
|
# Tests TODO
|
||||||
|
/bin/true
|
||||||
|
|
||||||
sudo tests/drive.sh
|
sudo tests/drive.sh
|
||||||
|
|
||||||
|
|
26043
tests/data/streams.json
26043
tests/data/streams.json
File diff suppressed because it is too large
Load Diff
|
@ -1,48 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
function test_stream()
|
|
||||||
{
|
|
||||||
local mimetype
|
|
||||||
get_streams
|
|
||||||
mimetype="$(file -b --mime-type "$streams")"
|
|
||||||
[ "$(lsb_release -cs)" == "bionic" ] && startSkipping
|
|
||||||
assertEquals "application/json" "$mimetype"
|
|
||||||
isSkipping && endSkipping
|
|
||||||
[ "$(lsb_release -cs)" == "focal" ] && startSkipping
|
|
||||||
assertEquals "text/plain" "$mimetype"
|
|
||||||
isSkipping && endSkipping
|
|
||||||
jq . "$streams" &> /dev/null
|
|
||||||
assertEquals 0 "$?"
|
|
||||||
cleanup_temp
|
|
||||||
}
|
|
||||||
|
|
||||||
function test_latest_maas_id()
|
|
||||||
{
|
|
||||||
get_latest_maas_id
|
|
||||||
assertEquals "20210223" "$release_version"
|
|
||||||
}
|
|
||||||
|
|
||||||
function test_checksum()
|
|
||||||
{
|
|
||||||
get_checksum 20210223 manifest
|
|
||||||
assertEquals "cf395299f1337f6ea69a86f70d76fb89b8a41274bbbe7047af43614a867a4af2" "$checksum"
|
|
||||||
}
|
|
||||||
|
|
||||||
#function test_download()
|
|
||||||
#{
|
|
||||||
# download_and_verify https://images.maas.io/ephemeral-v3/stable/${OS_CODENAME}/amd64/${id}/squashfs
|
|
||||||
# assertEquals "$?" 0
|
|
||||||
#}
|
|
||||||
|
|
||||||
function oneTimeSetUp()
|
|
||||||
{
|
|
||||||
. maas-images.inc
|
|
||||||
}
|
|
||||||
|
|
||||||
function setUp()
|
|
||||||
{
|
|
||||||
export streams=tests/data/streams.json
|
|
||||||
}
|
|
||||||
|
|
||||||
# Load shUnit2.
|
|
||||||
. /usr/bin/shunit2
|
|
|
@ -1,46 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
OSCODENAME=focal
|
|
||||||
OSVERSION=20.04
|
|
||||||
|
|
||||||
function find_oldest()
|
|
||||||
{
|
|
||||||
echo
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_latest_maas_id()
|
|
||||||
{
|
|
||||||
jq blah $OSCODENAME
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_checksum()
|
|
||||||
{
|
|
||||||
jq blah $OSVERSION
|
|
||||||
}
|
|
||||||
|
|
||||||
function download_and_verify()
|
|
||||||
{
|
|
||||||
local url="$1"
|
|
||||||
local checksum="$2"
|
|
||||||
local fname="$3"
|
|
||||||
|
|
||||||
wget "$url" -O "$fname"
|
|
||||||
if [ "checksum" == "$checksum" ]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
function download_files()
|
|
||||||
{
|
|
||||||
download kernel
|
|
||||||
download initrd
|
|
||||||
download squashfs
|
|
||||||
|
|
||||||
dd if=squashfs of="$partition" bs=1M
|
|
||||||
|
|
||||||
create_options_file
|
|
||||||
update_default
|
|
||||||
delete_oldest_if_needed
|
|
||||||
update_onerror_second_youngest
|
|
||||||
}
|
|
16
update.sh
16
update.sh
|
@ -1,22 +1,20 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
. install.inc
|
. drive.inc
|
||||||
|
. syslinux.inc
|
||||||
|
|
||||||
declare -a drives
|
declare -a drives
|
||||||
|
|
||||||
drives=("$@")
|
drives=("$@")
|
||||||
|
|
||||||
if [ ${#drives[@]} -eq 0 ]; then
|
if [ ${#drives[@]} -eq 0 ]; then
|
||||||
echo "Usage install.sh /dev/drive1 [/dev/drive2 [/dev/drive3 ]]"
|
echo "Usage update.sh /dev/drive1 [/dev/drive2 [/dev/drive3 ]]"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
get_streams
|
|
||||||
get_latest_maas_id
|
|
||||||
|
|
||||||
for drive in "${drives[@]}"; do
|
for drive in "${drives[@]}"; do
|
||||||
download_version "$release_version" "$drive"
|
mount_efi "$drive"
|
||||||
install_version "$release_version" "$drive"
|
install_ipxe "${mnt}/syslinux/ipxe.lkrn"
|
||||||
update_syslinux_menu "$drive"
|
umount_efi
|
||||||
done
|
done
|
||||||
cleanup_temp
|
|
||||||
|
|
Loading…
Reference in New Issue