diff --git a/internal/distro/fedora/images.go b/internal/distro/fedora/images.go index b1c95c4c9..23e70e92c 100644 --- a/internal/distro/fedora/images.go +++ b/internal/distro/fedora/images.go @@ -365,6 +365,8 @@ func iotRawImage(workload workload.Workload, img.Users = users.UsersFromBP(customizations.GetUsers()) img.Groups = users.GroupsFromBP(customizations.GetGroups()) + // "rw" kernel option is required when /sysroot is mounted read-only to + // keep stateful parts of the filesystem writeable (/var/ and /etc) img.KernelOptionsAppend = []string{"modprobe.blacklist=vc4", "rw"} img.Keyboard = "us" img.Locale = "C.UTF-8" diff --git a/internal/distro/rhel8/pipelines.go b/internal/distro/rhel8/pipelines.go index a125bcbe1..7293c2b9a 100644 --- a/internal/distro/rhel8/pipelines.go +++ b/internal/distro/rhel8/pipelines.go @@ -953,9 +953,12 @@ func ostreeDeployPipeline( OSName: osname, }, )) - p.AddStage(osbuild.NewOSTreeConfigStage(ostreeConfigStageOptions(repoPath, false))) + p.AddStage(osbuild.NewOSTreeConfigStage(ostreeConfigStageOptions(repoPath, true))) p.AddStage(osbuild.NewMkdirStage(efiMkdirStageOptions())) kernelOpts := osbuild.GenImageKernelOptions(pt) + // "rw" kernel option is required when /sysroot is mounted read-only to + // keep stateful parts of the filesystem writeable (/var/ and /etc) + kernelOpts = append(kernelOpts, "rw") p.AddStage(osbuild.NewOSTreeDeployStage( &osbuild.OSTreeDeployStageOptions{ OsName: osname, diff --git a/internal/distro/rhel9/images.go b/internal/distro/rhel9/images.go index 37a8d7df2..b8e136fd5 100644 --- a/internal/distro/rhel9/images.go +++ b/internal/distro/rhel9/images.go @@ -326,9 +326,12 @@ func edgeRawImage(workload workload.Workload, img.Users = users.UsersFromBP(customizations.GetUsers()) img.Groups = users.GroupsFromBP(customizations.GetGroups()) - img.KernelOptionsAppend = []string{"modprobe.blacklist=vc4"} + // "rw" kernel option is required when /sysroot is mounted read-only to + // keep stateful parts of the filesystem writeable (/var/ and /etc) + img.KernelOptionsAppend = []string{"modprobe.blacklist=vc4", "rw"} img.Keyboard = "us" img.Locale = "C.UTF-8" + img.SysrootReadOnly = true img.Platform = t.platform img.Workload = workload @@ -370,9 +373,12 @@ func edgeSimplifiedInstallerImage(workload workload.Workload, rawImg.Users = users.UsersFromBP(customizations.GetUsers()) rawImg.Groups = users.GroupsFromBP(customizations.GetGroups()) - rawImg.KernelOptionsAppend = []string{"modprobe.blacklist=vc4"} + // "rw" kernel option is required when /sysroot is mounted read-only to + // keep stateful parts of the filesystem writeable (/var/ and /etc) + rawImg.KernelOptionsAppend = []string{"modprobe.blacklist=vc4", "rw"} rawImg.Keyboard = "us" rawImg.Locale = "C.UTF-8" + rawImg.SysrootReadOnly = true rawImg.Platform = t.platform rawImg.Workload = workload diff --git a/test/cases/ostree-raw-image.sh b/test/cases/ostree-raw-image.sh index 571715115..243307ed6 100755 --- a/test/cases/ostree-raw-image.sh +++ b/test/cases/ostree-raw-image.sh @@ -491,7 +491,7 @@ ansible_become_pass=${EDGE_USER_PASSWORD} EOF # Test IoT/Edge OS - sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type="${OSTREE_OSNAME}" -e ostree_commit="${INSTALL_HASH}" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 + sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type="${OSTREE_OSNAME}" -e edge_type=edge-raw-image -e ostree_commit="${INSTALL_HASH}" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 check_result # Clean up BIOS VM @@ -567,7 +567,7 @@ ansible_become_pass=${EDGE_USER_PASSWORD} EOF # Test IoT/Edge OS -sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type="${OSTREE_OSNAME}" -e ostree_commit="${INSTALL_HASH}" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 +sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type="${OSTREE_OSNAME}" -e edge_type=edge-raw-image -e ostree_commit="${INSTALL_HASH}" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 check_result ################################################################## @@ -721,7 +721,7 @@ ansible_become_pass=${EDGE_USER_PASSWORD} EOF # Test IoT/Edge OS -sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type="${OSTREE_OSNAME}" -e ostree_commit="${UPGRADE_HASH}" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 +sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type="${OSTREE_OSNAME}" -e edge_type=edge-raw-image -e ostree_commit="${UPGRADE_HASH}" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 check_result # Final success clean up diff --git a/test/cases/ostree-simplified-installer.sh b/test/cases/ostree-simplified-installer.sh index ed8409608..f4d21b19f 100755 --- a/test/cases/ostree-simplified-installer.sh +++ b/test/cases/ostree-simplified-installer.sh @@ -519,7 +519,7 @@ ansible_become_pass=${EDGE_USER_PASSWORD} EOF # Test IoT/Edge OS -sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${INSTALL_HASH}" -e fdo_credential="true" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 +sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${INSTALL_HASH}" -e edge_type=edge-simplified-installer -e fdo_credential="true" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 check_result # Clean up BIOS VM @@ -643,7 +643,7 @@ ansible_become_pass=${EDGE_USER_PASSWORD} EOF # Test IoT/Edge OS -sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${INSTALL_HASH}" -e fdo_credential="true" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 +sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${INSTALL_HASH}" -e edge_type=edge-simplified-installer -e fdo_credential="true" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 check_result # Clean up BIOS VM @@ -765,7 +765,7 @@ ansible_become_pass=${EDGE_USER_PASSWORD} EOF # Test IoT/Edge OS -sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${INSTALL_HASH}" -e fdo_credential="true" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 +sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${INSTALL_HASH}" -e edge_type=edge-simplified-installer -e fdo_credential="true" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 check_result greenprint "🧹 Clean up VM" @@ -882,7 +882,7 @@ ansible_become_pass=${EDGE_USER_PASSWORD} EOF # Test IoT/Edge OS -sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${INSTALL_HASH}" -e fdo_credential="false" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 +sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${INSTALL_HASH}" -e edge_type=edge-simplified-installer -e fdo_credential="false" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 check_result ######################## @@ -1016,7 +1016,7 @@ ansible_become_pass=${EDGE_USER_PASSWORD} EOF # Test IoT/Edge OS -sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${UPGRADE_HASH}" -e fdo_credential="false" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 +sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${UPGRADE_HASH}" -e edge_type=edge-simplified-installer -e fdo_credential="false" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 check_result # Final success clean up diff --git a/test/data/ansible/check_ostree.yaml b/test/data/ansible/check_ostree.yaml index 96919b737..c8313c4d1 100644 --- a/test/data/ansible/check_ostree.yaml +++ b/test/data/ansible/check_ostree.yaml @@ -5,6 +5,7 @@ workspace: "{{ lookup('env', 'WORKSPACE') }}" skip_rollback_test: "false" fdo_credential: "false" + edge_type: "none" embeded_container: "false" total_counter: "0" failed_counter: "0" @@ -232,25 +233,12 @@ shell: findmnt -r -o OPTIONS -n /sysroot | awk -F "," '{print $1}' register: result_sysroot_mount_status - - name: /sysroot should be mount with rw permission - block: - - assert: - that: - - result_sysroot_mount_status.stdout == "rw" - fail_msg: "/sysroot is not mounted with rw permission" - success_msg: "/sysroot is mounted with rw permission" - always: - - set_fact: - total_counter: "{{ total_counter | int + 1 }}" - rescue: - - name: failed count + 1 - set_fact: - failed_counter: "{{ failed_counter | int + 1 }}" - when: (ansible_facts['distribution'] == 'Fedora' and ansible_facts['distribution_version'] is version('37', '<')) or - (ansible_facts['distribution'] == 'CentOS') or (ansible_facts['distribution'] == 'RedHat') - # https://fedoraproject.org/wiki/Changes/Silverblue_Kinoite_readonly_sysroot - - name: /sysroot should be mount with ro permission since Fedora 37 + # There are three checks here for /sysroot permission based on pr https://github.com/osbuild/osbuild-composer/pull/3053 + # 1. for edge-commit and edge-installer, check ro when fedora >= 37 + # 2. for edge-commit and edge-installer, check rw for other os. + # 3. for edge-simplified-installer and edge-raw-image, check ro for all os. + - name: /sysroot should be mount with ro permission for edge-commit and edge-installer on Fedora >= 37 block: - assert: that: @@ -264,7 +252,40 @@ - name: failed count + 1 set_fact: failed_counter: "{{ failed_counter | int + 1 }}" - when: ansible_facts['distribution'] == 'Fedora' and ansible_facts['distribution_version'] is version('37', '>=') + when: (edge_type == "none") and (ansible_facts['distribution'] == 'Fedora' and ansible_facts['distribution_version'] is version('37', '>=')) + + - name: /sysroot should be mount with rw permission for edge-commit and edge-installer on all OS except Fedora >= 37 + block: + - assert: + that: + - result_sysroot_mount_status.stdout == "rw" + fail_msg: "/sysroot is not mounted with rw permission" + success_msg: "/sysroot is mounted with rw permission" + always: + - set_fact: + total_counter: "{{ total_counter | int + 1 }}" + rescue: + - name: failed count + 1 + set_fact: + failed_counter: "{{ failed_counter | int + 1 }}" + when: (edge_type == "none") and ((ansible_facts['distribution'] == 'Fedora' and ansible_facts['distribution_version'] is version('37', '<')) or + (ansible_facts['distribution'] == 'CentOS') or (ansible_facts['distribution'] == 'RedHat')) + + - name: /sysroot should be mount with ro permission for edge-simplified-installer and edge-raw-image + block: + - assert: + that: + - result_sysroot_mount_status.stdout == "ro" + fail_msg: "/sysroot is not mounted with ro permission" + success_msg: "/sysroot is mounted with ro permission" + always: + - set_fact: + total_counter: "{{ total_counter | int + 1 }}" + rescue: + - name: failed count + 1 + set_fact: + failed_counter: "{{ failed_counter | int + 1 }}" + when: edge_type == "edge-simplified-installer" or edge_type == "edge-raw-image" # case: check /var mount point - name: check /var mount point @@ -397,8 +418,8 @@ - name: failed count + 1 set_fact: failed_counter: "{{ failed_counter | int + 1 }}" - when: (ansible_facts['distribution'] == 'Fedora' and ansible_facts['distribution_version'] is version('37', '<')) or - (ansible_facts['distribution'] == 'CentOS') or (ansible_facts['distribution'] == 'RedHat') + when: (edge_type == "none") and ((ansible_facts['distribution'] == 'Fedora' and ansible_facts['distribution_version'] is version('37', '<')) or + (ansible_facts['distribution'] == 'CentOS') or (ansible_facts['distribution'] == 'RedHat')) # case: check dmesg error and failed log - name: check dmesg output