diff --git a/image-builder/Dockerfile-qcow.ubuntu_focal b/image-builder/Dockerfile-qcow.ubuntu_focal index 7cbbd99..75747af 100644 --- a/image-builder/Dockerfile-qcow.ubuntu_focal +++ b/image-builder/Dockerfile-qcow.ubuntu_focal @@ -1,8 +1,6 @@ ARG FROM=alpine FROM ${FROM} -ARG WORKDIR - LABEL org.opencontainers.image.authors='airship-discuss@lists.airshipit.org, irc://#airshipit@freenode' \ org.opencontainers.image.url='https://airshipit.org' \ org.opencontainers.image.documentation='https://airship-images.readthedocs.org' \ @@ -10,4 +8,4 @@ LABEL org.opencontainers.image.authors='airship-discuss@lists.airshipit.org, irc org.opencontainers.image.vendor='The Airship Authors' \ org.opencontainers.image.licenses='Apache-2.0' -COPY $WORKDIR/*.qcow2 $WORKDIR/*.qcow2.md5sum /qcows/ +COPY *.qcow2 *.qcow2.md5sum /qcows/ diff --git a/image-builder/Makefile b/image-builder/Makefile index d1bc829..5557423 100644 --- a/image-builder/Makefile +++ b/image-builder/Makefile @@ -24,6 +24,7 @@ IMAGE_TYPE ?= iso # iso | qcow PUSH_IMAGE ?= false DISTRO ?= ubuntu_focal WORKDIR ?= ./config +QCOW_CONF_DIRS ?= IMAGE ?= ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${IMAGE_NAME}:${IMAGE_TAG}-${DISTRO} QCOW_IMAGE ?= ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${QCOW_IMAGE_NAME}:${IMAGE_TAG}-${DISTRO} PROXY ?= @@ -86,28 +87,38 @@ ifneq ($(PROXY), ) export HTTPS_PROXY=$(PROXY) export NO_PROXY=$(NO_PROXY) endif - # Assemble all qcows based on configs defined in each $(IMAGE_TYPE)* subdirectory - for subdir in `find $(WORKDIR) -name "$(IMAGE_TYPE)*" -type d -exec basename {} \;`; do +ifneq ($(EXPLICIT_DIRS), ) + iterDirs="$(EXPLICIT_DIRS)" +else + # Assemble all images based on configs defined in each $(IMAGE_TYPE)* subdirectory + iterDirs=`find $(WORKDIR) -name "$(IMAGE_TYPE)*" -type d -exec basename {} \;` +endif + for subdir in $$iterDirs; do + # ISO configs + export user_data=$(WORKDIR)/$$subdir/user_data + export network_config=$(WORKDIR)/$$subdir/network_data.json + # QCOW configs export osconfig_params=$(WORKDIR)/$$subdir/osconfig-*-vars.yaml export qcow_params=$(WORKDIR)/$$subdir/qcow-*-vars.yaml + # Shared configs export img_name=$$(cat $(WORKDIR)/$$subdir/img_name) sudo -E tools/cut_image.sh $(IMAGE_TYPE) $(WORKDIR) $(IMAGE) "$(PROXY)" "$(NO_PROXY)" || exit 1 done generate_iso: export IMAGE_TYPE=iso - make cut_image + sudo -E make cut_image package_qcow: export IMAGE_TYPE=qcow - make cut_image - sudo -E docker -D -l debug build --tag $(QCOW_IMAGE) -f Dockerfile-qcow.$(DISTRO) . \ + export EXPLICIT_DIRS=$(QCOW_CONF_DIRS) + sudo -E make cut_image + sudo -E docker -D -l debug build --tag $(QCOW_IMAGE) -f Dockerfile-qcow.$(DISTRO) $(WORKDIR) \ --label $(LABEL) \ --label "org.opencontainers.image.revision=$(COMMIT)" \ --label "org.opencontainers.image.created=\ $(shell date --rfc-3339=seconds --utc)" \ - --label "org.opencontainers.image.title=$(QCOW_IMAGE_NAME)" \ - --build-arg WORKDIR=$(WORKDIR) || exit 1 + --label "org.opencontainers.image.title=$(QCOW_IMAGE_NAME)" || exit 1 ifeq ($(PUSH_IMAGE), true) sudo -E docker push $(QCOW_IMAGE) endif @@ -117,3 +128,6 @@ tests: clean: sudo -E tools/multistrap.sh clean + rm $(WORKDIR)/*.iso + rm $(WORKDIR)/*.qcow2 + rm $(WORKDIR)/*.md5sum diff --git a/image-builder/assets/functions_v2.sh b/image-builder/assets/functions_v2.sh index 8ab285e..dc42522 100755 --- a/image-builder/assets/functions_v2.sh +++ b/image-builder/assets/functions_v2.sh @@ -137,9 +137,6 @@ _process_input_data_set_vars_qcow(){ # Optional user-supplied playbook vars if [[ -f "${QCOW_CONFIG_FILE}" ]]; then cp "${QCOW_CONFIG_FILE}" /opt/assets/playbooks/roles/qcow/vars/main.yaml - - # Extract the image output name in the ansible vars file provided - IMG_NAME="$(yq r "${QCOW_CONFIG_FILE}" img_name)" fi # Retrieve from playbook defaults if not provided in user input diff --git a/image-builder/assets/playbooks/roles/osconfig/defaults/main.yaml b/image-builder/assets/playbooks/roles/osconfig/defaults/main.yaml index ee514a9..cbf991d 100644 --- a/image-builder/assets/playbooks/roles/osconfig/defaults/main.yaml +++ b/image-builder/assets/playbooks/roles/osconfig/defaults/main.yaml @@ -33,8 +33,22 @@ kubelet: grub: GRUB_TIMEOUT: 5 GRUB_CMDLINE_LINUX_DEFAULT: + - name: console + value: 'ttyS0,115200n8' + - name: console + value: 'tty0' + - name: amd_iommu + value: 'on' + - name: intel_iommu + value: 'on' + - name: iommu + value: 'pt' - name: cgroup_disable value: 'hugetlb' + - name: dpdk-socket-mem + value: '4096,4096' + - name: rcu_nocb_poll + value: 'true' limits: - name: core_dump diff --git a/image-builder/assets/playbooks/roles/qcow/defaults/main.yaml b/image-builder/assets/playbooks/roles/qcow/defaults/main.yaml index 4efe3ae..f5b48c4 100644 --- a/image-builder/assets/playbooks/roles/qcow/defaults/main.yaml +++ b/image-builder/assets/playbooks/roles/qcow/defaults/main.yaml @@ -3,7 +3,7 @@ dst: /chroot nbd_build_dir: /tmp/nbd_build_dir img_output_dir: /config img_name: airship-ubuntu.qcow2 -qcow_capacity: 5G +qcow_capacity: 19G qcow_compress: true partitions: # Partition numbering is according to list ordering. diff --git a/image-builder/config/README.md b/image-builder/config/README.md new file mode 100644 index 0000000..8ac2a50 --- /dev/null +++ b/image-builder/config/README.md @@ -0,0 +1,24 @@ +The `generate_iso` and `package_qcow` make target can be used to build ISO and +QCOW artifacts respectively, after the shared `image-builder` container is +built (built with the `build` target). + +By default, one image will be built for each subdirectory that matches the +corresponding `IMAGE_TYPE` for the build. + +In other words, ISOs will be built using files from subdirs with names starting +with `iso*`, while QCOWs are built from subdirs with names starting with +`qcow*`. If you want to build QCOWs from an explicit list of dirs, you can +supply them using the `QCOW_CONF_DIRS` parameter to the makefile. + +ISOs expect the following files to be present in their directory: +- `user_data` - YAML file containing cloud-init user-data +- `network_data.json` - JSON file containing cloud-init network data +- `img_name` - text file containing the desired name for the image + +Note that ISO generation here is *only* for testing. It is not published or +promoted anywhere. + +QCOWs expect the following files to be present in their directory: +- `osconfig-*-vars.yaml` - YAML file containing `osconfig` playbook overrides +- `qcow-*-vars.yaml` - YAML file containing `qcow` playboook overrides +- `img_name` - text file containing the desired name for the image diff --git a/image-builder/config/qcow-control-plane/osconfig-control-plane-vars.yaml b/image-builder/config/qcow-control-plane/osconfig-control-plane-vars.yaml index 77acf80..f13d545 100644 --- a/image-builder/config/qcow-control-plane/osconfig-control-plane-vars.yaml +++ b/image-builder/config/qcow-control-plane/osconfig-control-plane-vars.yaml @@ -1,161 +1,10 @@ -kernel: - modules: - load: - - name: 8021q - - name: bonding - - name: ip_vs - - name: ip_vs_rr - - name: ip_vs_wrr - - name: ip_vs_sh - - name: br_netfilter - blacklist: - - name: krbd - -banners: - login: | - Airship Node \l: \n.\o - Kernel: \s \m \r \v - IP address: \4 - motd: | - #!/bin/sh - . /etc/lsb-release - printf "Airship Node, based on: %s (%s %s %s)\n" "$DISTRIB_DESCRIPTION" "$(uname -o)" "$(uname -r)" "$(uname -m)" - -limits: - - name: core_dump - domain: '0:' - type: 'hard' - item: 'core' - value: 0 - - name: nofile-root-soft - domain: 'root' - type: 'soft' - item: 'nofile' - value: '65536' - - name: nofile-root-hard - domain: 'root' - type: 'hard' - item: 'nofile' - value: '1048576' - - name: nofile-all-soft - domain: '*' - type: 'soft' - item: 'nofile' - value: '65536' - - name: nofile-all-hard - domain: '*' - type: 'hard' - item: 'nofile' - value: '1048576' - -grub: - GRUB_TIMEOUT: 5 - GRUB_CMDLINE_LINUX_DEFAULT: - - name: console - value: 'ttyS0,115200n8' - - name: console - value: 'tty0' - - name: amd_iommu - value: 'on' - - name: intel_iommu - value: 'on' - - name: iommu - value: 'pt' - - name: cgroup_disable - value: 'hugetlb' - - name: dpdk-socket-mem - value: '4096,4096' - - name: rcu_nocb_poll - value: 'true' - -sysctl: - - name: net.bridge.bridge-nf-call-ip6tables - value: '1' - - name: net.bridge.bridge-nf-call-iptables - value: '1' - - name: net.nf_conntrack_max - value: '1048576' - - name: kernel.panic - value: '3' - - name: kernel.pid_max - value: '4194303' - - name: net.ipv4.conf.default.arp_accept - value: '1' - - name: net.ipv4.conf.all.arp_accept - value: '1' - - name: net.ipv4.tcp_keepalive_intvl - value: '15' - - name: net.ipv4.tcp_keepalive_time - value: '30' - - name: net.ipv4.tcp_keepalive_probes - value: '8' - - name: net.ipv4.tcp_retries2 - value: '5' - - name: net.ipv4.neigh.default.gc_thresh1 - value: '4096' - - name: net.ipv4.neigh.default.gc_thresh3 - value: '16384' - - name: net.ipv4.conf.default.rp_filter - value: '2' - - name: net.ipv6.conf.all.accept_ra - value: '0' - - name: net.ipv6.conf.default.accept_ra - value: '0' - - name: net.ipv6.conf.lo.accept_ra - value: '0' - - name: net.ipv6.conf.lo.disable_ipv6 - value: '0' - - name: net.netfilter.nf_conntrack_acct - value: '1' - - name: fs.suid_dumpable - value: '2' - - name: fs.inotify.max_user_watches - value: '1048576' - - name: fs.protected_hardlinks - value: '1' - - name: fs.protected_symlinks - value: '1' - - name: kernel.sysrq - value: '8' - -directories: - - name: /testdir - permissions: '0755' - owner: root - group: root - -files: - - name: /testdir/test.sh - file_content: | - #!/bin/bash - echo hello world - permissions: '0755' - owner: root - group: root - -systemd: - - name: sample.service - file_content: | - [Unit] - Description=sample service - After=network.target - - [Service] - ExecStart=/bin/sleep infinity - - [Install] - WantedBy=multi-user.target - enabled: yes - force: no - -buildtime_user_scripts: - - file_content: | - #!/bin/bash - echo "custom container buildtime script" - -file_permissions: - # Full path to file to create - - name: /testdir/test.sh - permissions: '0700' - owner: root - group: root +# Custom user-defined overrides to the `osconfig` playbook can be placed here. +# Example, writing an extra file to the OS: +#files: +# - name: /test.sh +# file_content: | +# #!/bin/bash +# echo hello world +# permissions: '0755' +# owner: root +# group: root diff --git a/image-builder/config/qcow-control-plane/qcow-control-plane-vars.yaml b/image-builder/config/qcow-control-plane/qcow-control-plane-vars.yaml index c35ee61..68c01f2 100644 --- a/image-builder/config/qcow-control-plane/qcow-control-plane-vars.yaml +++ b/image-builder/config/qcow-control-plane/qcow-control-plane-vars.yaml @@ -1,43 +1,3 @@ -qcow_capacity: 5G -partitions: - # Partition numbering is according to list ordering. - # Ironic default cloud-init configdrive injection requires - # root partition to be the first numbered partition. - - mount: / - mount_order: 0 - part_start: 1284MiB - part_end: '100%' - filesystem: - type: ext4 - fstab: - options: "defaults,errors=remount-ro,noatime" - dump: 0 - fsck: 1 - - mount: none - mount_order: 99 - part_start: 1MiB - part_end: 5MiB - flags: - - bios_grub - - mount: /boot/efi - mount_order: 2 - part_start: 5MiB - part_end: 516MiB - flags: - - esp - filesystem: - type: vfat - fstab: - options: "defaults,errors=remount-ro,noatime" - dump: 0 - fsck: 1 - - mount: /boot - mount_order: 1 - part_start: 516MiB - part_end: 1284MiB - filesystem: - type: ext4 - fstab: - options: "defaults,errors=remount-ro,noatime" - dump: 0 - fsck: 2 +# Custom user-defined overrides to the `qcow` playbook can be placed here. +# Example, Changing disk size: +#qcow_capacity: 200G diff --git a/image-builder/tools/cut_image.sh b/image-builder/tools/cut_image.sh index 7b9c156..ac00e59 100755 --- a/image-builder/tools/cut_image.sh +++ b/image-builder/tools/cut_image.sh @@ -25,8 +25,8 @@ workdir="$(realpath ${host_mount_directory})" # Overrides : ${user_data:=$workdir/iso/user_data} : ${network_config:=$workdir/iso/network_data.json} -: ${osconfig_params:=$workdir/control-plane/osconfig-control-plane-vars.yaml} -: ${qcow_params:=$workdir/control-plane/qcow-control-plane-vars.yaml} +: ${osconfig_params:=$workdir/qcow-control-plane/osconfig-control-plane-vars.yaml} +: ${qcow_params:=$workdir/qcow-control-plane/qcow-control-plane-vars.yaml} if [ -n "$proxy" ]; then export http_proxy=$proxy diff --git a/playbooks/airship-images-build.yaml b/playbooks/airship-images-build.yaml index 354a57b..b7c78e7 100644 --- a/playbooks/airship-images-build.yaml +++ b/playbooks/airship-images-build.yaml @@ -39,4 +39,5 @@ COMMIT: "{{ zuul.newrev | default('') }}" PUSH_IMAGE: "false" WORKDIR: "{{ image_config_dir | default('config') }}" + QCOW_CONF_DIRS: "{{ qcow_conf_dirs | default('') }}" become: True diff --git a/playbooks/airship-images-publish.yaml b/playbooks/airship-images-publish.yaml index d2405d7..84fbe2d 100644 --- a/playbooks/airship-images-publish.yaml +++ b/playbooks/airship-images-publish.yaml @@ -44,4 +44,5 @@ GCP_SDK: "{{ gcp_sdk }}" AZ_SDK: "{{ az_sdk }}" WORKDIR: "{{ image_config_dir | default('config') }}" + QCOW_CONF_DIRS: "{{ qcow_conf_dirs | default('') }}" become: True