image-builder refactor

The original image-builder approach had an entirely containerized
approach for building target images.

This approach was flawed because:
1. There are a number of debian packages which will not install without
/sys, /proc, /dev, or /dev/pts mountpoints, and
2. Container build process does not support building with privileges
needed to bind-mount these directories into the chroot build space
3. It is a requirement for all packages to be installed in the container
image in order to avoid deployment risk of missing mirror resources

This patchset addresses this problem by performing necessary privileged
steps outside of a containerized build process. At the end of this
process, the root filesystem is packaged into a docker container when
elevated permissions are no longer required.

Change-Id: I5f8dc972f67c5649bf5f9403a5a512d06c948720
This commit is contained in:
Anderson, Craig (ca846m) 2021-02-11 02:01:54 -08:00
parent 20bf55629a
commit 0064db95fe
36 changed files with 464 additions and 412 deletions

View File

@ -43,7 +43,8 @@
- job:
name: airship-images-build
nodeset: airship-images-single-node
timeout: 3600
timeout: 7200
post-timeout: 7200
pre-run: playbooks/airship-images-deploy-docker.yaml
run: playbooks/airship-images-build.yaml
post-run: playbooks/airship-collect-logs.yaml
@ -74,7 +75,7 @@
name: airship-images-single-node
nodes:
- name: primary
label: ubuntu-bionic
label: ubuntu-bionic-32GB
- secret:
name: images_airshipit_github_secret

View File

@ -10,92 +10,21 @@ LABEL org.opencontainers.image.authors='airship-discuss@lists.airshipit.org, irc
SHELL ["bash", "-exc"]
ENV DEBIAN_FRONTEND noninteractive
# Update distro and install ansible
RUN apt-get update ;\
apt-get dist-upgrade -y ;\
apt-get install -y --no-install-recommends \
python3-minimal \
python3-pip \
python3-apt \
python3-setuptools ;\
pip3 install --upgrade wheel ;\
pip3 install --upgrade ansible ;\
rm -rf /var/lib/apt/lists/*
FROM base-image as rootfs-builder
# install requirements for building chroot
RUN apt-get update ;\
apt-get install -y --no-install-recommends \
ca-certificates \
multistrap \
equivs \
curl \
ca-certificates \
build-essential \
gnupg2 \
dosfstools;\
rm -rf /var/lib/apt/lists/*
COPY assets/playbooks/inventory.yaml /opt/assets/playbooks/inventory.yaml
COPY assets/playbooks/base-chroot.yaml /opt/assets/playbooks/base-chroot.yaml
COPY assets/playbooks/roles/multistrap /opt/assets/playbooks/roles/multistrap
RUN ansible-playbook -i /opt/assets/playbooks/inventory.yaml /opt/assets/playbooks/base-chroot.yaml
COPY assets/playbooks/base-osconfig.yaml /opt/assets/playbooks/base-osconfig.yaml
COPY assets/playbooks/roles/osconfig /opt/assets/playbooks/roles/osconfig
RUN ansible-playbook -i /opt/assets/playbooks/inventory.yaml /opt/assets/playbooks/base-osconfig.yaml --tags "pre_install"
FROM base-image as squashfs-builder
ENV root_chroot /mnt/rootfs
ENV root_image /mnt/image
ENV boot_src="/opt/grub"
RUN apt-get update ;\
apt-get install -y --no-install-recommends \
dosfstools \
mtools \
squashfs-tools \
grub-common \
grub2-common \
grub-pc-bin \
grub-efi-amd64-signed;\
rm -rf /var/lib/apt/lists/*
COPY --from=rootfs-builder ${root_chroot} ${root_chroot}
COPY assets/playbooks/inventory.yaml /opt/assets/playbooks/inventory.yaml
COPY assets/playbooks/base-livecdcontent.yaml /opt/assets/playbooks/base-livecdcontent.yaml
COPY assets/playbooks/roles/livecdcontent /opt/assets/playbooks/roles/livecdcontent
RUN ansible-playbook -i /opt/assets/playbooks/inventory.yaml /opt/assets/playbooks/base-livecdcontent.yaml
FROM base-image as image-builder
ENV boot_src="/opt/grub"
ENV root_image /mnt/image
RUN apt-get update ;\
apt-get install -y --no-install-recommends \
xorriso \
grub-pc-bin \
python3-minimal \
python3-yaml ;\
rm -rf /var/lib/apt/lists/*
COPY --from=squashfs-builder ${root_image} ${root_image}
COPY assets/playbooks/inventory.yaml /opt/assets/playbooks/inventory.yaml
COPY assets/playbooks/iso.yaml /opt/assets/playbooks/iso.yaml
COPY assets/playbooks/roles/iso /opt/assets/playbooks/roles/iso
RUN apt-get update ;\
apt-get install -y --no-install-recommends \
python3-yaml \
python3-pip \
python3-setuptools \
python3-apt \
grub-pc-bin \
coreutils \
curl \
qemu-utils \
@ -107,19 +36,30 @@ RUN apt-get update ;\
vim \
kmod \
efivar \
rsync \
dosfstools ;\
pip3 install --upgrade pip ;\
pip3 install --upgrade wheel ;\
pip3 install --upgrade ansible ;\
rm -rf /var/lib/apt/lists/*
COPY assets/playbooks/base-osconfig.yaml /opt/assets/playbooks/base-osconfig.yaml
COPY assets/playbooks/roles/osconfig /opt/assets/playbooks/roles/osconfig
COPY assets/playbooks/qcow.yaml /opt/assets/playbooks/qcow.yaml
COPY assets/playbooks/roles/qcow /opt/assets/playbooks/roles/qcow
RUN curl -L https://github.com/mikefarah/yq/releases/download/2.4.0/yq_linux_amd64 -o /bin/yq \
&& chmod +x /bin/yq
COPY assets/playbooks/inventory.yaml /opt/assets/playbooks/inventory.yaml
COPY assets/playbooks/base-chroot.yaml /opt/assets/playbooks/base-chroot.yaml
COPY assets/playbooks/roles/multistrap /opt/assets/playbooks/roles/multistrap
COPY assets/playbooks/base-osconfig.yaml /opt/assets/playbooks/base-osconfig.yaml
COPY assets/playbooks/roles/osconfig /opt/assets/playbooks/roles/osconfig
COPY assets/playbooks/base-livecdcontent.yaml /opt/assets/playbooks/base-livecdcontent.yaml
COPY assets/playbooks/roles/livecdcontent /opt/assets/playbooks/roles/livecdcontent
COPY assets/playbooks/iso.yaml /opt/assets/playbooks/iso.yaml
COPY assets/playbooks/roles/iso /opt/assets/playbooks/roles/iso
COPY assets/playbooks/qcow.yaml /opt/assets/playbooks/qcow.yaml
COPY assets/playbooks/roles/qcow /opt/assets/playbooks/roles/qcow
COPY assets/playbooks/build /build
COPY assets/*.sh /usr/bin/local/
COPY assets/*.json /usr/bin/local/
CMD /usr/bin/local/entrypoint.sh

View File

@ -24,11 +24,10 @@ PUSH_IMAGE ?= false
DISTRO ?= ubuntu_focal
IMAGE ?= ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${IMAGE_NAME}:${IMAGE_TAG}-${DISTRO}
IMAGE_ALIAS ?= $(DOCKER_REGISTRY)-$(IMAGE_NAME)-$(IMAGE_TAG)-${DISTRO}-${IMAGE_TYPE}
UEFI_BOOT ?= true
PROXY ?=
NO_PROXY ?= localhost,127.0.0.1
.PHONY: help build images install_prereqs cut_image run
.PHONY: help build images cut_image run clean
.ONESHELL:
@ -38,17 +37,6 @@ help: ## This help.
# Make target name that zuul expects for each project in this repo
images: build
install_prereqs:
ifneq ($(PROXY), )
export http_proxy=$(PROXY)
export https_proxy=$(PROXY)
export no_proxy=$(NO_PROXY)
export HTTP_PROXY=$(PROXY)
export HTTPS_PROXY=$(PROXY)
export NO_PROXY=$(NO_PROXY)
endif
sudo -E tools/install_prereqs.$(DISTRO)
build:
ifneq ($(PROXY), )
sudo -E ./tools/docker_proxy.sh $(PROXY) $(NO_PROXY)
@ -58,7 +46,8 @@ ifneq ($(PROXY), )
export HTTP_PROXY=$(PROXY)
export HTTPS_PROXY=$(PROXY)
export NO_PROXY=$(NO_PROXY)
sudo -E docker build --tag $(IMAGE) -f Dockerfile.$(DISTRO) . \
sudo -E ./tools/multistrap.sh
sudo -E docker -D -l debug build --tag $(IMAGE) -f Dockerfile.$(DISTRO) . \
--label $(LABEL) \
--label "org.opencontainers.image.revision=$(COMMIT)" \
--label "org.opencontainers.image.created=\
@ -69,22 +58,21 @@ ifneq ($(PROXY), )
--build-arg HTTP_PROXY=$(PROXY) \
--build-arg HTTPS_PROXY=$(PROXY) \
--build-arg no_proxy=$(NO_PROXY) \
--build-arg NO_PROXY=$(NO_PROXY) \
--build-arg UEFI_BOOT=$(UEFI_BOOT) || exit 1
--build-arg NO_PROXY=$(NO_PROXY) || exit 1
else
sudo -E docker build --tag $(IMAGE) -f Dockerfile.$(DISTRO) . \
sudo -E ./tools/multistrap.sh
sudo -E docker -D -l debug build --tag $(IMAGE) -f Dockerfile.$(DISTRO) . \
--label $(LABEL) \
--label "org.opencontainers.image.revision=$(COMMIT)" \
--label "org.opencontainers.image.created=\
$(shell date --rfc-3339=seconds --utc)" \
--label "org.opencontainers.image.title=$(IMAGE_NAME)" \
--build-arg UEFI_BOOT=$(UEFI_BOOT) || exit 1
--label "org.opencontainers.image.title=$(IMAGE_NAME)" || exit 1
endif
ifeq ($(PUSH_IMAGE), true)
sudo -E docker push $(IMAGE)
endif
cut_image: install_prereqs
cut_image:
ifneq ($(PROXY), )
sudo -E ./tools/docker_proxy.sh $(PROXY) $(NO_PROXY)
export http_proxy=$(PROXY)
@ -94,7 +82,7 @@ ifneq ($(PROXY), )
export HTTPS_PROXY=$(PROXY)
export NO_PROXY=$(NO_PROXY)
endif
sudo -E tools/cut_image.sh $(IMAGE_TYPE) ./examples $(IMAGE) $(IMAGE_ALIAS) "$(UEFI_BOOT)" "$(PROXY)" "$(NO_PROXY)"
sudo -E tools/cut_image.sh $(IMAGE_TYPE) ./examples $(IMAGE) $(IMAGE_ALIAS) "$(PROXY)" "$(NO_PROXY)"
run: ## Run the iso in kvm for testing
virsh start $(IMAGE_ALIAS)
@ -102,3 +90,5 @@ run: ## Run the iso in kvm for testing
tests:
true
clean:
sudo -E tools/multistrap.sh clean

View File

@ -13,12 +13,6 @@ cd "$BASEDIR"
BASEDIR="$(dirname "$(realpath "$0")")"
source "${BASEDIR}/functions.sh"
: "${uefi_boot:=}"
if [[ -n $uefi_boot ]]; then
extra_vars="uefi=$uefi_boot"
fi
export http_proxy
export https_proxy
export HTTP_PROXY
@ -26,6 +20,10 @@ export HTTPS_PROXY
export no_proxy
export NO_PROXY
if [ ! -e build ]; then
ln -s /chroot build
fi
# Instruct ansible to output the image artifact to the container's host mount
extra_vars="$extra_vars img_output_dir=${VOLUME}"
@ -37,7 +35,7 @@ if [[ "${IMAGE_TYPE}" == "iso" ]]; then
extra_vars="$extra_vars img_name=${IMG_NAME}"
echo "Executing Step 1"
ansible-playbook -i /opt/assets/playbooks/inventory.yaml /opt/assets/playbooks/iso.yaml --extra-vars "$extra_vars" -vvvv
ansible-playbook -i /opt/assets/playbooks/inventory.yaml /opt/assets/playbooks/iso.yaml --extra-vars "$extra_vars" -vv
elif [[ "${IMAGE_TYPE}" == "qcow" ]]; then
_process_input_data_set_vars_qcow
_process_input_data_set_vars_osconfig
@ -46,13 +44,14 @@ elif [[ "${IMAGE_TYPE}" == "qcow" ]]; then
extra_vars="$extra_vars img_name=${IMG_NAME}"
echo "Executing Step 1: Create qcow2 partitions and filesystems"
ansible-playbook -i /opt/assets/playbooks/inventory.yaml /opt/assets/playbooks/qcow.yaml --extra-vars "$extra_vars" --tags "prep_img" -vvvv
ansible-playbook -i /opt/assets/playbooks/inventory.yaml /opt/assets/playbooks/qcow.yaml --extra-vars "$extra_vars" --tags "prep_img" -vv
echo "Executing Step 2: Applying changes from base-osconfig playbook"
ansible-playbook -i /opt/assets/playbooks/inventory.yaml /opt/assets/playbooks/base-osconfig.yaml --extra-vars "$extra_vars" -vvvv
ansible-playbook -i /opt/assets/playbooks/inventory.yaml /opt/assets/playbooks/base-osconfig.yaml --extra-vars "$extra_vars" --tags "runtime_and_buildtime" -vv
ansible-playbook -i /opt/assets/playbooks/inventory.yaml /opt/assets/playbooks/base-osconfig.yaml --extra-vars "$extra_vars" --tags "runtime_only" -vv
echo "Executing Step 3: Close image and write qcow2"
ansible-playbook -i /opt/assets/playbooks/inventory.yaml /opt/assets/playbooks/qcow.yaml --extra-vars "$extra_vars" --tags "close_img" -vvvv
ansible-playbook -i /opt/assets/playbooks/inventory.yaml /opt/assets/playbooks/qcow.yaml --extra-vars "$extra_vars" --tags "close_img" -vv
else
echo "\${IMAGE_TYPE} value '${IMAGE_TYPE}' does not match an expected value: [ 'iso', 'qcow' ]"
exit 1

View File

@ -1,5 +1,5 @@
---
- hosts: /mnt/rootfs
- hosts: build
gather_facts: false
roles:
- osconfig

View File

@ -5,6 +5,6 @@ all:
ansible_python_interpreter: /usr/bin/python3
chroots:
hosts:
/mnt/rootfs:
build:
ansible_connection: chroot
ansible_python_interpreter: /usr/bin/python3

View File

@ -1,6 +1,6 @@
img_output_dir: /config
img_name: ephemeral.iso
root_image: /mnt/image
root_image: /build
meta_data_file: /config/meta_data.json
user_data_file: /config/user_data

View File

@ -1,3 +1,28 @@
- name: "ISO | Reduce image size"
file:
state: absent
path: "{{ root_image }}/lib"
- name: "ISO | Reduce image size"
file:
state: absent
path: "{{ root_image }}/usr"
- name: "ISO | Reduce image size"
file:
state: absent
path: "{{ root_image }}/bin"
- name: "ISO | Reduce image size"
file:
state: absent
path: "{{ root_image }}/sbin"
- name: "ISO | Reduce image size"
file:
state: absent
path: "{{ root_image }}/var"
- name: "ISO | Reduce image size"
file:
state: absent
path: "{{ root_image }}/opt"
- name: "ISO | Ensure any old iso image at target location is removed"
file:
state: absent

View File

@ -1,3 +1,2 @@
root_chroot: /mnt/rootfs
root_image: /mnt/image
boot_src: /opt/grub
root_chroot: build
root_image: build

View File

@ -1,29 +1,7 @@
- name: ansible copy file locally - vmlinuz.
copy:
src: "{{ item }}"
dest: "{{ root_image }}/vmlinuz"
remote_src: yes
with_fileglob: "{{ root_chroot }}/boot/vmlinuz-*"
- name: ansible copy file locally - initrd.
copy:
src: "{{ item }}"
dest: "{{ root_image }}/initrd"
remote_src: yes
with_fileglob: "{{ root_chroot }}/boot/initrd.img-*"
- name: ansible copy file locally - config.
copy:
src: "{{ item }}"
dest: "{{ root_image }}/config"
remote_src: yes
with_fileglob: "{{ root_chroot }}/boot/config-*"
- name: "Stamp out a marker file for grub to use when identifying the desired boot volume"
copy:
#TODO: populate this with meaningful content
content: "{{ ansible_date_time.date }}"
dest: "{{ root_image }}/AIRSHIP_EPHEMERAL"
dest: "{{ root_image }}/AIRSHIP"
- name: "create directory for boot image assembly"
tempfile:
@ -77,4 +55,4 @@
shell:
cmd: |
cat /usr/lib/grub/i386-pc/cdboot.img {{ bootimg_builddir.path }}/core.img > {{ root_image }}/boot/grub/bios.img
cp {{ bootimg_builddir.path }}/efiboot.img {{ root_image }}/boot/grub/
cp {{ bootimg_builddir.path }}/efiboot.img {{ root_image }}/boot/grub/efiboot.img

View File

@ -4,6 +4,11 @@
state: directory
mode: '0755'
- name: "ensure no previous squashfs file"
file:
path: "{{ root_image }}/live/filesystem.squashfs"
state: absent
- name: "Building squashfs"
shell:
cmd: |

View File

@ -1,4 +1,4 @@
search --set=root --file /AIRSHIP_EPHEMERAL
search --set=root --file /AIRSHIP
insmod all_video
@ -6,6 +6,6 @@ set default="0"
set timeout=1
menuentry "Airship Ephemeral" {
linux /vmlinuz boot=live quiet nomodeset overlay-size=70% systemd.unified_cgroup_hierarchy=0 ds=ConfigDrive
initrd /initrd
linux /boot/vmlinuz boot=live quiet nomodeset overlay-size=70% systemd.unified_cgroup_hierarchy=0 ds=ConfigDrive
initrd /boot/initrd.img
}

View File

@ -1,7 +1,10 @@
rootfs_root: /mnt/rootfs
rootfs_root: build
rootfs_arch: amd64
k8s_version: 1.18.6-00
kernel_base_pkg: linux-image-generic
kernel_headers_pkg: linux-headers-generic
ubuntu_packages:
- apparmor
- apt-file
- apt-utils
- apt-transport-https
@ -13,15 +16,19 @@ ubuntu_packages:
- cloud-init
- conntrack
- curl
- dbus
- dnsutils
- dosfstools
- e2fsprogs
- ebtables
- efivar
- ethtool
- file
- gawk
- gettext-base
- gnupg2
#- grub2 # cannot install until after boot partition is available
- grub2
- grub-efi-amd64-signed
- ifenslave
- isc-dhcp-client
- iproute2
@ -30,14 +37,19 @@ ubuntu_packages:
- iputils-ping
- iputils-tracepath
- ipvsadm
- kdump-tools
- "{{ kernel_base_pkg }}"
- "{{ kernel_headers_pkg }}"
- kmod
- less
- linux-image-generic # this will be reinstalled later when the boot partition is available
- live-boot
- locales
- locales-all
- logrotate
- lsb-release
- lsof
- man-db
- mawk
- mbr
- netplan.io
- net-tools
@ -46,6 +58,7 @@ ubuntu_packages:
- passwd
- python3
- python3-apt
- rsyslog
- socat
- systemd
- systemd-sysv

View File

@ -35,30 +35,36 @@
include_tasks: apt-key-install.yaml
loop: "{{ repos }}"
- name: "ensuring directory {{ rootfs_root }}/dev exists for chroot"
file:
path: "{{ rootfs_root }}/dev"
state: directory
mode: '0755'
- name: "Setting up devices for chroot"
# kdump-tools does not install properly in multistrap environment. This fix allows kdump-tools
# installation to succeed.
- name: "kdump-tools fix - create directory"
shell: |
mknod "{{ rootfs_root }}/dev/random" c 1 8
chmod 640 "{{ rootfs_root }}/dev/random"
chown 0:0 "{{ rootfs_root }}/dev/random"
mknod "{{ rootfs_root }}/dev/urandom" c 1 9
chmod 640 "{{ rootfs_root }}/dev/urandom"
chown 0:0 "{{ rootfs_root }}/dev/urandom"
mknod "{{ rootfs_root }}/dev/null" c 1 3
chmod 666 "{{ rootfs_root }}/dev/null"
chown 0:0 "{{ rootfs_root }}/dev/null"
set -e
mkdir -p "{{ rootfs_root }}/etc/kernel/postinst.d"
- name: "kdump-tools fix - deploy build script"
template:
src: kdump-tools.j2
dest: "{{ rootfs_root }}/etc/kernel/postinst.d/kdump-tools"
mode: '0755'
# kdump-tools deb package will overwrite script without write protection enabled
- name: "kdump-tools fix - lock build script"
shell: |
set -e
chattr +i "{{ rootfs_root }}/etc/kernel/postinst.d/kdump-tools"
- name: "Running multistrap"
shell:
cmd: "multistrap -f {{ multistrap_tempdir.path }}/multistrap.conf"
#- name: "create grub.cfg"
# shell:
# cmd: |
# chroot {{ rootfs_root }} update-grub
- name: "Lock sources.list to prevent conflict and duplicates with multistrap repo list"
shell: |
set -e
if [ -f {{ rootfs_root }}/etc/apt/sources.list ]; then rm {{ rootfs_root }}/etc/apt/sources.list; fi
ln -s /dev/null {{ rootfs_root }}/etc/apt/sources.list
if [ -f {{ rootfs_root }}/etc/apt/sources.list ] && [ ! -h {{ rootfs_root }}/etc/apt/sources.list ]; then
rm {{ rootfs_root }}/etc/apt/sources.list
ln -s /dev/null {{ rootfs_root }}/etc/apt/sources.list
fi

View File

@ -0,0 +1,75 @@
#!/bin/sh -e
version="$1"
kdumpdir="/var/lib/kdump"
[ -x /usr/sbin/mkinitramfs ] || exit 0
# passing the kernel version is required
if [ -z "${version}" ]; then
echo >&2 "W: kdump-tools: ${DPKG_MAINTSCRIPT_PACKAGE:-kdump-tools package} did not pass a version number"
exit 2
fi
if ! linux-version list | grep "${version}" > /dev/null ; then
exit 0
fi
# exit if kernel does not need an initramfs
if [ "$INITRD" = 'No' ]; then
exit 0
fi
# avoid running multiple times
if [ -n "$DEB_MAINT_PARAMS" ]; then
eval set -- "$DEB_MAINT_PARAMS"
if [ -z "$1" ] || [ "$1" != "configure" ]; then
exit 0
fi
fi
# We need a modified copy of initramfs-tools directory
# with MODULES=dep in initramfs.conf
if [ ! -d "$kdumpdir" ];then
mkdir "$kdumpdir" || true
fi
# Force re-creation of $kdumpdir/initramfs-tools
# in case the source has changed since last time
# we ran
if [ -d "$kdumpdir/initramfs-tools" ];then
rm -Rf $kdumpdir/initramfs-tools || true
fi
cp -pr /etc/initramfs-tools "$kdumpdir" || true
initramfsdir="$kdumpdir/initramfs-tools"
# Add scsi_dh_* modules if in use otherwise
# kexec reboot on multipath will fail
# (LP: #1635597)
for I in $(lsmod | grep scsi_dh | cut -d" " -f1);do
echo "${I}" >> $initramfsdir/modules
done
# canderson: This line needs to be commented out for kdump-tools to install with multistrap
#sed -e 's/MODULES=.*/MODULES=dep/' /etc/initramfs-tools/initramfs.conf > "$initramfsdir/initramfs.conf" || true
if ! [ -e "$initramfsdir/initramfs.conf" ];then
echo >&2 "W: kdump-tools: Unable to create $initramfsdir/initramfs.conf"
exit 2
fi
# Cleaning up existing initramfs with same version
# as mkinitramfs do not have a force option
if [ -e "$kdumpdir/initrd.img-${version}" ];then
rm -f "$kdumpdir/initrd.img-${version}" || true
fi
# we're good - create initramfs.
echo "kdump-tools: Generating $kdumpdir/initrd.img-${version}"
if mkinitramfs -d "$initramfsdir" -o "$kdumpdir/initrd.img-${version}.new" "${version}";then
mv "$kdumpdir/initrd.img-${version}.new" "$kdumpdir/initrd.img-${version}"
else
mkinitramfs_return="$?"
rm -f "${initramfs}.new"
echo "update-initramfs: failed for ${initramfs} with $mkinitramfs_return." >&2
exit $mkinitramfs_return
fi

View File

@ -1,11 +1,6 @@
rootfs_root: /mnt/rootfs
cni_version: v0.8.2
k8s_version: v1.18.6
rootfs_root: build
kernel:
base_pkg: linux-image-generic
headers_pkg: linux-headers-generic
modules:
load:
- name: 8021q
@ -92,26 +87,19 @@ systemd:
# Use only if you are intenting to overwrite an existing systemd unit
force: no
# Note: You are encouraged to build your own image-builder container, where your desired
# package list can be supplied to multistrap during the container build. However, this
# option will allow you to layer additional packages (installed during container runtime,
# instead of during the container build) where a customized container build is not possible
# or not desired.
# This is also needed for a specific subset of packages that fail to install successfully
# with multistrap (e.g., kdump-tools).
post_install_package_list:
- kdump-tools
- apparmor
- dbus
- rsyslog
- logrotate
# If any other custom shell scripts are needed for bare-metal provisioning, they can be
# added here.
post_install_scripts:
# If any custom shell scripts are needed for qcow building for image building,
# they can be added here.
buildtime_user_scripts:
- file_content: |
#!/bin/bash
echo "custom post-install script"
echo "custom container buildtime script"
# Custom user shell scripts to be run during container execution, right before
# final QCOW image is created.
runtime_user_scripts:
- file_content: |
#!/bin/bash
echo "custom container buildtime script"
# Any other adjustments to file or directory permissions, for files that already exist.
file_permissions:

View File

@ -0,0 +1,3 @@
- name: "user-scripts | running user-defined scripts"
shell: "{{ item.file_content }}"
with_items: "{{ buildtime_user_scripts }}"

View File

@ -34,8 +34,14 @@
include_tasks: file-permissions.yaml
- name: "finalise rootfs"
include_tasks: finalise-rootfs.yaml
tags: pre_install
tags: runtime_and_buildtime
- block:
- name: "POST-INSTALL | Starting post-install"
include_tasks: post-install.yaml
tags: post_install
- name: "run user-defined scripts"
include_tasks: buildtime-user-scripts.yaml
tags: buildtime_only
- block:
- name: "run system-defined scripts"
include_tasks: runtime-system-scripts.yaml
- name: "run user-defined scripts"
include_tasks: runtime-user-scripts.yaml
tags: runtime_only

View File

@ -1,108 +0,0 @@
- name: "POST-INSTALL | Append any user-defined post-install pkgs to install list"
set_fact:
post_install_package_list: "{{ post_install_package_list + post_install_package_list_append }}"
when: post_install_package_list_append is defined
- name: "POST-INSTALL | DNS sanity check"
shell:
executable: /bin/bash
cmd: |
set -e
proxy="{{ lookup('env', 'HTTP_PROXY') }}"
# Ensure proxy address is resolvable, if supplied as a domain name
if [[ -n $proxy ]]; then
# Extract proxy server address from url
proxy_address="$(echo "$proxy" | awk -F/ '{print $3}' | awk -F: '{print $1}')"
# If first letter of proxy address is a letter, verify that a DNS lookup is possible
if [[ $proxy_address == [a-zA-z]* ]]; then
echo "proxy check for '$proxy_address' ..."
nslookup $proxy_address > /dev/null || (
echo "Failed to resolve proxy '$proxy_address' with dns server '$(cat /etc/resolv.conf)'."
echo "Reconfigure DNS setting provided in the 'qcow' playbook to a DNS server that can resolve '$proxy_address'."
exit 1
)
fi
fi
echo "archive.ubuntu.com DNS check ..."
nslookup archive.ubuntu.com || (
echo "DNS lookup failure for archive.ubuntu.com with '$(cat /etc/resolv.conf)'"
exit 1
)
- name: "POST-INSTALL | update source list"
apt:
update_cache: yes
- name: "POST-INSTALL | generate locales"
shell: |
set -e
locale-gen en_US.UTF-8
- name: "POST-INSTALL | Remove incomplete kernel install by multistrap"
shell: |
set -e
apt-get remove -y '^linux-image-.*'
apt-get remove -y '^linux-modules-.*'
- name: "POST-INSTALL | install grub2 and kernel"
apt:
pkg:
- grub2
- grub-efi-amd64-signed
- efivar
- "{{ kernel.base_pkg }}"
- "{{ kernel.headers_pkg }}"
- kmod
- name: "POST-INSTALL | grub-install LEGACY"
shell: |
set -e
grub-install --target=i386-pc --no-uefi-secure-boot --skip-fs-probe --force "{{ lookup('file', '/tmp/nbd') }}"
grub-install --target=i386-pc --no-uefi-secure-boot --skip-fs-probe --force --recheck "{{ lookup('file', '/tmp/nbd') }}"
when: uefi is not defined
- name: "POST-INSTALL | grub-install UEFI"
shell: |
set -e
grub-install --target=i386-pc --uefi-secure-boot --skip-fs-probe --force "{{ lookup('file', '/tmp/nbd') }}"
grub-install --target=i386-pc --uefi-secure-boot --skip-fs-probe --force --recheck "{{ lookup('file', '/tmp/nbd') }}"
grub-install --target=x86_64-efi --uefi-secure-boot --skip-fs-probe --force "{{ lookup('file', '/tmp/nbd') }}"
grub-install --target=x86_64-efi --uefi-secure-boot --skip-fs-probe --force --recheck "{{ lookup('file', '/tmp/nbd') }}"
when: uefi is defined
- name: "POST-INSTALL | generate grub cfg file"
shell: |
set -e
update-grub
- name: "POST-INSTALL | install other user-requested packages, and kernel-dependent pkgs and ones that fail to install with multistrap"
apt:
pkg: "{{ post_install_package_list }}"
- name: "POST-INSTALL | write root partition UUID to grub.cfg"
shell: |
set -e
cp -r /usr/lib/grub/* /boot/grub
blkid -s UUID -o value $(df -h | grep /$ | awk "{print \$1}") > /tmp/root_uuid
sed -i "s@root=/dev/nbd[0-9]p[0-9]@root=UUID=$(cat /tmp/root_uuid)@g" /boot/grub/grub.cfg
rm /tmp/root_uuid
- name: "POST-INSTALL | write boot partition UUID to UEFI grub.cfg"
shell: |
set -e
blkid -s UUID -o value $(df -h | grep /boot$ | awk "{print \$1}") > /tmp/boot_uuid
echo "search.fs_uuid $(cat /tmp/boot_uuid) root hd0,gpt2" > /boot/efi/EFI/ubuntu/grub.cfg
echo "set prefix=(\$root)'/grub'" >> /boot/efi/EFI/ubuntu/grub.cfg
echo "configfile \$prefix/grub.cfg" >> /boot/efi/EFI/ubuntu/grub.cfg
rm /tmp/boot_uuid
when: uefi is defined
- name: "POST-INSTALL | running user-defined post-scripts"
shell: "{{ item.file_content }}"
with_items: "{{ post_install_scripts }}"
- name: "POST-INSTALL | cleanup deb cache"
shell: |
set -e
rm /var/cache/apt/archives/*.deb

View File

@ -0,0 +1,34 @@
- name: "POST-INSTALL | generate locales"
shell: |
set -e
locale-gen en_US.UTF-8
- name: "POST-INSTALL | grub-install"
shell: |
set -e
grub-install --target=i386-pc --skip-fs-probe --force "{{ lookup('file', '/tmp/nbd') }}"
grub-install --target=i386-pc --skip-fs-probe --force --recheck "{{ lookup('file', '/tmp/nbd') }}"
grub-install --target=x86_64-efi --skip-fs-probe --force "{{ lookup('file', '/tmp/nbd') }}"
grub-install --target=x86_64-efi --skip-fs-probe --force --recheck "{{ lookup('file', '/tmp/nbd') }}"
- name: "POST-INSTALL | generate grub cfg file"
shell: |
set -e
update-grub
- name: "POST-INSTALL | write root partition UUID to grub.cfg"
shell: |
set -e
cp -r /usr/lib/grub/* /boot/grub
blkid -s UUID -o value $(df -h | grep /$ | awk "{print \$1}") > /tmp/root_uuid
sed -i "s@root=/dev/nbd[0-9]p[0-9]@root=UUID=$(cat /tmp/root_uuid)@g" /boot/grub/grub.cfg
rm /tmp/root_uuid
- name: "POST-INSTALL | write boot partition UUID to UEFI grub.cfg"
shell: |
set -e
blkid -s UUID -o value $(df -h | grep /boot$ | awk "{print \$1}") > /tmp/boot_uuid
echo "search.fs_uuid $(cat /tmp/boot_uuid) root hd0,gpt2" > /boot/efi/EFI/ubuntu/grub.cfg
echo "set prefix=(\$root)'/grub'" >> /boot/efi/EFI/ubuntu/grub.cfg
echo "configfile \$prefix/grub.cfg" >> /boot/efi/EFI/ubuntu/grub.cfg
rm /tmp/boot_uuid

View File

@ -0,0 +1,3 @@
- name: "user-scripts | running user-defined scripts"
shell: "{{ item.file_content }}"
with_items: "{{ runtime_user_scripts }}"

View File

@ -1,15 +1 @@
# NOTE: This file will be *overwritten* by the container entrypoint with user-provided vars, if any are defined.
#
# The following are examples that show you how to override variables.
#
# Example 1: The following usage will *overwrite* the list of packages
# defined under defaults/main.yaml with the list here:
#post_install_package_list:
# - package1
# - package2
#
# Example 2: The following usage will *append* to the list of default pkgs
# defined under defaults/main.yaml with the list here:
#post_install_package_list_append:
# - package1
# - package2

View File

@ -1,8 +1,8 @@
root_chroot: /mnt/rootfs
src: /build
dst: /chroot
nbd_build_dir: /tmp/nbd_build_dir
img_output_dir: /config
img_name: airship-ubuntu.qcow2
dns: 8.8.8.8
qcow_capacity: 5G
partitions:
# Partition numbering is according to list ordering.
@ -46,3 +46,12 @@ partitions:
options: "defaults,errors=remount-ro,noatime"
dump: 0
fsck: 2
# If any custom post-install shell scripts are needed for qcow building,
# they can be added here. This should only be used if
# osconfig_container_buildtime_scripts does not work in osconfig playbook.
qcow_container_runtime_scripts:
- file_content: |
#!/bin/bash
echo "custom qcow post-install script"
# This is only needed if you want DNS working when running qcow scripts above
qcow_container_runtime_scripts_dns: 8.8.8.8

View File

@ -1,7 +1,7 @@
- name: "QCOW | Installing extlinux"
shell: |
mkdir -p "{{ root_chroot }}"/boot/syslinux
extlinux --install "{{ root_chroot }}"/boot/syslinux/ --device /dev/disk/by-partlabel/{{ ( partitions | selectattr('mount', 'equalto', '/boot') | list | first ).mount | hash('md5') }}
mkdir -p "{{ dst }}"/boot/syslinux
extlinux --install "{{ dst }}"/boot/syslinux/ --device /dev/disk/by-partlabel/{{ ( partitions | selectattr('mount', 'equalto', '/boot') | list | first ).mount | hash('md5') }}
- name: "QCOW | Writing out syslinux config"
copy:
@ -11,12 +11,12 @@
LABEL linux
KERNEL /vmlinuz
APPEND root=/dev/disk/by-partlabel/{{ ( partitions | selectattr('mount', 'equalto', '/') | list | first ).mount | hash('md5') }} initrd=/initrd.img
dest: ""{{ root_chroot }}/boot/syslinux/syslinux.cfg"
dest: ""{{ dst }}/boot/syslinux/syslinux.cfg"
- name: "QCOW | Installing kernel and init ramdisk"
shell: |
rm -rf "{{ root_chroot }}"/vmlinuz
cp -f /mnt/image/vmlinuz "{{ root_chroot }}"/boot/
rm -rf "{{ dst }}"/vmlinuz
cp -f /mnt/image/vmlinuz "{{ dst }}"/boot/
rm -rf /tmp/mnt/initrd.img
cp -f /mnt/image/initrd "{{ root_chroot }}"/boot/initrd.img
cp -f /mnt/image/initrd "{{ dst }}"/boot/initrd.img

View File

@ -1,16 +1,18 @@
- name: "QCOW | copy ansible playbooks to target image"
shell: |
set -e
cp -r /opt/assets "{{ root_chroot }}"/opt
cp -r /opt/assets "{{ dst }}"/opt
- name: "QCOW | unmount target"
shell: |
set -e
# restore resolv.conf
chroot "{{ root_chroot }}" /bin/bash -c 'rm /etc/resolv.conf; cd /etc; ln -s ../run/systemd/resolve/stub-resolv.conf resolv.conf'
cd "{{ root_chroot }}"
chroot "{{ dst }}" /bin/bash -c 'rm /etc/resolv.conf; cd /etc; ln -s ../run/systemd/resolve/stub-resolv.conf resolv.conf'
cd "{{ dst }}"
mountpoint dev/pts > /dev/null && umount dev/pts
mountpoint dev > /dev/null && umount dev
mountpoint sys/firmware/efi > /dev/null && umount sys/firmware/efi
if [ -d /sys/firmware/efi ]; then
mountpoint sys/firmware/efi > /dev/null && umount sys/firmware/efi
fi
mountpoint sys > /dev/null && umount sys
mountpoint proc > /dev/null && umount proc

View File

@ -1,30 +1,13 @@
- name: "QCOW | mount sys LEGACY"
shell: |
set -e
mkdir -p "{{ root_chroot }}"
cd "{{ root_chroot }}"
mountpoint sys > /dev/null || mount -t sysfs /sys sys
# mount an empty dir to efi directory, otherwise grub will try to configure EFI boot for the target image, **iff** the build node was booted with EFI.
if [ -d sys/firmware/efi ]; then mountpoint sys/firmware/efi > /dev/null || mkdir /dummy; mount -o bind /dummy sys/firmware/efi; fi
when: uefi is not defined
- name: "QCOW | mount sys UEFI"
shell: |
set -e
mkdir -p "{{ root_chroot }}"
cd "{{ root_chroot }}"
mountpoint sys > /dev/null || mount -t sysfs /sys sys
# Required for building UEFI targets
ls /sys/firmware/efi > /dev/null || (echo "efivars not present on build system. Build system must be booted into UEFI mode." && exit 1)
mountpoint sys/firmware/efi > /dev/null || mount -o bind /sys/firmware/efi sys/firmware/efi
when: uefi is defined
- name: "QCOW | Mount remaining targets"
shell: |
set -e
cd "{{ root_chroot }}"
cd "{{ dst }}"
mountpoint sys > /dev/null || mount -t sysfs /sys sys
if [ -d /sys/firmware/efi ]; then
mountpoint sys/firmware/efi > /dev/null || mount -o bind /sys/firmware/efi sys/firmware/efi
fi
mountpoint proc > /dev/null || mount -t proc /proc proc
mountpoint dev > /dev/null || mount -o bind /dev dev
mountpoint dev/pts > /dev/null || mount -t devpts /dev/pts dev/pts
# temporarily override resolv.conf to working dns
chroot "{{ root_chroot }}" /bin/bash -c 'rm /etc/resolv.conf; echo "nameserver {{ dns }}" > /etc/resolv.conf'
chroot "{{ dst }}" /bin/bash -c 'rm /etc/resolv.conf; echo "nameserver {{ qcow_container_runtime_scripts_dns }}" > /etc/resolv.conf'

View File

@ -0,0 +1,5 @@
# Copy files onto partitioned disk
- name: "mount-helper | Copy files onto partition"
shell: |
set -e
rsync -ah {{ src }}/ {{ dst }}/ --exclude 'live'

View File

@ -19,10 +19,14 @@
file: mount-helper.yaml
with_items: "{{ partitions | sort( case_sensitive=True, attribute='mount_order' ) }}"
vars:
mount_offset: "{{ root_chroot }}"
mount_offset: "{{ dst }}"
state: mounted
fstab: /tmp/junkfstab
- name: "QCOW | Copy files to partition"
include_tasks:
file: copy-files.yaml
- name: "QCOW | Writing image content"
include_tasks:
file: writing-image-content.yaml
@ -44,7 +48,7 @@
file: mount-helper.yaml
with_items: "{{ partitions | sort( reverse=True, case_sensitive=True, attribute='mount' ) }}"
vars:
mount_offset: "{{ root_chroot }}"
mount_offset: "{{ dst }}"
state: unmounted
fstab: /tmp/junkfstab

View File

@ -1,16 +1,11 @@
- name: "QCOW | Writing out rootfs from squashfs"
shell: |
unsquashfs -d "{{ root_chroot }}" -f /mnt/image/live/filesystem.squashfs
exit 0
- name: "QCOW | Writing out fstab"
include_tasks: mount-helper.yaml
with_items: "{{ partitions | sort( case_sensitive=True, attribute='mount' ) }}"
vars:
mount_offset: null
state: present
fstab: "{{ root_chroot }}/etc/fstab"
fstab: "{{ dst }}/etc/fstab"
- name: "QCOW | Setting debug password"
shell: |
chroot "{{ root_chroot }}" sh -c "echo \"root:password\" | chpasswd"
chroot "{{ dst }}" sh -c "echo \"root:password\" | chpasswd"

View File

@ -0,0 +1 @@
{{ item.file_content }}

View File

@ -1,11 +1,4 @@
rootfs_root: /mnt/rootfs
cni_version: v0.8.2
k8s_version: v1.18.6
kernel:
base_pkg: linux-image-generic
headers_pkg: linux-headers-generic
modules:
load:
- name: 8021q
@ -165,17 +158,10 @@ systemd:
enabled: yes
force: no
post_install_package_list:
- kdump-tools
- apparmor
- dbus
- rsyslog
- logrotate
post_install_scripts:
buildtime_user_scripts:
- file_content: |
#!/bin/bash
echo "custom post-install script"
echo "custom container buildtime script"
file_permissions:
# Full path to file to create

View File

@ -1,6 +1,3 @@
root_chroot: /mnt/rootfs
nbd_build_dir: /tmp/nbd_build_dir
dns: 8.8.8.8
qcow_capacity: 412G
partitions:
# Partition numbering is according to list ordering.

View File

@ -1,4 +1,3 @@
dns: 8.8.8.8
qcow_capacity: 5G
partitions:
# Partition numbering is according to list ordering.

View File

@ -18,14 +18,10 @@ image="${3:-port/image-builder:latest-ubuntu_focal}"
# Libvirt instance name to use for a new libvirt XML definition that
# will be created to reference the newly created ISO or QCOW2 image.
img_alias="${4:-port-image-builder-latest-ubuntu_focal-$build_type}"
# Whether or not to build the image with UEFI support.
# NOTE: Machines that are not booted with UEFI will be unable to create
# UEFI images.
uefi_boot="$5"
# proxy to use, if applicable
proxy="$6"
proxy="$5"
# noproxy to use, if applicable
noproxy="$7"
noproxy="$6"
if [ -n "$proxy" ]; then
export http_proxy=$proxy
@ -39,8 +35,23 @@ if [ -n "$noproxy" ]; then
export NO_PROXY=$noproxy
fi
if [ -n "$uefi_boot" ]; then
# Install pre-requisites
install_pkg(){
dpkg -l $1 2> /dev/null | grep ^ii > /dev/null || sudo -E apt-get -y install $1
}
sudo -E apt -y update
install_pkg qemu-kvm
install_pkg virtinst
install_pkg libvirt-bin
install_pkg cloud-image-utils
install_pkg ovmf
type docker >& /dev/null || install_pkg docker.io
if [ -d /sys/firmware/efi ]; then
uefi_mount='--volume /sys/firmware/efi:/sys/firmware/efi:rw'
uefi_boot_arg='--boot uefi'
fi
workdir="$(realpath ${host_mount_directory})"
@ -58,9 +69,9 @@ if [[ $build_type = iso ]]; then
--env NO_PROXY=$noproxy \
${image}
disk1="--disk path=${workdir}/ephemeral.iso,device=cdrom"
uefi_boot_arg='--boot uefi'
elif [[ $build_type == qcow ]]; then
sudo -E modprobe nbd
echo "Note: This step can be slow if you don't have an SSD."
sudo -E docker run -t --rm \
--privileged \
--volume /dev:/dev:rw \
@ -78,15 +89,11 @@ elif [[ $build_type == qcow ]]; then
--env HTTPS_PROXY=$proxy \
--env no_proxy=$noproxy \
--env NO_PROXY=$noproxy \
--env uefi_boot=$uefi_boot \
${image}
cloud_init_config_dir='assets/tests/qcow/cloud-init'
sudo -E cloud-localds -v --network-config="${cloud_init_config_dir}/network-config" "${workdir}/airship-ubuntu_config.iso" "${cloud_init_config_dir}/user-data" "${cloud_init_config_dir}/meta-data"
disk1="--disk path=${workdir}/control-plane.qcow2"
disk2="--disk path=${workdir}/airship-ubuntu_config.iso,device=cdrom"
if [ -n "$uefi_boot" ]; then
uefi_boot_arg='--boot uefi'
fi
else
echo Unknown build type: $build_type, exiting.
exit 1

View File

@ -1,15 +0,0 @@
#!/bin/bash
install_pkg(){
dpkg -l $1 >& /dev/null || sudo -E apt-get -y install $1
}
install_pkg qemu-kvm
install_pkg virtinst
install_pkg libvirt-bin
install_pkg cloud-image-utils
install_pkg ovmf
install_pkg efivar
type docker >& /dev/null || install_pkg docker.io
# required for building UEFI image
sudo -E modprobe efivars

136
image-builder/tools/multistrap.sh Executable file
View File

@ -0,0 +1,136 @@
#!/bin/bash
set -e
build_dir=assets/playbooks/build
osconfig_build_dir=$(basename $build_dir)
install_pkg(){
dpkg -l $1 2> /dev/null | grep ^ii > /dev/null || sudo -E apt-get -y install $1
}
setup_chroot(){
# Idempotently setup chroot mounts
mkdir -p $build_dir
mkdir -p $build_dir/sys
mountpoint $build_dir/sys > /dev/null || sudo mount -t sysfs /sys $build_dir/sys
if [ -d /sys/firmware/efi ]; then
mountpoint $build_dir/sys/firmware/efi > /dev/null || sudo mount -o bind /sys/firmware/efi $build_dir/sys/firmware/efi
fi
mkdir -p $build_dir/proc
mountpoint $build_dir/proc > /dev/null || sudo mount -t proc /proc $build_dir/proc
mkdir -p $build_dir/dev
mountpoint $build_dir/dev > /dev/null || sudo mount -o bind /dev $build_dir/dev
mountpoint $build_dir/dev/pts > /dev/null || sudo mount -t devpts /dev/pts $build_dir/dev/pts
mkdir -p $osconfig_build_dir
mountpoint $osconfig_build_dir > /dev/null || sudo mount -o bind $build_dir $osconfig_build_dir
}
umount_helper(){
if [[ -d "$1" ]] && mountpoint "$1" > /devnull; then
sudo umount "$1"
fi
}
umount_chroot(){
# Idempotently teardown chroot mounts
umount_helper $build_dir/dev/pts
umount_helper $build_dir/dev
if [[ -d /sys/firmware/efi ]]; then
umount_helper $build_dir/sys/firmware/efi
fi
umount_helper $build_dir/sys
umount_helper $build_dir/proc
umount_helper $osconfig_build_dir
}
# Install pre-requisites
sudo -E apt -y update
install_pkg efivar
# required for building UEFI image
sudo -E modprobe efivars
type docker >& /dev/null || install_pkg docker.io
install_pkg equivs
install_pkg ca-certificates
install_pkg build-essential
install_pkg gnupg2
install_pkg multistrap
install_pkg curl
install_pkg grub-common
install_pkg grub2-common
install_pkg grub-pc-bin
install_pkg grub-efi-amd64-signed
install_pkg dosfstools
install_pkg mtools
install_pkg squashfs-tools
install_pkg python3-minimal
install_pkg python3-pip
install_pkg python3-apt
install_pkg python3-setuptools
sudo -E pip3 install --upgrade pip
pip3 show wheel >& /dev/null || sudo -E pip3 install --upgrade wheel
pip3 show ansible >& /dev/null || sudo -E pip3 install --upgrade ansible
if [[ $1 = clean ]]; then
umount_chroot
sudo chattr -i $build_dir/etc/kernel/postinst.d/kdump-tools
if [[ -d $build_dir ]]; then
sudo rm -rf $build_dir
fi
if [[ -d $osconfig_build_dir ]]; then
sudo rm -rf $osconfig_build_dir
fi
exit 0
elif [[ $1 = umount ]]; then
umount_chroot
exit 0
elif [[ $1 = mount ]]; then
setup_chroot
exit 0
fi
setup_chroot
# Archive a copy of the ansible used to generate the image in the image itself
mkdir -p $build_dir/opt/assets/playbooks/roles
cp assets/playbooks/inventory.yaml $build_dir/opt/assets/playbooks/inventory.yaml
cp assets/playbooks/base-chroot.yaml $build_dir/opt/assets/playbooks/base-chroot.yaml
cp -r assets/playbooks/roles/multistrap $build_dir/opt/assets/playbooks/roles
# Run multistrap
sudo -E ansible-playbook -i assets/playbooks/inventory.yaml assets/playbooks/base-chroot.yaml -vv
cp assets/playbooks/base-osconfig.yaml $build_dir/opt/assets/playbooks/base-osconfig.yaml
cp -r assets/playbooks/roles/osconfig $build_dir/opt/assets/playbooks/roles
sudo -E ansible-playbook -i assets/playbooks/inventory.yaml assets/playbooks/base-osconfig.yaml --tags "runtime_and_buildtime" -vv
sudo -E ansible-playbook -i assets/playbooks/inventory.yaml assets/playbooks/base-osconfig.yaml --tags "buildtime_only" -vv
umount_chroot
cp assets/playbooks/base-livecdcontent.yaml $build_dir/opt/assets/playbooks/base-livecdcontent.yaml
cp -r assets/playbooks/roles/livecdcontent $build_dir/opt/assets/playbooks/roles
sudo -E ansible-playbook -i assets/playbooks/inventory.yaml assets/playbooks/base-livecdcontent.yaml -vv
cp assets/playbooks/iso.yaml $build_dir/opt/assets/playbooks/iso.yaml
cp -r assets/playbooks/roles/iso $build_dir/opt/assets/playbooks/roles
cp assets/playbooks/qcow.yaml $build_dir/opt/assets/playbooks/qcow.yaml
cp -r assets/playbooks/roles/qcow $build_dir/opt/assets/playbooks/roles
if [ ! -e $build_dir/dev/random ]; then
sudo -E mknod $build_dir/dev/random c 1 8
sudo -E chmod 640 $build_dir/dev/random
sudo -E chown 0:0 $build_dir/dev/random
fi
if [ ! -e $build_dir/dev/urandom ]; then
sudo -E mknod $build_dir/dev/urandom c 1 9
sudo -E chmod 640 $build_Dir/dev/urandom
sudo -E chown 0:0 $build_Dir/dev/urandom
fi
if [ -f $build_dir/dev/null ]; then
sudo rm -f $build_dir/dev/null
fi
if [ ! -e $build_dir/dev/null ]; then
sudo -E mknod $build_dir/dev/null c 1 3
sudo -E chmod 666 $build_dir/dev/null
sudo -E chown 0:0 $build_dir/dev/null
fi