Refactor to install and chainload IPXE

This commit is contained in:
Max Weiss 2021-04-22 22:10:01 -07:00
parent 8c58dcbd70
commit 6cb980775b
Signed by: maxweiss
GPG Key ID: C2D8443BA1D372DB
12 changed files with 87 additions and 26387 deletions

View File

@ -1,3 +0,0 @@
# sysdeploy
Sysdeploy

View File

@ -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:

View File

@ -1,7 +1,7 @@
#!/bin/bash
. install.inc
. drive.inc
. syslinux.inc
declare -a drives
@ -12,14 +12,7 @@ if [ ${#drives[@]} -eq 0 ]; then
exit 1
fi
get_streams
get_latest_maas_id
for drive in "${drives[@]}"; do
setup_drive "$drive"
install_syslinux "$drive"
download_version "$release_version" "$drive"
install_version "$release_version" "$drive"
update_syslinux_menu "$drive"
done
cleanup_temp

58
ipxe.inc Normal file
View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -1,5 +1,8 @@
#!/bin/bash
. ipxe.inc
function dev_from_partnum()
{
local drive="$1"
@ -30,7 +33,7 @@ function mount_efi()
mkfs.vfat "$partition"
if ! mount "$partition" "$mnt"; then
echo "Can't mount \"$partition\""
cleanup_mnt
#cleanup_mnt # Commented out by Max because it's not defined anywhere.
exit 1
fi
fi
@ -43,6 +46,7 @@ function umount_efi()
rmdir "$mnt"
}
function install_syslinux()
{
local drive="$1"
@ -67,6 +71,17 @@ function install_syslinux()
cp syslinux/{mainmenu,syslinux}.cfg "$mnt"/syslinux
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
dev_from_partnum "$drive" 1

View File

@ -1,4 +1,8 @@
#!/bin/bash
tests/maas.sh
# Tests TODO
/bin/true
sudo tests/drive.sh

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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
}

View File

@ -1,22 +1,20 @@
#!/bin/bash
. install.inc
. drive.inc
. syslinux.inc
declare -a drives
drives=("$@")
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
fi
get_streams
get_latest_maas_id
for drive in "${drives[@]}"; do
download_version "$release_version" "$drive"
install_version "$release_version" "$drive"
update_syslinux_menu "$drive"
mount_efi "$drive"
install_ipxe "${mnt}/syslinux/ipxe.lkrn"
umount_efi
done
cleanup_temp