mirror of
https://git.launchpad.net/livecd-rootfs
synced 2025-02-15 15:18:26 +00:00
* Replace "snap download" with tool that uses snap store's coherence feature This is important for parallel image builds to ensure all pre-seeded snaps have the same versions across image variants. * Inject a proxy into the build providing a snapshot view of the package repo. When the REPO_SNAPSHOT_STAMP variable is set, the auto/build script will attempt to launch a transparent HTTP proxy on port 8080, and insert an iptables rule to redirect all outgoing HTTP requests to this proxy. The proxy, contained in the `magic-proxy` Python script, examines each request and silently overrides those pointing to InRelease files or files that are listed in InRelease files. It will instead provide the contents of the requested file as it was at REPO_SNAPSHOT_STAMP, by downloading the corresponding asset "by hash". * Use series files with dependency handling to generate hook symlinks dynamically This patch currently only applies to the "ubuntu-cpc" project. More and more logic has been going into the hook scripts to decide under which conditions they should run or not. As we are moving to parallelized builds of image sets, this will get even more complicated. Base hooks will have to know which image sets they belong to and modification of the dependency chain between scripts will become more complicated and prone to errors, as the number of image sets grows. This patch introduces explicit ordering and dependency handling for scripts through the use of `series` files and an explicit syntax for dependency specification.
331 lines
9.6 KiB
Bash
Executable File
331 lines
9.6 KiB
Bash
Executable File
#!/bin/bash -x
|
|
rootd="${1:-/}"
|
|
root_fs_label=cloudimg-rootfs
|
|
set -ex
|
|
|
|
. /root/config/chroot
|
|
|
|
CLOUD_IMG_STR="# CLOUD_IMG: This file was created/modified by the Cloud Image build process"
|
|
|
|
LANG=C
|
|
|
|
_xchroot() {
|
|
# Prevent multiple chroots
|
|
if [ "$1" = "/" ]; then
|
|
shift;
|
|
"$@"
|
|
else
|
|
chroot "$@"
|
|
fi
|
|
}
|
|
|
|
#### COMMON architecture independent functions
|
|
arch=$(_xchroot "${rootd}" dpkg --print-architecture)
|
|
|
|
add_serial_console() {
|
|
condev=$1
|
|
idir="$rootd/etc/init"
|
|
cat << EOF > "${idir}/${condev}.conf"
|
|
# CONDEV - getty
|
|
#
|
|
# This service maintains a getty on CONDEV from the point the system is
|
|
# started until it is shut down again.
|
|
|
|
start on stopped rc RUNLEVEL=[2345] and (
|
|
not-container or
|
|
container CONTAINER=lxc or
|
|
container CONTAINER=lxc-libvirt)
|
|
|
|
stop on runlevel [!2345]
|
|
|
|
pre-start script
|
|
# getty will not be started if the serial console is not present
|
|
stty -F /dev/CONDEV -a 2> /dev/null > /dev/null || { stop ; exit 0; }
|
|
end script
|
|
|
|
respawn
|
|
script
|
|
exec /sbin/getty -L CONDEV 115200 vt102
|
|
end script
|
|
${IMAGE_STR}
|
|
EOF
|
|
sed -i "s/CONDEV/${condev}/g" "$idir/${condev}.conf"
|
|
}
|
|
|
|
fake_cloud_init() {
|
|
# If the cloud does not provide a meta-data service this should be run
|
|
# This will setup a nocloud datasource.
|
|
|
|
seed_d="${rootd}/var/lib/cloud/seed/nocloud-net"
|
|
mkdir -p "${seed_d}"
|
|
|
|
# fake instance-id
|
|
cat << EOF > "${seed_d}/meta-data"
|
|
instance_id: cloud-image
|
|
EOF
|
|
|
|
# fake user-data to create the default user/password
|
|
cat << EOF > "${seed_d}/user-data"
|
|
#cloud-config
|
|
password: ubuntu
|
|
chpasswd: ubuntu
|
|
ssh_pwauth: True
|
|
EOF
|
|
|
|
# tell cloud-init not to look for meta-data sources
|
|
cat << EOF > ${rootd}/etc/cloud/cloud.cfg.d/99-fake_cloud.cfg
|
|
# configure cloud-init for NoCloud
|
|
datasource_list: [ NoCloud, None ]
|
|
EOF
|
|
}
|
|
|
|
## --------------
|
|
# remove 127.0.1.1 entry (LP: #440757)
|
|
_xchroot "${rootd}" sh -c 'sed -i "/^127.0.1.1/d" /etc/hosts'
|
|
|
|
## --------------
|
|
# remove ssh pregenerated keys (LP: #512377)
|
|
|
|
_xchroot "${rootd}" sh -c 'rm -f /etc/ssh/ssh_host_[rd]sa_key*'
|
|
|
|
## --------------
|
|
if [ "${SUBPROJECT:-}" != minimized ]; then
|
|
_xchroot "${rootd}" locale-gen en_US.utf8
|
|
fi
|
|
|
|
## --------------
|
|
# set cloud-init to be on
|
|
values="NoCloud, ConfigDrive, AltCloud, OVF, MAAS, Ec2, None"
|
|
printf "%s\t%s\t%s\t%s\n" \
|
|
cloud-init cloud-init/datasources multiselect "$values" |
|
|
_xchroot "${rootd}" debconf-set-selections
|
|
_xchroot "${rootd}" dpkg-reconfigure --frontend=noninteractive cloud-init
|
|
|
|
## --------------
|
|
# write some build information to the guest
|
|
# the idea is that given runtime info and this info, the instance
|
|
# can at least determine if there is a newer build available
|
|
# these variables are passed in in environment from cloudimg-build-launcher
|
|
if [ -n "${build_name}" -o -n "${serial}" ]; then
|
|
d="${rootd}/etc/cloud"
|
|
[ -d "$d" ] || mkdir -p "${d}"
|
|
{
|
|
[ -n "${build_name}" ] && echo "build_name: ${build_name}"
|
|
[ -n "${serial}" ] && echo "serial: ${serial}"
|
|
} > "$d/build.info"
|
|
fi
|
|
|
|
## --------------
|
|
# for maverick and newer, use LABEL= for the '/' entry in fstab
|
|
if [ -n "${root_fs_label}" ]; then
|
|
bl="[:blank:]"
|
|
lstr="LABEL=${root_fs_label}"
|
|
sed -i "s,^[^#${bl}]*\([${bl}]*/[${bl}].*\),${lstr}\1," "${rootd}/etc/fstab"
|
|
fi
|
|
cat > /etc/fstab << EOM
|
|
LABEL=cloudimg-rootfs / ext4 defaults 0 0
|
|
EOM
|
|
|
|
# for quantal and newer, add /etc/overlayroot.local.conf
|
|
# but do not overwrite anything that somehow got there
|
|
if [ -f "${rootd}/etc/overlayroot.conf" ] &&
|
|
[ ! -f "${rootd}/etc/overlayroot.local.conf" ]; then
|
|
{
|
|
echo "${CLOUD_IMG_STR}"
|
|
echo "overlayroot_cfgdisk=LABEL=OROOTCFG"
|
|
} > "${rootd}/etc/overlayroot.local.conf"
|
|
fi
|
|
|
|
# previous steps may have left a dangling symlink here with
|
|
# SUBPROJECT=minimized and that breaks lb_chroot_hacks step
|
|
if [ -L "${rootd}/boot/initrd.img" ] && [ ! -e "${rootd}/boot/initrd.img" ]; then
|
|
rm "${rootd}/boot/initrd.img"
|
|
fi
|
|
|
|
if [ "${SUBPROJECT:-}" = minimized ]; then
|
|
# Remove various packages that we don't want in the minimized images.
|
|
# Some of these are tools that don't make sense by default
|
|
# non-interactively; some are libraries whose reverse-dependencies
|
|
# will have already been removed; open-vm-tools, it's a bug that this
|
|
# is in the common cloud seed because this should only be included
|
|
# in VMWare guest images, and we know none of the minimized images
|
|
# are targeted at VMWare.
|
|
_xchroot "${rootd}" env DEBIAN_FRONTEND=noninteractive \
|
|
apt-mark auto '^lib.*' '^python*' vim-runtime 2>/dev/null
|
|
# FIXME: iso-codes is a dep of software-properties and shouldn't be
|
|
_xchroot "${rootd}" env DEBIAN_FRONTEND=noninteractive \
|
|
apt-get -y autoremove --purge iso-codes xauth pastebinit \
|
|
plymouth open-vm-tools git shared-mime-info vim vim-common \
|
|
console-setup ncurses-term tmux screen policykit-1 \
|
|
xdg-user-dirs less run-one apport-symptoms \
|
|
ubuntu-cloudimage-keyring file
|
|
# Add back pollinate, which gets removed due to a dependency on vim-common
|
|
_xchroot "${rootd}" env DEBIAN_FRONTEND=noninteractive \
|
|
apt-get -y install --no-install-recommends pollinate
|
|
|
|
_xchroot "${rootd}" apt clean
|
|
fi
|
|
|
|
#### END COMMON ARCH FUNCTIONS
|
|
|
|
|
|
case $arch in
|
|
# ARM images are special
|
|
armhf|arm64)
|
|
echo "Configuring ARM Serial Port"
|
|
add_serial_console ttyAMA0
|
|
# Dirty hack because SUBARCH doesn't exist when running chroot hooks,
|
|
# and we don't want raspi2 images to depend on a cloud data source:
|
|
if _xchroot "${rootd}" dpkg -l linux-image-raspi2 2>/dev/null | grep -q '^.i'; then
|
|
fake_cloud_init
|
|
fi
|
|
|
|
echo "Image architecture is ARM. Existing vmbuilder-fixups"
|
|
|
|
exit 0
|
|
;;
|
|
## Add ttyS0 for i386/amd64 for Trusty and newer
|
|
i386|amd64)
|
|
add_serial_console ttyS0
|
|
;;
|
|
powerpc|ppc64el)
|
|
add_serial_console hvc0
|
|
exit 0
|
|
;;
|
|
s390x)
|
|
exit 0
|
|
;;
|
|
esac
|
|
|
|
psuedo_grub_probe() {
|
|
cat <<"PSUEDO_GRUB_PROBE"
|
|
#!/bin/sh
|
|
Usage() {
|
|
cat <<EOF
|
|
Usage: euca-psuedo-grub-probe
|
|
this is a wrapper around grub-probe to provide the answers for an ec2 guest
|
|
EOF
|
|
}
|
|
bad_Usage() { Usage 1>&2; fail "$@"; }
|
|
|
|
short_opts=""
|
|
long_opts="device-map:,target:,device"
|
|
getopt_out=$(getopt --name "${0##*/}" \
|
|
--options "${short_opts}" --long "${long_opts}" -- "$@") &&
|
|
eval set -- "${getopt_out}" ||
|
|
bad_Usage
|
|
|
|
device_map=""
|
|
target=""
|
|
device=0
|
|
arg=""
|
|
|
|
while [ $# -ne 0 ]; do
|
|
cur=${1}; next=${2};
|
|
case "$cur" in
|
|
--device-map) device_map=${next}; shift;;
|
|
--device) device=1;;
|
|
--target) target=${next}; shift;;
|
|
--) shift; break;;
|
|
esac
|
|
shift;
|
|
done
|
|
arg=${1}
|
|
|
|
case "${target}:${device}:${arg}" in
|
|
device:*:/*) echo "/dev/sda1"; exit 0;;
|
|
fs:*:*) echo "ext2"; exit 0;;
|
|
partmap:*:*)
|
|
# older versions of grub (lucid) want 'part_msdos' written
|
|
# rather than 'msdos'
|
|
legacy_pre=""
|
|
grubver=$(dpkg-query --show --showformat '${Version}\n' grub-pc 2>/dev/null) &&
|
|
dpkg --compare-versions "${grubver}" lt 1.98+20100804-5ubuntu3 &&
|
|
legacy_pre="part_"
|
|
echo "${legacy_pre}msdos";
|
|
exit 0;;
|
|
abstraction:*:*) echo ""; exit 0;;
|
|
drive:*:/dev/sda) echo "(hd0)";;
|
|
drive:*:/dev/sda*) echo "(hd0,1)";;
|
|
fs_uuid:*:*) exit 1;;
|
|
esac
|
|
PSUEDO_GRUB_PROBE
|
|
}
|
|
|
|
## install / setup grub2
|
|
gprobe="${rootd}/usr/sbin/grub-probe"
|
|
moved=0
|
|
if [ -f "${gprobe}" ]; then
|
|
mv "${gprobe}" "${gprobe}.dist"
|
|
moved=1
|
|
fi
|
|
psuedo_grub_probe > "${gprobe}"
|
|
chmod 755 "${gprobe}"
|
|
|
|
# for Quantal and later, use /etc/default/grub.d functionality
|
|
# rather than modifying the grub configuration itself.
|
|
# This avoids the mess of having to do dpkg stuff
|
|
# LP: 1179940
|
|
mkdir -p "${rootd}/etc/default/grub.d"
|
|
cat << EOF > "${rootd}/etc/default/grub.d/50-cloudimg-settings.cfg"
|
|
# Cloud Image specific Grub settings for Generic Cloud Images
|
|
${CLOUD_IMG_STR}
|
|
|
|
# Set the recordfail timeout
|
|
GRUB_RECORDFAIL_TIMEOUT=0
|
|
|
|
# Do not wait on grub prompt
|
|
GRUB_TIMEOUT=0
|
|
|
|
# Set the default commandline
|
|
GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0"
|
|
|
|
# Set the grub console type
|
|
GRUB_TERMINAL=console
|
|
EOF
|
|
_xchroot "${rootd}" update-grub2
|
|
|
|
# since this is a disk image, we technically don't need to install all the
|
|
# grub modules, as the image itself is not bootable. This makes for a small
|
|
# disk image
|
|
_xchroot "${rootd}" update-grub
|
|
|
|
# reconfigure grub so that upgrades to grub-pc do not force a debconf config
|
|
# changed prompt (LP: #1009294). This re-runs update-grub
|
|
_xchroot "${rootd}" env DEBIAN_FRONTEND=noninteractive \
|
|
dpkg-reconfigure grub-pc
|
|
|
|
grub2cfg="${rootd}/boot/grub/grub.cfg"
|
|
[ ! -f "${grub2cfg}" ] ||
|
|
sed -i -e "s,root=/dev/[hs]da1,root=LABEL=${root_fs_label}," "${grub2cfg}"
|
|
|
|
[ ${moved} -eq 0 ] || mv "${gprobe}.dist" "${gprobe}"
|
|
|
|
## modify /boot/grub/menu.lst if it exists
|
|
## this is generated at install time by grub-legacy-ec2, but will have
|
|
## devices as found from the _xchroot. Here we write what it will be on ec2
|
|
if [ -f "${rootd}/boot/grub/menu.lst" ]; then
|
|
grub_root="(hd0)"
|
|
linux_root=/dev/sda1
|
|
[ -n "${root_fs_label}" ] && linux_root="LABEL=${root_fs_label}"
|
|
# the sed code below basically fixes/sets the following lines in a
|
|
# /boot/grub/menu.lst file:
|
|
# # kopt=root=xxxxxxx ro
|
|
# kernel /boot/vmlinuz-... root=xxxxxx ....
|
|
# # groot=xxxxx
|
|
# root xxxxx
|
|
# uuuid xxxxx
|
|
sed -i "${rootd}/boot/grub/menu.lst" \
|
|
-e "s|^\(# kopt=root=\)[^ ]*|\1${linux_root}|" \
|
|
-e "s|^\(kernel.*root=\)[^ ]*|\1${linux_root}|" \
|
|
-e "s|^\(# groot=\)[^ ]*|\1${grub_root}|" \
|
|
-e "s|^\(root\|uuid\)\([[:space:]]*\).*|root\2${grub_root}|"
|
|
|
|
# grub-legacy-ec2 writes this ucf entry. since we've modified
|
|
# /boot/grub/menu.lst, we have to remove it, or the user will
|
|
# get prompted for a 3 way merge of the changes the first time this runs
|
|
_xchroot "${rootd}" /usr/bin/ucfr --purge grub /var/run/grub/menu.lst
|
|
fi
|
|
|
|
# vi: ts=3 expandtab
|