diff --git a/.github/workflows/vagrant-install.yaml b/.github/workflows/vagrant-install.yaml new file mode 100644 index 000000000..28dc352d6 --- /dev/null +++ b/.github/workflows/vagrant-install.yaml @@ -0,0 +1,96 @@ +name: Vagrant install + +on: + pull_request: + types: [opened, reopened, synchronize] + +env: + LIBVIRT_DEFAULT_URI: "qemu:///system" + +jobs: + main: + name: Build and deploy + runs-on: + - self-hosted + - Linux + - kvm + - vagrant + - equinix + steps: + - uses: actions/checkout@v3 + - name: Build Harvester artifacts + run: | + make + - name: Clone and checkout ipxe-examples + id: ipxe + run: | + cd $HOME + if [ ! -d ipxe-examples ]; then + git clone https://github.com/harvester/ipxe-examples.git + fi + + cd ipxe-examples + git reset && git checkout . + git clean -fd + git pull + echo "VAGRANT_HOME=$HOME/ipxe-examples/vagrant-pxe-harvester" >> $GITHUB_OUTPUT + - name: Clean up previous vagrant deployment + working-directory: ${{ steps.ipxe.outputs.VAGRANT_HOME }} + run: | + vagrant destroy -f + - name: Remove OVMF.fd line if needed + working-directory: ${{ steps.ipxe.outputs.VAGRANT_HOME }} + run: | + if [ ! -f /usr/share/qemu/OVMF.fd ]; then + echo "Remove libvirt loader: can't find UEFI firmware" + sed 's/libvirt.loader.*/#libvirt.loader = /' Vagrantfile + fi + - name: Generate SSH keys + run: | + ssh-keygen -t rsa -q -N "" -f ./ci/terraform/tmp-ssh-key + - name: Set SSH key in ipxe-examples settings + run: | + export PUB_KEY=$(cat ./ci/terraform/tmp-ssh-key.pub) + yq e -i ".harvester_config.ssh_authorized_keys += [ strenv(PUB_KEY) ]" ${{ steps.ipxe.outputs.VAGRANT_HOME }}/settings.yml + - name: Set artifacts in ipxe-examples settings + run: | + yq e -i ".harvester_iso_url = \"file://${{ github.workspace }}/dist/artifacts/harvester-master-amd64.iso\"" ${{ steps.ipxe.outputs.VAGRANT_HOME }}/settings.yml + yq e -i ".harvester_kernel_url = \"file://${{ github.workspace }}/dist/artifacts/harvester-master-vmlinuz-amd64\"" ${{ steps.ipxe.outputs.VAGRANT_HOME }}/settings.yml + yq e -i ".harvester_ramdisk_url = \"file://${{ github.workspace }}/dist/artifacts/harvester-master-initrd-amd64\"" ${{ steps.ipxe.outputs.VAGRANT_HOME }}/settings.yml + yq e -i ".harvester_rootfs_url = \"file://${{ github.workspace }}/dist/artifacts/harvester-master-rootfs-amd64.squashfs\"" ${{ steps.ipxe.outputs.VAGRANT_HOME }}/settings.yml + - name: Setup cluster + working-directory: ${{ steps.ipxe.outputs.VAGRANT_HOME }} + run: | + ./setup_harvester.sh + - name: Enable soft emulation + working-directory: ./ci/terraform + run: | + ./enable_soft_emulation.sh ${{ steps.ipxe.outputs.VAGRANT_HOME }}/settings.yml + - name: Clean the previous temp files + working-directory: ./ci/terraform + run: | + ./cleanup_test_files.sh + - name: Testing existing files + working-directory: ./ci/terraform + run: | + ./check_files.sh ${{ steps.ipxe.outputs.VAGRANT_HOME }}/settings.yml + - name: Testing services status + working-directory: ./ci/terraform + run: | + ./check_services_status.sh ${{ steps.ipxe.outputs.VAGRANT_HOME }}/settings.yml + - name: Testing basic operations with terraform + working-directory: ./ci/terraform + run: | + curl https://releases.hashicorp.com/terraform/1.3.7/terraform_1.3.7_linux_amd64.zip -o terraform_bin.zip + unzip -o terraform_bin.zip + ./get_kubeconfig.sh ${{ steps.ipxe.outputs.VAGRANT_HOME }}/settings.yml + ./terraform init -no-color + ./terraform apply -auto-approve -no-color + - name: Test network on the VMs + working-directory: ./ci/terraform + run: | + ./test_terraform_vm.sh ${{ steps.ipxe.outputs.VAGRANT_HOME }}/settings.yml + - name: Clean up vagrant cluster + working-directory: ${{ steps.ipxe.outputs.VAGRANT_HOME }} + run: | + vagrant destroy -f diff --git a/ci/README.md b/ci/README.md deleted file mode 100644 index 57409315e..000000000 --- a/ci/README.md +++ /dev/null @@ -1,56 +0,0 @@ -Harvester-installer CI Job Scripts -================================== - -Introduction ------------- - -This directory containers the [Ansible] playbook for harvester-installer CI -job. The harvester-installer CI job is responsible for validating the pull -requests (for the harvester-installer repo) by performing the following: - -1. checkout the given pull request -2. build the artifacts (i.e. ISO, ramdisk, kernel, and rootfs) by running the - `make` command -3. test the newly built artifacts in the [Harvester Vagrant iPXE] environment -4. post the test result to the pull request - -Jenkins -------- - -The harvester-installer CI job is running on [Jenkins], which is accessible by -either clicking on the `Details` link next to the `Vagrant installation testing` -check job from the pull request, or explicitly via -`https://ci.harvesterhci.io/job/harvester-vagrant-installation-test//`. -Though anonymouse access is disabled, developers can login as -`harvester/harvester030` to view the job result. - -**NOTE:** developers only read access to the job. - -Run The Job Locally -------------------- - -Though the Ansible playbook is meant to be used by CI, you one can run it -locally as desire. To run it locally, make sure the following variables are -sepcified. - -* `WORKSPACE`: this should point to the parent dir of the harvester-installer - directory. -* `PR_ID`: pull request ID - -**WARNING:** the playbook will clone the `harvester/ipxe-examples` repository -under the `WORKSPACE` directory. If you already have `harvester/ipxe-examples' -checked out, make sure to move it out of the way so it won't get overwritten. -Also, make sure your host satisfy the minimal requirements specified in -https://github.com/harvester/ipxe-examples/tree/main/vagrant-pxe-harvester#prerequisites -You can install the latest version of [Ansible] via [Python PIP]. - -To run the job locally: - -1. Checkout the pull request branch. -2. `ansible-playbook -e WORKSPACE= -e PR_ID= run_vagrant_install_test.yml` - - -[Ansible]: https://www.ansible.com/ -[Harvester Vagrant iPXE]: https://github.com/harvester/ipxe-examples/tree/main/vagrant-pxe-harvester -[Jenkins]: https://www.jenkins.io/ -[Python PIP]: https://pip.pypa.io/en/stable/ diff --git a/ci/run_vagrant_install_test.yml b/ci/run_vagrant_install_test.yml deleted file mode 100644 index 3e02e2b9a..000000000 --- a/ci/run_vagrant_install_test.yml +++ /dev/null @@ -1,189 +0,0 @@ ---- -- name: Run Vagrant Harvester Installation Test - hosts: localhost - connection: local - gather_facts: false - - vars: - REPO: "{{ harvester_installer_repo_name | default('harvester/harvester-installer') }}" - - tasks: - - name: Make sure WORKSPACE is defined - fail: - msg: "Variable WORKSPACE is not defined." - when: WORKSPACE is not defined - - - name: Check for harvester-installer - stat: - path: "{{ WORKSPACE }}/harvester-installer" - register: harvester_installer_dir_check_result - - - name: Make sure harvester-installer directory exist - fail: - msg: "{{ WORKSPACE }}/harvester-installer not found" - when: not harvester_installer_dir_check_result.stat.exists - - - name: Build harvester-installer artifacts - shell: > - make - args: - chdir: "{{ WORKSPACE }}/harvester-installer" - retries: 5 - delay: 20 - register: shell_result - until: shell_result.rc == 0 - - - name: Check for existing environment - stat: - path: "{{ WORKSPACE }}/ipxe-examples" - register: check_ipxe_examples_result - - - name: Cleanup vagrants - shell: > - vagrant destroy -f --parallel - args: - chdir: "{{ WORKSPACE }}/ipxe-examples/vagrant-pxe-harvester" - when: check_ipxe_examples_result.stat.exists - - - name: Cleanup ipxe-examples dir - file: - path: "{{ WORKSPACE }}/ipxe-examples" - state: absent - - - name: Clone ipxe-examples repo - git: - repo: https://github.com/harvester/ipxe-examples.git - version: main - dest: "{{ WORKSPACE }}/ipxe-examples" - - - name: Check to see if "/usr/share/qemu/OVMF.fd" exist - stat: - path: /usr/share/qemu/OVMF.fd - register: file_ovmf_fd_check_result - - - name: Remove OVMF.fd line if needed - lineinfile: - path: "{{ WORKSPACE }}/ipxe-examples/vagrant-pxe-harvester/Vagrantfile" - regexp: '.*\/OVMF\.fd.*' - state: absent - when: not file_ovmf_fd_check_result.stat.exists - - - name: Generate the SSH key - vars: - ssh_key_filename: "{{ WORKSPACE }}/harvester-installer/ci/terraform/tmp-ssh-key" - openssh_keypair: - path: "{{ ssh_key_filename }}" - type: rsa - size: 3072 - state: present - force: no - - - name: Set SSH Key - vars: - generated_ssh_key: "{{ lookup('file', '{{ WORKSPACE }}/harvester-installer/ci/terraform/tmp-ssh-key.pub') }}" - settings_file: "{{ WORKSPACE }}/ipxe-examples/vagrant-pxe-harvester/settings.yml" - shell: yq e -i ".harvester_config.ssh_authorized_keys += [\"{{ generated_ssh_key }}\"]" "{{ settings_file }}" - - - name: Set harvester_iso_url - replace: - path: "{{ WORKSPACE }}/ipxe-examples/vagrant-pxe-harvester/settings.yml" - regexp: "^harvester_iso_url:.*" - replace: "harvester_iso_url: file://{{ WORKSPACE }}/harvester-installer/dist/artifacts/harvester-master-amd64.iso" - - - name: Set harvester_kernel_url - replace: - path: "{{ WORKSPACE }}/ipxe-examples/vagrant-pxe-harvester/settings.yml" - regexp: "^harvester_kernel_url:.*" - replace: "harvester_kernel_url: file://{{ WORKSPACE }}/harvester-installer/dist/artifacts/harvester-master-vmlinuz-amd64" - - - name: Set harvester_ramdisk_url - replace: - path: "{{ WORKSPACE }}/ipxe-examples/vagrant-pxe-harvester/settings.yml" - regexp: "^harvester_ramdisk_url:.*" - replace: "harvester_ramdisk_url: file://{{ WORKSPACE }}/harvester-installer/dist/artifacts/harvester-master-initrd-amd64" - - - name: Set harvester_rootfs_url - replace: - path: "{{ WORKSPACE }}/ipxe-examples/vagrant-pxe-harvester/settings.yml" - regexp: "^harvester_rootfs_url:.*" - replace: "harvester_rootfs_url: file://{{ WORKSPACE }}/harvester-installer/dist/artifacts/harvester-master-rootfs-amd64.squashfs" - - - name: Run setup Harvester - shell: > - ./setup_harvester.sh - register: setup_harvester_result - args: - chdir: "{{ WORKSPACE }}/ipxe-examples/vagrant-pxe-harvester" - ignore_errors: yes - - - name: Print Harvester installation output - debug: - msg: "{{ setup_harvester_result.stdout_lines }}" - - - name: Enable software-emulation in KubeVirt - register: kubevirt_result - vars: - settings_file: "{{ WORKSPACE }}/ipxe-examples/vagrant-pxe-harvester/settings.yml" - shell: > - ./enable_soft_emulation.sh {{ settings_file }} - args: - chdir: "{{ WORKSPACE }}/harvester-installer/ci/terraform" - - - name: Print Enable software-emulation in KubeVirt output - debug: - msg: "{{ kubevirt_result.stdout_lines }}" - - - name: Clear the previous temp file - shell: > - ./cleanup_test_files.sh - args: - chdir: "{{ WORKSPACE }}/harvester-installer/ci/terraform" - - - name: Testing services status - vars: - settings_file: "{{ WORKSPACE }}/ipxe-examples/vagrant-pxe-harvester/settings.yml" - shell: > - ./check_services_status.sh {{ settings_file}} - args: - chdir: "{{ WORKSPACE }}/harvester-installer/ci/terraform" - - - name: Testing basic operations with terraform - register: terraform_test - vars: - settings_file: "{{ WORKSPACE }}/ipxe-examples/vagrant-pxe-harvester/settings.yml" - shell: | - curl https://releases.hashicorp.com/terraform/1.3.7/terraform_1.3.7_linux_amd64.zip -o terraform_bin.zip - unzip -o terraform_bin.zip - ./get_kubeconfig.sh {{ settings_file }} - ./terraform init -no-color - ./terraform apply -auto-approve -no-color - args: - chdir: "{{ WORKSPACE }}/harvester-installer/ci/terraform" - - - name: Print terraform output - debug: - msg: "{{ terraform_test.stdout_lines }}" - - - name: Test network on the VMs - register: network_test - vars: - settings_file: "{{ WORKSPACE }}/ipxe-examples/vagrant-pxe-harvester/settings.yml" - shell: | - ./test_terraform_vm.sh {{ settings_file }} - args: - chdir: "{{ WORKSPACE }}/harvester-installer/ci/terraform" - - - name: Print network testing output - debug: - msg: "{{ network_test.stdout_lines }}" - - - name: Cleanup Harvester Vagrant VMs - shell: > - vagrant destroy -f - args: - chdir: "{{ WORKSPACE }}/ipxe-examples/vagrant-pxe-harvester" - - - name: Check result - fail: - msg: "ERROR: {{ setup_harvester_result.stderr }}" - when: setup_harvester_result.failed diff --git a/ci/terraform/check_files.sh b/ci/terraform/check_files.sh new file mode 100755 index 000000000..aacc91d89 --- /dev/null +++ b/ci/terraform/check_files.sh @@ -0,0 +1,23 @@ +#!/bin/bash -ex + +if [[ $# != 1 ]] +then + echo "We need the settings.yaml from ipxe repo" + exit 1 +fi + +SETTINGS=$1 + +EXISTING_FILES="/oem/grubenv /oem/grubcustom" +NODE0_IP=$(yq e ".harvester_network_config.cluster[0].ip" ${SETTINGS}) + +echo "Check files that should exist." + +SSHKEY=./tmp-ssh-key +for filepath in ${EXISTING_FILES}; do + echo "Prepare to check file: ${filepath} ..." + if ! ssh -o "StrictHostKeyChecking no" -i tmp-ssh-key rancher@$NODE0_IP "sudo stat ${filepath}" | grep -q ${filepath}; then + echo "${filepath} should exist, exit!" + exit 1 + fi +done \ No newline at end of file diff --git a/package/harvester-os/files/usr/sbin/harv-install b/package/harvester-os/files/usr/sbin/harv-install index fc566fa37..6be586211 100755 --- a/package/harvester-os/files/usr/sbin/harv-install +++ b/package/harvester-os/files/usr/sbin/harv-install @@ -366,11 +366,20 @@ update_grub_settings() # stuck on the grub file search for about 30 minutes, this can be # mitigated by adding the `grubenv` file. # - # PATCH: add /oem/grubenv if it does not exist + # We need to patch grubenv, grubcustom oem_dir=${TARGET}/oem - GRUBENV_FILE="${oem_dir}/grubenv" - if ! [ -f ${GRUBENV_FILE} ]; then - grub2-editenv ${GRUBENV_FILE} create + + # PATCH1: add /oem/grubenv if it does not exist + # grubenv use load_env to load, so we use grub2-editenv + TARGET_FILE="${oem_dir}/grubenv" + if ! [ -f ${TARGET_FILE} ]; then + grub2-editenv ${TARGET_FILE} create + fi + # PATCH2: add /oem/grubcustom if it does not exist + # grubcustom use source to load, so we can use touch directly + TARGET_FILE="${oem_dir}/grubcustom" + if ! [ -f ${TARGET_FILE} ]; then + touch ${TARGET_FILE} fi add_debug_grub_entry