diff --git a/.github/workflows/test_deployment.yml b/.github/workflows/test_deployment.yml index e1951be..01ceecd 100644 --- a/.github/workflows/test_deployment.yml +++ b/.github/workflows/test_deployment.yml @@ -80,8 +80,8 @@ jobs: - name: Install test tools run: | sudo apt-get update - sudo apt-get install -y make - sudo make install-test-deps PACKAGE_MANAGER=apt-get + sudo apt-get install -y unzip make + sudo make test/vm/install-deps PACKAGE_MANAGER=apt-get - name: Download generated ISO uses: actions/download-artifact@v4 @@ -90,46 +90,15 @@ jobs: - name: Add Kickstart and Grub options to ISO run: | - mv ${{ inputs[format('iso_name-{0}', matrix.version)] }} deploy.iso - sudo mkdir /mnt/iso || true - sudo mount -o loop deploy.iso /mnt/iso - cp /mnt/iso/boot/grub2/grub.cfg grub.cfg - sudo umount /mnt/iso - sed -i 's/quiet/console=ttyS0,115200n8 inst.ks=cdrom:\/ks.cfg/' grub.cfg - sed -i 's/set default="1"/set default="0"/' grub.cfg - sed -i 's/set timeout=60/set timeout=1/' grub.cfg - cat << EOF > ks.cfg - lang en_US.UTF-8 - keyboard us - timezone Americas/New_York - zerombr - clearpart --all --initlabel - autopart - poweroff - user --name=core --groups=wheel --password=foobar - %include /usr/share/anaconda/interactive-defaults.ks - EOF - xorriso -dialog on << EOF - -indev deploy.iso - -outdev test.iso - -boot_image any replay - -map ks.cfg ks.cfg - -chmod 0444 ks.cfg - -map grub.cfg boot/grub2/grub.cfg - -end - EOF + make test/vm/files/install.iso - name: Create VM disk run: | - qemu-img create -f qcow2 disk.qcow2 50G + make test/vm/files/disk.qcow2 - name: Install the test VM run: | - timeout 1h qemu-system-x86_64 -name "Anaconda" -boot d -m 4096 -cpu qemu64 -display none -cdrom test.iso -smp 2 -hda disk.qcow2 -serial telnet:localhost:4321,server=on,wait=off & QEMU_PID=$! - echo "PID: $QEMU_PID" - timeout 1m bash -c "while ! (echo > /dev/tcp/127.0.0.1/4321); do sleep 0.1; done" - (nc localhost 4321 | tee vm.stdout) & - wait $QEMU_PID + make test/vm/install_os - name: Start the test VM env: @@ -138,30 +107,9 @@ jobs: VM_IP: "127.0.0.1" VM_PORT: "5555" run: | - mkfifo vm.stdin - qemu-system-x86_64 -name "Anaconda" \ - -m 4096 -cpu qemu64 -display none -smp 2 \ - -chardev socket,path=/tmp/qga.sock,server=on,wait=off,id=qga0 \ - -device e1000,netdev=net0 \ - -netdev user,id=net0,hostfwd=tcp::${VM_PORT}-:22 \ - -device virtio-serial \ - -device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0 \ - -boot c -hda disk.qcow2 -serial telnet:localhost:4321,server=on,wait=off & export QEMU_PID=$! - echo "PID: $QEMU_PID" - - timeout 1m bash -c "while ! (echo > /dev/tcp/127.0.0.1/4321); do sleep 0.1; done" - (tail -f vm.stdin | nc localhost 4321 | tee vm.stdout) & + make test/vm/start_vm - timeout 30m bash -c "while ! (echo > /dev/tcp/${VM_IP}/${VM_PORT}); do sleep 1; done" - - if ! (echo > /dev/tcp/${VM_IP}/${VM_PORT}) - then - echo "SSH must be installed and enabled inside the container" - fi - - echo "VM ready for tests at IP ${VM_IP}:${VM_PORT}" - - make test-vm VM_IP=${VM_IP} VM_PORT=${VM_PORT} VM_USER=${VM_USER} VM_PASS=${VM_PASS} \ + make test/vm VM_IP=${VM_IP} VM_PORT=${VM_PORT} VM_USER=${VM_USER} VM_PASS=${VM_PASS} \ ARCH=${{ needs.load_vars.outputs.ARCH}} \ IMAGE_NAME=${{ needs.load_vars.outputs.IMAGE_NAME}} \ IMAGE_REPO=${{ needs.load_vars.outputs.IMAGE_REPO}} \ diff --git a/Makefile b/Makefile index 2907b80..d75b3ac 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ export ISO_NAME = $(_BASE_DIR)/build/deploy.iso ################### # Hidden vars -SHELL = /bin/sh +export SHELL = /bin/sh # Cache export DNF_CACHE = export PACKAGE_MANAGER = dnf @@ -40,6 +40,11 @@ define get_templates $(foreach file,$(notdir $(wildcard lorax_templates/scripts/post/$(1)_*)),lorax_templates/post_$(file).tmpl) endef +define install_pkg + $(PACKAGE_MANAGER) install -y +endef +export install_pkg + # Generated/internal vars ## Formatting = _UPPERCASE export _BASE_DIR = $(shell pwd) @@ -109,14 +114,14 @@ _SUBDIRS = container external flatpak_refs lorax_templates repos xorriso # Step 7: Build end ISO ## Default action build/deploy.iso: results/images/boot.iso container/$(IMAGE_NAME)-$(IMAGE_TAG) xorriso/input.txt - mkdir $(_BASE_DIR)/build || true + $(if $(wildcard build),,mkdir build) xorriso -dialog on < $(_BASE_DIR)/xorriso/input.txt implantisomd5 $(ISO_NAME) # Step 3: Build boot.iso using Lorax results/images/boot.iso: external/lorax/branch-$(VERSION) $(filter lorax_templates/%,$(_LORAX_TEMPLATES)) $(_REPO_FILES) $(if $(wildcard results), rm -Rf results) - mv /etc/rpm/macros.image-language-conf $(_TEMP_DIR)/macros.image-language-conf || true + $(if $(wildcard /etc/rpm/macros.image-language-conf),mv /etc/rpm/macros.image-language-conf $(_TEMP_DIR)/macros.image-language-conf) # Download the secure boot key $(if $(SECURE_BOOT_KEY_URL), curl --fail -L -o $(_BASE_DIR)/sb_pubkey.der $(SECURE_BOOT_KEY_URL)) @@ -132,7 +137,7 @@ results/images/boot.iso: external/lorax/branch-$(VERSION) $(filter lorax_templat --rootfs-size $(ROOTFS_SIZE) \ $(foreach var,$(_TEMPLATE_VARS),--add-template-var "$(shell echo $(var) | tr '[:upper:]' '[:lower:]')=$($(var))") \ $(_BASE_DIR)/results/ - mv -f $(_TEMP_DIR)/macros.image-language-conf /etc/rpm/macros.image-language-conf || true + $(if $(wildcard $(_TEMP_DIR)/macros.image-language-conf),mv -f $(_TEMP_DIR)/macros.image-language-conf /etc/rpm/macros.image-language-conf) FILES_TO_CLEAN = $(wildcard build debugdata pkglists results original-pkgsizes.txt final-pkgsizes.txt lorax.conf *.iso *log) @@ -143,9 +148,8 @@ clean: .PHONY: install-deps install-deps: - $(if $(findstring apt,$(PACKAGE_MANAGER)),$(PACKAGE_MANAGER) update) - $(PACKAGE_MANAGER) install -y lorax xorriso coreutils gettext - $(foreach DIR,$(_SUBDIRS),$(MAKE) -w -C $(DIR) install-deps;) + $(install_pkg) lorax xorriso coreutils gettext) + $(foreach DIR,$(_SUBDIRS),$(MAKE) -w -C $(DIR) install-deps;) .PHONY: $(_SUBDIRS) test $(wildcard test/*) $(wildcard test/*/*) diff --git a/container/Makefile b/container/Makefile index 7aeb894..88024a0 100644 --- a/container/Makefile +++ b/container/Makefile @@ -2,8 +2,7 @@ $(IMAGE_NAME)-$(IMAGE_TAG): skopeo copy docker://$(IMAGE_REPO)/$(IMAGE_NAME):$(IMAGE_TAG) oci:$(IMAGE_NAME)-$(IMAGE_TAG) install-deps: - if [ "$(PACKAGE_MANAGER)" =~ apt.* ]; then $(PACKAGE_MANAGER) update; fi - $(PACKAGE_MANAGER) install -y skopeo + $(install_pkg) skopeo FILES=$(filter-out Makefile,$(wildcard *)) clean: diff --git a/external/Makefile b/external/Makefile index 6bb8cb2..b0debe4 100644 --- a/external/Makefile +++ b/external/Makefile @@ -4,10 +4,9 @@ lorax/branch-$(VERSION): touch lorax/branch-$(VERSION) install-deps: - if [ "$(PACKAGE_MANAGER)" =~ apt.* ]; then $(PACKAGE_MANAGER) update; fi - # Used by external/fedora-lorax-templates/ostree-based-installer/lorax-embed-flatpaks.tmpl - $(PACKAGE_MANAGER) install -y flatpak dbus-daemon ostree - # Used to clone proper lorax branch - $(PACKAGE_MANAGER) install -y git +# Used by external/fedora-lorax-templates/ostree-based-installer/lorax-embed-flatpaks.tmpl + $(install_pkg) flatpak dbus-daemon ostree +# Used to clone proper lorax branch + $(install_pkg) install -y git clean: \ No newline at end of file diff --git a/test/Makefile b/test/Makefile index 92244a1..3ef6e63 100644 --- a/test/Makefile +++ b/test/Makefile @@ -10,7 +10,6 @@ $(filter-out README.md Makefile,$(wildcard */*)): $(MAKE) -w -C $(DIR) $(TARGET) install-deps: - if [ "$(PACKAGE_MANAGER)" =~ apt.* ]; then $(PACKAGE_MANAGER) update; fi - $(PACKAGE_MANAGER) install -y qemu qemu-utils xorriso unzip qemu-system-x86 netcat socat jq isomd5sum ansible make coreutils squashfs-tools + $(foreach DIR,$(filter-out README.md Makefile,$(wildcard *)),$(MAKE) -w -C $(DIR) install-deps;) .PHONY: all $(filter-out README.md Makefile,$(wildcard *)) $(filter-out README.md Makefile,$(wildcard */*)) \ No newline at end of file diff --git a/test/iso/Makefile b/test/iso/Makefile index 1af6a5e..c82b415 100644 --- a/test/iso/Makefile +++ b/test/iso/Makefile @@ -25,4 +25,7 @@ prep: sudo umount /mnt/install sudo umount /mnt/iso +install-deps: + $(install_pkg) isomd5sum coreutils squashfs-tools + .PHONY: all $(ISO_TESTS) \ No newline at end of file diff --git a/test/vm/Makefile b/test/vm/Makefile index bec6b72..3729ebb 100644 --- a/test/vm/Makefile +++ b/test/vm/Makefile @@ -1,9 +1,9 @@ -VM_TESTS=$(filter-out README.md,$(shell ls)) +VM_TESTS=$(filter-out README.md Makefile files,$(wildcard *)) # Get a list of tests for the feature # $1 = test type # $2 = feature -run_tests = \ +define run_tests tests="$(shell ls tests/$(1)/$(2)_*)"; \ if [ -n "$$tests" ]; \ then \ @@ -18,8 +18,9 @@ run_tests = \ fi; \ done; \ fi +endef -$(VM_TESTS): +$(VM_TESTS): start_vm ansible_inventory $(eval _VARS = IMAGE_REPO IMAGE_NAME IMAGE_TAG) ansible -i ansible_inventory -m ansible.builtin.wait_for_connection vm @@ -37,11 +38,81 @@ ansible_inventory: echo "ungrouped:" > ansible_inventory echo " hosts:" >> ansible_inventory echo " vm:" >> ansible_inventory - echo " ansible_host: ${VM_IP}" >> ansible_inventory - echo " ansible_port: ${VM_PORT}" >> ansible_inventory - echo " ansible_user: ${VM_USER}" >> ansible_inventory - echo " ansible_password: ${VM_PASS}" >> ansible_inventory - echo " ansible_become_pass: ${VM_PASS}" >> ansible_inventory + echo " ansible_host: $(VM_IP)" >> ansible_inventory + echo " ansible_port: $(VM_PORT)" >> ansible_inventory + echo " ansible_user: $(VM_USER)" >> ansible_inventory + echo " ansible_password: $(VM_PASS)" >> ansible_inventory + echo " ansible_become_pass: $(VM_PASS)" >> ansible_inventory echo " ansible_ssh_common_args: '-o StrictHostKeyChecking=no'" >> ansible_inventory -.PHONY: $(VM_TESTS) \ No newline at end of file +.PHONY: $(VM_TESTS) install-deps + +install-deps: + $(install_pkg) qemu qemu-utils xorriso qemu-system-x86 netcat socat jq ansible + +files/mnt/iso: + $(if $(wildcard files/mnt),,mkdir files/mnt) + $(if $(wildcard files/mnt/iso),,mkdir files/mnt/iso) + sudo mount -o loop $(ISO_NAME) files/mnt/iso + +files/grub.cfg: files/mnt/iso + cp files/mnt/iso/boot/grub2/grub.cfg files/grub.cfg + sed -i 's/quiet/console=ttyS0,115200n8 inst.ks=cdrom:\/ks.cfg/' files/grub.cfg + sed -i 's/set default="1"/set default="0"/' files/grub.cfg + sed -i 's/set timeout=60/set timeout=1/' files/grub.cfg + +.PHONY: remove_files/mnt/iso +remove_files/mnt/iso: files/mnt/iso + sudo umount files/mnt/iso + rmdir files/mnt/iso + + +files/install.iso: files/grub.cfg remove_files/mnt/iso + xorriso -dialog on << EOF + -indev $(ISO_NAME) + -outdev files/install.iso + -boot_image any replay + -map files/ks.cfg ks.cfg + -chmod 0444 ks.cfg + -map files/grub.cfg boot/grub2/grub.cfg + -end + EOF + +files/disk.qcow2: + qemu-img create -f qcow2 files/disk.qcow2 50G + +.PHONY: install_os +install_os: files/install.iso files/disk.qcow2 + timeout 1h qemu-system-x86_64 -name "Anaconda" -boot d -m 4096 -cpu qemu64 -display none -cdrom test.iso -smp 2 -hda disk.qcow2 -serial telnet:localhost:4321,server=on,wait=off & QEMU_PID=$! + echo "PID: $QEMU_PID" + timeout 1m bash -c "while ! (echo > /dev/tcp/127.0.0.1/4321); do sleep 0.1; done" + (nc localhost 4321 | tee vm.stdout) & + wait $QEMU_PID + +.ONESHELL: + +.PHONY: start_vm +start_vm: install_os + mkfifo vm.stdin + qemu-system-x86_64 -name "Anaconda" \ + -m 4096 -cpu qemu64 -display none -smp 2 \ + -chardev socket,path=/tmp/qga.sock,server=on,wait=off,id=qga0 \ + -device e1000,netdev=net0 \ + -netdev user,id=net0,hostfwd=tcp::${VM_PORT}-:22 \ + -device virtio-serial \ + -device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0 \ + -boot c -hda disk.qcow2 -serial telnet:localhost:4321,server=on,wait=off & export QEMU_PID=$! + echo "PID: $QEMU_PID" + + timeout 1m bash -c "while ! (echo > /dev/tcp/127.0.0.1/4321); do sleep 0.1; done" + (tail -f vm.stdin | nc localhost 4321 | tee vm.stdout) & + + timeout 30m bash -c "while ! (echo > /dev/tcp/${VM_IP}/${VM_PORT}); do sleep 1; done" + + if ! (echo > /dev/tcp/${VM_IP}/${VM_PORT}) + then + echo "SSH must be installed and enabled inside the container" + fi + + echo "VM ready for tests at IP ${VM_IP}:${VM_PORT}" + $(MAKE) ansible_inventory VM_IP=${VM_IP} VM_PORT=${VM_PORT} VM_USER=core VM_PASS=foobar \ No newline at end of file diff --git a/test/vm/files/ks.cfg b/test/vm/files/ks.cfg new file mode 100644 index 0000000..2864a28 --- /dev/null +++ b/test/vm/files/ks.cfg @@ -0,0 +1,9 @@ +lang en_US.UTF-8 +keyboard us +timezone Americas/New_York +zerombr +clearpart --all --initlabel +autopart +poweroff +user --name=core --groups=wheel --password=foobar +%include /usr/share/anaconda/interactive-defaults.ks \ No newline at end of file diff --git a/xorriso/gen_input.sh b/xorriso/gen_input.sh index 251e805..05b220e 100644 --- a/xorriso/gen_input.sh +++ b/xorriso/gen_input.sh @@ -7,7 +7,7 @@ echo "-boot_image any replay" echo "-joliet on" echo "-compliance joliet_long_names" pushd ${_BASE_DIR}/results > /dev/null -for file in $(find *) +for file in $(find -type f *) do if [[ "$file" == "images/boot.iso" ]] then @@ -21,7 +21,7 @@ popd > /dev/null if [[ -n "${FLATPAK_DIR}" ]] then pushd ${FLATPAK_DIR} > /dev/null - for file in $(find *) + for file in $(find -type f *) do echo "-map $(pwd)/${file} flatpak/${file}" echo "-chmod 0444 flatpak/${file}" @@ -36,7 +36,7 @@ then fi pushd container > /dev/null -for file in $(find ${IMAGE_NAME}-${IMAGE_TAG}) +for file in $(find -type f ${IMAGE_NAME}-${IMAGE_TAG}) do echo "-map $(pwd)/${file} ${file}" echo "-chmod 0444 ${file}"