remove obsolete installer directory
This commit is contained in:
parent
eec72a34a6
commit
ef77910880
|
@ -1,39 +0,0 @@
|
||||||
Getting Started
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Grab a copy of curtin (for some conversion tools):
|
|
||||||
|
|
||||||
sudo apt-get install bzr
|
|
||||||
mkdir -p ~/download
|
|
||||||
cd ~/download
|
|
||||||
bzr branch lp:curtin
|
|
||||||
|
|
||||||
Create the image
|
|
||||||
----------------
|
|
||||||
|
|
||||||
Generate the install image from subiquity's root directory:
|
|
||||||
|
|
||||||
installer/geninstaller -a amd64 -b grub2 -r zesty -l
|
|
||||||
|
|
||||||
(-l means build the current working tree into a deb and install that,
|
|
||||||
leaving it out will install subiquity from the archive).
|
|
||||||
|
|
||||||
Run the installer
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
# generate target device
|
|
||||||
qemu-img create -f raw target.img 10G
|
|
||||||
|
|
||||||
# run installer
|
|
||||||
sudo qemu-system-x86_64 -m 1024 -enable-kvm \
|
|
||||||
-hda installer.img -hdb target.img \
|
|
||||||
-serial telnet:127.0.0.1:2445,server,nowait \
|
|
||||||
-monitor stdio
|
|
||||||
|
|
||||||
Boot the installed image
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
sudo qemu-system-x86_64 -m 1024 -enable-kvm \
|
|
||||||
-hda target.img \
|
|
||||||
-serial telnet:127.0.0.1:2445,server,nowait
|
|
||||||
|
|
|
@ -1,669 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# Copyright 2015 Canonical, Ltd.
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU Affero General Public License as
|
|
||||||
# published by the Free Software Foundation, either version 3 of the
|
|
||||||
# License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU Affero General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
PROG=`basename $0`
|
|
||||||
INSTALLER_IMAGE_SIZE_M=2048 # 2G image
|
|
||||||
RSYNC_OPTS="-aXHAS --one-file-system"
|
|
||||||
MKFS_OPTS="-J size=4 -m 0 -q"
|
|
||||||
LOGFILE="geninstaller.log"
|
|
||||||
TOPDIR=./
|
|
||||||
USQUERY=installer/usquery
|
|
||||||
RESOURCES=installer/resources
|
|
||||||
LOCAL_SUBIQUITY=no
|
|
||||||
PKG_DEPS="
|
|
||||||
qemu-utils
|
|
||||||
kpartx
|
|
||||||
parted
|
|
||||||
gdisk
|
|
||||||
extlinux
|
|
||||||
dosfstools
|
|
||||||
simplestreams
|
|
||||||
syslinux-common
|
|
||||||
shim-signed
|
|
||||||
grub-efi-amd64-signed
|
|
||||||
grub-pc-bin
|
|
||||||
wget
|
|
||||||
rsync
|
|
||||||
ubuntu-cloudimage-keyring
|
|
||||||
cloud-image-utils
|
|
||||||
qemu-system-x86
|
|
||||||
"
|
|
||||||
INSTALLER_DEPS=(
|
|
||||||
"bcache-tools"
|
|
||||||
"lvm2"
|
|
||||||
"mdadm"
|
|
||||||
"petname"
|
|
||||||
"python3-attr"
|
|
||||||
"python3-urwid"
|
|
||||||
"python3-pyudev"
|
|
||||||
"python-urwid"
|
|
||||||
"probert"
|
|
||||||
"xfsprogs"
|
|
||||||
"curtin"
|
|
||||||
)
|
|
||||||
CACHEDIR=""
|
|
||||||
GRUB_MODS="configfile fat part_gpt part_msdos cat echo test search search_label search_fs_uuid boot chain linux reboot halt normal efi_gop efi_uga font gfxterm gfxterm_menu gfxterm_background gfxmenu serial"
|
|
||||||
|
|
||||||
cleanup_noexit() {
|
|
||||||
[ -n "${CACHEDIR}" ] && {
|
|
||||||
sync
|
|
||||||
sudo umount -l ${CACHEDIR}/mnt/{dev,proc,sys}
|
|
||||||
sudo umount ${CACHEDIR}/mnt
|
|
||||||
sudo umount ${CACHEDIR}/lower
|
|
||||||
sudo umount ${CACHEDIR}/upper
|
|
||||||
sudo umount ${CACHEDIR}/efimnt
|
|
||||||
sudo kpartx -d ${CACHEDIR}/installer.img &>/dev/null || exit
|
|
||||||
for DEV in $EFI_DEV $ROOTFS_DEV $OVERLAY_DEV; do
|
|
||||||
[ -e "/dev/mapper/`basename $DEV`" ] && {
|
|
||||||
sudo dmsetup remove $DEV &>/dev/null || exit
|
|
||||||
}
|
|
||||||
done
|
|
||||||
# it's ok to fail here, it means kpartx did it for us
|
|
||||||
sudo losetup -d $LOOPDEV &>/dev/null | :
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
cleanup_noexit &>/dev/null
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
trap cleanup EXIT HUP INT TERM
|
|
||||||
|
|
||||||
log() {
|
|
||||||
echo "`date +%s`: $@" | tee -a ${LOGFILE}
|
|
||||||
}
|
|
||||||
|
|
||||||
blockalign_up() {
|
|
||||||
local block_size=$((1 << 20)) # 1M
|
|
||||||
local new_size=$(($1 + ($block_size - ($1 % $block_size))))
|
|
||||||
echo $(($new_size >> 20)) # return in MB
|
|
||||||
}
|
|
||||||
|
|
||||||
write_metadata() {
|
|
||||||
cat <<EOF
|
|
||||||
instance-id: 'inst-${RANDOM}'
|
|
||||||
local-hostname: ubuntu-server-installer
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
cat << EOF
|
|
||||||
|
|
||||||
usage: $PROG [PARAMS] [ARGS]
|
|
||||||
-a, --arch=ARCH For ARCH in [i386, amd64, ppc64el, armf, arm64]
|
|
||||||
-b, --bootloader=TYPE For TYPE in [syslinux, grub2, uboot]
|
|
||||||
-h, --help This output.
|
|
||||||
-r, --release=RELEASE For RELEASE in [trusty, utopic, vivid, wily]
|
|
||||||
-s, --stream=STREAM For STREAM in [daily, released]
|
|
||||||
-V, --version=VERSION VERSION=YYYYMMDD , 20150623
|
|
||||||
-v, --verbose
|
|
||||||
|
|
||||||
|
|
||||||
Example usage:
|
|
||||||
# generate an grub2-based install image for wily on amd64
|
|
||||||
$PROG --arch=amd64 --release=wily --bootloader=grub2
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
install_deps() {
|
|
||||||
local packages="$1"
|
|
||||||
local to_install=""
|
|
||||||
|
|
||||||
log "Checking for build package dependencies"
|
|
||||||
for p in $packages; do
|
|
||||||
if ! dpkg-query -s "$p" &>/dev/null; then
|
|
||||||
to_install="$to_install $p";
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
[ -n "$to_install" ] && {
|
|
||||||
log "Installing dependencies: $to_install";
|
|
||||||
sudo apt-get install -q -y $to_install || {
|
|
||||||
log "Failed to install one or more dependencies in $to_install";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
acquire_image() {
|
|
||||||
_RETVAL=""
|
|
||||||
[ $# -lt 1 ] && {
|
|
||||||
log "ERROR: not enough arguments passed to $FUNCNAME";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
# what to get from maas
|
|
||||||
local item_name="root-image.gz"
|
|
||||||
local dldir=${1}; shift;
|
|
||||||
|
|
||||||
local label=${1:-"daily"}
|
|
||||||
local release=${2-"wily"};
|
|
||||||
local arch=${3-"amd64"};
|
|
||||||
local version=${4};
|
|
||||||
|
|
||||||
set -x
|
|
||||||
# run a query unless they specify all params
|
|
||||||
if [ $# -le 4 -a -z "${version}" ]; then
|
|
||||||
log "Querying simplestreams for latest image: $label $release $arch"
|
|
||||||
case "$label" in
|
|
||||||
daily)
|
|
||||||
ssresult=( `${USQUERY} --output-format="%(version_name)s %(item_url)s %(sha256)s" --max=1 maas-daily release=$release arch=$arch item_name=$item_name` )
|
|
||||||
local version=${ssresult[0]}
|
|
||||||
local item_url=${ssresult[1]}
|
|
||||||
local sha256=${ssresult[2]}
|
|
||||||
kernel=( `${USQUERY} --output-format="%(version_name)s %(item_url)s %(sha256)s" --max=1 maas-daily release=$release arch=$arch item_name=boot-kernel` )
|
|
||||||
initrd=( `${USQUERY} --output-format="%(version_name)s %(item_url)s %(sha256)s" --max=1 maas-daily release=$release arch=$arch item_name=boot-initrd` )
|
|
||||||
local kernel_url=${kernel[1]}
|
|
||||||
local initrd_url=${initrd[1]}
|
|
||||||
;;
|
|
||||||
release)
|
|
||||||
ssresult=( `${USQUERY} --output-format="%(version_name)s %(item_url)s %(sha256)s" --max=1 maas-release release=$release arch=$arch item_name=$item_name` )
|
|
||||||
local version=${ssresult[0]}
|
|
||||||
local item_url=${ssresult[1]}
|
|
||||||
local sha256=${ssresult[2]}
|
|
||||||
kernel=( `${USQUERY} --output-format="%(version_name)s %(item_url)s %(sha256)s" --max=1 maas-daily release=$release arch=$arch item_name=boot-kernel` )
|
|
||||||
initrd=( `${USQUERY} --output-format="%(version_name)s %(item_url)s %(sha256)s" --max=1 maas-daily release=$release arch=$arch item_name=boot-initrd` )
|
|
||||||
local kernel_url=${kernel[1]}
|
|
||||||
local initrd_url=${initrd[1]}
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
log "ERROR: simplestream label must be one of: [daily, release]"
|
|
||||||
return 1;
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
local cachedir=$dldir/maas/${label}/${release}/${arch}/${version}
|
|
||||||
local ephimg=${cachedir}/${item_name}
|
|
||||||
local kernel_img=${cachedir}/vmlinuz
|
|
||||||
local initrd_img=${cachedir}/initrd.img
|
|
||||||
local roottar=${cachedir}/root.tar.gz
|
|
||||||
local rootfs=${cachedir}/rootfs
|
|
||||||
set +x
|
|
||||||
|
|
||||||
# cache policy:
|
|
||||||
# $ephimg must be a file and it must checksum to $sha256 value otherwise
|
|
||||||
# we will nuke the cachedir and reacquire $item_name @ $item_url
|
|
||||||
# and re-assemble roottar and rootfs which was based on ephimg
|
|
||||||
|
|
||||||
[ -r "$ephimg" ] && CACHE_SUM=( `sha256sum $ephimg 2>/dev/null` )
|
|
||||||
if [ -z "${sha256}" -a -f "${ephimg}.sha256" ]; then
|
|
||||||
log "Using sha256sum from cached file";
|
|
||||||
sha256=`cat ${ephimg}.sha256 | cut -d' ' -f1`
|
|
||||||
fi
|
|
||||||
if [ "${sha256}" != "${CACHE_SUM[0]}" ]; then
|
|
||||||
log "WARNING: sha256 csum mismatch"
|
|
||||||
log "WARNING: expected: [$sha256]"
|
|
||||||
log " found: [${CACHE_SUM[0]}]"
|
|
||||||
# didn't match so nuke the cache
|
|
||||||
log "WARNING: removing old cache"
|
|
||||||
sudo rm -fr "${cachedir}" || {
|
|
||||||
log "ERROR: failed to remove stale cachedir: $cachedir";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
|
|
||||||
# download the image if it's not in the cache
|
|
||||||
log "Downloading installer root image @ $item_url"
|
|
||||||
if [ ! -r "${ephimg}" ]; then
|
|
||||||
mkdir -p $cachedir &&
|
|
||||||
wget --progress=bar -c "${item_url}" -O "${ephimg}" || {
|
|
||||||
log "ERROR: failed to download: ${item_url}";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
wget --progress=bar -c "${kernel_url}" -O "${kernel_img}" || {
|
|
||||||
log "ERROR: failed to download: ${kernel_url}";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
wget --progress=bar -c "${initrd_url}" -O "${initrd_img}" || {
|
|
||||||
log "ERROR: failed to download: ${initrd_url}";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
(cd `dirname ${ephimg}` &&
|
|
||||||
sha256sum `basename ${ephimg}` > ${ephimg}.sha256)
|
|
||||||
else
|
|
||||||
log " Using cached $label $release $arch $item_name:"
|
|
||||||
log " $ephimg"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# convert to root.tar.gz
|
|
||||||
log "Converting mass ephemeral image to roottar"
|
|
||||||
if [ ! -r ${roottar} ]; then
|
|
||||||
$dldir/curtin/tools/maas2roottar $ephimg $roottar
|
|
||||||
[ "$?" != "0" ] && {
|
|
||||||
log "ERROR: Failed to convert ephemeral to roottar";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
log " Using cached $label $release $arch root.tar.gz"
|
|
||||||
log " $roottar"
|
|
||||||
fi
|
|
||||||
|
|
||||||
set -x
|
|
||||||
# unpack rootfs tar
|
|
||||||
log "Unpacking roottar: $label $release $arch";
|
|
||||||
local kernel_img=${cachedir}/vmlinuz
|
|
||||||
if [ ! -e ${rootfs}/vmlinuz ]; then
|
|
||||||
mkdir -p ${rootfs} &&
|
|
||||||
sudo tar -C $rootfs -xz --numeric-owner --xattrs -f $roottar
|
|
||||||
else
|
|
||||||
log " Using cached $label $release $arch rootfs:"
|
|
||||||
log " $rootfs"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -e "${kernel_img}" ] && [ -e "${initrd_img}" ]; then
|
|
||||||
log " Using cached $label $release $arch kernel and initrd:"
|
|
||||||
sudo cp "${kernel_img}" "${initrd_img}" "${rootfs}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
set +x
|
|
||||||
|
|
||||||
_RETVAL=${cachedir}
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_seed() {
|
|
||||||
_RETVAL=""
|
|
||||||
[ $# -lt 2 ] && {
|
|
||||||
log "ERROR: not enough arguments passed to $FUNCNAME";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
local dldir=${1};
|
|
||||||
local cachedir=${2};
|
|
||||||
local seed=$cachedir/seed/nocloud-net
|
|
||||||
local installer_user_data=${RESOURCES}/user-data/installer-user-data
|
|
||||||
|
|
||||||
# inject user-data/meta-data into seed
|
|
||||||
log "Writing seed meta-data"
|
|
||||||
mkdir -p ${seed} && write_metadata > $seed/meta-data || {
|
|
||||||
log "Failed to write meta-data into $seed";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
log "Writing seed user-data"
|
|
||||||
rm -f ${seed}/user-data && cp $installer_user_data $seed/user-data
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
disable_daemons_in_root() {
|
|
||||||
local target=${1};
|
|
||||||
[ -z "${target}" ] && {
|
|
||||||
log "ERROR: $FUNCNAME was not passed a target"
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
log "Disabling deamons in target"
|
|
||||||
fpath="${target}/usr/sbin/policy-rc.d"
|
|
||||||
sudo tee $fpath << EOF
|
|
||||||
#!/bin/sh
|
|
||||||
# see invoke-rc.d for exit codes. 101 is "do not run"
|
|
||||||
while true; do
|
|
||||||
case "\$1" in
|
|
||||||
-*) shift;;
|
|
||||||
makedev|x11-common) exit 0;;
|
|
||||||
*) exit 101;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
EOF
|
|
||||||
sudo chmod 0755 $fpath
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
undisable_daemons_in_root() {
|
|
||||||
local target=${1};
|
|
||||||
[ -z "${target}" ] && {
|
|
||||||
log "ERROR: $FUNCNAME was not passed a target"
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
log "Enabling daemons in target"
|
|
||||||
fpath="${target}/usr/sbin/policy-rc.d"
|
|
||||||
sudo rm -f $fpath
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_img() {
|
|
||||||
_RETVAL=""
|
|
||||||
[ $# -lt 3 ] && {
|
|
||||||
log "ERROR: not enough arguments passed to $FUNCNAME";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
local dldir=${1};
|
|
||||||
local cachedir=${2};
|
|
||||||
local bootloader=${3};
|
|
||||||
local extlinux_conf=${RESOURCES}/menu/extlinux-menu.conf
|
|
||||||
local grub_efi_core=${RESOURCES}/grub/bootx64.efi # FIXME, ARCH
|
|
||||||
local grub_conf=${RESOURCES}/grub/grub.cfg
|
|
||||||
local embed_conf=${RESOURCES}/grub/embed_efi.cfg
|
|
||||||
local efi_grub_conf=${RESOURCES}/grub/efi_grub.cfg
|
|
||||||
local gptmbr=$(dpkg -L syslinux-common | grep \/gptmbr.bin | grep -v efi)
|
|
||||||
local installimg=${cachedir}/installer.img
|
|
||||||
local mnt=${cachedir}/mnt
|
|
||||||
local rootfs=${cachedir}/rootfs
|
|
||||||
local efimnt=${cachedir}/efimnt
|
|
||||||
local lower=${cachedir}/lower
|
|
||||||
local upper=${cachedir}/upper
|
|
||||||
local work=${cachedir}/upper/overlay-work
|
|
||||||
local seed=$cachedir/seed/nocloud-net
|
|
||||||
local syslinux_path=$(dpkg -L syslinux-common | grep \/vesamenu.c32 |
|
|
||||||
grep -v efi | xargs -i dirname {})
|
|
||||||
|
|
||||||
# prep image
|
|
||||||
log "Generating Installer image file"
|
|
||||||
local image_size=${INSTALLER_IMAGE_SIZE_M}
|
|
||||||
qemu-img create -f raw $installimg ${image_size}M 2>&1 >> ${LOGFILE} || {
|
|
||||||
log "Failed to create empty file: $installimg"
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Calculate the partition sizes and offsets. Rootfs size can change
|
|
||||||
# from build to build and the total size of the image is no longer
|
|
||||||
# encoded here, but set globally.
|
|
||||||
local efi_start="0%"
|
|
||||||
local efi_end=200 # 200M efi partition
|
|
||||||
local rootfs_size=$(blockalign_up `sudo du -s -B1 $rootfs`)
|
|
||||||
local rootfs_start=$efi_end
|
|
||||||
local fs_overhead=130 # best guess fs metadata and other overhead
|
|
||||||
local rootfs_end=$(($rootfs_start + $rootfs_size + $fs_overhead))
|
|
||||||
local overlay_start=$rootfs_end
|
|
||||||
local overlay_end=$(($image_size - 1)) # save last 1M for GPT
|
|
||||||
log "Partitioning Installer image (UEFI)"
|
|
||||||
(parted -s $installimg mklabel msdos &&
|
|
||||||
parted -s $installimg mkpart primary fat32 ${efi_start} ${efi_end}M &&
|
|
||||||
parted -s $installimg mkpart primary ext3 ${efi_end}M ${rootfs_end}M &&
|
|
||||||
parted -s $installimg mkpart primary ext3 ${overlay_start}M ${overlay_end}M &&
|
|
||||||
parted -s $installimg set 1 boot on) 2>&1 >> ${LOGFILE} || {
|
|
||||||
log "Failed to partition image: $installimg"
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
log "$(parted -s $installimg print)"
|
|
||||||
|
|
||||||
if [ "${bootloader}" != "grub2" ]; then
|
|
||||||
log "Bootloader ${bootloader} not supported, cannot install"
|
|
||||||
usage;
|
|
||||||
return 1;
|
|
||||||
fi
|
|
||||||
|
|
||||||
log "Syncing rootfs into install image"
|
|
||||||
local kpartx_ret=$(sudo kpartx -va $installimg)
|
|
||||||
[ -z "$kpartx_ret" ] && {
|
|
||||||
log "Failed to map image partitions into LVM"
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
sudo udevadm settle
|
|
||||||
|
|
||||||
local loopparts=( `echo ${kpartx_ret} | fmt -w 1 | grep ^loop` )
|
|
||||||
EFI_DEV="/dev/mapper/${loopparts[0]}"
|
|
||||||
ROOTFS_DEV="/dev/mapper/${loopparts[1]}"
|
|
||||||
OVERLAY_DEV="/dev/mapper/${loopparts[2]}"
|
|
||||||
LOOPDEV="`losetup | grep "$installimg" | fmt -w 1 | grep ^/dev`"
|
|
||||||
[ -z "${LOOPDEV}" ] && {
|
|
||||||
log "empty loopdev! aieeeeee!";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
log "Building Grub (EFI and BIOS) boot partition"
|
|
||||||
(sudo mkfs.vfat -F32 -n GRUB2EFI ${EFI_DEV} 2>/dev/null &&
|
|
||||||
mkdir -p ${efimnt} &&
|
|
||||||
sudo mount $EFI_DEV ${efimnt} &&
|
|
||||||
sudo mkdir -p ${efimnt}/EFI/BOOT &&
|
|
||||||
sudo mkdir -p ${efimnt}/boot/grub &&
|
|
||||||
sudo mkdir -p ${efimnt}/grub/fonts &&
|
|
||||||
sudo mkdir -p ${efimnt}/grub/x86_64-efi &&
|
|
||||||
sudo cp -a /usr/share/grub/unicode.pf2 ${efimnt}/grub/fonts/ &&
|
|
||||||
sudo cp -a /usr/share/grub/unicode.pf2 ${efimnt}/boot/grub &&
|
|
||||||
cat ${efi_grub_conf} | sudo tee ${efimnt}/EFI/BOOT/grub.cfg &&
|
|
||||||
cat ${embed_conf} | sudo tee ${efimnt}/grub/embed_efi.cfg &&
|
|
||||||
cat ${grub_conf} | sudo tee ${efimnt}/grub/grub.cfg &&
|
|
||||||
sudo rsync ${RSYNC_OPTS} /usr/lib/grub/x86_64-efi/ ${efimnt}/grub/x86_64-efi/ &&
|
|
||||||
sudo grub-install --force --removable --no-floppy \
|
|
||||||
--target=x86_64-efi \
|
|
||||||
--efi-directory=${efimnt} \
|
|
||||||
--boot-directory=${efimnt}/boot $LOOPDEV &&
|
|
||||||
sudo grub-mkimage -O x86_64-efi -p /grub -c ${efimnt}/grub/embed_efi.cfg -o ${efimnt}/EFI/BOOT/bootx64.efi ${GRUB_MODS} &&
|
|
||||||
sudo grub-install --force --removable --no-floppy \
|
|
||||||
--target=i386-pc \
|
|
||||||
--boot-directory=${efimnt}/boot $LOOPDEV) 2>&1 >> ${LOGFILE} || {
|
|
||||||
log "ERROR: failed to create multiboot partition"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
log "Creating and syncing filesystem (original cloudimg rootfs)"
|
|
||||||
set -x
|
|
||||||
(sudo mkfs.ext4 ${MKFS_OPTS} -L cloudimg-rootfs $ROOTFS_DEV &&
|
|
||||||
sudo tune2fs -r 0 $ROOTFS_DEV &&
|
|
||||||
mkdir -p ${lower} &&
|
|
||||||
sudo mount $ROOTFS_DEV ${lower} &&
|
|
||||||
sudo rsync ${RSYNC_OPTS} ${rootfs}/ ${lower}/) 2>&1 >> ${LOGFILE} || {
|
|
||||||
log "ERROR: failed to sync rootfs into install image";
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
log "Creating and syncing filesystem (installer overlay)"
|
|
||||||
# mount -t overlay overlay -olowerdir=/lower,upperdir=/upper,\
|
|
||||||
# workdir=/work /merged
|
|
||||||
OVERLAY_VERSION=( `modinfo -V overlayfs` ) # returns: kmod version XX
|
|
||||||
if [ ${OVERLAY_VERSION[2]} -le 15 ]; then
|
|
||||||
# trusty 3.13 overlayfs version 15 or older doesn't use workdir
|
|
||||||
FS=overlayfs
|
|
||||||
OPTS="-olowerdir=$lower,upperdir=$upper/overlay"
|
|
||||||
else
|
|
||||||
# newer kernels than trusty 3.13 have workdir
|
|
||||||
FS=overlay
|
|
||||||
OPTS="-olowerdir=$lower,upperdir=$upper/overlay,workdir=$work"
|
|
||||||
fi
|
|
||||||
# load the right overlay module
|
|
||||||
if ! lsmod | grep -q ${FS}; then sudo modprobe -v $FS; fi
|
|
||||||
|
|
||||||
(sudo mkfs.ext3 ${MKFS_OPTS} -L overlay-rootfs $OVERLAY_DEV
|
|
||||||
sudo tune2fs -r 0 $OVERLAY_DEV &&
|
|
||||||
sudo mkdir -p ${work} ${upper} ${mnt} &&
|
|
||||||
sudo mount $OVERLAY_DEV ${upper} &&
|
|
||||||
sudo mkdir -p ${upper}/overlay ${work} &&
|
|
||||||
sudo mount -t $FS $FS $OPTS ${mnt}) 2>&1 >> ${LOGFILE} || {
|
|
||||||
log "ERROR: failed to overlay mount installer";
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
set +x
|
|
||||||
|
|
||||||
log "Installing bootloader configuration"
|
|
||||||
(sudo mkdir -p ${mnt}/proc
|
|
||||||
sudo mkdir -p ${mnt}/sys
|
|
||||||
sudo mkdir -p ${mnt}/dev
|
|
||||||
sudo mount none -t proc ${mnt}/proc &&
|
|
||||||
sudo mount none -t sysfs ${mnt}/sys &&
|
|
||||||
sudo mount -o bind /dev ${mnt}/dev) 2>&1 >> ${LOGFILE} || {
|
|
||||||
log "ERROR: failed to prepare target mounts for sync";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
log "Installing subiquity package dependencies"
|
|
||||||
local resolvconf=${mnt}/etc/resolv.conf
|
|
||||||
local packages=""
|
|
||||||
for installer_package in "${INSTALLER_DEPS[@]}"; do
|
|
||||||
packages="$packages $installer_package"
|
|
||||||
done
|
|
||||||
if [ "${LOCAL_SUBIQUITY}" = "no" ]; then
|
|
||||||
packages="$packages subiquity"
|
|
||||||
fi
|
|
||||||
sudo mv ${resolvconf} ${resolvconf}.old &&
|
|
||||||
sudo cp /etc/resolv.conf ${resolvconf} &&
|
|
||||||
|
|
||||||
log "Installing on rootfs: $packages"
|
|
||||||
log "WARNING: skipping preinstallation of mdadm, lvm2"
|
|
||||||
log "WARNING: will install packages during runtime"
|
|
||||||
# if we don't have the right curtin features, we can't easily
|
|
||||||
# install mdadm/lvm2 into the target as it will start up system
|
|
||||||
# daemons and prevent us from unmounting the target
|
|
||||||
packages=$(echo $packages | fmt -w1 | egrep -v "(mdadm|lvm2)")
|
|
||||||
sudo chroot ${mnt} apt-get update
|
|
||||||
sudo chroot ${mnt} apt-get -y install $packages || {
|
|
||||||
log "Failed to install packages on rootfs";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if [ "${LOCAL_SUBIQUITY}" = "yes" ]; then
|
|
||||||
dpkg-buildpackage -uc -us
|
|
||||||
V=$(dpkg-parsechangelog -SVersion)
|
|
||||||
sudo cp ../subiquity_${V}*.deb ../subiquitycore_${V}*.deb ${mnt}
|
|
||||||
sudo chroot ${mnt} sh -c 'dpkg -i *.deb'
|
|
||||||
sudo chroot ${mnt} apt-get install -f
|
|
||||||
sudo rm ${mnt}/*.deb
|
|
||||||
fi
|
|
||||||
|
|
||||||
log "Cleaning up overlay apt cache"
|
|
||||||
local before=( `sudo du -sk ${upper}` )
|
|
||||||
sudo chroot ${mnt} apt-get clean || {
|
|
||||||
log "ERROR: failed to run apt-get clean in ${mnt}";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
local after=( `sudo du -sk ${upper}` )
|
|
||||||
local delta=$((($before - $after) / 1024))
|
|
||||||
log "Saved ${delta} MiB"
|
|
||||||
|
|
||||||
sudo rm ${resolvconf}
|
|
||||||
sudo mv ${resolvconf}.old ${resolvconf}
|
|
||||||
|
|
||||||
if [ "${bootloader}" == "syslinux" ]; then
|
|
||||||
sudo mkdir -p ${mnt}/boot/extlinux &&
|
|
||||||
sudo extlinux --install ${mnt}/boot/extlinux &&
|
|
||||||
sudo cp -av ${syslinux_path}/*.c32 ${mnt}/boot/extlinux &&
|
|
||||||
cat ${extlinux_conf} | sudo tee ${mnt}/boot/extlinux/extlinux.conf
|
|
||||||
else
|
|
||||||
log "Installing grub2"
|
|
||||||
cat ${grub_conf} | sudo tee ${efimnt}/boot/grub/grub.cfg 2>&1 >> ${LOGFILE} && true
|
|
||||||
fi
|
|
||||||
|
|
||||||
log "Installing cloud seed"
|
|
||||||
sudo mkdir -p ${mnt}/var/lib/cloud/seed &&
|
|
||||||
sudo cp -a ${seed} ${mnt}/var/lib/cloud/seed && sync || {
|
|
||||||
log "Failed to install bootloader and configuration";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
log "Configuring netplan"
|
|
||||||
sudo mkdir -p ${mnt}/etc/netplan
|
|
||||||
cat <<EOF | sudo tee ${mnt}/etc/netplan/00-installer-config.yaml > /dev/null
|
|
||||||
network:
|
|
||||||
version: 2
|
|
||||||
ethernets:
|
|
||||||
all-en:
|
|
||||||
match:
|
|
||||||
name: "en*"
|
|
||||||
dhcp4: true
|
|
||||||
all-eth:
|
|
||||||
match:
|
|
||||||
name: "eth*"
|
|
||||||
dhcp4: true
|
|
||||||
EOF
|
|
||||||
sudo mkdir -p ${mnt}/etc/cloud/cloud.cfg.d
|
|
||||||
cat <<EOF | sudo tee ${mnt}/etc/cloud/cloud.cfg.d/99-no-cloud-init-net.cfg > /dev/null
|
|
||||||
network: {config: disabled}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
_RETVAL="$installimg";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
parse_args() {
|
|
||||||
# -b,--bootloader [syslinux, grub2]
|
|
||||||
# -h,--help <help output>
|
|
||||||
# -r,--release [trusty, utopic, vivid, wily]
|
|
||||||
# -v,--verbose
|
|
||||||
|
|
||||||
# args:
|
|
||||||
[ $# -lt 1 ] && { usage; exit 0; }
|
|
||||||
|
|
||||||
OPTS_LONG="arch:,bootloader:,download:,help,release:,stream:,verbose,version:,local-subiquity"
|
|
||||||
OPTS="a:b:d:hor:s:vV:l"
|
|
||||||
ARGS=`getopt --name "$PROG" --long $OPTS_LONG --options $OPTS -- "$@"`
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "$PROG: usage error (use -h for help)" >&2
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
eval set -- $ARGS
|
|
||||||
|
|
||||||
ARCH="amd64"
|
|
||||||
BOOTLOADER="syslinux"
|
|
||||||
DLDIR=~/download
|
|
||||||
RELEASE="wily"
|
|
||||||
STREAM="daily"
|
|
||||||
VERBOSE="no"
|
|
||||||
VERSION=""
|
|
||||||
while [ $# -gt 0 ]; do
|
|
||||||
case "$1" in
|
|
||||||
-a | --arch) ARCH="$2"; shift;;
|
|
||||||
-b | --bootloader) BOOTLOADER="$2"; shift;;
|
|
||||||
-d | --download) DLDIR="$2"; shift;;
|
|
||||||
-h | --help) usage; exit 0;;
|
|
||||||
-r | --release) RELEASE="$2"; shift;;
|
|
||||||
-s | --stream) STREAM="$2"; shift;;
|
|
||||||
-V | --version) VERSION="$2"; shift;;
|
|
||||||
-v | --verbose) VERBOSE="yes";;
|
|
||||||
-l | --local-subiquity) LOCAL_SUBIQUITY="yes";;
|
|
||||||
--) shift; break;; # end of options
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
ARGS="$@"
|
|
||||||
|
|
||||||
[ "${VERBOSE}" == "yes" ] && set -x
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
main() {
|
|
||||||
log "INFO: Starting $PROG with params: $@"
|
|
||||||
|
|
||||||
parse_args "$@"
|
|
||||||
|
|
||||||
# get prereqs installed first
|
|
||||||
install_deps "$PKG_DEPS" || { return 1; }
|
|
||||||
|
|
||||||
[ -z "$OUTPUT" ] && {
|
|
||||||
OUTPUT="ubuntu-server-${STREAM}-${RELEASE}-${ARCH}-installer.img"
|
|
||||||
}
|
|
||||||
|
|
||||||
acquire_image ${DLDIR} "$STREAM" "$RELEASE" "$ARCH" "$VERSION" || {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
CACHEDIR=${_RETVAL}
|
|
||||||
log "CACHEDIR=$CACHEDIR"
|
|
||||||
|
|
||||||
generate_seed ${DLDIR} $CACHEDIR || {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_img ${DLDIR} $CACHEDIR $BOOTLOADER || {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
INSTALLIMG=${_RETVAL}
|
|
||||||
log "Cleaning up ..."
|
|
||||||
cleanup_noexit &&
|
|
||||||
mv $INSTALLIMG ${OUTPUT} &&
|
|
||||||
ln -fs ${OUTPUT} installer.img || {
|
|
||||||
log "ERROR: failed to move $INSTALLIMG to $OUTPUT";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
log "Installer image complete: $OUTPUT"
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
main $@
|
|
||||||
exit $?
|
|
|
@ -1,3 +0,0 @@
|
||||||
search.fs_label GRUB2EFI root
|
|
||||||
set prefix=($root)/boot/grub
|
|
||||||
configfile $prefix/grub.cfg
|
|
|
@ -1,3 +0,0 @@
|
||||||
search.fs_label GRUB2EFI root
|
|
||||||
set prefix=($root)/grub
|
|
||||||
configfile $prefix/grub.cfg
|
|
|
@ -1,80 +0,0 @@
|
||||||
function strcontains {
|
|
||||||
set str="$1"
|
|
||||||
set pattern="$2"
|
|
||||||
if regexp ".*${pattern}.*" "$str"; then
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return 1;
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function scan_disk {
|
|
||||||
# Scan the disk and create a menuentry to boot it if it contains a linux
|
|
||||||
# install
|
|
||||||
disk=$1
|
|
||||||
if [ -e $disk/etc/lsb-release ]; then
|
|
||||||
probe -s uuid -u $disk
|
|
||||||
source $disk/etc/lsb-release
|
|
||||||
menuentry "Discovered: $DISTRIB_ID $DISTRIB_RELEASE $disk" $disk $uuid {
|
|
||||||
set root=$2
|
|
||||||
linux /vmlinuz root=UUID=$3
|
|
||||||
initrd /initrd.img
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Load modules
|
|
||||||
insmod all_video
|
|
||||||
insmod ext2
|
|
||||||
insmod gfxterm
|
|
||||||
insmod linux
|
|
||||||
insmod normal
|
|
||||||
insmod part_gpt
|
|
||||||
insmod part_msdos
|
|
||||||
insmod png
|
|
||||||
insmod probe
|
|
||||||
insmod regexp
|
|
||||||
insmod serial
|
|
||||||
|
|
||||||
# Set up display
|
|
||||||
set gfxmode=auto
|
|
||||||
terminal_output gfxterm
|
|
||||||
terminal_input console
|
|
||||||
|
|
||||||
# Set boot type
|
|
||||||
if [ x$grub_platform = xefi ]; then
|
|
||||||
set boottype=efi
|
|
||||||
else
|
|
||||||
set boottype=bios
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Try to set up serial
|
|
||||||
serial --unit=0 --speed=9600
|
|
||||||
terminal_output --append serial
|
|
||||||
terminal_input --append serial
|
|
||||||
|
|
||||||
# Set up appearance
|
|
||||||
loadfont /boot/grub/unicode.pf2
|
|
||||||
|
|
||||||
regexp -s install_disk 'hd([0-9]+)' $root
|
|
||||||
# Scan all disks except for current root
|
|
||||||
for disk in (*); do
|
|
||||||
if ! strcontains "$disk" $install_disk; then
|
|
||||||
scan_disk $disk
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Create menuentry for installer
|
|
||||||
menuentry "Boot Installer - Graphical Console" {
|
|
||||||
set root=(hd0,msdos2)
|
|
||||||
linux /vmlinuz ro root=LABEL=cloudimg-rootfs overlayroot=device:dev=LABEL=overlay-rootfs console=ttyS0 console=tty0 quiet splash
|
|
||||||
initrd /initrd.img
|
|
||||||
}
|
|
||||||
menuentry "Boot Installer - Serial Console" {
|
|
||||||
set root=(hd0,msdos2)
|
|
||||||
linux /vmlinuz ro root=LABEL=cloudimg-rootfs overlayroot=device:dev=LABEL=overlay-rootfs console=tty0 console=ttyS0
|
|
||||||
initrd /initrd.img
|
|
||||||
}
|
|
||||||
|
|
||||||
set default=0
|
|
||||||
set timeout=50
|
|
|
@ -1,17 +0,0 @@
|
||||||
SERIAL 0 115200
|
|
||||||
ui vesamenu.c32
|
|
||||||
prompt 0
|
|
||||||
menu background splash.png
|
|
||||||
menu title Boot Menu
|
|
||||||
timeout 50
|
|
||||||
|
|
||||||
label text-installer
|
|
||||||
menu label ^Ubuntu Server Installer (text)
|
|
||||||
menu default
|
|
||||||
linux /vmlinuz
|
|
||||||
append initrd=/initrd.img ip=dhcp ro root=LABEL=cloudimg-rootfs overlayroot=tmpfs console=ttyS0 console=tty0 splash
|
|
||||||
|
|
||||||
label serial-installer
|
|
||||||
menu label ^Ubuntu Server Installer (serial)
|
|
||||||
linux /vmlinuz
|
|
||||||
append initrd=/initrd.img ip=dhcp ro root=LABEL=cloudimg-rootfs overlayroot=tmpfs console=tty0 console=ttyS0 splash
|
|
|
@ -1 +0,0 @@
|
||||||
users: []
|
|
|
@ -1,81 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# Copyright 2015 Canonical, Ltd.
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU Affero General Public License as
|
|
||||||
# published by the Free Software Foundation, either version 3 of the
|
|
||||||
# License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU Affero General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
ARCH=${ARCH-"`uname -m`"}
|
|
||||||
MEM=${MEM-"1024"}
|
|
||||||
INSTALLER=${INSTALLER-"installer.img"}
|
|
||||||
UEFI=${UEFI-"1"}
|
|
||||||
TARGET=${TARGET-"target.img"}
|
|
||||||
GRAPHIC="-serial stdio"
|
|
||||||
SPORT=2445
|
|
||||||
|
|
||||||
QEMU=`which qemu-system-$ARCH`;
|
|
||||||
case $ARCH in
|
|
||||||
i386|x86_64)
|
|
||||||
PKG="ovmf qemu-system-x86"
|
|
||||||
if [ "${UEFI}" == "1" ]; then
|
|
||||||
UEFI=" -bios /usr/share/ovmf/OVMF.fd"
|
|
||||||
else
|
|
||||||
UEFI=""
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
arm*) PKG=qemu-system-arm ;;
|
|
||||||
ppc*) PKG=qemu-system-ppc ;;
|
|
||||||
*)
|
|
||||||
echo "Unsupported arch: $ARCH";
|
|
||||||
exit 1;
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
if [ -z $QEMU ]; then
|
|
||||||
echo "Installing required packages: $PKG"
|
|
||||||
sudo apt-get install $PKG || {
|
|
||||||
echo "Failed to install qemu-system package(s) $PKG";
|
|
||||||
if echo $PKG | grep -q ovmf; then
|
|
||||||
echo "ovmf package is only available in multiverse."
|
|
||||||
echo "You can enable multiverse and try again:"
|
|
||||||
echo "sudo add-apt-repository multiverse"
|
|
||||||
fi
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
# don't spawn sdl if we're headless
|
|
||||||
if [ -z $DISPLAY ]; then
|
|
||||||
GRAPHIC="-nographic"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# always recreate the target image
|
|
||||||
echo "Creating dummy target image: ${TARGET}"
|
|
||||||
qemu-img create -f raw ${TARGET}_1 5G
|
|
||||||
qemu-img create -f raw ${TARGET}_2 1G
|
|
||||||
qemu-img create -f raw ${TARGET}_3 1G
|
|
||||||
qemu-img create -f raw ${TARGET}_4 1G
|
|
||||||
|
|
||||||
# TODO, curses should work, make serial|nographic optional
|
|
||||||
echo "Launching Installer VM"
|
|
||||||
sudo qemu-system-$ARCH -smp 2 -m $MEM -enable-kvm $UEFI\
|
|
||||||
-drive snapshot=on,format=raw,cache=unsafe,if=ide,file=$INSTALLER,serial=QM_INSTALL_01 \
|
|
||||||
-drive format=raw,cache=unsafe,if=ide,file=${TARGET}_1,serial=QM_TARGET_01 \
|
|
||||||
-drive format=raw,cache=unsafe,if=virtio,file=${TARGET}_2,serial=QM_TARGET_02 \
|
|
||||||
-drive format=raw,cache=unsafe,if=virtio,file=${TARGET}_3,serial=QM_TARGET_03 \
|
|
||||||
-drive format=raw,cache=unsafe,if=virtio,file=${TARGET}_4,serial=QM_TARGET_04 \
|
|
||||||
-global isa-fdc.driveA= -net user \
|
|
||||||
-net nic,model=e1000 \
|
|
||||||
-net nic,model=virtio \
|
|
||||||
-net nic,model=i82559er \
|
|
||||||
-monitor telnet:127.0.0.1:2446,server,nowait \
|
|
||||||
${GRAPHIC}
|
|
||||||
|
|
||||||
exit $?
|
|
|
@ -1,97 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# Copyright 2015 Canonical, Ltd.
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU Affero General Public License as
|
|
||||||
# published by the Free Software Foundation, either version 3 of the
|
|
||||||
# License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU Affero General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# https://github.com/smoser/talk-simplestreams/blob/master/bin/u-stool
|
|
||||||
|
|
||||||
declare -A sdata
|
|
||||||
CIU_COM="http://cloud-images.ubuntu.com"
|
|
||||||
CIU_COM_R="$CIU_COM/releases"
|
|
||||||
MU_COM="http://maas.ubuntu.com/images/ephemeral-v2/"
|
|
||||||
CST="https://swift.canonistack.canonical.com/v1/AUTH_a48765cc0e864be980ee21ae26aaaed4"
|
|
||||||
sdata=(
|
|
||||||
[uc-release]="$CIU_COM_R/streams/v1/index.sjson"
|
|
||||||
[uc-aws]="$CIU_COM_R/streams/v1/com.ubuntu.cloud:released:aws.sjson"
|
|
||||||
[uc-azure]="$CIU_COM_R/streams/v1/com.ubuntu.cloud:released:azure.sjson"
|
|
||||||
[uc-dl]="$CIU_COM_R/streams/v1/com.ubuntu.cloud:released:download.sjson"
|
|
||||||
[uc-daily]="$CIU_COM/daily/streams/v1/index.sjson"
|
|
||||||
[maas-release]="$MU_COM/releases/streams/v1/index.sjson"
|
|
||||||
[maas-daily]="$MU_COM/daily/streams/v1/index.sjson"
|
|
||||||
[cirros]="http://download.cirros-cloud.net/streams/v1/index.json"
|
|
||||||
[cstack]="$CST/simplestreams/data/streams/v1/index.json"
|
|
||||||
[luc-release]="./luc-release/streams/v1/index.json"
|
|
||||||
[luc-aws]="./luc-release/streams/v1/com.ubuntu.cloud:released:aws.json"
|
|
||||||
)
|
|
||||||
|
|
||||||
SPROG="sstream-query"
|
|
||||||
case "$0" in
|
|
||||||
*smirror) SPROG="sstream-mirror";;
|
|
||||||
*squery) SPROG="sstream-query";;
|
|
||||||
*)
|
|
||||||
echo "Expect to be called usmirror or usquery, not ${0##*/}";
|
|
||||||
exit 1;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
error() { echo "$@" 1>&2; }
|
|
||||||
fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
|
|
||||||
Usage() {
|
|
||||||
cat <<EOF
|
|
||||||
Usage: ${0##*/} name options opt
|
|
||||||
a friendly wrapper to $SPROG.
|
|
||||||
|
|
||||||
Name must be one of:
|
|
||||||
EOF
|
|
||||||
for i in "${!sdata[@]}"; do
|
|
||||||
printf "%-12s %s\n" "$i" "${sdata[$i]}"
|
|
||||||
done | sort
|
|
||||||
}
|
|
||||||
|
|
||||||
name=""
|
|
||||||
url=""
|
|
||||||
dry=false
|
|
||||||
for i in "$@"; do
|
|
||||||
case "$i" in
|
|
||||||
--help) { Usage; exit 0; };;
|
|
||||||
--dry-run) dry=true;;
|
|
||||||
---dry-run) opts[${#opts[@]}]="--dry-run";;
|
|
||||||
-*) opts[${#opts[@]}]="$i";;
|
|
||||||
*)
|
|
||||||
# the first argument is 'name'
|
|
||||||
if [ -z "$name" ]; then
|
|
||||||
name="$i"
|
|
||||||
[ -n "${sdata[$name]}" ] ||
|
|
||||||
fail "unknown name $name. see '--help' for list"
|
|
||||||
url=${sdata[$name]}
|
|
||||||
i="$url"
|
|
||||||
fi
|
|
||||||
args[${#args[@]}]="$i"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
[ -n "$name" ] || { Usage 1>&2; exit 1; }
|
|
||||||
|
|
||||||
keyopt=""
|
|
||||||
case "$url" in
|
|
||||||
*.json) :;;
|
|
||||||
*) keyopt="--keyring=/usr/share/keyrings/ubuntu-cloudimage-keyring.gpg";;
|
|
||||||
esac
|
|
||||||
|
|
||||||
cmd=( "$SPROG" ${keyopt:+"${keyopt}"} "${opts[@]}" "${args[@]}" )
|
|
||||||
|
|
||||||
$dry && echo "${cmd[@]}" && exit
|
|
||||||
|
|
||||||
"${cmd[@]}"
|
|
Loading…
Reference in New Issue