From a7e5a729ce749b2a562b610ab804a0ab99bd779b Mon Sep 17 00:00:00 2001 From: Neil Hanlon Date: Thu, 20 Oct 2022 19:51:23 -0400 Subject: [PATCH] r8 branch init --- .gitignore | 4 + LICENSE | 201 ++++++++++++++ README.md | 33 +++ build.sh | 12 + commands.txt | 6 + image-base.yaml | 33 +++ image.yaml | 1 + live/EFI/rocky/grub.cfg | 36 +++ live/README.md | 1 + live/isolinux/boot.msg | 5 + live/isolinux/isolinux.cfg | 75 +++++ manifest.yaml | 12 + manifests/bootable-rpm-ostree.yaml | 53 ++++ manifests/bootupd.yaml | 13 + manifests/fallback-hostname.yaml | 11 + manifests/group | 46 ++++ manifests/grub2-removals.yaml | 9 + manifests/ignition-and-ostree.yaml | 44 +++ manifests/passwd | 40 +++ manifests/rocky-coreos-base.yaml | 60 ++++ manifests/rocky-coreos.yaml | 60 ++++ manifests/shared-el9.yaml | 11 + manifests/shared-workarounds.yaml | 35 +++ manifests/system-configuration.yaml | 50 ++++ manifests/user-experience.yaml | 47 ++++ .../pwquality.conf.d/20-disable-dict.conf | 3 + .../05core/etc/sudoers.d/coreos-sudo-group | 2 + overlay.d/05core/statoverride | 6 + .../conf.d/20-client-id-from-mac.conf | 2 + .../05core/usr/lib/coreos/generator-lib.sh | 30 ++ .../modules.d/01scsi-rules/module-setup.sh | 13 + .../modules.d/10coreos-sysctl/module-setup.sh | 23 ++ .../25coreos-azure-udev/module-setup.sh | 18 ++ .../coreos-boot-edit.service | 26 ++ .../35coreos-ignition/coreos-boot-edit.sh | 51 ++++ .../coreos-diskful-generator | 60 ++++ .../coreos-gpt-setup.service | 36 +++ .../35coreos-ignition/coreos-gpt-setup.sh | 42 +++ .../coreos-ignition-setup-user.service | 23 ++ .../coreos-ignition-setup-user.sh | 32 +++ .../coreos-kargs-reboot.service | 23 ++ .../35coreos-ignition/coreos-kargs.sh | 12 + .../coreos-teardown-initramfs.service | 38 +++ .../coreos-teardown-initramfs.sh | 216 +++++++++++++++ .../35coreos-ignition/module-setup.sh | 59 ++++ .../coreos-live-clear-sssd-cache.service | 18 ++ .../coreos-live-unmount-tmpfs-var.service | 24 ++ .../coreos-live-unmount-tmpfs-var.sh | 33 +++ .../coreos-liveiso-persist-osmet.service | 17 ++ .../coreos-livepxe-persist-osmet.service | 14 + .../coreos-livepxe-rootfs.service | 21 ++ .../35coreos-live/coreos-livepxe-rootfs.sh | 70 +++++ .../modules.d/35coreos-live/is-live-image.sh | 6 + .../modules.d/35coreos-live/live-generator | 257 ++++++++++++++++++ .../modules.d/35coreos-live/module-setup.sh | 55 ++++ .../modules.d/35coreos-live/ostree-cmdline.sh | 25 ++ .../coreos-multipath-generator | 30 ++ .../coreos-multipath-trigger.service | 19 ++ .../coreos-multipath-wait.target | 17 ++ .../coreos-propagate-multipath-conf.service | 21 ++ .../coreos-propagate-multipath-conf.sh | 17 ++ .../35coreos-multipath/module-setup.sh | 28 ++ .../50-afterburn-network-kargs-default.conf | 7 + .../coreos-copy-firstboot-network.service | 65 +++++ .../coreos-copy-firstboot-network.sh | 49 ++++ .../coreos-enable-network.service | 30 ++ .../35coreos-network/coreos-enable-network.sh | 27 ++ .../35coreos-network/module-setup.sh | 26 ++ .../modules.d/40ignition-conf/00-core.ign | 19 ++ .../modules.d/40ignition-conf/README.md | 1 + .../modules.d/40ignition-conf/module-setup.sh | 13 + .../coreos-check-rootfs-size | 37 +++ .../40ignition-ostree/coreos-relabel | 35 +++ .../40ignition-ostree/coreos-rootflags.sh | 30 ++ .../ignition-ostree-check-rootfs-size.service | 13 + .../ignition-ostree-firstboot-uuid | 68 +++++ .../ignition-ostree-growfs.service | 15 + .../ignition-ostree-growfs.sh | 120 ++++++++ ...ion-ostree-mount-firstboot-sysroot.service | 25 ++ ...on-ostree-mount-subsequent-sysroot.service | 24 ++ .../ignition-ostree-mount-sysroot.sh | 18 ++ .../ignition-ostree-mount-var.service | 26 ++ .../ignition-ostree-mount-var.sh | 52 ++++ .../ignition-ostree-populate-var.service | 16 ++ .../ignition-ostree-populate-var.sh | 45 +++ ...ignition-ostree-transposefs-detect.service | 20 ++ ...gnition-ostree-transposefs-restore.service | 20 ++ .../ignition-ostree-transposefs-save.service | 19 ++ .../ignition-ostree-transposefs.sh | 244 +++++++++++++++++ .../ignition-ostree-uuid-boot.service | 22 ++ .../ignition-ostree-uuid-root.service | 25 ++ .../40ignition-ostree/module-setup.sh | 104 +++++++ .../coreos-check-kernel.service | 10 + .../modules.d/50coreos-kernel/module-setup.sh | 15 + .../coreos-touch-run-agetty.service | 12 + .../module-setup.sh | 21 ++ .../ignition-virtio-dump-journal.service | 15 + .../ignition-virtio-dump-journal.sh | 13 + .../99emergency-timeout/module-setup.sh | 24 ++ .../modules.d/99emergency-timeout/timeout.sh | 99 +++++++ .../00-journal-log-forwarding.conf | 12 + .../modules.d/99journal-conf/module-setup.sh | 12 + .../sysctl.d/10-coreos-ratelimit-kmsg.conf | 3 + .../journald.conf.d/10-coreos-persistent.conf | 6 + .../coreos-boot-mount-generator | 115 ++++++++ .../coreos-liveiso-autologin-generator | 105 +++++++ .../system-preset/40-coreos-systemd.preset | 16 ++ .../systemd/system-preset/40-coreos.preset | 27 ++ .../coreos-check-ignition-config.service | 14 + ...coreos-ignition-firstboot-complete.service | 21 ++ .../system/coreos-liveiso-success.service | 26 ++ .../system/coreos-update-ca-trust.service | 31 +++ .../coreos-sulogin-force.conf | 7 + .../coreos-sulogin-force.conf | 1 + .../45-after-ostree-remount.conf | 4 + .../fcos-disable.conf | 5 + .../lib/udev/rules.d/65-gce-disk-naming.rules | 38 +++ .../rules.d/68-azure-sriov-nm-unmanaged.rules | 4 + .../rules.d/90-coreos-device-mapper.rules | 27 ++ .../usr/libexec/coreos-check-ignition-config | 47 ++++ .../coreos-ignition-firstboot-complete | 18 ++ .../licenses/fedora-coreos-config/LICENSE | 21 ++ .../licenses/fedora-coreos-config/README.md | 17 ++ .../etc/modprobe.d/blacklist-nouveau.conf | 2 + overlay.d/08nouveau/statoverride | 2 + overlay.d/09misc/etc/sysconfig/README | 9 + overlay.d/09misc/statoverride | 2 + .../14NetworkManager-plugins/statoverride | 2 + .../conf.d/10-disable-default-plugins.conf | 9 + .../sshd_config.d/40-disable-passwords.conf | 5 + overlay.d/15fcos/statoverride | 2 + .../20-aws-nm-cloud-setup.ign | 16 ++ .../20-azure-nm-cloud-setup.ign | 16 ++ .../20-gcp-nm-cloud-setup.ign | 16 ++ .../30-afterburn-sshkeys-core.ign | 13 + .../modules.d/50ignition-conf-fcos/README.md | 1 + .../50ignition-conf-fcos/module-setup.sh | 31 +++ overlay.d/15fcos/usr/lib/motd.d/tracker.motd | 3 + .../lib/systemd/system-preset/45-fcos.preset | 5 + .../system/coreos-check-cgroups.service | 11 + .../system/coreos-check-ssh-keys.service | 24 ++ .../15fcos/usr/libexec/coreos-check-cgroups | 25 ++ .../15fcos/usr/libexec/coreos-check-ssh-keys | 46 ++++ overlay.d/20platform-chrony/statoverride | 2 + .../system-generators/coreos-platform-chrony | 99 +++++++ overlay.d/README.md | 43 +++ rocky.repo | 26 ++ 147 files changed, 4696 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100755 build.sh create mode 100644 commands.txt create mode 100644 image-base.yaml create mode 100644 image.yaml create mode 100644 live/EFI/rocky/grub.cfg create mode 100644 live/README.md create mode 100644 live/isolinux/boot.msg create mode 100644 live/isolinux/isolinux.cfg create mode 100644 manifest.yaml create mode 100644 manifests/bootable-rpm-ostree.yaml create mode 100644 manifests/bootupd.yaml create mode 100644 manifests/fallback-hostname.yaml create mode 100644 manifests/group create mode 100644 manifests/grub2-removals.yaml create mode 100644 manifests/ignition-and-ostree.yaml create mode 100644 manifests/passwd create mode 100644 manifests/rocky-coreos-base.yaml create mode 100644 manifests/rocky-coreos.yaml create mode 100644 manifests/shared-el9.yaml create mode 100644 manifests/shared-workarounds.yaml create mode 100644 manifests/system-configuration.yaml create mode 100644 manifests/user-experience.yaml create mode 100644 overlay.d/05core/etc/security/pwquality.conf.d/20-disable-dict.conf create mode 100644 overlay.d/05core/etc/sudoers.d/coreos-sudo-group create mode 100644 overlay.d/05core/statoverride create mode 100644 overlay.d/05core/usr/lib/NetworkManager/conf.d/20-client-id-from-mac.conf create mode 100644 overlay.d/05core/usr/lib/coreos/generator-lib.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/01scsi-rules/module-setup.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/10coreos-sysctl/module-setup.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/25coreos-azure-udev/module-setup.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-boot-edit.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-boot-edit.sh create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-diskful-generator create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-gpt-setup.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-gpt-setup.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-ignition-setup-user.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-ignition-setup-user.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-kargs-reboot.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-kargs.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-teardown-initramfs.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-teardown-initramfs.sh create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/module-setup.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-live-clear-sssd-cache.service create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-live-unmount-tmpfs-var.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-live-unmount-tmpfs-var.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-liveiso-persist-osmet.service create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-livepxe-persist-osmet.service create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-livepxe-rootfs.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-livepxe-rootfs.sh create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/is-live-image.sh create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/live-generator create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/module-setup.sh create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/ostree-cmdline.sh create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-multipath-generator create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-multipath-trigger.service create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-multipath-wait.target create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-propagate-multipath-conf.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-propagate-multipath-conf.sh create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/module-setup.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/50-afterburn-network-kargs-default.conf create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/coreos-copy-firstboot-network.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/coreos-copy-firstboot-network.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/coreos-enable-network.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/coreos-enable-network.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/module-setup.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-conf/00-core.ign create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-conf/README.md create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-conf/module-setup.sh create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/coreos-check-rootfs-size create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/coreos-relabel create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/coreos-rootflags.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-check-rootfs-size.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-firstboot-uuid create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-firstboot-sysroot.service create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-subsequent-sysroot.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-sysroot.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-var.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-var.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-populate-var.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-populate-var.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-detect.service create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-restore.service create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-save.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-boot.service create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-root.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/50coreos-kernel/coreos-check-kernel.service create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/50coreos-kernel/module-setup.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/60coreos-agetty-workaround/coreos-touch-run-agetty.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/60coreos-agetty-workaround/module-setup.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/99emergency-timeout/ignition-virtio-dump-journal.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/99emergency-timeout/ignition-virtio-dump-journal.sh create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/99emergency-timeout/module-setup.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/99emergency-timeout/timeout.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/99journal-conf/00-journal-log-forwarding.conf create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/99journal-conf/module-setup.sh create mode 100644 overlay.d/05core/usr/lib/sysctl.d/10-coreos-ratelimit-kmsg.conf create mode 100644 overlay.d/05core/usr/lib/systemd/journald.conf.d/10-coreos-persistent.conf create mode 100755 overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator create mode 100755 overlay.d/05core/usr/lib/systemd/system-generators/coreos-liveiso-autologin-generator create mode 100644 overlay.d/05core/usr/lib/systemd/system-preset/40-coreos-systemd.preset create mode 100644 overlay.d/05core/usr/lib/systemd/system-preset/40-coreos.preset create mode 100644 overlay.d/05core/usr/lib/systemd/system/coreos-check-ignition-config.service create mode 100644 overlay.d/05core/usr/lib/systemd/system/coreos-ignition-firstboot-complete.service create mode 100644 overlay.d/05core/usr/lib/systemd/system/coreos-liveiso-success.service create mode 100644 overlay.d/05core/usr/lib/systemd/system/coreos-update-ca-trust.service create mode 100644 overlay.d/05core/usr/lib/systemd/system/emergency.service.d/coreos-sulogin-force.conf create mode 120000 overlay.d/05core/usr/lib/systemd/system/rescue.service.d/coreos-sulogin-force.conf create mode 100644 overlay.d/05core/usr/lib/systemd/system/systemd-backlight@.service.d/45-after-ostree-remount.conf create mode 100644 overlay.d/05core/usr/lib/systemd/system/systemd-firstboot.service.d/fcos-disable.conf create mode 100644 overlay.d/05core/usr/lib/udev/rules.d/65-gce-disk-naming.rules create mode 100644 overlay.d/05core/usr/lib/udev/rules.d/68-azure-sriov-nm-unmanaged.rules create mode 100644 overlay.d/05core/usr/lib/udev/rules.d/90-coreos-device-mapper.rules create mode 100755 overlay.d/05core/usr/libexec/coreos-check-ignition-config create mode 100755 overlay.d/05core/usr/libexec/coreos-ignition-firstboot-complete create mode 100644 overlay.d/05core/usr/share/licenses/fedora-coreos-config/LICENSE create mode 100644 overlay.d/05core/usr/share/licenses/fedora-coreos-config/README.md create mode 100644 overlay.d/08nouveau/etc/modprobe.d/blacklist-nouveau.conf create mode 100644 overlay.d/08nouveau/statoverride create mode 100644 overlay.d/09misc/etc/sysconfig/README create mode 100644 overlay.d/09misc/statoverride create mode 100644 overlay.d/14NetworkManager-plugins/statoverride create mode 100644 overlay.d/14NetworkManager-plugins/usr/lib/NetworkManager/conf.d/10-disable-default-plugins.conf create mode 100644 overlay.d/15fcos/etc/ssh/sshd_config.d/40-disable-passwords.conf create mode 100644 overlay.d/15fcos/statoverride create mode 100644 overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/20-aws-nm-cloud-setup.ign create mode 100644 overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/20-azure-nm-cloud-setup.ign create mode 100644 overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/20-gcp-nm-cloud-setup.ign create mode 100644 overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/30-afterburn-sshkeys-core.ign create mode 100644 overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/README.md create mode 100755 overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/module-setup.sh create mode 100644 overlay.d/15fcos/usr/lib/motd.d/tracker.motd create mode 100644 overlay.d/15fcos/usr/lib/systemd/system-preset/45-fcos.preset create mode 100644 overlay.d/15fcos/usr/lib/systemd/system/coreos-check-cgroups.service create mode 100644 overlay.d/15fcos/usr/lib/systemd/system/coreos-check-ssh-keys.service create mode 100755 overlay.d/15fcos/usr/libexec/coreos-check-cgroups create mode 100755 overlay.d/15fcos/usr/libexec/coreos-check-ssh-keys create mode 100644 overlay.d/20platform-chrony/statoverride create mode 100755 overlay.d/20platform-chrony/usr/lib/systemd/system-generators/coreos-platform-chrony create mode 100644 overlay.d/README.md create mode 100644 rocky.repo diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e50125c --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +build/ +.direnv/ +.envrc +ass diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..65a3863 --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# Rocky Linux Ostree +This repository contains all the bits to get a working Ostree for Rocky Linux (8.6). Although Fedora and Red Hat CoreOS use (rpm)Ostree, this is NOT a CoreOS clone. + +If you want to build a Rocky Linux CoreOS, in other words a Red Hat CoreOS clone, then checkout [coreos-assembler](https://coreos.github.io/rpm-ostree/compose-server). Other sites with information about CoreOS and building custom OStree(s): + +* https://coreos.github.io/rpm-ostree/compose-server/ +* https://www.osbuild.org/ + +Especially osbuild is a very nice project/tool which is now incorperated in the more recent Red Hat versions. + +## Dir: bootserver +Contains an Ansible playbook to configure a PXE bootserver + +## Dir: ostree-config +Contains the config files to build a basic Ostree for Rocky Linux + +# How to use +From the root directory of this project: +* Create a build directory with the repo and cache directory below it. The repo directory will have the final OStree repository where you could boot from. +* Initialize the ./build/repo directory as a OStree repository +* Build the OStree repo + +``` +mkdir -p ./build/{repo,cache} +ostree --repo=./build/repo init --mode=archive +sudo rpm-ostree --unified-core compose tree --cachedir=./build/cache --repo=./build/repo config/manifest.yaml +``` + +When the compose state is finished, rsync the repo to the bootserver and network boot from it. + +``` +sudo rsync -av --delete ./build/repo root@192.168.122.89:/var/www/html/ostree/ +``` \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..e688e48 --- /dev/null +++ b/build.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +Error () { + echo "Oops, something did not work" + exit 101 +} + +sudo rm -rf ./build || Error +mkdir -p ./build/{repo,cache} || Error +ostree --repo=build/repo init --mode=archive || Error +sudo rpm-ostree compoe tree --unified-core --cachedir=./build/cache --repo=./build/repo config/manifest.yaml || Error +sudo rsync -av --delete ./build/repo root@192.168.122.89:/var/www/html/ostree/ || Error diff --git a/commands.txt b/commands.txt new file mode 100644 index 0000000..061f349 --- /dev/null +++ b/commands.txt @@ -0,0 +1,6 @@ +Commands/notes + +ostree --repo=./build/repo ls rocky/x86_64/ostree +ostree --repo=./build/repo ls rocky/x86_64/ostree /etc +ostree --repo=./build/repo cat rocky/x86_64/ostree /usr/etc/passwd +ostree --repo=./build/repo ls rocky/x86_64/ostree /usr/lib/systemd/system/*get* diff --git a/image-base.yaml b/image-base.yaml new file mode 100644 index 0000000..c91a639 --- /dev/null +++ b/image-base.yaml @@ -0,0 +1,33 @@ +# This file is shared by all streams. For a stream-specific change, use +# image.yaml instead. + +# Target disk size in GB. +# Make it at least 10G because we want the rootfs to be at least 8G: +# https://github.com/coreos/fedora-coreos-tracker/issues/586 +size: 10 + +extra-kargs: + # Disable SMT on systems vulnerable to MDS or any similar future issue. + - mitigations=auto,nosmt + +# Disable networking by default on firstboot. We can drop this once cosa stops +# defaulting to `ip=auto rd.neednet=1` when it doesn't see this key. +ignition-network-kcmdline: [] + +# Optional remote by which to prefix the deployed OSTree ref +ostree-remote: rocky + +# opt in to using the `metadata_csum_seed` feature of the ext4 filesystem +# for the /boot filesystem. Support for this was only recently added to grub +# and isn't available everywhere yet so we'll gate it behind this image.yaml +# knob. It should be easy to know when RHEL/RHCOS supports this by just flipping +# this to `true` and doing a build. It should error when building the disk +# images if grub doesn't support it. +# https://lists.gnu.org/archive/html/grub-devel/2021-06/msg00031.html +bootfs_metadata_csum_seed: true + +vmware-os-type: fedora64Guest +# VMware hardware versions: https://kb.vmware.com/s/article/1003746 +# We use the newest version allowed by the oldest non-EOL VMware +# Workstation/Player/Fusion/ESXi release: https://lifecycle.vmware.com/ +vmware-hw-version: 13 diff --git a/image.yaml b/image.yaml new file mode 100644 index 0000000..706814b --- /dev/null +++ b/image.yaml @@ -0,0 +1 @@ +include: image-base.yaml diff --git a/live/EFI/rocky/grub.cfg b/live/EFI/rocky/grub.cfg new file mode 100644 index 0000000..a69afda --- /dev/null +++ b/live/EFI/rocky/grub.cfg @@ -0,0 +1,36 @@ +# Note this file mostly matches the grub.cfg file from within the +# efiboot.img on the Fedora Server DVD iso. Diff this file with that +# file in the future to pick up changes. +# +# One diff to note is we use linux and initrd instead of linuxefi and +# initrdefi. We do this because it works and allows us to use this same +# file on other architectures. https://github.com/coreos/fedora-coreos-config/issues/63 +# +# This file is loaded directly when booting via El Torito, and indirectly +# from a stub config in efiboot.img when booting via the hybrid ESP. + +set default="1" + +function load_video { + insmod efi_gop + insmod efi_uga + insmod video_bochs + insmod video_cirrus + insmod all_video +} + +load_video +set gfxpayload=keep +insmod gzio +insmod part_gpt +insmod ext2 + +set timeout=5 +### END /etc/grub.d/00_header ### + +### BEGIN /etc/grub.d/10_linux ### +menuentry 'Rocky Linux Core (Live)' --class fedora --class gnu-linux --class gnu --class os { + linux /images/pxeboot/vmlinuz @@KERNEL-ARGS@@ ignition.firstboot ignition.platform.id=metal +################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################ COREOS_KARG_EMBED_AREA + initrd /images/pxeboot/initrd.img /images/ignition.img +} diff --git a/live/README.md b/live/README.md new file mode 100644 index 0000000..5b84347 --- /dev/null +++ b/live/README.md @@ -0,0 +1 @@ +Files in this tree are copied into the live ISO and are required for EFI booting (and booting, generally) diff --git a/live/isolinux/boot.msg b/live/isolinux/boot.msg new file mode 100644 index 0000000..362e9e5 --- /dev/null +++ b/live/isolinux/boot.msg @@ -0,0 +1,5 @@ + +splash.lss + + - Press the 0107 key to boot. + diff --git a/live/isolinux/isolinux.cfg b/live/isolinux/isolinux.cfg new file mode 100644 index 0000000..e52bed0 --- /dev/null +++ b/live/isolinux/isolinux.cfg @@ -0,0 +1,75 @@ +# Note this file mostly matches the isolinux.cfg file from the Fedora +# Server DVD iso. Diff this file with that file in the future to pick up +# changes. +serial 0 +default vesamenu.c32 +# timeout in units of 1/10s. 50 == 5 seconds +timeout 50 + +display boot.msg + +# Clear the screen when exiting the menu, instead of leaving the menu displayed. +# For vesamenu, this means the graphical background is still displayed without +# the menu itself for as long as the screen remains in graphics mode. +menu clear +menu background splash.png +menu title Rocky Linux Core +menu vshift 8 +menu rows 18 +menu margin 8 +#menu hidden +menu helpmsgrow 15 +menu tabmsgrow 13 + +# Border Area +menu color border * #00000000 #00000000 none + +# Selected item +menu color sel 0 #ffffffff #00000000 none + +# Title bar +menu color title 0 #ff7ba3d0 #00000000 none + +# Press [Tab] message +menu color tabmsg 0 #ff3a6496 #00000000 none + +# Unselected menu item +menu color unsel 0 #84b8ffff #00000000 none + +# Selected hotkey +menu color hotsel 0 #84b8ffff #00000000 none + +# Unselected hotkey +menu color hotkey 0 #ffffffff #00000000 none + +# Help text +menu color help 0 #ffffffff #00000000 none + +# A scrollbar of some type? Not sure. +menu color scrollbar 0 #ffffffff #ff355594 none + +# Timeout msg +menu color timeout 0 #ffffffff #00000000 none +menu color timeout_msg 0 #ffffffff #00000000 none + +# Command prompt text +menu color cmdmark 0 #84b8ffff #00000000 none +menu color cmdline 0 #ffffffff #00000000 none + +# Do not display the actual menu unless the user presses a key. All that is displayed is a timeout message. + +menu tabmsg Press Tab for full configuration options on menu items. + +menu separator # insert an empty line +menu separator # insert an empty line + +label linux + menu label ^Rocky Linux Core (Live) + menu default + kernel /images/pxeboot/vmlinuz + append initrd=/images/pxeboot/initrd.img,/images/ignition.img @@KERNEL-ARGS@@ ignition.firstboot ignition.platform.id=metal +################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################ COREOS_KARG_EMBED_AREA + +menu separator # insert an empty line + +menu end diff --git a/manifest.yaml b/manifest.yaml new file mode 100644 index 0000000..86e7da1 --- /dev/null +++ b/manifest.yaml @@ -0,0 +1,12 @@ +releasever: 9 + +variables: + stream: testing + prod: false + +repos: + - appstream + - baseos + - extras + +include: manifests/rocky-coreos.yaml diff --git a/manifests/bootable-rpm-ostree.yaml b/manifests/bootable-rpm-ostree.yaml new file mode 100644 index 0000000..c93ecbe --- /dev/null +++ b/manifests/bootable-rpm-ostree.yaml @@ -0,0 +1,53 @@ +# This minimal base starts just from: kernel + systemd + rpm-ostree + bootloader. +# The intent of this is to inherit from this if you are doing something highly +# custom that e.g. might not involve Ignition or podman, but you do want +# rpm-ostree. +# We expect most people though using coreos-assembler to inherit from +# fedora-coreos-base.yaml. +packages: + # Kernel + systemd. + - kernel systemd + # linux-firmware now a recommends so let's explicitly include it + # https://gitlab.com/cki-project/kernel-ark/-/commit/32271d0cd9bd52d386eb35497c4876a8f041f70b + # https://src.fedoraproject.org/rpms/kernel/c/f55c3e9ed8605ff28cb9a922efbab1055947e213?branch=rawhide + - linux-firmware + # rpm-ostree + - rpm-ostree nss-altfiles + +# bootloader +packages-aarch64: + - grub2-efi-aa64 efibootmgr shim + # firmware updates + - fwupd +packages-ppc64le: + - grub2 ostree-grub2 + # firmware updates + - fwupd +packages-s390x: + # On Fedora, this is provided by s390utils-core. on RHEL, this is for now + # provided by s390utils-base, but soon will be -core too. + - /usr/sbin/zipl + # for Secure Execution + - veritysetup +packages-x86_64: + - grub2 grub2-efi-x64 efibootmgr shim + - microcode_ctl + # firmware updates + - fwupd + +postprocess: + # See: https://github.com/coreos/fedora-coreos-tracker/issues/1253 + # https://bugzilla.redhat.com/show_bug.cgi?id=2112857 + # https://github.com/coreos/rpm-ostree/issues/3918 + # Temporary workaround to remove the SetGID binary from liblockfile that is + # pulled by the s390utils but not needed for /usr/sbin/zipl. + - | + #!/usr/bin/env bash + set -xeuo pipefail + rm -f /usr/bin/dotlockfile + +exclude-packages: + # Exclude kernel-debug-core to make sure that it doesn't somehow get + # chosen as the package to satisfy the `kernel-core` dependency from + # the kernel package. + - kernel-debug-core diff --git a/manifests/bootupd.yaml b/manifests/bootupd.yaml new file mode 100644 index 0000000..ca8c5de --- /dev/null +++ b/manifests/bootupd.yaml @@ -0,0 +1,13 @@ +# Integration with https://github.com/coreos/bootupd +# xref https://github.com/coreos/fedora-coreos-tracker/issues/510 +packages: + - bootupd + +postprocess: + - | + #!/bin/bash + set -xeuo pipefail + # Until we have https://github.com/coreos/rpm-ostree/pull/2275 + mkdir -p /run + # Transforms /usr/lib/ostree-boot into a bootupd-compatible update payload + /usr/bin/bootupctl backend generate-update-metadata / diff --git a/manifests/fallback-hostname.yaml b/manifests/fallback-hostname.yaml new file mode 100644 index 0000000..f3bc6b4 --- /dev/null +++ b/manifests/fallback-hostname.yaml @@ -0,0 +1,11 @@ +postprocess: + # Set the fallback hostname to `localhost`. This can be removed + # once we are based on Fedora 37+. + # See https://github.com/coreos/fedora-coreos-tracker/issues/902 + - | + #!/usr/bin/env bash + set -euxo pipefail + source /etc/os-release + if [ -z "${DEFAULT_HOSTNAME:-}" ]; then + echo 'DEFAULT_HOSTNAME=localhost' >> /usr/lib/os-release + fi diff --git a/manifests/group b/manifests/group new file mode 100644 index 0000000..2fd197c --- /dev/null +++ b/manifests/group @@ -0,0 +1,46 @@ +root:x:0: +bin:x:1: +daemon:x:2: +sys:x:3: +adm:x:4: +tty:x:5: +disk:x:6: +lp:x:7: +mem:x:8: +kmem:x:9: +wheel:x:10: +cdrom:x:11: +mail:x:12: +man:x:15: +sudo:x:16: +dialout:x:18: +floppy:x:19: +games:x:20: +tape:x:33: +video:x:39: +ftp:x:50: +lock:x:54: +audio:x:63: +nobody:x:99: +users:x:100: +ssh_keys:x:999: +systemd-journal:x:190: +polkitd:x:998: +etcd:x:997: +dip:x:40: +cgred:x:996: +avahi-autoipd:x:170: +sssd:x:993: +dockerroot:x:986: +rpcuser:x:29: +nfsnobody:x:65534: +kube:x:994: +chrony:x:992: +tcpdump:x:72: +ceph:x:167: +input:x:104: +systemd-timesync:x:991: +systemd-network:x:990: +systemd-resolve:x:989: +systemd-bus-proxy:x:988: +cockpit-ws:x:987: diff --git a/manifests/grub2-removals.yaml b/manifests/grub2-removals.yaml new file mode 100644 index 0000000..d87ec01 --- /dev/null +++ b/manifests/grub2-removals.yaml @@ -0,0 +1,9 @@ +remove-from-packages: + # The grub bits are mainly designed for desktops, and IMO haven't seen + # enough testing in concert with ostree. At some point we'll flesh out + # the full plan in https://github.com/coreos/fedora-coreos-tracker/issues/47 + - [grub2-tools, /etc/grub.d/08_fallback_counting, + /etc/grub.d/10_reset_boot_success, + /etc/grub.d/12_menu_auto_hide, + /usr/lib/systemd/.*] + diff --git a/manifests/ignition-and-ostree.yaml b/manifests/ignition-and-ostree.yaml new file mode 100644 index 0000000..8416a6d --- /dev/null +++ b/manifests/ignition-and-ostree.yaml @@ -0,0 +1,44 @@ +# Defines the "core" of a Fedora CoreOS like system; basically (ignition, ostree) +# plus other default tweaks. Things in this file should be something we expect +# basically everyone using both Ignition and (rpm-)ostree to want. +# It may be used as an inheritance base by other projects like Fedora Silverblue or RHCOS. +# One good model is to add fedora-coreos-config as a git submodule. See: +# https://github.com/coreos/coreos-assembler/pull/639 + +# Include rpm-ostree + kernel + bootloader +include: bootable-rpm-ostree.yaml + +# Modern defaults we want +boot-location: modules +tmp-is-dir: true + +# Required by Ignition, and makes the system not compatible with Anaconda +machineid-compat: false + +packages: + - ignition + - dracut-network + # for encryption + - clevis clevis-luks clevis-dracut clevis-systemd + +remove-from-packages: + # We don't want systemd-firstboot.service. It conceptually conflicts with + # Ignition. We also inject runtime bits to disable it in systemd-firstboot.service.d/fcos-disable.conf + # to make it easier to use systemd builds from git. + - [systemd, /usr/bin/systemd-firstboot, + /usr/lib/systemd/system/systemd-firstboot.service, + /usr/lib/systemd/system/sysinit.target.wants/systemd-firstboot.service] + # We don't want auto-generated mount units. See also + # https://github.com/systemd/systemd/issues/13099 + - [systemd-udev, /usr/lib/systemd/system-generators/systemd-gpt-auto-generator] + +postprocess: + # Undo RPM scripts enabling units; we want the presets to be canonical + # https://github.com/projectatomic/rpm-ostree/issues/1803 + - | + #!/usr/bin/env bash + set -xeuo pipefail + rm -rf /etc/systemd/system/* + systemctl preset-all + rm -rf /etc/systemd/user/* + systemctl --user --global preset-all diff --git a/manifests/passwd b/manifests/passwd new file mode 100644 index 0000000..8b00e55 --- /dev/null +++ b/manifests/passwd @@ -0,0 +1,40 @@ +root:x:0:0:root:/root:/bin/bash +bin:x:1:1:bin:/bin:/sbin/nologin +daemon:x:2:2:daemon:/sbin:/sbin/nologin +adm:x:3:4:adm:/var/adm:/sbin/nologin +lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin +sync:x:5:0:sync:/sbin:/bin/sync +shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown +halt:x:7:0:halt:/sbin:/sbin/halt +adm:x:3:4:adm:/var/adm:/usr/sbin/nologin +avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/usr/sbin/nologin +bin:x:1:1:bin:/bin:/usr/sbin/nologin +ceph:x:167:167:Ceph daemons:/var/lib/ceph:/usr/sbin/nologin +chrony:x:994:992::/var/lib/chrony:/usr/sbin/nologin +cockpit-ws:x:988:987:User for cockpit-ws:/:/usr/sbin/nologin +daemon:x:2:2:daemon:/sbin:/usr/sbin/nologin +dbus:x:81:81:System Message Bus:/:/usr/sbin/nologin +dockerroot:x:997:986:Docker User:/var/lib/docker:/usr/sbin/nologin +etcd:x:998:997:etcd user:/var/lib/etcd:/usr/sbin/nologin +ftp:x:14:50:FTP User:/var/ftp:/usr/sbin/nologin +games:x:12:100:games:/usr/games:/usr/sbin/nologin +halt:x:7:0:halt:/sbin:/sbin/halt +kube:x:996:994:Kubernetes user:/:/usr/sbin/nologin +lp:x:4:7:lp:/var/spool/lpd:/usr/sbin/nologin +mail:x:8:12:mail:/var/spool/mail:/usr/sbin/nologin +nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/usr/sbin/nologin +nobody:x:99:99:Kernel Overflow User:/:/usr/sbin/nologin +operator:x:11:0:operator:/root:/usr/sbin/nologin +polkitd:x:999:998:User for polkitd:/:/usr/sbin/nologin +root:x:0:0:Super User:/root:/bin/bash +rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/usr/sbin/nologin +rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/usr/sbin/nologin +shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown +sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/usr/sbin/nologin +sssd:x:995:993:User for sssd:/:/usr/sbin/nologin +sync:x:5:0:sync:/sbin:/bin/sync +systemd-bus-proxy:x:989:988:systemd Bus Proxy:/:/usr/sbin/nologin +systemd-network:x:991:990:systemd Network Management:/:/usr/sbin/nologin +systemd-resolve:x:990:989:systemd Resolver:/:/usr/sbin/nologin +systemd-timesync:x:993:991:systemd Time Synchronization:/:/usr/sbin/nologin +tcpdump:x:72:72::/:/usr/sbin/nologin diff --git a/manifests/rocky-coreos-base.yaml b/manifests/rocky-coreos-base.yaml new file mode 100644 index 0000000..5615a19 --- /dev/null +++ b/manifests/rocky-coreos-base.yaml @@ -0,0 +1,60 @@ +# Inherits from "Core" + + +include: + - ignition-and-ostree.yaml + - shared-workarounds.yaml + - system-configuration.yaml + - user-experience.yaml + +conditional-include: + - if: releasever <= 8 + include: fallback-hostname.yaml + +ostree-layers: + - overlay/05core + - overlay/08nouveau + - overlay/09misc + - overlay/20platform-chrony + + +recommends: false +packages: + - rpm + - policycoreutils + - kernel + - kernel-modules-extra + - rpm-ostree + - ostree-grub2 + - selinux-policy-targeted + - biosdevname + - keyutils + - binutils + - nss-altfiles + - polkit + - coreos-installer + +ignore-removed-users: + - root +ignore-removed-groups: + - root +etc-group-members: + - wheel + - sudo + - systemd-journal + - adm + - docker + +check-passwd: + type: "file" + filename: "passwd" +check-groups: + type: "file" + filename: "group" + +# See https://github.com/coreos/bootupd +arch-include: + x86_64: bootupd.yaml + aarch64: bootupd.yaml + +default-target: multi-user.target diff --git a/manifests/rocky-coreos.yaml b/manifests/rocky-coreos.yaml new file mode 100644 index 0000000..86929df --- /dev/null +++ b/manifests/rocky-coreos.yaml @@ -0,0 +1,60 @@ +ref: rocky/${basearch}/ostree/${stream} +rojig: + name: rocky-ostree + summary: "Rocky Linux OSTree ${stream}" + license: MIT + +add-commit-metadata: + rocky-core.stream: ${stream} + +include: + - rocky-coreos-base.yaml + +conditional-include: + - if: basearch != "s390x" + # And remove some cruft from grub2 + include: grub2-removals.yaml + +ostree-layers: + - overlay/15fcos + +automatic-version-prefix: "${releasever}..dev" +mutate-os-release: "${releasever}" + +remove-from-packages: + # Drop NetworkManager support for ifcfg files, see also corresponding + # overlay.d/14NetworkManager-plugins + - [NetworkManager, /usr/lib64/NetworkManager/.*/libnm-settings-plugin-ifcfg-rh.so] + # Drop some buggy sysusers fragments which do not match static IDs allocation: + # https://bugzilla.redhat.com/show_bug.cgi?id=2105177 + # - [dbus-common, /usr/lib/sysusers.d/dbus.conf] + +remove-files: + # We don't ship man(1) or info(1) + - usr/share/info + - usr/share/man + # Drop text docs too + - usr/share/doc + +# Things we don't expect to ship on the host. We currently +# have recommends: false so these could only come in via +# hard requirement, in which case the build will fail. +exclude-packages: + - python + - python2 + - python2-libs + # - python3 + # - python3-libs + - perl + - perl-interpreter + - nodejs + - dnf + - grubby + - cowsay # Just in case + # Let's make sure initscripts doesn't get pulled back in + # https://github.com/coreos/fedora-coreos-tracker/issues/220#issuecomment-611566254 + - initscripts + # For (datacenter/cloud oriented) servers, we want to see the details by default. + # https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/HSMISZ3ETWQ4ETVLWZQJ55ARZT27AAV3/ + - plymouth + diff --git a/manifests/shared-el9.yaml b/manifests/shared-el9.yaml new file mode 100644 index 0000000..ad15bdc --- /dev/null +++ b/manifests/shared-el9.yaml @@ -0,0 +1,11 @@ +# These are packages that are shared between FCOS and +# RHCOS/SCOS 9+ + +packages: + # SSH + - ssh-key-dir + - zstd + +ostree-layers: + - overlay/06el9 + diff --git a/manifests/shared-workarounds.yaml b/manifests/shared-workarounds.yaml new file mode 100644 index 0000000..42fd4e2 --- /dev/null +++ b/manifests/shared-workarounds.yaml @@ -0,0 +1,35 @@ +# This manifest is a list of shared workarounds that are needed in both Fedora CoreOS +# and downstreams (i.e. Red Hat CoreOS). + +postprocess: + # Put in the fix for multipathd.service in dracut on releases that haven't + # been fixed yet. + # https://github.com/dracutdevs/dracut/pull/1606 + # https://github.com/coreos/fedora-coreos-config/pull/1233 + - | + #!/usr/bin/env bash + set -xeuo pipefail + source /etc/os-release + # This has landed in Fedora but not in any version of RHEL yet + if [[ ${ID} != "rocky" ]]; then + exit 0 + fi + mkdir /usr/lib/dracut/modules.d/36coreos-multipath-fix + cat > /usr/lib/dracut/modules.d/36coreos-multipath-fix/90-multipathd-remove-execstop.conf <<'EOF' + # Temporary workaround for https://github.com/dracutdevs/dracut/pull/1606. + [Service] + ExecStop= + EOF + cat > /usr/lib/dracut/modules.d/36coreos-multipath-fix/module-setup.sh <<'EOF' + #!/bin/bash + # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- + # ex: ts=8 sw=4 sts=4 et filetype=sh + install() { + # Temporary workaround for https://github.com/dracutdevs/dracut/pull/1606. + mkdir -p "$systemdsystemunitdir/multipathd.service.d" + inst_simple "$moddir/90-multipathd-remove-execstop.conf" \ + "$systemdsystemunitdir/multipathd.service.d/90-multipathd-remove-execstop.conf" + } + EOF + chmod +x /usr/lib/dracut/modules.d/36coreos-multipath-fix/module-setup.sh + diff --git a/manifests/system-configuration.yaml b/manifests/system-configuration.yaml new file mode 100644 index 0000000..e8f48d0 --- /dev/null +++ b/manifests/system-configuration.yaml @@ -0,0 +1,50 @@ +# These are packages that are related to configuring parts of the system. +# It is intended to be kept generic so that it may be shared downstream with +# RHCOS. + +packages: + # Configuring SSH keys, cloud provider check-in, etc + - afterburn afterburn-dracut + # NTP support + - chrony + # Installing CoreOS itself + - coreos-installer coreos-installer-bootinfra + # Storage configuration/management + ## cloud-utils-growpart - For growing root partition + - cifs-utils + - cloud-utils-growpart + - cryptsetup + - device-mapper-multipath + - e2fsprogs + - iscsi-initiator-utils + - lvm2 + - mdadm + - sg3_utils + - xfsprogs + # User configuration + - passwd + - shadow-utils + - acl + # SELinux policy + - selinux-policy-targeted + # There are things that write outside of the journal still (such as the + # classic wtmp, etc.). auditd also writes outside the journal but it has its + # own log rotation. + # Anything package layered will also tend to expect files dropped in + # /etc/logrotate.d to work. Really, this is a legacy thing, but if we don't + # have it then people's disks will slowly fill up with logs. + - logrotate + # Boost starving threads + # https://github.com/coreos/fedora-coreos-tracker/issues/753 + - stalld + +postprocess: + # Make kdump work on firstboot + - | + #!/usr/bin/env bash + # Make kdump ignore `ignition.firstboot` when copying kargs from + # the running kernel to the kdump kernel when passing to be kexec. + # This makes it so kdump can be set up on the very first boot. + # Upstream request to have this upstream so we can stop carrying it here: + # https://lists.fedoraproject.org/archives/list/kexec@lists.fedoraproject.org/thread/5P4WIJLW2TSGF4PZGRZGOXYML4RXZU23/ + sed -i -e 's/KDUMP_COMMANDLINE_REMOVE="/KDUMP_COMMANDLINE_REMOVE="ignition.firstboot /' /etc/sysconfig/kdump diff --git a/manifests/user-experience.yaml b/manifests/user-experience.yaml new file mode 100644 index 0000000..33ccd6b --- /dev/null +++ b/manifests/user-experience.yaml @@ -0,0 +1,47 @@ +# This file is included in RHEL CoreOS, see +# https://github.com/openshift/os/blob/71c974b1e456292033e3ef3fe7bcfe17d1855ebc/manifest.yaml#L12 +# Only apply changes here that should apply to both FCOS and RHCOS. + +# Default to `bash` in our container, the same as other containers we ship. +container-cmd: + - /usr/bin/bash + +# These packages are either widely used utilities/services or +# are targeted for improving the general CoreOS user experience. +# It is intended to be kept generic so that it may be shared downstream with +# RHCOS. +packages: + # Basic user tools + ## jq - parsing/interacting with JSON data + - bash-completion + - coreutils + - file + - jq + - less + - sudo + - vim-minimal + # File compression/decompression + ## bsdtar - dependency of 35coreos-live dracut module + - bsdtar + - bzip2 + - gzip + - tar + - xz + - zstd + # Improved MOTD experience + - console-login-helper-messages-issuegen + - console-login-helper-messages-profile + # kdump support + # https://github.com/coreos/fedora-coreos-tracker/issues/622 + - kexec-tools + # Remote Access + - openssh-clients openssh-server + # Container tooling + - crun + - podman + - runc + - skopeo + - toolbox + # nvme-cli for managing nvme disks + - nvme-cli + - rpaste diff --git a/overlay.d/05core/etc/security/pwquality.conf.d/20-disable-dict.conf b/overlay.d/05core/etc/security/pwquality.conf.d/20-disable-dict.conf new file mode 100644 index 0000000..e946311 --- /dev/null +++ b/overlay.d/05core/etc/security/pwquality.conf.d/20-disable-dict.conf @@ -0,0 +1,3 @@ +# We don't ship cracklib dicts, so don't try to use them to validate +# password changes. +dictcheck = 0 diff --git a/overlay.d/05core/etc/sudoers.d/coreos-sudo-group b/overlay.d/05core/etc/sudoers.d/coreos-sudo-group new file mode 100644 index 0000000..2b3669d --- /dev/null +++ b/overlay.d/05core/etc/sudoers.d/coreos-sudo-group @@ -0,0 +1,2 @@ +# https://github.com/openshift/os/issues/96 +%sudo ALL=(ALL) NOPASSWD: ALL diff --git a/overlay.d/05core/statoverride b/overlay.d/05core/statoverride new file mode 100644 index 0000000..9769b8c --- /dev/null +++ b/overlay.d/05core/statoverride @@ -0,0 +1,6 @@ +# Config file for overriding permission bits on overlay files/dirs +# Format: = + +# Some security scanners complain if /etc/sudoers.d files have 0044 mode bits +# https://bugzilla.redhat.com/show_bug.cgi?id=1981979 +=384 /etc/sudoers.d/coreos-sudo-group diff --git a/overlay.d/05core/usr/lib/NetworkManager/conf.d/20-client-id-from-mac.conf b/overlay.d/05core/usr/lib/NetworkManager/conf.d/20-client-id-from-mac.conf new file mode 100644 index 0000000..320ea4a --- /dev/null +++ b/overlay.d/05core/usr/lib/NetworkManager/conf.d/20-client-id-from-mac.conf @@ -0,0 +1,2 @@ +[connection] +ipv4.dhcp-client-id=mac diff --git a/overlay.d/05core/usr/lib/coreos/generator-lib.sh b/overlay.d/05core/usr/lib/coreos/generator-lib.sh new file mode 100644 index 0000000..dd19ad8 --- /dev/null +++ b/overlay.d/05core/usr/lib/coreos/generator-lib.sh @@ -0,0 +1,30 @@ +# File intended to be sourced by shell script generators shipped with CoreOS systems + +# Generators don't have logging right now +# https://github.com/systemd/systemd/issues/15638 +exec 1>/dev/kmsg; exec 2>&1 + +UNIT_DIR="${1:-/tmp}" + +have_karg() { + local arg="$1" + local cmdline=( $( "$initdir/etc/sysctl.d/10-dont-ratelimit-kmsg.conf" +} diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/25coreos-azure-udev/module-setup.sh b/overlay.d/05core/usr/lib/dracut/modules.d/25coreos-azure-udev/module-setup.sh new file mode 100644 index 0000000..e796e89 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/25coreos-azure-udev/module-setup.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +# We want to provide Azure udev rules as part of the initrd, so that Ignition +# is able to detect disks and act on them. +# +# If the WALinuxAgent-udev package is changed to install the udev rules as +# part of the initramfs, we should drop this module. +# +# See https://bugzilla.redhat.com/show_bug.cgi?id=1909287 +# See also https://bugzilla.redhat.com/show_bug.cgi?id=1756173 + +install() { + inst_multiple \ + /usr/lib/udev/rules.d/66-azure-storage.rules \ + /usr/lib/udev/rules.d/99-azure-product-uuid.rules +} diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-boot-edit.service b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-boot-edit.service new file mode 100644 index 0000000..b51059f --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-boot-edit.service @@ -0,0 +1,26 @@ +# This unit will run late in the initrd process after Ignition is completed +# successfully and temporarily mount /boot read-write to make edits +# (e.g. removing firstboot networking configuration files if necessary). + +[Unit] +Description=CoreOS Boot Edit +ConditionPathExists=/usr/lib/initrd-release +OnFailure=emergency.target +OnFailureJobMode=isolate + +# Since we are mounting /boot, require the device first. This isn't strictly +# necessary since we run late, but on principle let's make clear the dependency. +Requires=dev-disk-by\x2dlabel-boot.device +After=dev-disk-by\x2dlabel-boot.device +# Start after Ignition has finished +After=ignition-files.service +# As above, this isn't strictly necessary, but on principle. +After=coreos-multipath-wait.target + +[Service] +Type=oneshot +ExecStart=/usr/sbin/coreos-boot-edit +RemainAfterExit=yes +# MountFlags=slave is so the umount of /boot is guaranteed to happen. +# /boot will only be mounted for the lifetime of the unit. +MountFlags=slave diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-boot-edit.sh b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-boot-edit.sh new file mode 100755 index 0000000..4116f03 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-boot-edit.sh @@ -0,0 +1,51 @@ +#!/bin/bash +set -euo pipefail + +# For a description of how this is used, see `coreos-boot-edit.service`. + +cmdline=( $(&2 + exit 1 + fi + rdcore kargs --boot-mount ${bootmnt} --append boot=UUID=${UUID} + # but also put it in /run for the first boot real root mount + mkdir -p /run/coreos + echo "${UUID}" > /run/coreos/bootfs_uuid +fi diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-diskful-generator b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-diskful-generator new file mode 100755 index 0000000..8c41621 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-diskful-generator @@ -0,0 +1,60 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +# Originally this was known as 'ignition-generator' found in ignition-dracut. +# With Ignition v 2.5.0, ignition-dracut was merged into Ignition and the CoreOS +# specific bits were deposited here. + +set -e + +# Generators don't have logging right now +# https://github.com/systemd/systemd/issues/15638 +exec 1>/dev/kmsg; exec 2>&1 + +UNIT_DIR="${1:-/tmp}" + +cmdline=( $( "${UNIT_DIR}/coreos-ignition-setup-user.service.d/diskful.conf" <&2 + exit 1 + fi +else + /usr/bin/rdcore kargs --boot-device /dev/disk/by-label/boot --create-if-changed /run/coreos-kargs-reboot "$@" +fi diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-teardown-initramfs.service b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-teardown-initramfs.service new file mode 100644 index 0000000..060530e --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-teardown-initramfs.service @@ -0,0 +1,38 @@ +# Clean up the initramfs networking on first boot +# so the real network is being brought up +# https://github.com/coreos/fedora-coreos-tracker/issues/394#issuecomment-599721763 + +[Unit] +Description=CoreOS Tear Down Initramfs +DefaultDependencies=false + +# We want to run the teardown after all other Ignition stages +# have run because some platforms (like Packet) do remote status +# reporting for each Ignition stage. Since we are tearing down +# the networking using an ExecStop we need to make sure we run +# the ExecStop *after* any other ignition*.service unit's ExecStop. +# The only other one right now is ignition-mount that has an ExecStop +# for doing an unmount. Since the ordering for ExecStop is the +# opposite of ExecStart we need to use `Before=ignition-mount.service`. +# https://github.com/coreos/fedora-coreos-tracker/issues/440 +Before=ignition-mount.service +Before=ignition-complete.target + +# Make sure ExecStop= runs before we switch root +Conflicts=initrd-switch-root.target umount.target +Before=initrd-switch-root.target + +OnFailure=emergency.target +OnFailureJobMode=isolate + +# If we are already heading towards emergency.target +# then don't try to stop this unit because it will fail +# when trying to access files in /sysroot/etc/. The failure +# is mostly harmless but having the extra error messages +# leads us away from the original problem. +IgnoreOnIsolate=true + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStop=/usr/sbin/coreos-teardown-initramfs diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-teardown-initramfs.sh b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-teardown-initramfs.sh new file mode 100755 index 0000000..7f8135a --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-teardown-initramfs.sh @@ -0,0 +1,216 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +set -euo pipefail + +# Load dracut libraries. Using getargbool() and getargs() from +# dracut-lib and ip_to_var() from net-lib +load_dracut_libs() { + # dracut is not friendly to set -eu + set +euo pipefail + type getargbool &>/dev/null || . /lib/dracut-lib.sh + type ip_to_var &>/dev/null || . /lib/net-lib.sh + set -euo pipefail +} + +dracut_func() { + # dracut is not friendly to set -eu + set +euo pipefail + "$@"; local rc=$? + set -euo pipefail + return $rc +} + +# Determine if the generated NM connection profiles match the default +# that would be given to us if the user had provided no additional +# configuration. i.e. did the user give us any network configuration +# other than the default? We determine this by comparing the generated +# output of nm-initrd-generator with a new run of nm-initrd-generator. +# If it matches then it was the default, if not then the user provided +# something extra. +are_default_NM_configs() { + # pick up our CoreOS default networking kargs from the afterburn dropin + DEFAULT_KARGS_FILE=/usr/lib/systemd/system/afterburn-network-kargs.service.d/50-afterburn-network-kargs-default.conf + source <(grep -o 'AFTERBURN_NETWORK_KARGS_DEFAULT=.*' $DEFAULT_KARGS_FILE) + # Make two dirs for storing files to use in the comparison + mkdir -p /run/coreos-teardown-initramfs/connections-compare-{1,2} + # Make another that's just a throwaway for the initrd-data-dir + mkdir -p /run/coreos-teardown-initramfs/initrd-data-dir + # Copy over the previously generated connection(s) profiles + cp /run/NetworkManager/system-connections/* \ + /run/coreos-teardown-initramfs/connections-compare-1/ + # Do a new run with the default input + /usr/libexec/nm-initrd-generator \ + -c /run/coreos-teardown-initramfs/connections-compare-2 \ + -i /run/coreos-teardown-initramfs/initrd-data-dir -- $AFTERBURN_NETWORK_KARGS_DEFAULT + # remove unique identifiers from the files (so our diff can work) + sed -i '/^uuid=/d' /run/coreos-teardown-initramfs/connections-compare-{1,2}/* + # currently the output will differ based on whether rd.neednet=1 + # was part of the kargs. Let's ignore the single difference (wait-device-timeout) + sed -i '/^wait-device-timeout=/d' /run/coreos-teardown-initramfs/connections-compare-{1,2}/* + if diff -r -q /run/coreos-teardown-initramfs/connections-compare-{1,2}/; then + rc=0 # They are the default configs + else + rc=1 # They are not the defaults, user must have added configuration + fi + rm -rf /run/coreos-teardown-initramfs + return $rc +} + +# Propagate initramfs networking if desired. The policy here is: +# +# - If a networking configuration was provided before this point +# (most likely via Ignition) and exists in the real root then +# we do nothing and don't propagate any initramfs networking. +# - If a user did not provide any networking configuration +# then we'll propagate the initramfs networking configuration +# into the real root, but only if it's different than the NM +# defaults (trying dhcp/dhcp6 on everything). If it's just the +# defaults then we want to avoid a slight behavior diff between +# propagating configs and just booting with no configuration. See +# https://github.com/coreos/fedora-coreos-tracker/issues/696 +# +# See https://github.com/coreos/fedora-coreos-tracker/issues/394#issuecomment-599721173 +propagate_initramfs_networking() { + # Check for any real root config in the two locations where a user could have + # provided network configuration. On FCOS we only support keyfiles, but on RHCOS + # we support keyfiles and ifcfg + if [ -n "$(ls -A /sysroot/etc/NetworkManager/system-connections/)" -o \ + -n "$(ls -A /sysroot/etc/sysconfig/network-scripts/)" ]; then + echo "info: networking config is defined in the real root" + realrootconfig=1 + else + echo "info: no networking config is defined in the real root" + realrootconfig=0 + fi + + # Did the user tell us to force initramfs networking config + # propagation even if real root networking config exists? + # Hopefully we only need this in rare circumstances. + # https://github.com/coreos/fedora-coreos-tracker/issues/853 + forcepropagate=0 + if dracut_func getargbool 0 'coreos.force_persist_ip'; then + forcepropagate=1 + echo "info: coreos.force_persist_ip detected: will force network config propagation" + fi + + if [ $realrootconfig == 1 -a $forcepropagate == 0 ]; then + echo "info: will not attempt to propagate initramfs networking" + fi + + if [ $realrootconfig == 0 -o $forcepropagate == 1 ]; then + if [ -n "$(ls -A /run/NetworkManager/system-connections/)" ]; then + if are_default_NM_configs; then + echo "info: skipping propagation of default networking configs" + else + echo "info: propagating initramfs networking config to the real root" + cp -v /run/NetworkManager/system-connections/* /sysroot/etc/NetworkManager/system-connections/ + coreos-relabel /etc/NetworkManager/system-connections/ + fi + else + echo "info: no initramfs networking information to propagate" + fi + fi +} + +# Propagate the ip= karg hostname if desired. The policy here is: +# +# - IF a hostname was detected in ip= kargs by NetworkManager +# - AND no hostname was set via Ignition (realroot `/etc/hostname`) +# - THEN we make the hostname detected by NM apply permanently +# by writing it into `/etc/hostname` +# +propagate_initramfs_hostname() { + if [ -e '/sysroot/etc/hostname' ]; then + echo "info: hostname is defined in the real root" + echo "info: will not attempt to propagate initramfs hostname" + return 0 + fi + + # If any hostname was provided NetworkManager will write it out to + # /run/NetworkManager/initrd/hostname. See + # https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/481 + if [ -s /run/NetworkManager/initrd/hostname ]; then + hostname=$( /sysroot/etc/hostname + coreos-relabel /etc/hostname + else + echo "info: no initramfs hostname information to propagate" + fi +} + +down_interface() { + echo "info: taking down network device: $1" + # On recommendation from the NM team let's try to delete the device + # first and if that doesn't work then set it to down and flush any + # associated addresses. Deleting virtual devices (bonds, teams, bridges, + # ip-tunnels, etc) will clean up any associated kernel resources. A real + # device can't be deleted so that will fail and we'll fallback to setting + # it down and flushing addresses. + if ! ip link delete $1; then + ip link set $1 down + ip addr flush dev $1 + fi +} + +# Iterate through the interfaces in the machine and take them down. +# Note that in the futre we would like to possibly use `nmcli` networking off` +# for this. See the following two comments for details: +# https://github.com/coreos/fedora-coreos-tracker/issues/394#issuecomment-599721763 +# https://github.com/coreos/fedora-coreos-tracker/issues/394#issuecomment-599746049 +down_interfaces() { + if ! [ -z "$(ls /sys/class/net)" ]; then + for f in /sys/class/net/*; do + interface=$(basename "$f") + # The `bonding_masters` entry is not a true interface and thus + # cannot be taken down. Also skip local loopback + case "$interface" in + "lo" | "bonding_masters") + continue + ;; + esac + # When we start taking down devices some other devices can + # start to disappear (for example vlan on top of interface). + # If the device we're about to take down has disappeared + # since the start of this loop then skip taking it down. + if [ ! -e "$f" ]; then + echo "info: skipping teardown of ${interface}; no longer exists." + continue + fi + down_interface $interface + done + fi +} + +main() { + # Load libraries from dracut + load_dracut_libs + + # Take down all interfaces set up in the initramfs + down_interfaces + + # Clean up all routing + echo "info: flushing all routing" + ip route flush table main + ip route flush cache + + # Hopefully our logic is sound enough that this is never needed, but + # user's can explicitly disable initramfs network/hostname propagation + # with the coreos.no_persist_ip karg. + if dracut_func getargbool 0 'coreos.no_persist_ip'; then + echo "info: coreos.no_persist_ip karg detected" + echo "info: skipping propagating initramfs settings" + else + propagate_initramfs_hostname + propagate_initramfs_networking + fi + + # Now that the configuration has been propagated (or not) + # clean it up so that no information from outside of the + # real root is passed on to NetworkManager in the real root + rm -rf /run/NetworkManager/ +} + +main diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/module-setup.sh b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/module-setup.sh new file mode 100755 index 0000000..a42bcc3 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/module-setup.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +depends() { + echo systemd network ignition coreos-live +} + +install_ignition_unit() { + local unit="$1"; shift + local target="${1:-ignition-complete.target}"; shift + local instantiated="${1:-$unit}"; shift + inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit" + # note we `|| exit 1` here so we error out if e.g. the units are missing + # see https://github.com/coreos/fedora-coreos-config/issues/799 + systemctl -q --root="$initdir" add-requires "$target" "$instantiated" || exit 1 +} + +install() { + inst_multiple \ + basename \ + diff \ + lsblk \ + sed \ + sgdisk + + inst_simple "$moddir/coreos-diskful-generator" \ + "$systemdutildir/system-generators/coreos-diskful-generator" + + inst_script "$moddir/coreos-gpt-setup.sh" \ + "/usr/sbin/coreos-gpt-setup" + + inst_script "$moddir/coreos-ignition-setup-user.sh" \ + "/usr/sbin/coreos-ignition-setup-user" + + # For consistency tear down the network and persist multipath between the initramfs and + # real root. See https://github.com/coreos/fedora-coreos-tracker/issues/394#issuecomment-599721763 + inst_script "$moddir/coreos-teardown-initramfs.sh" \ + "/usr/sbin/coreos-teardown-initramfs" + install_ignition_unit coreos-teardown-initramfs.service + + # units only started when we have a boot disk + # path generated by systemd-escape --path /dev/disk/by-label/root + install_ignition_unit coreos-gpt-setup.service ignition-diskful.target + + # dracut inst_script doesn't allow overwrites and we are replacing + # the default script placed by Ignition + binpath="/usr/sbin/ignition-kargs-helper" + cp "$moddir/coreos-kargs.sh" "$initdir$binpath" + install_ignition_unit coreos-kargs-reboot.service + + inst_script "$moddir/coreos-boot-edit.sh" \ + "/usr/sbin/coreos-boot-edit" + # Only start when the system has disks since we are editing /boot. + install_ignition_unit "coreos-boot-edit.service" \ + "ignition-diskful.target" + + install_ignition_unit coreos-ignition-setup-user.service +} diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-live-clear-sssd-cache.service b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-live-clear-sssd-cache.service new file mode 100644 index 0000000..758bb61 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-live-clear-sssd-cache.service @@ -0,0 +1,18 @@ +# SSSD caches passwd data from /etc in /var. If we have a persistent /var +# but not a persistent /etc, ignition-files.service can think a user +# already exists when in fact it needs to be (re-)created. Clear the +# cache to avoid this. + +[Unit] +Description=Clear SSSD NSS cache in persistent /var +DefaultDependencies=false +ConditionPathExists=/run/ostree-live +ConditionPathExists=/sysroot/var/lib/sss/mc + +After=ignition-mount.service +Before=ignition-files.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/bin/rm -r /sysroot/var/lib/sss/mc diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-live-unmount-tmpfs-var.service b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-live-unmount-tmpfs-var.service new file mode 100644 index 0000000..de5080f --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-live-unmount-tmpfs-var.service @@ -0,0 +1,24 @@ +# If the user specified a persistent /var, ideally it'd just be mounted +# overtop of our tmpfs /var and everything would be fine. That works +# fine in the initramfs, where ignition-mount handles the mounting. +# But in the real root, the user's mount unit is ignored by systemd, +# since there's already a filesystem mounted on /var. To fix this, we +# notice that the user wants to mount /var, and unmount our tmpfs /var +# before switching roots. + +[Unit] +Description=Unmount live /var if persistent /var is configured +DefaultDependencies=false +ConditionPathExists=/run/ostree-live +ConditionPathExists=|/sysroot/etc/systemd/system/var.mount +ConditionPathExists=|/sysroot/etc/fstab +Before=initrd-switch-root.target + +# Run after Ignition mounts are unmounted, since the Ignition config +# presumably mounted overtop /sysroot/var +After=ignition-mount.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/coreos-live-unmount-tmpfs-var diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-live-unmount-tmpfs-var.sh b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-live-unmount-tmpfs-var.sh new file mode 100755 index 0000000..9b61d89 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-live-unmount-tmpfs-var.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# If the user specified a persistent /var, ideally it'd just be mounted +# overtop of our tmpfs /var and everything would be fine. That works +# fine in the initramfs, where ignition-mount handles the mounting. +# But in the real root, the user's mount unit is ignored by systemd, +# since there's already a filesystem mounted on /var. To fix this, we +# notice that the user wants to mount /var, and unmount our tmpfs /var +# before switching roots. + +set -euo pipefail + +should_unmount() { + # Did the user specify a mount unit for /var? + if [ -e /sysroot/etc/systemd/system/var.mount ]; then + return 0 + fi + + # Is there an fstab entry for /var? + if [ -e /sysroot/etc/fstab ]; then + # Uncommented entry with mountpoint on /var, without noauto in options + result=$(awk '(! /^\s*#/) && ($2 == "/var") && ($4 !~ /noauto/) {print "found"}' /sysroot/etc/fstab) + if [ -n "$result" ]; then + return 0 + fi + fi + + return 1 +} + +if should_unmount; then + echo "Unmounting /sysroot/var" + umount /sysroot/var +fi diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-liveiso-persist-osmet.service b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-liveiso-persist-osmet.service new file mode 100644 index 0000000..ea82d77 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-liveiso-persist-osmet.service @@ -0,0 +1,17 @@ +[Unit] +Description=Persist osmet files (ISO) +DefaultDependencies=false +ConditionPathExists=/run/ostree-live +ConditionKernelCommandLine=coreos.liveiso +RequiresMountsFor=/run/media/iso +# on el8, the ISO is mounted by our own systemd unit +After=run-media-iso-mount.service +Before=initrd-switch-root.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/bin/mkdir -p /run/coreos-installer/osmet +# bsdtar reads cpio archives, and unlike cpio(1L), knows how to seek over +# members it isn't reading +ExecStart=/usr/bin/bsdtar -x -C /run/coreos-installer/osmet -f /run/media/iso/images/pxeboot/rootfs.img *.osmet diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-livepxe-persist-osmet.service b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-livepxe-persist-osmet.service new file mode 100644 index 0000000..17484e6 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-livepxe-persist-osmet.service @@ -0,0 +1,14 @@ +[Unit] +Description=Persist osmet files (PXE) +DefaultDependencies=false +ConditionPathExists=/run/ostree-live +ConditionKernelCommandLine=!coreos.liveiso +# Downloads and unpacks the osmet files if not already appended +After=coreos-livepxe-rootfs.service +Before=initrd-switch-root.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/bin/mkdir -p /run/coreos-installer/osmet +ExecStart=/usr/bin/sh -c "if ls /*.osmet &>/dev/null; then cp /*.osmet /run/coreos-installer/osmet; fi" diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-livepxe-rootfs.service b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-livepxe-rootfs.service new file mode 100644 index 0000000..ed935ba --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-livepxe-rootfs.service @@ -0,0 +1,21 @@ +[Unit] +Description=Acquire live PXE rootfs image +DefaultDependencies=false +ConditionPathExists=/usr/lib/initrd-release +ConditionPathExists=/run/ostree-live +ConditionKernelCommandLine=!coreos.liveiso + +After=basic.target +# Network is enabled here +After=nm-run.service +# compat: remove when everyone is on dracut 053+ +After=dracut-initqueue.service + +# If we fail, the boot will fail. Be explicit about it. +OnFailure=emergency.target +OnFailureJobMode=isolate + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/coreos-livepxe-rootfs diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-livepxe-rootfs.sh b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-livepxe-rootfs.sh new file mode 100755 index 0000000..9f59a8d --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/coreos-livepxe-rootfs.sh @@ -0,0 +1,70 @@ +#!/bin/bash +# Ensure that a PXE-booted system has a valid rootfs. + +set -euo pipefail + +# Get rootfs_url karg +set +euo pipefail +. /usr/lib/dracut-lib.sh +rootfs_url=$(getarg coreos.live.rootfs_url=) +set -euo pipefail + +if [[ -f /etc/coreos-live-rootfs ]]; then + # rootfs image was injected via PXE. Verify that the initramfs and + # rootfs versions match. + initramfs_ver=$(cat /etc/coreos-live-initramfs) + rootfs_ver=$(cat /etc/coreos-live-rootfs) + if [[ $initramfs_ver != $rootfs_ver ]]; then + echo "Found initramfs version $initramfs_ver but rootfs version $rootfs_ver." >&2 + echo "Please fix your PXE configuration." >&2 + exit 1 + fi +elif [[ -n "${rootfs_url}" ]]; then + # rootfs URL was provided as karg. Fetch image, check its hash, and + # unpack it. + echo "Fetching rootfs image from ${rootfs_url}..." + if [[ ${rootfs_url} != http:* && ${rootfs_url} != https:* ]]; then + # Don't commit to supporting protocols we might not want to expose in + # the long term. + echo "Unsupported scheme for image specified by:" >&2 + echo "coreos.live.rootfs_url=${rootfs_url}" >&2 + echo "Only HTTP and HTTPS are supported. Please fix your PXE configuration." >&2 + exit 1 + fi + + # First, reach out to the server to verify connectivity before + # trying to download and pipe content through other programs. + # Doing this allows us to retry all errors (including transient + # "no route to host" errors during startup). Note we can't use + # curl's --retry-all-errors here because it's not in el8's curl yet. + # We retry forever, matching Ignition's semantics. + curl_common_args="--silent --show-error --insecure --location" + while ! curl --head $curl_common_args "${rootfs_url}" >/dev/null; do + echo "Couldn't establish connectivity with the server specified by:" >&2 + echo "coreos.live.rootfs_url=${rootfs_url}" >&2 + echo "Retrying in 5s..." >&2 + sleep 5 + done + + # We don't need to verify TLS certificates because we're checking the + # image hash. + # bsdtar can read cpio archives and we already depend on it for + # coreos-liveiso-persist-osmet.service, so use it instead of cpio. + # We shouldn't need a --retry here since we've just successfully HEADed the + # file, but let's add one just to be safe (e.g. if the connection just went + # online and flickers or something). + if ! curl $curl_common_args --retry 5 "${rootfs_url}" | \ + rdcore stream-hash /etc/coreos-live-want-rootfs | \ + bsdtar -xf - -C / ; then + echo "Couldn't fetch, verify, and unpack image specified by:" >&2 + echo "coreos.live.rootfs_url=${rootfs_url}" >&2 + echo "Check that the URL is correct and that the rootfs version matches the initramfs." >&2 + exit 1 + fi +else + # Nothing. Fail. + echo "No rootfs image found. Modify your PXE configuration to add the rootfs" >&2 + echo "image as a second initrd, or use the coreos.live.rootfs_url kernel parameter" >&2 + echo "to specify an HTTP or HTTPS URL to the rootfs." >&2 + exit 1 +fi diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/is-live-image.sh b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/is-live-image.sh new file mode 100755 index 0000000..318ad0b --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/is-live-image.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# Script invoked by ignition-dracut generator to detect whether this is a +# live system without a root device. We can't test for /run/ostree-live +# because it's created by a generator. +# This file is created by coreos-assembler buildextend-live. +test -f /etc/coreos-live-initramfs diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/live-generator b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/live-generator new file mode 100755 index 0000000..49b80e5 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/live-generator @@ -0,0 +1,257 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +# Generators don't have logging right now +# https://github.com/systemd/systemd/issues/15638 +exec 1>/dev/kmsg; exec 2>&1 + +command -v getarg >/dev/null || . /usr/lib/dracut-lib.sh + +set -e + +UNIT_DIR="${1:-/tmp}" + +add_requires() { + local name="$1"; shift + local target="$1"; shift + local requires_dir="${UNIT_DIR}/${target}.requires" + mkdir -p "${requires_dir}" + ln -sf "../${name}" "${requires_dir}/${name}" +} + +if ! is-live-image; then + exit 0 +fi + +# Create stamp file that everything else should use to detect a live boot +> /run/ostree-live + +add_requires sysroot.mount initrd-root-fs.target +add_requires sysroot-etc.mount initrd-root-fs.target +add_requires sysroot-var.mount initrd-root-fs.target + +mkdir -p "${UNIT_DIR}/ostree-prepare-root.service.d" +cat > "${UNIT_DIR}/ostree-prepare-root.service.d/10-live.conf" <"${UNIT_DIR}/sysroot.mount" < "${initrd_rootdev_target_d}/50-root-device.conf" <"${UNIT_DIR}/run-media-iso-mount.service" <"${UNIT_DIR}/run-media-iso.mount" <"${UNIT_DIR}/sysroot.mount" <"${UNIT_DIR}/sysroot-xfs-ephemeral-mkfs.service" <<'EOF' +[Unit] +DefaultDependencies=false +# Let's be sure we have basic devices, but other than that we +# can run really early. +After=systemd-tmpfiles-setup-dev.service +ConditionPathExists=/usr/lib/initrd-release +# Something seems to be causing us to rerun? +ConditionPathExists=!/run/ephemeral + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/bin/sh -c 'set -euo pipefail; mem=$$(($$(stat -f -c "%%b * %%s / 1024" /run))) && /bin/truncate -s $${mem}k /run/ephemeral.xfsloop' +ExecStart=/sbin/mkfs.xfs /run/ephemeral.xfsloop +ExecStart=/bin/mkdir /run/ephemeral +EOF +add_requires sysroot-xfs-ephemeral-mkfs.service initrd-root-fs.target + +cat >>"${UNIT_DIR}/run-ephemeral.mount" <"${UNIT_DIR}/sysroot-xfs-ephemeral-setup.service" < "${UNIT_DIR}/sysroot-etc.mount" +cat >>"${UNIT_DIR}/sysroot-etc.mount" <"${UNIT_DIR}/sysroot-var.mount" +cat >>"${UNIT_DIR}/sysroot-var.mount" <>"${UNIT_DIR}/sysroot-relabel.service" < /tmp/cmdline + mount --bind /tmp/cmdline /proc/cmdline + ;; + stop) + umount /proc/cmdline + rm /tmp/cmdline + ;; + *) + echo "Usage: $0 {start|stop}" >&2 + exit 1 + ;; +esac diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-multipath-generator b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-multipath-generator new file mode 100755 index 0000000..7165620 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-multipath-generator @@ -0,0 +1,30 @@ +#!/bin/bash + +# Generators don't have logging right now +# https://github.com/systemd/systemd/issues/15638 +exec 1>/dev/kmsg; exec 2>&1 + +command -v getargbool >/dev/null || . /usr/lib/dracut-lib.sh + +set -e + +if is-live-image; then + exit 0 +fi + +UNIT_DIR="${1:-/tmp}" + +add_requires() { + local name="$1"; shift + local target="$1"; shift + local requires_dir="${UNIT_DIR}/${target}.requires" + mkdir -p "${requires_dir}" + ln -sf "../${name}" "${requires_dir}/${name}" +} + +if getargbool 0 rd.multipath; then + add_requires coreos-multipath-wait.target initrd.target + if ! getargbool 0 ignition.firstboot; then + add_requires coreos-multipath-trigger.service initrd.target + fi +fi diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-multipath-trigger.service b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-multipath-trigger.service new file mode 100644 index 0000000..524dc91 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-multipath-trigger.service @@ -0,0 +1,19 @@ +# This unit is needed in the LUKS-on-multipath case on subsequent boots. When +# multipathd takes ownership of the individual paths, the by-uuid/ symlink +# which systemd-cryptsetup@.service binds to gets lost. So we retrigger udev +# here to make sure it's re-added. +# +# This is tracked at: +# https://bugzilla.redhat.com/show_bug.cgi?id=1963242 + +[Unit] +Description=CoreOS Trigger Multipath +DefaultDependencies=false +Requires=coreos-multipath-wait.target +After=coreos-multipath-wait.target +Before=cryptsetup-pre.target + +[Service] +Type=oneshot +ExecStart=/usr/sbin/udevadm trigger --settle --subsystem-match block +RemainAfterExit=yes diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-multipath-wait.target b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-multipath-wait.target new file mode 100644 index 0000000..b003f4d --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-multipath-wait.target @@ -0,0 +1,17 @@ +[Unit] +Description=CoreOS Wait For Multipathed Boot +DefaultDependencies=false +Before=dracut-initqueue.service +After=dracut-cmdline.service +Requires=dev-disk-by\x2dlabel-dm\x2dmpath\x2dboot.device +After=dev-disk-by\x2dlabel-dm\x2dmpath\x2dboot.device +Requires=multipathd.service +After=multipathd.service + +# This is already enforced transitively by coreos-gpt-setup.service, but +# let's be more explicit and list it directly here too. +Before=coreos-ignition-setup-user.service + +# This is already enforced by coreos-multipath-trigger.service, though ideally +# eventually we can get rid of that one and then we *would* need this. +Before=cryptsetup-pre.target diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-propagate-multipath-conf.service b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-propagate-multipath-conf.service new file mode 100644 index 0000000..27d1d5e --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-propagate-multipath-conf.service @@ -0,0 +1,21 @@ +[Unit] +Description=CoreOS Propagate Multipath Configuration +Before=initrd.target + +# we write to the rootfs, so run after it's ready +After=initrd-root-fs.target + +# That service starts initrd-cleanup.service which will race with us completing +# before we get nuked. Need to get to the bottom of it, but for now we need +# this (XXX: add link to systemd issue here). +Before=initrd-parse-etc.service + +ConditionKernelCommandLine=rd.multipath=default + +OnFailure=emergency.target +OnFailureJobMode=isolate + +[Service] +Type=oneshot +ExecStart=/usr/sbin/coreos-propagate-multipath-conf +RemainAfterExit=yes diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-propagate-multipath-conf.sh b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-propagate-multipath-conf.sh new file mode 100755 index 0000000..ebf0113 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/coreos-propagate-multipath-conf.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -euo pipefail + +# Persist automatic multipath configuration, if any. +# When booting with `rd.multipath=default`, the default multipath +# configuration is written. We need to ensure that the multipath configuration +# is persisted to the final target. + +if [ ! -f /sysroot/etc/multipath.conf ] && [ -f /etc/multipath.conf ]; then + echo "info: propagating automatic multipath configuration" + cp -v /etc/multipath.conf /sysroot/etc/ + mkdir -p /sysroot/etc/multipath/multipath.conf.d + coreos-relabel /etc/multipath.conf + coreos-relabel /etc/multipath/multipath.conf.d +else + echo "info: no initramfs automatic multipath configuration to propagate" +fi diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/module-setup.sh b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/module-setup.sh new file mode 100755 index 0000000..4ab4bc4 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-multipath/module-setup.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +install_ignition_unit() { + local unit=$1; shift + local target=${1:-complete} + inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit" + # note we `|| exit 1` here so we error out if e.g. the units are missing + # see https://github.com/coreos/fedora-coreos-config/issues/799 + systemctl -q --root="$initdir" add-requires "ignition-${target}.target" "$unit" || exit 1 +} + +install() { + inst_script "$moddir/coreos-propagate-multipath-conf.sh" \ + "/usr/sbin/coreos-propagate-multipath-conf" + + install_ignition_unit coreos-propagate-multipath-conf.service subsequent + + inst_simple "$moddir/coreos-multipath-generator" \ + "$systemdutildir/system-generators/coreos-multipath-generator" + + # we don't enable these; they're enabled dynamically via the generator + inst_simple "$moddir/coreos-multipath-wait.target" \ + "$systemdsystemunitdir/coreos-multipath-wait.target" + inst_simple "$moddir/coreos-multipath-trigger.service" \ + "$systemdsystemunitdir/coreos-multipath-trigger.service" +} diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/50-afterburn-network-kargs-default.conf b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/50-afterburn-network-kargs-default.conf new file mode 100644 index 0000000..8c411e5 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/50-afterburn-network-kargs-default.conf @@ -0,0 +1,7 @@ +# This contains the default kargs for firstboot network configuration. +# Default values can be dynamically overridden by platform-specific +# logic (e.g. injected via a back-channel). +# https://github.com/coreos/fedora-coreos-tracker/issues/460 + +[Service] +Environment=AFTERBURN_NETWORK_KARGS_DEFAULT='ip=auto' diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/coreos-copy-firstboot-network.service b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/coreos-copy-firstboot-network.service new file mode 100644 index 0000000..a1dd64b --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/coreos-copy-firstboot-network.service @@ -0,0 +1,65 @@ +# This unit will run early in boot and detect if: +# - In the diskful case, the user copied in firstboot networking config files +# into `/boot` (most likely by using `coreos-installer install +# --copy-network`). +# - In the live case, the user provided firstboot networking config files in +# `/etc` (most likely by using `coreos-installer iso network embed`). +# +# Since this unit is modifying network configuration there are some +# dependencies that we have: +# +# - In the diskful case, we need to look for networking configuration on the +# /boot partition +# - i.e. after /dev/disk/by-label/boot is available +# - which is implied by running after coreos-gpt-setup (see below) +# - Need to run before networking is brought up. +# - This is done in nm-initrd.service [1] +# - i.e. Before=nm-initrd.service +# - Need to make sure karg networking configuration isn't applied +# - There are two ways to do this. +# - One is to run *before* the nm-config.sh [2] that runs as part of +# dracut-cmdline [3] and `ln -sf /bin/true /usr/libexec/nm-initrd-generator`. +# - i.e. Before=dracut-cmdline.service +# - Another is to run *after* nm-config.sh [2] in dracut-cmdline [3] +# and just delete all the files created by nm-initrd-generator. +# - i.e. After=dracut-cmdline.service, but Before=nm-initrd.service +# - We'll go with the second option here because the need for the /boot +# device (mentioned above) means we can't start before dracut-cmdline.service +# +# [1] https://github.com/dracutdevs/dracut/blob/master/modules.d/35network-manager/nm-initrd.service +# [2] https://github.com/dracutdevs/dracut/blob/master/modules.d/35network-manager/nm-config.sh +# [3] https://github.com/dracutdevs/dracut/blob/master/modules.d/35network-manager/module-setup.sh#L34 +# +[Unit] +Description=Copy CoreOS Firstboot Networking Config +ConditionPathExists=/usr/lib/initrd-release +DefaultDependencies=false +# We're pulled in by ignition-complete.target; as good practice, add a matching +# Before to be explicit about it gating on this unit passing. +Before=ignition-complete.target +Before=nm-initrd.service +# compat: remove when everyone is on dracut 054+ +Before=dracut-initqueue.service +After=dracut-cmdline.service +# Any services looking at mounts need to order after this +# because it causes device re-probing. +After=coreos-gpt-setup.service +# And since the boot device may be on multipath; optionally wait for it to +# appear via the dynamic target. +After=coreos-multipath-wait.target +# Need to run after coreos-enable-network since it may re-run the NM cmdline +# hook which will generate NM configs from the network kargs, but we want to +# have precedence. +After=coreos-enable-network.service +# We've seen races with ignition-kargs.service, which accesses /boot rw. +# Let's introduce some ordering here. Need to use `Before` because otherwise +# we get a systemd ordering cycle. https://github.com/coreos/fedora-coreos-tracker/issues/883 +Before=ignition-kargs.service + +[Service] +Type=oneshot +RemainAfterExit=yes +# The MountFlags=slave is so the umount of /boot is guaranteed to happen +# /boot will only be mounted for the lifetime of the unit. +MountFlags=slave +ExecStart=/usr/sbin/coreos-copy-firstboot-network diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/coreos-copy-firstboot-network.sh b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/coreos-copy-firstboot-network.sh new file mode 100755 index 0000000..51ea283 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/coreos-copy-firstboot-network.sh @@ -0,0 +1,49 @@ +#!/bin/bash +set -euo pipefail + +# For a description of how this is used see coreos-copy-firstboot-network.service + +bootmnt=/mnt/boot_partition +bootdev=/dev/disk/by-label/boot +firstboot_network_dir_basename="coreos-firstboot-network" +boot_firstboot_network_dir="${bootmnt}/${firstboot_network_dir_basename}" +etc_firstboot_network_dir="/etc/${firstboot_network_dir_basename}" +initramfs_network_dir="/run/NetworkManager/system-connections/" + +copy_firstboot_network() { + local src=$1; shift + + # Clear out any files that may have already been generated from + # kargs by nm-initrd-generator + rm -f ${initramfs_network_dir}/* + # Copy files that were placed into the source + # to the appropriate location for NetworkManager to use the configuration. + echo "info: copying files from ${src} to ${initramfs_network_dir}" + mkdir -p ${initramfs_network_dir} + cp -v ${src}/* ${initramfs_network_dir}/ +} + +if ! is-live-image; then + # Mount /boot. Note that we mount /boot but we don't unmount boot because we + # are run in a systemd unit with MountFlags=slave so it is unmounted for us. + # Mount as read-only since we don't strictly need write access and we may be + # running alongside other code that also has it mounted ro + mkdir -p ${bootmnt} + mount -o ro ${bootdev} ${bootmnt} + + if [ -n "$(ls -A ${boot_firstboot_network_dir} 2>/dev/null)" ]; then + # Likely placed there by coreos-installer, see: + # https://github.com/coreos/coreos-installer/pull/212 + copy_firstboot_network "${boot_firstboot_network_dir}" + else + echo "info: no files to copy from ${boot_firstboot_network_dir}; skipping" + fi +else + if [ -n "$(ls -A ${etc_firstboot_network_dir} 2>/dev/null)" ]; then + # Also placed there by coreos-installer but in a different flow, see: + # https://github.com/coreos/coreos-installer/pull/713 + copy_firstboot_network "${etc_firstboot_network_dir}" + else + echo "info: no files to copy from ${etc_firstboot_network_dir}; skipping" + fi +fi diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/coreos-enable-network.service b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/coreos-enable-network.service new file mode 100644 index 0000000..92c4829 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/coreos-enable-network.service @@ -0,0 +1,30 @@ +[Unit] +Description=CoreOS Enable Network +ConditionPathExists=/etc/initrd-release +DefaultDependencies=false +After=basic.target + +# Triggering conditions for cases where we need network: +# * when Ignition signals that it is required for provisioning. +# * on live systems fetching the remote rootfs in initramfs. +# * on Azure and Azure Stack Hub, for hostname fetching (metadata endpoint) and boot check-in (wireserver). +ConditionPathExists=|/run/ignition/neednet +ConditionKernelCommandLine=|coreos.live.rootfs_url +ConditionKernelCommandLine=|ignition.platform.id=azure +ConditionKernelCommandLine=|ignition.platform.id=azurestack + +# Creates /run/ignition/neednet +After=ignition-fetch-offline.service +# Needs networking +Before=ignition-fetch.service + +# See hack in coreos-enable-network, as well as coreos-copy-firstboot-network.service. +After=dracut-cmdline.service +Before=nm-initrd.service +# compat: remove when everyone is on dracut 054+ +Before=dracut-initqueue.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/coreos-enable-network diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/coreos-enable-network.sh b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/coreos-enable-network.sh new file mode 100755 index 0000000..6c54f49 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/coreos-enable-network.sh @@ -0,0 +1,27 @@ +#!/bin/bash +set -euo pipefail + +set +euo pipefail +. /usr/lib/dracut-lib.sh +set -euo pipefail + +dracut_func() { + # dracut is not friendly to set -eu + set +euo pipefail + "$@"; local rc=$? + set -euo pipefail + return $rc +} + +# If networking hasn't been requested yet, request it. +if ! dracut_func getargbool 0 'rd.neednet'; then + echo "rd.neednet=1" > /etc/cmdline.d/40-coreos-neednet.conf + + # Hack: we need to rerun the NM cmdline hook because we run after + # dracut-cmdline.service because we need udev. We should be able to move + # away from this once we run NM as a systemd unit. See also: + # https://github.com/coreos/fedora-coreos-config/pull/346#discussion_r409843428 + set +euo pipefail + . /usr/lib/dracut/hooks/cmdline/99-nm-config.sh + set -euo pipefail +fi diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/module-setup.sh b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/module-setup.sh new file mode 100644 index 0000000..0cf3a1a --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-network/module-setup.sh @@ -0,0 +1,26 @@ +install_and_enable_unit() { + unit="$1"; shift + target="$1"; shift + inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit" + # note we `|| exit 1` here so we error out if e.g. the units are missing + # see https://github.com/coreos/fedora-coreos-config/issues/799 + systemctl -q --root="$initdir" add-requires "$target" "$unit" || exit 1 +} + +install() { + inst_simple "$moddir/coreos-enable-network.sh" \ + "/usr/sbin/coreos-enable-network" + install_and_enable_unit "coreos-enable-network.service" \ + "initrd.target" + + inst_simple "$moddir/coreos-copy-firstboot-network.sh" \ + "/usr/sbin/coreos-copy-firstboot-network" + install_and_enable_unit "coreos-copy-firstboot-network.service" \ + "ignition-complete.target" + + # Dropin with firstboot network configuration kargs, applied via + # Afterburn. + inst_simple "$moddir/50-afterburn-network-kargs-default.conf" \ + "/usr/lib/systemd/system/afterburn-network-kargs.service.d/50-afterburn-network-kargs-default.conf" + +} diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-conf/00-core.ign b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-conf/00-core.ign new file mode 100644 index 0000000..3ddac11 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-conf/00-core.ign @@ -0,0 +1,19 @@ +{ + "ignition": { + "version": "3.0.0" + }, + "passwd": { + "users": [ + { + "name": "core", + "gecos": "CoreOS Admin", + "groups": [ + "adm", + "sudo", + "systemd-journal", + "wheel" + ] + } + ] + } +} diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-conf/README.md b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-conf/README.md new file mode 100644 index 0000000..793e519 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-conf/README.md @@ -0,0 +1 @@ +`00-core.ign` is the base config shared between FCOS and RHCOS. The configs specific to FCOS are in [50ignition-conf-fcos](../../../../../../15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos). \ No newline at end of file diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-conf/module-setup.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-conf/module-setup.sh new file mode 100755 index 0000000..7e06855 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-conf/module-setup.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +depends() { + echo ignition +} + +install() { + mkdir -p "$initdir/usr/lib/ignition/base.d" + inst "$moddir/00-core.ign" \ + "/usr/lib/ignition/base.d/00-core.ign" +} diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/coreos-check-rootfs-size b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/coreos-check-rootfs-size new file mode 100755 index 0000000..2c320be --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/coreos-check-rootfs-size @@ -0,0 +1,37 @@ +#!/bin/bash +set -euo pipefail + +# See also ignition-ostree-check-rootfs-size.service +# https://github.com/coreos/fedora-coreos-tracker/issues/586#issuecomment-777220000 + +srcdev=$(findmnt -nvr -o SOURCE /sysroot | tail -n1) +size=$(lsblk --nodeps --noheadings --bytes -o SIZE "${srcdev}") + +MINIMUM_GB=8 +MINIMUM_BYTES=$((1024 * 1024 * 1024 * MINIMUM_GB)) + +MOTD_DROPIN=/etc/motd.d/60-coreos-rootfs-size.motd + +YELLOW=$(echo -e '\033[0;33m') +RESET=$(echo -e '\033[0m') + +if [ "${size}" -lt "${MINIMUM_BYTES}" ]; then + mkdir -p "/sysroot/$(dirname "${MOTD_DROPIN}")" + cat > "/sysroot/${MOTD_DROPIN}" <&2 +} + +fatal() { + err "$@" + exit 1 +} + +if [ $# -eq 0 ]; then + err "Usage: $0 [PATTERN...]" + err " e.g.: $0 /etc/passwd '/etc/group*'" +fi + +if [ ! -f /sysroot/etc/selinux/config ]; then + exit 0 +fi + +source /sysroot/etc/selinux/config + +if [ -z "${SELINUXTYPE:-}" ]; then + fatal "Couldn't find SELINUXTYPE in /sysroot/etc/selinux/config" +fi + +file_contexts="/sysroot/etc/selinux/${SELINUXTYPE}/contexts/files/file_contexts" + +prefixed_patterns=() +while [ $# -ne 0 ]; do + pattern=$1; shift + prefixed_patterns+=("/sysroot/$pattern") +done +setfiles -vFi0 -r /sysroot "$file_contexts" "${prefixed_patterns[@]}" diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/coreos-rootflags.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/coreos-rootflags.sh new file mode 100755 index 0000000..1a7c0a2 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/coreos-rootflags.sh @@ -0,0 +1,30 @@ +#!/bin/bash +set -euo pipefail + +# see related comment block in transposefs.sh re. inspecting the config directly +ignition_cfg=/run/ignition.json +rootpath=/dev/disk/by-label/root + +query_rootfs() { + local filter=$1 + jq -re ".storage?.filesystems? // [] | + map(select(.label == \"root\" and .wipeFilesystem == true)) | + .[0] | $filter" "${ignition_cfg}" +} + +# If the rootfs was reprovisioned, then the mountOptions from the Ignition +# config has priority. +if [ -d /run/ignition-ostree-transposefs/root ]; then + if query_rootfs 'has("mountOptions")' >/dev/null; then + query_rootfs '.mountOptions | join(",")' + exit 0 + fi +fi + +eval $(blkid -o export ${rootpath}) +if [ "${TYPE}" == "xfs" ]; then + # We use prjquota on XFS by default to aid multi-tenant Kubernetes (and + # other container) clusters. See + # https://github.com/coreos/coreos-assembler/pull/303/commits/6103effbd006bb6109467830d6a3e42dd847668d + echo "prjquota" +fi diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-check-rootfs-size.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-check-rootfs-size.service new file mode 100644 index 0000000..5802f49 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-check-rootfs-size.service @@ -0,0 +1,13 @@ +[Unit] +Description=Ignition OSTree: Check Root Filesystem Size +Documentation=https://docs.fedoraproject.org/en-US/fedora-coreos/storage/ +DefaultDependencies=false +ConditionKernelCommandLine=ostree +ConditionPathExists=!/run/ostree-live +After=ignition-ostree-growfs.service +After=ostree-prepare-root.service + +[Service] +Type=oneshot +ExecStart=/usr/libexec/coreos-check-rootfs-size +RemainAfterExit=yes diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-firstboot-uuid b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-firstboot-uuid new file mode 100755 index 0000000..b217735 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-firstboot-uuid @@ -0,0 +1,68 @@ +#!/bin/bash +set -euo pipefail +# https://github.com/coreos/fedora-coreos-tracker/issues/465 +# coreos-assembler generates disk images which are installed bit-for-bit +# or booted directly in the cloud. +# Generate new UUID on firstboot; this is general best practice, but in the future +# we may use this for mounting by e.g. adding a boot= and root= kernel args. + +label=$1 + +# Keep this in sync with https://github.com/coreos/coreos-assembler/blob/e3905fd2e138de04184c1cd86b99b0fd83cbe5cf/src/create_disk.sh#L17 +bootfs_uuid="96d15588-3596-4b3c-adca-a2ff7279ea63" +rootfs_uuid="910678ff-f77e-4a7d-8d53-86f2ac47a823" + +target=/dev/disk/by-label/${label} +if ! [ -b "${target}" ]; then + echo "$0: Failed to find block device ${target}" 1>&2 + exit 1 +fi + +eval $(blkid -o export ${target}) +case "${label}" in + root) orig_uuid="${rootfs_uuid}"; orig_type=xfs ;; + boot) orig_uuid="${bootfs_uuid}"; orig_type=ext4 ;; + *) echo "unexpected ${label}"; exit 1 ;; +esac + +if [ "${TYPE}" == "${orig_type}" ] && [ "${UUID}" == "${orig_uuid}" ]; then + case "${TYPE}" in + ext4) + # If the filesystem supports metadata_csum_seed then the UUID is stored + # in the superblock and there is no need to worry with an fsck. For the + # boot filesystem this FS feature wasn't supported by GRUB until recently. + # https://lists.gnu.org/archive/html/grub-devel/2021-06/msg00031.html + # Once grub is updated in all systems we care about we can standardize + # on the metadata_csum_seed and delete the `else` code block. + if tune2fs -l ${target} | grep 'metadata_csum_seed'; then + tune2fs -U random "${target}" + else + # Run an fsck since tune2fs -U requires the FS to be clean + e2fsck -fy "${target}" + # We just ran an fsck, but there is a bug where tune2fs -U will still + # complain. It will still error if the last checked timestamp (just + # set by the e2fsck above) is older than the last mount timestamp (happens + # on systems with out of date or non-functioning hardware clocks). + # See https://github.com/coreos/fedora-coreos-tracker/issues/735#issuecomment-859605953 + # Potentially fixed in future by: https://www.spinics.net/lists/linux-ext4/msg78012.html + tune2fsinfo="$(tune2fs -l ${target})" + lastmount=$(echo "$tune2fsinfo" | grep '^Last mount time:' | cut -d ':' -f 2,3,4) + lastfsck=$(echo "$tune2fsinfo" | grep '^Last checked:' | cut -d ':' -f 2,3,4) + lastmountsse=$(date --date="$lastmount" +%s) + lastfscksse=$(date --date="$lastfsck" +%s) + if (( lastfscksse < lastmountsse )); then + echo "Detected timestamp of last fsck is older than timestamp of last mount." + echo "Setting "${target}" timestamp of last fsck to same time as last mount." + tune2fs -T $(date --date="$lastmount" +%Y%m%d%H%M%S) "${target}" + fi + # Finally, we can randomize the UUID + tune2fs -U random "${target}" + fi ;; + xfs) xfs_admin -U generate "${target}" ;; + *) echo "unexpected filesystem type ${TYPE}" 1>&2; exit 1 ;; + esac + udevadm settle || : + echo "Regenerated UUID for ${target}" +else + echo "No changes required for ${target} TYPE=${TYPE} UUID=${UUID}" +fi diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.service new file mode 100644 index 0000000..8704894 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.service @@ -0,0 +1,15 @@ +[Unit] +Description=Ignition OSTree: Grow root filesystem +DefaultDependencies=false +ConditionKernelCommandLine=ostree +ConditionPathExists=!/run/ostree-live +Before=initrd-root-fs.target +After=sysroot.mount ignition-ostree-mount-firstboot-sysroot.service +# This shouldn't be strictly necessary, but it's cleaner to not have OSTree muck +# around with moving mounts while we're still resizing the filesystem. +Before=ostree-prepare-root.service + +[Service] +Type=oneshot +ExecStart=/usr/sbin/ignition-ostree-growfs +RemainAfterExit=yes diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.sh new file mode 100755 index 0000000..d20b6a0 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.sh @@ -0,0 +1,120 @@ +#!/bin/bash +set -euo pipefail + +# This script is run by ignition-ostree-growfs.service. It grows the root +# partition, unless it determines that either the rootfs was moved or the +# partition was already resized (e.g. via Ignition). + +# If root reprovisioning was triggered, this file contains state of the root +# partition *before* ignition-disks. +saved_partstate=/run/ignition-ostree-rootfs-partstate.sh + +# We run after the rootfs is mounted at /sysroot, but before ostree-prepare-root +# moves it to /sysroot/sysroot. +path=/sysroot + +# The use of tail is to avoid errors from duplicate mounts; +# this shouldn't happen for us but we're being conservative. +src=$(findmnt -nvr -o SOURCE "$path" | tail -n1) + +if [ ! -f "${saved_partstate}" ]; then + partition=$(realpath /dev/disk/by-label/root) +else + # The rootfs was reprovisioned. Our rule in this case is: we only grow if + # the partition backing the rootfs is the same and its size didn't change + # (IOW, it was an in-place reprovisioning; e.g. LUKS or xfs -> btrfs). + source "${saved_partstate}" + if [ "${TYPE}" != "part" ]; then + # this really should never happen; but play nice + echo "$0: original rootfs blockdev not of type 'part'; not auto-growing" + exit 0 + fi + partition=$(realpath "${NAME}") + if [ "${SIZE}" != "$(lsblk --nodeps -bno SIZE "${partition}")" ]; then + echo "$0: original root partition changed size; not auto-growing" + exit 0 + fi + if ! lsblk -no MOUNTPOINT "${partition}" | grep -q '^/sysroot$'; then + echo "$0: original root partition no longer backing rootfs; not auto-growing" + exit 0 + fi +fi + +# Go through each blockdev in the hierarchy and verify we know how to grow them +lsblk -no TYPE "${partition}" | while read dev; do + case "${dev}" in + part|crypt) ;; + *) echo "error: Unsupported blockdev type ${dev}" 1>&2; exit 1 ;; + esac +done + +# Get the filesystem type before extending the partition. This matters +# because the partition, once extended, might include leftover superblocks +# from the previous contents of the disk (notably ZFS), causing blkid to +# refuse to return any filesystem type at all. +eval $(blkid -o export "${src}") +ROOTFS_TYPE=${TYPE:-} +case "${ROOTFS_TYPE}" in + xfs|ext4|btrfs) ;; + *) echo "error: Unsupported filesystem for ${path}: '${ROOTFS_TYPE}'" 1>&2; exit 1 ;; +esac + +# Now, go through the hierarchy, growing everything. Note we go one device at a +# time using --nodeps, because ordering is buggy in el8: +# https://bugzilla.redhat.com/show_bug.cgi?id=1940607 +current_blkdev=${partition} +while true; do + eval "$(lsblk --paths --nodeps --pairs -o NAME,TYPE,PKNAME "${current_blkdev}")" + MAJMIN=$(echo $(lsblk -dno MAJ:MIN "${NAME}")) + case "${TYPE}" in + part) + eval $(udevadm info --query property --export "${current_blkdev}" | grep ^DM_ || :) + if [ -n "${DM_MPATH:-}" ]; then + # Since growpart does not understand device mapper, we have to use sfdisk. + echo ", +" | sfdisk --no-reread --no-tell-kernel --force -N "${DM_PART}" "/dev/mapper/${DM_MPATH}" + udevadm settle || : # Wait for udev-triggered kpartx to update mappings + else + partnum=$(cat "/sys/dev/block/${MAJMIN}/partition") + # XXX: ideally this'd be idempotent and we wouldn't `|| :` + growpart "${PKNAME}" "${partnum}" || : + fi + ;; + crypt) + # XXX: yuck... we need to expose this sanely in clevis + (. /usr/bin/clevis-luks-common-functions + eval $(udevadm info --query=property --export "${NAME}") + # lsblk doesn't print PKNAME of crypt devices with --nodeps + PKNAME=/dev/$(ls "/sys/dev/block/${MAJMIN}/slaves") + clevis_luks_unlock_device "${PKNAME}" | cryptsetup resize -d- "${DM_NAME}" + ) + ;; + # already checked + *) echo "unreachable" 1>&2; exit 1 ;; + esac + holders="/sys/dev/block/${MAJMIN}/holders" + [ -d "${holders}" ] || break + nholders="$(ls "${holders}" | wc -l)" + if [ "${nholders}" -eq 0 ]; then + break + elif [ "${nholders}" -gt 1 ]; then + # this shouldn't happen since we've checked the partition types already + echo "error: Unsupported block device with multiple children: ${NAME}" 1>&2 + exit 1 + fi + current_blkdev=/dev/$(ls "${holders}") +done + +# Wipe any filesystem signatures from the extended partition that don't +# correspond to the FS type we detected earlier. +wipefs -af -t "no${ROOTFS_TYPE}" "${src}" + +# TODO: Add XFS to https://github.com/systemd/systemd/blob/master/src/partition/growfs.c +# and use it instead. +case "${ROOTFS_TYPE}" in + xfs) xfs_growfs "${path}" ;; + ext4) resize2fs "${src}" ;; + btrfs) btrfs filesystem resize max ${path} ;; +esac + +# this is useful for tests +touch /run/ignition-ostree-growfs.stamp diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-firstboot-sysroot.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-firstboot-sysroot.service new file mode 100644 index 0000000..3ba677d --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-firstboot-sysroot.service @@ -0,0 +1,25 @@ +[Unit] +Description=Ignition OSTree: Mount (firstboot) /sysroot +# These dependencies should match the "other" in +# ignition-ostree-mount-subsequent-sysroot.service +DefaultDependencies=false +# If root is specified, then systemd's generator will win +ConditionKernelCommandLine=!root +ConditionKernelCommandLine=ostree +# This is redundant since we're queued on -diskful.target, but eh. +ConditionPathExists=!/run/ostree-live +# There can be only one, Highlander style +Conflicts=ignition-ostree-mount-subsequent-sysroot.service +Before=initrd-root-fs.target +After=ignition-disks.service +# Note we don't have a Requires: /dev/disk/by-label/root here like +# the -subsequent service does because ignition-disks may have +# regenerated it. +Requires=ignition-disks.service +# These have an explicit dependency on After=sysroot.mount today +Before=ostree-prepare-root.service ignition-remount-sysroot.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/ignition-ostree-mount-sysroot diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-subsequent-sysroot.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-subsequent-sysroot.service new file mode 100644 index 0000000..92dde88 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-subsequent-sysroot.service @@ -0,0 +1,24 @@ +# Note this unit is conditionally enabled by ignition-ostree-generator +[Unit] +Description=CoreOS: Mount (subsequent) /sysroot +# These dependencies should match the "other" in +# ignition-ostree-mount-firsboot-sysroot.service +DefaultDependencies=false +# If root is specified, then systemd's generator will win +ConditionKernelCommandLine=!root +ConditionKernelCommandLine=ostree +ConditionPathExists=!/run/ostree-live +# There can be only one, Highlander style +Conflicts=ignition-ostree-mount-firstboot-sysroot.service +# And in contrast to the firstboot, we expect +# the root device to be ready. +Requires=dev-disk-by\x2dlabel-root.device +After=dev-disk-by\x2dlabel-root.device +Before=initrd-root-fs.target +# This has an explicit dependency on After=sysroot.mount today +Before=ostree-prepare-root.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/ignition-ostree-mount-sysroot diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-sysroot.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-sysroot.sh new file mode 100755 index 0000000..a51c4b2 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-sysroot.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -euo pipefail + +# Note that on *new machines* this script is now only ever used on firstboot. On +# subsequent boots, systemd-fstab-generator mounts /sysroot from the +# root=UUID=... and rootflags=... kargs. + +# We may do a migration window at some point where older machines have these +# kargs injected so that we can simplify the model further. + +rootpath=/dev/disk/by-label/root +if ! [ -b "${rootpath}" ]; then + echo "ignition-ostree-mount-sysroot: Failed to find ${rootpath}" 1>&2 + exit 1 +fi + +echo "Mounting ${rootpath} ($(realpath "${rootpath}")) to /sysroot" +mount -o "$(coreos-rootflags)" "${rootpath}" /sysroot diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-var.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-var.service new file mode 100644 index 0000000..09d6c15 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-var.service @@ -0,0 +1,26 @@ +[Unit] +Description=Mount OSTree /var +DefaultDependencies=false +ConditionKernelCommandLine=ostree +ConditionPathExists=!/run/ostree-live + +# Make sure ExecStop= runs before we switch root +Before=initrd-switch-root.target + +# Make sure if ExecStop= fails, the boot fails +OnFailure=emergency.target +OnFailureJobMode=isolate + +# Make sure /sysroot is mounted first, since we're mounting under there +Requires=initrd-root-fs.target +After=initrd-root-fs.target + +# Need to do this before Ignition mounts any other filesystems (potentially +# shadowing our own bind mount). +Before=ignition-mount.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/ignition-ostree-mount-var mount +ExecStop=/usr/sbin/ignition-ostree-mount-var umount diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-var.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-var.sh new file mode 100755 index 0000000..885598e --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-var.sh @@ -0,0 +1,52 @@ +#!/bin/bash +set -euo pipefail + +fatal() { + echo "$@" >&2 + exit 1 +} + +if [ $# -ne 1 ] || { [[ $1 != mount ]] && [[ $1 != umount ]]; }; then + fatal "Usage: $0 " +fi + +get_ostree_arg() { + # yes, this doesn't account for spaces within args, e.g. myarg="my val", but + # it still works for our purposes + ( + IFS=$' ' + # shellcheck disable=SC2013 + for arg in $(cat /proc/cmdline); do + if [[ $arg == ostree=* ]]; then + echo "${arg#ostree=}" + fi + done + ) +} + +do_mount() { + ostree=$(get_ostree_arg) + if [ -z "${ostree}" ]; then + fatal "No ostree= kernel argument in /proc/cmdline" + fi + + deployment_path=/sysroot/${ostree} + if [ ! -L "${deployment_path}" ]; then + fatal "${deployment_path} is not a symlink" + fi + + stateroot_var_path=$(realpath "${deployment_path}/../../var") + if [ ! -d "${stateroot_var_path}" ]; then + fatal "${stateroot_var_path} is not a directory" + fi + + echo "Mounting $stateroot_var_path" + mount --bind "$stateroot_var_path" /sysroot/var +} + +do_umount() { + echo "Unmounting /sysroot/var" + umount /sysroot/var +} + +"do_$1" diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-populate-var.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-populate-var.service new file mode 100644 index 0000000..d7aa622 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-populate-var.service @@ -0,0 +1,16 @@ +[Unit] +Description=Populate OSTree /var +DefaultDependencies=false +ConditionKernelCommandLine=|ostree +ConditionPathExists=|/run/ostree-live + +# Need to do this with all mount points active +After=ignition-mount.service + +# But *before* we start dumping files in there +Before=ignition-files.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/ignition-ostree-populate-var diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-populate-var.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-populate-var.sh new file mode 100755 index 0000000..01212db --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-populate-var.sh @@ -0,0 +1,45 @@ +#!/bin/bash +set -euo pipefail + +fatal() { + echo "$@" >&2 + exit 1 +} + +if [ $# -ne 0 ]; then + fatal "Usage: $0" +fi + +# See the similar code block in Anaconda, which handles this today for Atomic +# Host and Silverblue: +# https://github.com/rhinstaller/anaconda/blob/b9ea8ce4e68196b30a524c1cc5680dcdc4b89371/pyanaconda/payload/rpmostreepayload.py#L332 + +for varsubdir in lib log home roothome opt srv usrlocal mnt media; do + + # If the directory already existed, just ignore. This addresses the live + # image case with persistent `/var`; we don't want to relabel all the files + # there on each boot. + if [ -d "/sysroot/var/${varsubdir}" ]; then + continue + fi + + if [[ $varsubdir == lib ]] || [[ $varsubdir == log ]]; then + # Simply manually mkdir /var/{lib,log}; the tmpfiles.d entries otherwise + # reference users/groups which we don't have access to from here + # (though... we *could* import them from the sysroot, and have + # nss-altfiles in the initrd, but meh... let's just wait for + # systemd-sysusers which will make this way easier: + # https://github.com/coreos/fedora-coreos-config/pull/56/files#r262592361). + mkdir -p /sysroot/var/${varsubdir} + else + systemd-tmpfiles --create --boot --root=/sysroot --prefix="/var/${varsubdir}" + fi + + if [[ $varsubdir == roothome ]]; then + # TODO move this to tmpfiles.d once systemd-tmpfiles handles C! with --root correctly. + # See https://github.com/coreos/fedora-coreos-config/pull/137 + cp /sysroot/etc/skel/.bash* /sysroot/var/${varsubdir} + fi + + coreos-relabel "/var/${varsubdir}" +done diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-detect.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-detect.service new file mode 100644 index 0000000..389dc9e --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-detect.service @@ -0,0 +1,20 @@ +[Unit] +Description=Ignition OSTree: Detect Partition Transposition +DefaultDependencies=false +After=ignition-fetch.service +Before=ignition-disks.service +Before=initrd-root-fs.target +Before=sysroot.mount +ConditionKernelCommandLine=ostree +OnFailure=emergency.target +OnFailureJobMode=isolate + +# This stage requires udevd to detect disks +Requires=systemd-udevd.service +After=systemd-udevd.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/libexec/ignition-ostree-transposefs detect +ExecStop=/usr/libexec/ignition-ostree-transposefs cleanup diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-restore.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-restore.service new file mode 100644 index 0000000..4eca578 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-restore.service @@ -0,0 +1,20 @@ +[Unit] +Description=Ignition OSTree: Restore Partitions +DefaultDependencies=false +After=ignition-disks.service +# Avoid racing with UUID regeneration +After=ignition-ostree-uuid-root.service +Before=ignition-ostree-growfs.service +Before=ignition-ostree-mount-firstboot-sysroot.service +OnFailure=emergency.target +OnFailureJobMode=isolate + +ConditionKernelCommandLine=ostree +ConditionPathIsDirectory=/run/ignition-ostree-transposefs + +[Service] +Type=oneshot +RemainAfterExit=yes +# So we can transiently mount sysroot +MountFlags=slave +ExecStart=/usr/libexec/ignition-ostree-transposefs restore diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-save.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-save.service new file mode 100644 index 0000000..bc03499 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-save.service @@ -0,0 +1,19 @@ +[Unit] +Description=Ignition OSTree: Save Partitions +DefaultDependencies=false +After=ignition-ostree-transposefs-detect.service +Before=ignition-disks.service +ConditionKernelCommandLine=ostree +ConditionPathIsDirectory=/run/ignition-ostree-transposefs +# Any services looking at mounts need to order after this +# because it causes device re-probing. +After=coreos-gpt-setup.service +OnFailure=emergency.target +OnFailureJobMode=isolate + +[Service] +Type=oneshot +RemainAfterExit=yes +# So we can transiently mount sysroot +MountFlags=slave +ExecStart=/usr/libexec/ignition-ostree-transposefs save diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh new file mode 100755 index 0000000..18224c3 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh @@ -0,0 +1,244 @@ +#!/bin/bash +set -euo pipefail + +boot_sector_size=440 +esp_typeguid=c12a7328-f81f-11d2-ba4b-00a0c93ec93b +bios_typeguid=21686148-6449-6e6f-744e-656564454649 +prep_typeguid=9e1a2d38-c612-4316-aa26-8b49521e5a8b + +# This is implementation details of Ignition; in the future, we should figure +# out a way to ask Ignition directly whether there's a filesystem with label +# "root" being set up. +ignition_cfg=/run/ignition.json +root_part=/dev/disk/by-label/root +boot_part=/dev/disk/by-label/boot +esp_part=/dev/disk/by-label/EFI-SYSTEM +bios_part=/dev/disk/by-partlabel/BIOS-BOOT +prep_part=/dev/disk/by-partlabel/PowerPC-PReP-boot +saved_data=/run/ignition-ostree-transposefs +saved_root=${saved_data}/root +saved_boot=${saved_data}/boot +saved_esp=${saved_data}/esp +saved_bios=${saved_data}/bios +saved_prep=${saved_data}/prep +zram_dev=${saved_data}/zram_dev +partstate_root=/run/ignition-ostree-rootfs-partstate.sh + +# Print jq query string for wiped filesystems with label $1 +query_fslabel() { + echo ".storage?.filesystems? // [] | map(select(.label == \"$1\" and .wipeFilesystem == true))" +} + +# Print jq query string for partitions with type GUID $1 +query_parttype() { + echo ".storage?.disks? // [] | map(.partitions?) | flatten | map(select(try .typeGuid catch \"\" | ascii_downcase == \"$1\"))" +} + +# Print partition labels for partitions with type GUID $1 +get_partlabels_for_parttype() { + jq -r "$(query_parttype $1) | .[].label" "${ignition_cfg}" +} + +# Mounts device to directory, with extra logging of the src device +mount_verbose() { + local srcdev=$1; shift + local destdir=$1; shift + echo "Mounting ${srcdev} ($(realpath "$srcdev")) to $destdir" + mkdir -p "${destdir}" + mount "${srcdev}" "${destdir}" +} + +# Sometimes, for some reason the by-label symlinks aren't updated. Detect these +# cases, and explicitly `udevadm trigger`. +# See: https://bugzilla.redhat.com/show_bug.cgi?id=1908780 +udev_trigger_on_label_mismatch() { + local label=$1; shift + local expected_dev=$1; shift + local actual_dev + expected_dev=$(realpath "${expected_dev}") + actual_dev=$(realpath "/dev/disk/by-label/$label") + if [ "$actual_dev" != "$expected_dev" ]; then + echo "Expected /dev/disk/by-label/$label to point to $expected_dev, but points to $actual_dev; triggering udev" + udevadm trigger --settle "$expected_dev" + fi +} + +# Print partition offset for device node $1 +get_partition_offset() { + local devpath=$(udevadm info --query=path "$1") + cat "/sys${devpath}/start" +} + +mount_and_restore_filesystem_by_label() { + local label=$1; shift + local mountpoint=$1; shift + local saved_fs=$1; shift + local new_dev + new_dev=$(jq -r "$(query_fslabel "${label}") | .[0].device" "${ignition_cfg}") + udev_trigger_on_label_mismatch "${label}" "${new_dev}" + mount_verbose "/dev/disk/by-label/${label}" "${mountpoint}" + find "${saved_fs}" -mindepth 1 -maxdepth 1 -exec mv -t "${mountpoint}" {} \; +} + +case "${1:-}" in + detect) + # Mounts are not in a private namespace so we can mount ${saved_data} + wipes_root=$(jq "$(query_fslabel root) | length" "${ignition_cfg}") + wipes_boot=$(jq "$(query_fslabel boot) | length" "${ignition_cfg}") + creates_esp=$(jq "$(query_parttype ${esp_typeguid}) | length" "${ignition_cfg}") + creates_bios=$(jq "$(query_parttype ${bios_typeguid}) | length" "${ignition_cfg}") + creates_prep=$(jq "$(query_parttype ${prep_typeguid}) | length" "${ignition_cfg}") + if [ "${wipes_root}${wipes_boot}${creates_esp}${creates_bios}${creates_prep}" = "00000" ]; then + exit 0 + fi + echo "Detected partition replacement in fetched Ignition config: /run/ignition.json" + # verify all ESP, BIOS, and PReP partitions have non-null unique labels + unique_esp=$(jq -r "$(query_parttype ${esp_typeguid}) | [.[].label | values] | unique | length" "${ignition_cfg}") + unique_bios=$(jq -r "$(query_parttype ${bios_typeguid}) | [.[].label | values] | unique | length" "${ignition_cfg}") + unique_prep=$(jq -r "$(query_parttype ${prep_typeguid}) | [.[].label | values] | unique | length" "${ignition_cfg}") + if [ "${creates_esp}" != "${unique_esp}" -o "${creates_bios}" != "${unique_bios}" -o "${creates_prep}" != "${unique_prep}" ]; then + echo "Found duplicate or missing ESP, BIOS-BOOT, or PReP labels in config" >&2 + exit 1 + fi + mem_available=$(grep MemAvailable /proc/meminfo | awk '{print $2}') + # Just error out early if we don't even have 1G to work with. This + # commonly happens if you `cosa run` but forget to add `--memory`. That + # way you get a nicer error instead of the spew of EIO errors from `cp`. + # The amount we need is really dependent on a bunch of factors, but just + # ballpark it at 3G. + if [ "${mem_available}" -lt $((1*1024*1024)) ] && [ "${wipes_root}" != 0 ]; then + echo "Root reprovisioning requires at least 3G of RAM" >&2 + exit 1 + fi + modprobe zram num_devices=0 + read dev < /sys/class/zram-control/hot_add + # disksize is set arbitrarily large, as zram is capped by mem_limit + echo 10G > /sys/block/zram"${dev}"/disksize + # Limit zram to 90% of available RAM: we want to be greedy since the + # boot breaks anyway, but we still want to leave room for everything + # else so it hits ENOSPC and doesn't invoke the OOM killer + echo $(( mem_available * 90 / 100 ))K > /sys/block/zram"${dev}"/mem_limit + mkfs.xfs -q /dev/zram"${dev}" + mkdir "${saved_data}" + mount /dev/zram"${dev}" "${saved_data}" + # save the zram device number created for when called to cleanup + echo "${dev}" > "${zram_dev}" + + if [ "${wipes_root}" != "0" ]; then + mkdir "${saved_root}" + fi + if [ "${wipes_boot}" != "0" ]; then + mkdir "${saved_boot}" + fi + if [ "${creates_esp}" != "0" ]; then + mkdir "${saved_esp}" + fi + if [ "${creates_bios}" != "0" ]; then + mkdir "${saved_bios}" + fi + if [ "${creates_prep}" != "0" ]; then + mkdir "${saved_prep}" + fi + ;; + save) + # Mounts happen in a private mount namespace since we're not "offically" mounting + if [ -d "${saved_root}" ]; then + echo "Moving rootfs to RAM..." + mount_verbose "${root_part}" /sysroot + cp -aT /sysroot "${saved_root}" + # also store the state of the partition + lsblk "${root_part}" --nodeps --pairs -b --paths -o NAME,TYPE,SIZE > "${partstate_root}" + fi + if [ -d "${saved_boot}" ]; then + echo "Moving bootfs to RAM..." + mount_verbose "${boot_part}" /sysroot/boot + cp -aT /sysroot/boot "${saved_boot}" + fi + if [ -d "${saved_esp}" ]; then + echo "Moving EFI System Partition to RAM..." + mount_verbose "${esp_part}" /sysroot/boot/efi + cp -aT /sysroot/boot/efi "${saved_esp}" + fi + if [ -d "${saved_bios}" ]; then + echo "Moving BIOS Boot partition and boot sector to RAM..." + # save partition + cat "${bios_part}" > "${saved_bios}/partition" + # save boot sector + bios_disk=$(lsblk --noheadings --output PKNAME --paths "${bios_part}") + dd if="${bios_disk}" of="${saved_bios}/boot-sector" bs="${boot_sector_size}" count=1 status=none + # store partition start offset so we can check it later + get_partition_offset "${bios_part}" > "${saved_bios}/start" + fi + if [ -d "${saved_prep}" ]; then + echo "Moving PReP partition to RAM..." + cat "${prep_part}" > "${saved_prep}/partition" + fi + echo "zram usage:" + read dev < "${zram_dev}" + cat /sys/block/zram"${dev}"/mm_stat + ;; + restore) + # Mounts happen in a private mount namespace since we're not "offically" mounting + if [ -d "${saved_root}" ]; then + echo "Restoring rootfs from RAM..." + mount_and_restore_filesystem_by_label root /sysroot "${saved_root}" + chcon -v --reference "${saved_root}" /sysroot # the root of the fs itself + chattr +i $(ls -d /sysroot/ostree/deploy/*/deploy/*/) + fi + if [ -d "${saved_boot}" ]; then + echo "Restoring bootfs from RAM..." + mount_and_restore_filesystem_by_label boot /sysroot/boot "${saved_boot}" + chcon -v --reference "${saved_boot}" /sysroot/boot # the root of the fs itself + fi + if [ -d "${saved_esp}" ]; then + echo "Restoring EFI System Partition from RAM..." + get_partlabels_for_parttype "${esp_typeguid}" | while read label; do + # Don't use mount_and_restore_filesystem_by_label because: + # 1. We're mounting by partlabel, not FS label + # 2. We need to copy the contents to each partition, not move + # them once + # 3. We don't need the by-label symlink to be correct and + # nothing later in boot will be mounting the filesystem + mountpoint="/mnt/esp-${label}" + mount_verbose "/dev/disk/by-partlabel/${label}" "${mountpoint}" + find "${saved_esp}" -mindepth 1 -maxdepth 1 -exec cp -a {} "${mountpoint}" \; + done + fi + if [ -d "${saved_bios}" ]; then + echo "Restoring BIOS Boot partition and boot sector from RAM..." + expected_start=$(cat "${saved_bios}/start") + get_partlabels_for_parttype "${bios_typeguid}" | while read label; do + cur_part="/dev/disk/by-partlabel/${label}" + # boot sector hardcodes the partition start; ensure it matches + cur_start=$(get_partition_offset "${cur_part}") + if [ "${cur_start}" != "${expected_start}" ]; then + echo "Partition ${cur_part} starts at ${cur_start}; expected ${expected_start}" >&2 + exit 1 + fi + # copy partition contents + cat "${saved_bios}/partition" > "${cur_part}" + # copy boot sector + cur_disk=$(lsblk --noheadings --output PKNAME --paths "${cur_part}") + cat "${saved_bios}/boot-sector" > "${cur_disk}" + done + fi + if [ -d "${saved_prep}" ]; then + echo "Restoring PReP partition from RAM..." + get_partlabels_for_parttype "${prep_typeguid}" | while read label; do + cat "${saved_prep}/partition" > "/dev/disk/by-partlabel/${label}" + done + fi + ;; + cleanup) + # Mounts are not in a private namespace so we can unmount ${saved_data} + if [ -d "${saved_data}" ]; then + read dev < "${zram_dev}" + umount "${saved_data}" + rm -rf "${saved_data}" "${partstate_root}" + echo "${dev}" > /sys/class/zram-control/hot_remove + fi + ;; + *) + echo "Unsupported operation: ${1:-}" 1>&2; exit 1 + ;; +esac diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-boot.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-boot.service new file mode 100644 index 0000000..cde3b16 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-boot.service @@ -0,0 +1,22 @@ +[Unit] +Description=Ignition OSTree: Regenerate Filesystem UUID (boot) +DefaultDependencies=false +ConditionPathExists=/usr/lib/initrd-release +ConditionKernelCommandLine=ostree +ConditionPathExists=!/run/ostree-live +# We run pretty early +Before=coreos-copy-firstboot-network.service +Before=coreos-ignition-setup-user.service +Before=ignition-fetch-offline.service +# Any services looking at mounts need to order after this +# because it causes device re-probing. +After=coreos-gpt-setup.service + +Before=systemd-fsck@dev-disk-by\x2dlabel-boot.service +Requires=dev-disk-by\x2dlabel-boot.device +After=dev-disk-by\x2dlabel-boot.device + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/ignition-ostree-firstboot-uuid boot diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-root.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-root.service new file mode 100644 index 0000000..d4b78e3 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-root.service @@ -0,0 +1,25 @@ +[Unit] +Description=Ignition OSTree: Regenerate Filesystem UUID (root) +# These conditions match ignition-ostree-mount-firstboot-sysroot.service +DefaultDependencies=false +ConditionKernelCommandLine=ostree +ConditionPathExists=!/run/ostree-live +Before=sysroot.mount initrd-root-fs.target +After=ignition-disks.service +# If we've reprovisioned the rootfs, then there's no need to restamp +ConditionPathExists=!/run/ignition-ostree-transposefs + +After=dev-disk-by\x2dlabel-root.device +# Avoid racing with fsck +Before=systemd-fsck@dev-disk-by\x2dlabel-root.service +Before=systemd-fsck@dev-disk-by\x2dlabel-dm-mpath-root.service + +# Note we don't have a Requires: /dev/disk/by-label/root here like +# the -subsequent service does because ignition-disks may have +# regenerated it. +Before=ignition-ostree-mount-firstboot-sysroot.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/ignition-ostree-firstboot-uuid root diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh new file mode 100755 index 0000000..bf9a787 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh @@ -0,0 +1,104 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +depends() { + echo ignition rdcore +} + +install_ignition_unit() { + local unit=$1; shift + local target=${1:-complete} + inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit" + # note we `|| exit 1` here so we error out if e.g. the units are missing + # see https://github.com/coreos/fedora-coreos-config/issues/799 + systemctl -q --root="$initdir" add-requires "ignition-${target}.target" "$unit" || exit 1 +} + +installkernel() { + # Used by ignition-ostree-transposefs + instmods -c zram +} + +install() { + inst_multiple \ + realpath \ + setfiles \ + chcon \ + systemd-sysusers \ + systemd-tmpfiles \ + sort \ + uniq + + # ignition-ostree-growfs deps + inst_multiple \ + basename \ + blkid \ + cat \ + dirname \ + findmnt \ + growpart \ + realpath \ + resize2fs \ + tail \ + tune2fs \ + touch \ + xfs_admin \ + xfs_growfs \ + wc \ + wipefs + + # growpart deps + # Mostly generated from the following command: + # $ bash --rpm-requires /usr/bin/growpart | sort | uniq | grep executable + # with a few false positives (rq, rqe, -v) and one missed (mktemp) + inst_multiple \ + awk \ + cat \ + dd \ + grep \ + mktemp \ + partx \ + rm \ + sed \ + sfdisk \ + sgdisk \ + find + + for x in mount populate; do + install_ignition_unit ignition-ostree-${x}-var.service + inst_script "$moddir/ignition-ostree-${x}-var.sh" "/usr/sbin/ignition-ostree-${x}-var" + done + + inst_simple \ + /usr/lib/udev/rules.d/90-coreos-device-mapper.rules + + inst_multiple jq chattr + inst_script "$moddir/ignition-ostree-transposefs.sh" "/usr/libexec/ignition-ostree-transposefs" + for x in detect save restore; do + install_ignition_unit ignition-ostree-transposefs-${x}.service + done + + # Disk support + install_ignition_unit ignition-ostree-mount-firstboot-sysroot.service diskful + for p in boot root; do + install_ignition_unit ignition-ostree-uuid-${p}.service diskful + done + inst_script "$moddir/ignition-ostree-firstboot-uuid" \ + "/usr/sbin/ignition-ostree-firstboot-uuid" + install_ignition_unit ignition-ostree-mount-subsequent-sysroot.service diskful-subsequent + inst_script "$moddir/ignition-ostree-mount-sysroot.sh" \ + "/usr/sbin/ignition-ostree-mount-sysroot" + inst_script "$moddir/coreos-rootflags.sh" \ + "/usr/sbin/coreos-rootflags" + + install_ignition_unit ignition-ostree-growfs.service + inst_script "$moddir/ignition-ostree-growfs.sh" \ + /usr/sbin/ignition-ostree-growfs + + install_ignition_unit ignition-ostree-check-rootfs-size.service + inst_script "$moddir/coreos-check-rootfs-size" \ + /usr/libexec/coreos-check-rootfs-size + + inst_script "$moddir/coreos-relabel" /usr/bin/coreos-relabel +} diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/50coreos-kernel/coreos-check-kernel.service b/overlay.d/05core/usr/lib/dracut/modules.d/50coreos-kernel/coreos-check-kernel.service new file mode 100644 index 0000000..ce8a0ac --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/50coreos-kernel/coreos-check-kernel.service @@ -0,0 +1,10 @@ +[Unit] +Description=Check that initrd matches kernel +DefaultDependencies=false +Before=sysinit.target systemd-modules-load.service +ConditionPathIsDirectory=!/usr/lib/modules/%v + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/bin/false diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/50coreos-kernel/module-setup.sh b/overlay.d/05core/usr/lib/dracut/modules.d/50coreos-kernel/module-setup.sh new file mode 100644 index 0000000..cac7b64 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/50coreos-kernel/module-setup.sh @@ -0,0 +1,15 @@ +install_unit() { + unit="$1"; shift + target="$1"; shift + inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit" + # note we `|| exit 1` here so we error out if e.g. the units are missing + # see https://github.com/coreos/fedora-coreos-config/issues/799 + systemctl -q --root="$initdir" add-requires "$target" "$unit" || exit 1 +} + +install() { + inst_multiple \ + false + + install_unit "coreos-check-kernel.service" "sysinit.target" +} diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/60coreos-agetty-workaround/coreos-touch-run-agetty.service b/overlay.d/05core/usr/lib/dracut/modules.d/60coreos-agetty-workaround/coreos-touch-run-agetty.service new file mode 100644 index 0000000..743670e --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/60coreos-agetty-workaround/coreos-touch-run-agetty.service @@ -0,0 +1,12 @@ +# Temporary hack to work around agetty SELinux denials. +# https://github.com/coreos/fedora-coreos-config/pull/859#issuecomment-783713383 +# https://bugzilla.redhat.com/show_bug.cgi?id=1932053 +[Unit] +Description=CoreOS: Touch /run/agetty.reload +Documentation=https://bugzilla.redhat.com/show_bug.cgi?id=1932053 +DefaultDependencies=false + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/bin/touch /run/agetty.reload diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/60coreos-agetty-workaround/module-setup.sh b/overlay.d/05core/usr/lib/dracut/modules.d/60coreos-agetty-workaround/module-setup.sh new file mode 100755 index 0000000..1423fd5 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/60coreos-agetty-workaround/module-setup.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +# Temporary workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1932053. + +install_unit() { + local unit=$1; shift + inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit" + # note we `|| exit 1` here so we error out if e.g. the units are missing + # see https://github.com/coreos/fedora-coreos-config/issues/799 + systemctl -q --root="$initdir" add-requires initrd.target "$unit" || exit 1 +} + +install() { + inst_multiple \ + touch + + # TODO f35: check if we can drop this whole module + install_unit coreos-touch-run-agetty.service +} diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/99emergency-timeout/ignition-virtio-dump-journal.service b/overlay.d/05core/usr/lib/dracut/modules.d/99emergency-timeout/ignition-virtio-dump-journal.service new file mode 100644 index 0000000..18a964c --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/99emergency-timeout/ignition-virtio-dump-journal.service @@ -0,0 +1,15 @@ +[Unit] +Description=Dump journal to virtio port +ConditionPathExists=/etc/initrd-release +DefaultDependencies=false +ConditionVirtualization=|kvm +ConditionVirtualization=|qemu +Requires=systemd-journald.service +After=systemd-journald.service +After=basic.target + +[Service] +Type=oneshot +RemainAfterExit=yes +EnvironmentFile=/run/ignition.env +ExecStart=/usr/bin/ignition-virtio-dump-journal diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/99emergency-timeout/ignition-virtio-dump-journal.sh b/overlay.d/05core/usr/lib/dracut/modules.d/99emergency-timeout/ignition-virtio-dump-journal.sh new file mode 100755 index 0000000..806b374 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/99emergency-timeout/ignition-virtio-dump-journal.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -euo pipefail + +port=/dev/virtio-ports/com.coreos.ignition.journal +if [ -e "${port}" ]; then + # Sync to backing filesystem before dumping what's there + journalctl --sync + journalctl -o json > "${port}" + # And this signals end of stream + echo '{}' > "${port}" +else + echo "Didn't find virtio port ${port}" +fi diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/99emergency-timeout/module-setup.sh b/overlay.d/05core/usr/lib/dracut/modules.d/99emergency-timeout/module-setup.sh new file mode 100755 index 0000000..63907da --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/99emergency-timeout/module-setup.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +install_unit_wants() { + local unit="$1"; shift + local target="$1"; shift + local instantiated="${1:-$unit}"; shift + inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit" + # note we `|| exit 1` here so we error out if e.g. the units are missing + # see https://github.com/coreos/fedora-coreos-config/issues/799 + systemctl -q --root="$initdir" add-wants "$target" "$instantiated" || exit 1 +} + +install() { + inst_multiple \ + cut \ + date + + inst_hook emergency 99 "${moddir}/timeout.sh" + + inst_script "$moddir/ignition-virtio-dump-journal.sh" "/usr/bin/ignition-virtio-dump-journal" + install_unit_wants ignition-virtio-dump-journal.service emergency.target +} diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/99emergency-timeout/timeout.sh b/overlay.d/05core/usr/lib/dracut/modules.d/99emergency-timeout/timeout.sh new file mode 100644 index 0000000..85fb3d7 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/99emergency-timeout/timeout.sh @@ -0,0 +1,99 @@ +# Before starting the emergency shell, prompt the user to press Enter. +# If they don't, reboot the system. +# +# Assumes /bin/sh is bash. + +# _wait_for_journalctl_to_stop will block until either: +# - no messages have appeared in journalctl for the past 5 seconds +# - 15 seconds have elapsed +_wait_for_journalctl_to_stop() { + local time_since_last_log=0 + + local time_started="$(date '+%s')" + local now="$(date '+%s')" + + while [ ${time_since_last_log} -lt 5 -a $((now-time_started)) -lt 15 ]; do + sleep 1 + + local last_log_timestamp="$(journalctl -e -n 1 -q -o short-unix | cut -d '.' -f 1)" + local now="$(date '+%s')" + + local time_since_last_log=$((now-last_log_timestamp)) + done +} + +_prompt_for_timeout() { + local timeout=300 + local interval=15 + + if [[ -e /.emergency-shell-confirmed ]]; then + return + fi + failed=$(systemctl --failed --no-legend --plain | cut -f 1 -d ' ') + if [ -n "${failed}" ]; then + # Something failed, suppress kernel logs so that it's more likely + # the useful bits from the journal are available. + dmesg --console-off + + # There's a couple straggler systemd messages. Wait until it's been 5 + # seconds since something was written to the journal. + _wait_for_journalctl_to_stop + + # Print Ignition logs + if echo ${failed} | grep -qFe 'ignition-'; then + cat < 0 ]]; do + local m=$(( $timeout / 60 )) + local s=$(( $timeout % 60 )) + local m_label="minutes" + if [[ $m = 1 ]]; then + m_label="minute" + fi + + if [[ $s != 0 ]]; then + echo -n -e "Press Enter for emergency shell or wait $m $m_label $s seconds for reboot. \r" + else + echo -n -e "Press Enter for emergency shell or wait $m $m_label for reboot. \r" + fi + + local anything + if read -t $interval anything; then + > /.emergency-shell-confirmed + return + fi + timeout=$(( $timeout - $interval )) + done + + echo -e "\nRebooting." + # This is not very nice, but since reboot.target likely conflicts with + # the existing goal target wrt the desired state of shutdown.target, + # there doesn't seem to be a better option. + systemctl reboot --force + exit 0 +} + +# If we're invoked from a dracut breakpoint rather than +# dracut-emergency.service, we won't have a controlling terminal and stdio +# won't be connected to it. Explicitly read/write /dev/console. +_prompt_for_timeout < /dev/console > /dev/console diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/99journal-conf/00-journal-log-forwarding.conf b/overlay.d/05core/usr/lib/dracut/modules.d/99journal-conf/00-journal-log-forwarding.conf new file mode 100644 index 0000000..091a114 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/99journal-conf/00-journal-log-forwarding.conf @@ -0,0 +1,12 @@ +[Journal] +# For now we are using kmsg for multiplexing output to +# multiple console devices during early boot. +# +# We do not want to use kmsg in the future as there may be sensitive +# ignition data that leaks to non-root users (by reading the kernel +# ring buffer using `dmesg`). In the future we will rely on kernel +# console multiplexing (link below) for this and will not use kmsg. +# +# https://github.com/coreos/fedora-coreos-tracker/issues/136 +ForwardToKMsg=yes +MaxLevelKMsg=info diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/99journal-conf/module-setup.sh b/overlay.d/05core/usr/lib/dracut/modules.d/99journal-conf/module-setup.sh new file mode 100755 index 0000000..e6626b2 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/99journal-conf/module-setup.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +depends() { + echo systemd +} + +install() { + inst_simple "$moddir/00-journal-log-forwarding.conf" \ + "/etc/systemd/journald.conf.d/00-journal-log-forwarding.conf" +} diff --git a/overlay.d/05core/usr/lib/sysctl.d/10-coreos-ratelimit-kmsg.conf b/overlay.d/05core/usr/lib/sysctl.d/10-coreos-ratelimit-kmsg.conf new file mode 100644 index 0000000..e605a61 --- /dev/null +++ b/overlay.d/05core/usr/lib/sysctl.d/10-coreos-ratelimit-kmsg.conf @@ -0,0 +1,3 @@ +# See also 10coreos-sysctl dracut module, which turns off ratelimiting in the +# initrd. +kernel.printk_devkmsg = ratelimit diff --git a/overlay.d/05core/usr/lib/systemd/journald.conf.d/10-coreos-persistent.conf b/overlay.d/05core/usr/lib/systemd/journald.conf.d/10-coreos-persistent.conf new file mode 100644 index 0000000..7910c16 --- /dev/null +++ b/overlay.d/05core/usr/lib/systemd/journald.conf.d/10-coreos-persistent.conf @@ -0,0 +1,6 @@ +# Hardcode persistent journal by default. journald has this "auto" behaviour +# that only makes logs persistent if `/var/log/journal` exists, which it won't +# on first boot because `/var` isn't fully populated. We should be able to get +# rid of this once we move to sysusers and create the dir in the initrd. +[Journal] +Storage=persistent diff --git a/overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator b/overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator new file mode 100755 index 0000000..5724fdc --- /dev/null +++ b/overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator @@ -0,0 +1,115 @@ +#!/bin/bash +export PATH="/usr/bin:/usr/sbin:${PATH}" +set -euo pipefail + +. /usr/lib/coreos/generator-lib.sh + +# Turn out if you boot with "root=..." $UNIT_DIR is not writable. +[ -w "${UNIT_DIR}" ] || { + echo "skipping coreos-boot-mount-generator: ${UNIT_DIR} is not writable" + exit 0 +} + +# If there's already an /etc/fstab entries for /boot, then this is is a non-FCOS +# system, likely RHCOS pre-4.3 (which still used Anaconda). In that case, we +# don't want to overwrite what the systemd-fstab-generator will do. +if findmnt --fstab /boot &>/dev/null; then + exit 0 +fi + +# Don't create mount units for /boot on live systems. +# ConditionPathExists won't work here because conditions don't affect +# the dependency on the underlying device unit. +if [ -f /run/ostree-live ]; then + exit 0 +fi + +add_wants() { + local name="$1"; shift + local wants_dir="${UNIT_DIR}/local-fs.target.wants" + mkdir -p "${wants_dir}" + ln -sf "../${name}" "${wants_dir}/${name}" +} + +# Generate mount units that work with device mapper. The traditional +# device unit (dev-disk-by\x2dlabel...) does not work since it is not the +# device that systemd will fsck. This code ensures that if the label +# is backed by a device-mapper target the dev-mapper.*.device is used. +mk_mount() { + local mount_pt="${1}"; shift + local path="${1}"; shift + local options="${1}"; shift + + local devservice=$(systemd-escape -p ${path} --suffix=service) + local unit_name=$(systemd-escape -p ${mount_pt} --suffix=mount) + + cat > "${UNIT_DIR}/${unit_name}" < "${out_dir}/10-autologin.conf" < /etc/sysctl.d/20-coreos-autologin-kernel-printk.conf +# Raise console message logging level from DEBUG (7) to WARNING (4) +# so that kernel debug message don't get interspersed on the console +# that +# may frustrate a user trying to interactively do an install with +# nmtui and coreos-installer. +kernel.printk=4 +EOF +} + +write_interactive_live_motd() { + # Write motd to a tmp file and not directly to /etc/motd because + # SELinux denies write from init_t to etc_t + cat < /run/interactive-live-motd + +########################################################################### +Welcome to the CoreOS live environment. This system is running completely +from memory, making it a good candidate for hardware discovery and +installing persistently to disk. Here is an example of running an install +to disk via coreos-installer: + +sudo coreos-installer install /dev/sda \\ + --ignition-url https://example.com/example.ign + +You may configure networking via 'sudo nmcli' or 'sudo nmtui' and have +that configuration persist into the installed system by passing the +'--copy-network' argument to 'coreos-installer install'. Please run +'coreos-installer install --help' for more information on the possible +install options. +########################################################################### + +EOF + # Create coreos-cp-interactive-live-motd.service to copy over the motd in + # place. Note this intentionally overwrites the existing motd, which is + # blank on FCOS and populated on RHCOS. + service="coreos-cp-interactive-live-motd.service" + cat < "${UNIT_DIR}/${service}" +# generated by coreos-liveiso-autologin-generator +[Unit] +Description=Copy CoreOS Interactive Live MOTD +Before=systemd-user-sessions.service +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/bin/cp -v /run/interactive-live-motd /etc/motd +EOF + mkdir -p "${UNIT_DIR}/multi-user.target.wants" + ln -sf "../${service}" "${UNIT_DIR}/multi-user.target.wants/" +} + +# Only allow automatic autologin on live systems +if [ ! -e /run/ostree-live ]; then + exit 0 +fi + +# Autologin on ISO boots but not PXE boots. The only way to tell the +# difference is a kernel argument. +if ! have_karg coreos.liveiso; then + exit 0 +fi + +# If the user supplied an Ignition config, they have the ability to enable +# autologin themselves. Don't automatically render them insecure, since +# they might be running in production and booting via e.g. IPMI. +if jq -e .userConfigProvided /etc/.ignition-result.json &>/dev/null; then + exit 0 +fi + +write_dropin "getty@.service" "--noclear" +# Also autologin on serial console if someone enables that +write_dropin "serial-getty@.service" "--keep-baud 115200,38400,9600" + +# When the installer runs a lot of things happen on the system (audit +# messages from running via sudo, re-reading partition table messages, +# mounting filesystem messages, etc.). Quieting the verbosity of the +# kernel console will help us keep our sanity. +quiet_kernel_console_messages + + +# Write an motd that will let the user know about the live environment +# and what is possible. +write_interactive_live_motd diff --git a/overlay.d/05core/usr/lib/systemd/system-preset/40-coreos-systemd.preset b/overlay.d/05core/usr/lib/systemd/system-preset/40-coreos-systemd.preset new file mode 100644 index 0000000..a242eba --- /dev/null +++ b/overlay.d/05core/usr/lib/systemd/system-preset/40-coreos-systemd.preset @@ -0,0 +1,16 @@ +# This file contains overrides for systemd services that are +# enabled by default, but conflict with things we ship. + +# We don't have swap by default, and systemd-oomd hard requires it. +disable systemd-oomd.service + +# Disable systemd-firstboot because it conflicts with Ignition. +# In most cases this is handled via the remove-from-packages +# bits in the manifest (ignition-and-ostree.yaml), but +# we want to support overlaying builds of systemd from git. +disable systemd-firstboot.service + +# This hasn't been tested with ostree/rpm-ostree and heavily overlaps +# with the latter. Preemptively disable the service; it will hopefully +# be subpackaged though for Fedora. +disable systemd-sysext.service diff --git a/overlay.d/05core/usr/lib/systemd/system-preset/40-coreos.preset b/overlay.d/05core/usr/lib/systemd/system-preset/40-coreos.preset new file mode 100644 index 0000000..13963ef --- /dev/null +++ b/overlay.d/05core/usr/lib/systemd/system-preset/40-coreos.preset @@ -0,0 +1,27 @@ +# Presets here that eventually should live in the generic fedora presets + +# console-login-helper-messages - https://github.com/coreos/console-login-helper-messages +enable console-login-helper-messages-gensnippet-os-release.service +enable console-login-helper-messages-gensnippet-ssh-keys.service +# CA certs (probably to add to base fedora eventually) +enable coreos-update-ca-trust.service +# https://github.com/coreos/ignition/issues/1125 +enable coreos-ignition-firstboot-complete.service +# Boot checkin services for cloud providers. +enable afterburn-checkin.service +enable afterburn-firstboot-checkin.service +# Target to write SSH key snippets from cloud providers. +enable afterburn-sshkeys.target +# Update agent +enable zincati.service +# Testing aid +enable coreos-liveiso-success.service +# See bootupd.yaml +enable bootupd.socket +# Enable rtas_errd for ppc64le to discover dynamically attached pci devices - https://bugzilla.redhat.com/show_bug.cgi?id=1811537 +# The event for the attached device comes as a diag event. +# Ideally it should have been added as part of base Fedora - but since it was arch specific, it was not added: https://bugzilla.redhat.com/show_bug.cgi?id=1433859 +enable rtas_errd.service +enable clevis-luks-askpass.path +# Provide information if no ignition is provided +enable coreos-check-ignition-config.service diff --git a/overlay.d/05core/usr/lib/systemd/system/coreos-check-ignition-config.service b/overlay.d/05core/usr/lib/systemd/system/coreos-check-ignition-config.service new file mode 100644 index 0000000..569de69 --- /dev/null +++ b/overlay.d/05core/usr/lib/systemd/system/coreos-check-ignition-config.service @@ -0,0 +1,14 @@ +# This service is used for printing a message if +# no Ignition config is provided. +[Unit] +Description=Check if Ignition config is provided +Before=systemd-user-sessions.service +ConditionPathExists=/etc/.ignition-result.json + +[Service] +Type=oneshot +ExecStart=/usr/libexec/coreos-check-ignition-config +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/overlay.d/05core/usr/lib/systemd/system/coreos-ignition-firstboot-complete.service b/overlay.d/05core/usr/lib/systemd/system/coreos-ignition-firstboot-complete.service new file mode 100644 index 0000000..42adf1e --- /dev/null +++ b/overlay.d/05core/usr/lib/systemd/system/coreos-ignition-firstboot-complete.service @@ -0,0 +1,21 @@ +[Unit] +Description=CoreOS Mark Ignition Boot Complete +Documentation=https://docs.fedoraproject.org/en-US/fedora-coreos/ +ConditionKernelCommandLine=ignition.firstboot +ConditionPathExists=!/run/ostree-live +RequiresMountsFor=/boot + +[Service] +Type=oneshot +RemainAfterExit=yes +# The MountFlags=slave is so we remount /boot temporarily writable; +# see https://github.com/ostreedev/ostree/issues/1265 for the bigger picture. +# This option creates a new mount namespace; from the point of view of +# everything else, /boot stays readonly. We only have a transient writable mount +# for the lifetime of the unit. +MountFlags=slave +ExecStart=/usr/libexec/coreos-ignition-firstboot-complete + +[Install] +# Part of basic.target so this happens early on in firstboot +WantedBy=basic.target diff --git a/overlay.d/05core/usr/lib/systemd/system/coreos-liveiso-success.service b/overlay.d/05core/usr/lib/systemd/system/coreos-liveiso-success.service new file mode 100644 index 0000000..d148d12 --- /dev/null +++ b/overlay.d/05core/usr/lib/systemd/system/coreos-liveiso-success.service @@ -0,0 +1,26 @@ +# This is used by our test framework in coreos-assembler +# since for the "live ISO without Ignition" case we +# don't have an easy way to test it. +[Unit] +Description=CoreOS Live ISO virtio success +Documentation=https://github.com/coreos/fedora-coreos-config +# Only run on the Live ISO, and only if there's no Ignition config +ConditionKernelCommandLine=coreos.liveiso +ConditionPathExists=!/config.ign +ConditionVirtualization=|kvm +ConditionVirtualization=|qemu +# Start running late to help ensure that the below conditional works +After=systemd-user-sessions.service +ConditionPathExists=/dev/virtio-ports/coreos.liveiso-success + +[Service] +Type=simple +# Wait for a user session to start, then write a static message to the +# virtio channel, which https://github.com/coreos/coreos-assembler/pull/1330 +# knows how to read. We previously did "journalctl -f ... | head -1" here, +# but RHEL 8 has systemd 239, which has +# https://github.com/systemd/systemd/issues/9374. +ExecStart=/bin/sh -c 'while [ -z "$(loginctl list-sessions --no-legend)" ]; do sleep 1; done; echo coreos-liveiso-success > /dev/virtio-ports/coreos.liveiso-success' + +[Install] +WantedBy=multi-user.target diff --git a/overlay.d/05core/usr/lib/systemd/system/coreos-update-ca-trust.service b/overlay.d/05core/usr/lib/systemd/system/coreos-update-ca-trust.service new file mode 100644 index 0000000..d5e811f --- /dev/null +++ b/overlay.d/05core/usr/lib/systemd/system/coreos-update-ca-trust.service @@ -0,0 +1,31 @@ +# This service is currently specific to Fedora CoreOS, +# but we may want to add it to the base OS in the future. +# The idea here is to allow users to just drop in CA roots +# via Ignition without having to know to run the special +# update command. +[Unit] +Description=Run update-ca-trust +ConditionFirstBoot=true +# All services which use ConditionFirstBoot=yes should use +# Before=first-boot-complete.target, which is a target that +# was introduced in https://github.com/systemd/systemd/issues/4511 +# and hasn't propagated everywhere yet. Once the target propagates +# everywhere, we can drop the systemd-machine-id-commit.service +# from the Before= line. +Before=first-boot-complete.target systemd-machine-id-commit.service +Wants=first-boot-complete.target +ConditionDirectoryNotEmpty=/etc/pki/ca-trust/source/anchors/ +# We want to run quite early, in particular before anything +# that may speak TLS to external services. In the future, +# it may make sense to do this in the initramfs too. +DefaultDependencies=no +After=local-fs.target +Requires=local-fs.target + +[Service] +ExecStart=/usr/bin/update-ca-trust extract +Type=oneshot +RemainAfterExit=yes + +[Install] +WantedBy=basic.target diff --git a/overlay.d/05core/usr/lib/systemd/system/emergency.service.d/coreos-sulogin-force.conf b/overlay.d/05core/usr/lib/systemd/system/emergency.service.d/coreos-sulogin-force.conf new file mode 100644 index 0000000..390f727 --- /dev/null +++ b/overlay.d/05core/usr/lib/systemd/system/emergency.service.d/coreos-sulogin-force.conf @@ -0,0 +1,7 @@ +# https://github.com/coreos/coreos-installer/commit/15a79263d0bd5d72056a6080f6687dc10cba2dda +# https://github.com/systemd/systemd/pull/10397 +# We want things like `systemd.unit=emergency.target` and `single` on the +# kernel command line to just work even with our locked root account. +# This file is used as an override for both emergency.target and rescue.target. +[Service] +Environment=SYSTEMD_SULOGIN_FORCE=1 diff --git a/overlay.d/05core/usr/lib/systemd/system/rescue.service.d/coreos-sulogin-force.conf b/overlay.d/05core/usr/lib/systemd/system/rescue.service.d/coreos-sulogin-force.conf new file mode 120000 index 0000000..a8a1f7a --- /dev/null +++ b/overlay.d/05core/usr/lib/systemd/system/rescue.service.d/coreos-sulogin-force.conf @@ -0,0 +1 @@ +../emergency.service.d/coreos-sulogin-force.conf \ No newline at end of file diff --git a/overlay.d/05core/usr/lib/systemd/system/systemd-backlight@.service.d/45-after-ostree-remount.conf b/overlay.d/05core/usr/lib/systemd/system/systemd-backlight@.service.d/45-after-ostree-remount.conf new file mode 100644 index 0000000..fc1c821 --- /dev/null +++ b/overlay.d/05core/usr/lib/systemd/system/systemd-backlight@.service.d/45-after-ostree-remount.conf @@ -0,0 +1,4 @@ +# Temporary fix for https://github.com/coreos/fedora-coreos-tracker/issues/975 +# until https://github.com/ostreedev/ostree/issues/2115 is fixed. +[Unit] +After=ostree-remount.service diff --git a/overlay.d/05core/usr/lib/systemd/system/systemd-firstboot.service.d/fcos-disable.conf b/overlay.d/05core/usr/lib/systemd/system/systemd-firstboot.service.d/fcos-disable.conf new file mode 100644 index 0000000..fc7f005 --- /dev/null +++ b/overlay.d/05core/usr/lib/systemd/system/systemd-firstboot.service.d/fcos-disable.conf @@ -0,0 +1,5 @@ +# See the comment in 40-coreos-systemd.preset; we're +# keeping this even stronger disable override for now, +# but it may not really be necessary. +[Unit] +ConditionPathExists=/run/nosuchfile diff --git a/overlay.d/05core/usr/lib/udev/rules.d/65-gce-disk-naming.rules b/overlay.d/05core/usr/lib/udev/rules.d/65-gce-disk-naming.rules new file mode 100644 index 0000000..e19c1c5 --- /dev/null +++ b/overlay.d/05core/usr/lib/udev/rules.d/65-gce-disk-naming.rules @@ -0,0 +1,38 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Name the attached disks as the specified by deviceName. + +ACTION!="add|change", GOTO="gce_disk_naming_end" +SUBSYSTEM!="block", GOTO="gce_disk_naming_end" + +# SCSI naming +KERNEL=="sd*|vd*", ENV{ID_VENDOR}=="Google", IMPORT{program}="scsi_id --export --whitelisted -d $tempnode" + +# NVME naming +KERNEL=="nvme0n1*", ENV{ID_VENDOR}=="Google", ENV{ID_SERIAL_SHORT}="local-nvme-ssd-0" +KERNEL=="nvme0n2*", ENV{ID_VENDOR}=="Google", ENV{ID_SERIAL_SHORT}="local-nvme-ssd-1" +KERNEL=="nvme0n3*", ENV{ID_VENDOR}=="Google", ENV{ID_SERIAL_SHORT}="local-nvme-ssd-2" +KERNEL=="nvme0n4*", ENV{ID_VENDOR}=="Google", ENV{ID_SERIAL_SHORT}="local-nvme-ssd-3" +KERNEL=="nvme0n5*", ENV{ID_VENDOR}=="Google", ENV{ID_SERIAL_SHORT}="local-nvme-ssd-4" +KERNEL=="nvme0n6*", ENV{ID_VENDOR}=="Google", ENV{ID_SERIAL_SHORT}="local-nvme-ssd-5" +KERNEL=="nvme0n7*", ENV{ID_VENDOR}=="Google", ENV{ID_SERIAL_SHORT}="local-nvme-ssd-6" +KERNEL=="nvme0n8*", ENV{ID_VENDOR}=="Google", ENV{ID_SERIAL_SHORT}="local-nvme-ssd-7" +KERNEL=="nvme*", ENV{ID_VENDOR}=="Google", ENV{ID_SERIAL}="Google_EphemeralDisk_$env{ID_SERIAL_SHORT}" + +# Symlinks +KERNEL=="sd*|vd*|nvme*", ENV{DEVTYPE}=="disk", ENV{ID_VENDOR}=="Google", SYMLINK+="disk/by-id/google-$env{ID_SERIAL_SHORT}" +KERNEL=="sd*|vd*|nvme*", ENV{DEVTYPE}=="partition", ENV{ID_VENDOR}=="Google", SYMLINK+="disk/by-id/google-$env{ID_SERIAL_SHORT}-part%n" + +LABEL="gce_disk_naming_end" diff --git a/overlay.d/05core/usr/lib/udev/rules.d/68-azure-sriov-nm-unmanaged.rules b/overlay.d/05core/usr/lib/udev/rules.d/68-azure-sriov-nm-unmanaged.rules new file mode 100644 index 0000000..59cf73b --- /dev/null +++ b/overlay.d/05core/usr/lib/udev/rules.d/68-azure-sriov-nm-unmanaged.rules @@ -0,0 +1,4 @@ +# Accelerated Networking on Azure exposes a new SRIOV interface to the VM. +# This interface is transparently bonded to the synthetic interface, +# so NetworkManager should just ignore any SRIOV interfaces. +SUBSYSTEM=="net", DRIVERS=="hv_pci", ACTION=="add", ENV{NM_UNMANAGED}="1" diff --git a/overlay.d/05core/usr/lib/udev/rules.d/90-coreos-device-mapper.rules b/overlay.d/05core/usr/lib/udev/rules.d/90-coreos-device-mapper.rules new file mode 100644 index 0000000..385f262 --- /dev/null +++ b/overlay.d/05core/usr/lib/udev/rules.d/90-coreos-device-mapper.rules @@ -0,0 +1,27 @@ +# CoreOS-specific symlinks for dm-multipath filesystem labels, +# used for `label=boot` and `label=root`. + +ACTION=="remove", GOTO="dm_label_end" +SUBSYSTEM!="block", GOTO="dm_label_end" +KERNEL!="dm-*", GOTO="dm_label_end" + +# Ensure that the device mapper target is active +ENV{DM_SUSPENDED}=="1", GOTO="dm_label_end" + +# Only act on filesystems. This should prevent layered devices +# such as Raid on Multipath devices from appearing. +ENV{ID_FS_USAGE}!="filesystem", GOTO="dm_label_end" + +# And if the filesystem doesn't have a label+uuid, we're done. +ENV{ID_FS_LABEL_ENC}!="?*", GOTO="dm_label_end" +ENV{ID_FS_UUID_ENC}!="?*", GOTO="dm_label_end" + +# Setup up Multipath labels and UUID's. Match on DM_UUID which +# is stable regardless of whether friendly names are used or not. +# 66-kpartx.rules use DM_UUID to match for linear mappings on multipath +# targets. +ENV{DM_UUID}=="*mpath*" \ + , SYMLINK+="disk/by-label/dm-mpath-$env{ID_FS_LABEL_ENC}" \ + , SYMLINK+="disk/by-uuid/dm-mpath-$env{ID_FS_UUID_ENC}" + +LABEL="dm_label_end" diff --git a/overlay.d/05core/usr/libexec/coreos-check-ignition-config b/overlay.d/05core/usr/libexec/coreos-check-ignition-config new file mode 100755 index 0000000..794efe9 --- /dev/null +++ b/overlay.d/05core/usr/libexec/coreos-check-ignition-config @@ -0,0 +1,47 @@ +#!/usr/bin/bash +set -euo pipefail + +IGNITION_RESULT=/etc/.ignition-result.json + +WARN='\033[0;33m' # yellow +RESET='\033[0m' # reset + +mkdir -p /run/issue.d +touch /run/issue.d/30_coreos_ignition_provisioning.issue + +d=$(date --date "$(jq -r .provisioningDate "${IGNITION_RESULT}")" +"%Y/%m/%d %H:%M:%S %Z") +ignitionBoot=$(jq -r .provisioningBootID "${IGNITION_RESULT}") +if [ $(cat /proc/sys/kernel/random/boot_id) = "${ignitionBoot}" ]; then + echo "Ignition: ran on ${d} (this boot)" \ + > /run/issue.d/30_coreos_ignition_provisioning.issue + + # checking for /run/ostree-live as the live system with persistent storage can run Ignition more than once + if ! test -f /run/ostree-live && jq -e .previousReport.provisioningDate "${IGNITION_RESULT}" &>/dev/null; then + prevdate=$(date --date "$(jq -r .previousReport.provisioningDate "${IGNITION_RESULT}")" +"%Y/%m/%d %H:%M:%S %Z") + cat << EOF > /etc/issue.d/30_coreos_ignition_run_more_than_once.issue +${WARN} +############################################################################ +WARNING: Ignition previously ran on ${prevdate}. Unexpected +behavior may occur. Ignition is not designed to run more than once per system. +############################################################################ +${RESET} +EOF + fi +else + nreboots=$(($(journalctl --list-boots | wc -l) - 1)) + [ "${nreboots}" -eq 1 ] && boot="boot" || boot="boots" + echo "Ignition: ran on ${d} (at least $nreboots $boot ago)" \ + > /run/issue.d/30_coreos_ignition_provisioning.issue +fi + +if jq -e .userConfigProvided "${IGNITION_RESULT}" &>/dev/null; then + echo "Ignition: user-provided config was applied" \ + >> /run/issue.d/30_coreos_ignition_provisioning.issue +else + echo -e "${WARN}Ignition: no config provided by user${RESET}" \ + >> /run/issue.d/30_coreos_ignition_provisioning.issue +fi + +# Our makeshift way of getting /run/issue.d semantics. See: +# https://github.com/coreos/console-login-helper-messages/blob/e06fc88ae8fbcc3a422bc8c686f70c15aebb9d9a/usr/lib/console-login-helper-messages/issue.defs#L8-L17 +ln -sf /run/issue.d/30_coreos_ignition_provisioning.issue /etc/issue.d/ diff --git a/overlay.d/05core/usr/libexec/coreos-ignition-firstboot-complete b/overlay.d/05core/usr/libexec/coreos-ignition-firstboot-complete new file mode 100755 index 0000000..3973d11 --- /dev/null +++ b/overlay.d/05core/usr/libexec/coreos-ignition-firstboot-complete @@ -0,0 +1,18 @@ +#!/bin/bash +set -euo pipefail + +mount -o remount,rw /boot + +if [[ $(uname -m) = s390x ]]; then + zipl +fi + +# We're done provisioning. Remove the whole /boot/ignition directory if present, +# which may include a baked Ignition config. See +# https://github.com/coreos/fedora-coreos-tracker/issues/889. +rm -rf /boot/ignition + +# Regarding the lack of `-f` for rm ; we should have only run if GRUB detected +# this file. Fail if we are unable to remove it, rather than risking rerunning +# Ignition at next boot. +rm /boot/ignition.firstboot diff --git a/overlay.d/05core/usr/share/licenses/fedora-coreos-config/LICENSE b/overlay.d/05core/usr/share/licenses/fedora-coreos-config/LICENSE new file mode 100644 index 0000000..b81e261 --- /dev/null +++ b/overlay.d/05core/usr/share/licenses/fedora-coreos-config/LICENSE @@ -0,0 +1,21 @@ +Copyright 2018 Fedora CoreOS Authors. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/overlay.d/05core/usr/share/licenses/fedora-coreos-config/README.md b/overlay.d/05core/usr/share/licenses/fedora-coreos-config/README.md new file mode 100644 index 0000000..ba7a326 --- /dev/null +++ b/overlay.d/05core/usr/share/licenses/fedora-coreos-config/README.md @@ -0,0 +1,17 @@ +# fedora-coreos-config + +Today most components of Fedora CoreOS are built as RPMs; this +is the main exception. fedora-coreos-config is "architecture-independent glue" +and the overhead of building an RPM for each change is onerous. + +It's also *the* central point of management (e.g. it contains lockfiles), so having it be +an RPM too would become circular. Instead, coreos-assembler directly consumes it. + +The upstream git repository is: https://github.com/coreos/fedora-coreos-config + +From a running system, to find the source commit use: +``` +$ rpm-ostree status -b --json | jq -r '.deployments[0]."base-commit-meta"."coreos-assembler.config-gitrev"' +c8dbed9ce223bf86737c82dd763670c8a34e950f +$ +``` diff --git a/overlay.d/08nouveau/etc/modprobe.d/blacklist-nouveau.conf b/overlay.d/08nouveau/etc/modprobe.d/blacklist-nouveau.conf new file mode 100644 index 0000000..0cc994e --- /dev/null +++ b/overlay.d/08nouveau/etc/modprobe.d/blacklist-nouveau.conf @@ -0,0 +1,2 @@ +# See https://bugzilla.redhat.com/show_bug.cgi?id=1700056 +blacklist nouveau diff --git a/overlay.d/08nouveau/statoverride b/overlay.d/08nouveau/statoverride new file mode 100644 index 0000000..27a95af --- /dev/null +++ b/overlay.d/08nouveau/statoverride @@ -0,0 +1,2 @@ +# Config file for overriding permission bits on overlay files/dirs +# Format: = diff --git a/overlay.d/09misc/etc/sysconfig/README b/overlay.d/09misc/etc/sysconfig/README new file mode 100644 index 0000000..4d8d9bb --- /dev/null +++ b/overlay.d/09misc/etc/sysconfig/README @@ -0,0 +1,9 @@ +This directory is a legacy of Red Hat Linux days. +Do not write new software that uses configuration +files here. Instead your software should use a regular +config file in `/etc/foo.conf`, a configuration directory +such as `/etc/foo/`. + +Where appropriate, it's also best practice to use "systemd style config" +where default config files live in `/usr/lib/foo` that can be +overridden in `/etc` and `/run`. diff --git a/overlay.d/09misc/statoverride b/overlay.d/09misc/statoverride new file mode 100644 index 0000000..27a95af --- /dev/null +++ b/overlay.d/09misc/statoverride @@ -0,0 +1,2 @@ +# Config file for overriding permission bits on overlay files/dirs +# Format: = diff --git a/overlay.d/14NetworkManager-plugins/statoverride b/overlay.d/14NetworkManager-plugins/statoverride new file mode 100644 index 0000000..27a95af --- /dev/null +++ b/overlay.d/14NetworkManager-plugins/statoverride @@ -0,0 +1,2 @@ +# Config file for overriding permission bits on overlay files/dirs +# Format: = diff --git a/overlay.d/14NetworkManager-plugins/usr/lib/NetworkManager/conf.d/10-disable-default-plugins.conf b/overlay.d/14NetworkManager-plugins/usr/lib/NetworkManager/conf.d/10-disable-default-plugins.conf new file mode 100644 index 0000000..3182f67 --- /dev/null +++ b/overlay.d/14NetworkManager-plugins/usr/lib/NetworkManager/conf.d/10-disable-default-plugins.conf @@ -0,0 +1,9 @@ +# Stop NetworkManager from trying to load the ifcfg-rh plugin by default, +# which we don't ship. This actually disables all default plugins, of which +# ifcfg-rh is currently the only one. +# +# Note that we must do this for now because `-=` syntax doesn't work +# with compiled-in defaults. Proposed upstream fix: +# https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/491 +[main] +plugins= diff --git a/overlay.d/15fcos/etc/ssh/sshd_config.d/40-disable-passwords.conf b/overlay.d/15fcos/etc/ssh/sshd_config.d/40-disable-passwords.conf new file mode 100644 index 0000000..5785acd --- /dev/null +++ b/overlay.d/15fcos/etc/ssh/sshd_config.d/40-disable-passwords.conf @@ -0,0 +1,5 @@ +# Disable password logins by default. +# https://github.com/coreos/fedora-coreos-tracker/issues/138 +# This file must sort before 50-redhat.conf, which enables +# PasswordAuthentication. +PasswordAuthentication no diff --git a/overlay.d/15fcos/statoverride b/overlay.d/15fcos/statoverride new file mode 100644 index 0000000..27a95af --- /dev/null +++ b/overlay.d/15fcos/statoverride @@ -0,0 +1,2 @@ +# Config file for overriding permission bits on overlay files/dirs +# Format: = diff --git a/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/20-aws-nm-cloud-setup.ign b/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/20-aws-nm-cloud-setup.ign new file mode 100644 index 0000000..0d39b16 --- /dev/null +++ b/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/20-aws-nm-cloud-setup.ign @@ -0,0 +1,16 @@ +{ + "ignition": { + "version": "3.0.0" + }, + "storage": { + "files": [ + { + "path": "/etc/systemd/system/nm-cloud-setup.service.d/env-aws.conf", + "contents": { + "source": "data:,%5BService%5D%0AEnvironment%3DNM_CLOUD_SETUP_EC2%3Dyes%0A" + }, + "mode": 420 + } + ] + } +} diff --git a/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/20-azure-nm-cloud-setup.ign b/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/20-azure-nm-cloud-setup.ign new file mode 100644 index 0000000..ed2a5c5 --- /dev/null +++ b/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/20-azure-nm-cloud-setup.ign @@ -0,0 +1,16 @@ +{ + "ignition": { + "version": "3.0.0" + }, + "storage": { + "files": [ + { + "path": "/etc/systemd/system/nm-cloud-setup.service.d/env-azure.conf", + "contents": { + "source": "data:,%5BService%5D%0AEnvironment%3DNM_CLOUD_SETUP_AZURE%3Dyes%0A" + }, + "mode": 420 + } + ] + } +} diff --git a/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/20-gcp-nm-cloud-setup.ign b/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/20-gcp-nm-cloud-setup.ign new file mode 100644 index 0000000..22966dd --- /dev/null +++ b/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/20-gcp-nm-cloud-setup.ign @@ -0,0 +1,16 @@ +{ + "ignition": { + "version": "3.0.0" + }, + "storage": { + "files": [ + { + "path": "/etc/systemd/system/nm-cloud-setup.service.d/env-gcp.conf", + "contents": { + "source": "data:,%5BService%5D%0AEnvironment%3DNM_CLOUD_SETUP_GCP%3Dyes%0A" + }, + "mode": 420 + } + ] + } +} diff --git a/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/30-afterburn-sshkeys-core.ign b/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/30-afterburn-sshkeys-core.ign new file mode 100644 index 0000000..98fc47a --- /dev/null +++ b/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/30-afterburn-sshkeys-core.ign @@ -0,0 +1,13 @@ +{ + "ignition": { + "version": "3.0.0" + }, + "systemd": { + "units": [ + { + "enabled": true, + "name": "afterburn-sshkeys@core.service" + } + ] + } +} diff --git a/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/README.md b/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/README.md new file mode 100644 index 0000000..a9a2be9 --- /dev/null +++ b/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/README.md @@ -0,0 +1 @@ +FCOS enables `afterburn-sshkeys@core.service` from `30-afterburn-sshkeys-core.ign`, allowing the user to prevent Ignition from enabling the service with a user config if the user wants to change the username. Unlike FCOS, RHCOS doesn't fetch SSH keys from cloud providers and thus doesn't need `afterburn-sshkeys@core.service`. diff --git a/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/module-setup.sh b/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/module-setup.sh new file mode 100755 index 0000000..8e9f9d9 --- /dev/null +++ b/overlay.d/15fcos/usr/lib/dracut/modules.d/50ignition-conf-fcos/module-setup.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +depends() { + echo ignition +} + +install() { + mkdir -p "$initdir/usr/lib/ignition/base.d" + mkdir -p "$initdir/usr/lib/ignition/base.platform.d" + + # Common entries + inst "$moddir/30-afterburn-sshkeys-core.ign" \ + "/usr/lib/ignition/base.d/30-afterburn-sshkeys-core.ign" + + # Platform specific: aws + mkdir -p "$initdir/usr/lib/ignition/base.platform.d/aws" + inst "$moddir/20-aws-nm-cloud-setup.ign" \ + "/usr/lib/ignition/base.platform.d/aws/20-aws-nm-cloud-setup.ign" + + # Platform specific: azure + mkdir -p "$initdir/usr/lib/ignition/base.platform.d/azure" + inst "$moddir/20-azure-nm-cloud-setup.ign" \ + "/usr/lib/ignition/base.platform.d/azure/20-azure-nm-cloud-setup.ign" + + # Platform specific: gcp + mkdir -p "$initdir/usr/lib/ignition/base.platform.d/gcp" + inst "$moddir/20-gcp-nm-cloud-setup.ign" \ + "/usr/lib/ignition/base.platform.d/gcp/20-gcp-nm-cloud-setup.ign" +} diff --git a/overlay.d/15fcos/usr/lib/motd.d/tracker.motd b/overlay.d/15fcos/usr/lib/motd.d/tracker.motd new file mode 100644 index 0000000..837cc57 --- /dev/null +++ b/overlay.d/15fcos/usr/lib/motd.d/tracker.motd @@ -0,0 +1,3 @@ +Tracker: https://github.com/coreos/fedora-coreos-tracker +Discuss: https://discussion.fedoraproject.org/c/server/coreos/ + diff --git a/overlay.d/15fcos/usr/lib/systemd/system-preset/45-fcos.preset b/overlay.d/15fcos/usr/lib/systemd/system-preset/45-fcos.preset new file mode 100644 index 0000000..c1d3e4d --- /dev/null +++ b/overlay.d/15fcos/usr/lib/systemd/system-preset/45-fcos.preset @@ -0,0 +1,5 @@ +# User metrics client +enable fedora-coreos-pinger.service +enable coreos-check-ssh-keys.service +# Check if cgroupsv1 is still being used +enable coreos-check-cgroups.service diff --git a/overlay.d/15fcos/usr/lib/systemd/system/coreos-check-cgroups.service b/overlay.d/15fcos/usr/lib/systemd/system/coreos-check-cgroups.service new file mode 100644 index 0000000..18e4b85 --- /dev/null +++ b/overlay.d/15fcos/usr/lib/systemd/system/coreos-check-cgroups.service @@ -0,0 +1,11 @@ +# This service is used for printing a message if +# cgroups v1 is still being used +[Unit] +Description=Check if cgroupsv1 is still being used +ConditionControlGroupController=v1 +[Service] +Type=oneshot +ExecStart=/usr/libexec/coreos-check-cgroups +RemainAfterExit=yes +[Install] +WantedBy=multi-user.target diff --git a/overlay.d/15fcos/usr/lib/systemd/system/coreos-check-ssh-keys.service b/overlay.d/15fcos/usr/lib/systemd/system/coreos-check-ssh-keys.service new file mode 100644 index 0000000..858e7ed --- /dev/null +++ b/overlay.d/15fcos/usr/lib/systemd/system/coreos-check-ssh-keys.service @@ -0,0 +1,24 @@ +# This service is used for printing a message if no ssh keys were added +# by Ignition/Afterburn +[Unit] +Description=Check that ssh-keys are added by Afterburn/Ignition +# It allows other units to synchronize around any instance +# of `afterburn-sshkeys@` and not just the `core` user. +# See https://github.com/coreos/afterburn/pull/481 +After=afterburn-sshkeys.target +# Only perform checks on the first (Ignition) boot as they are +# mostly useful only on that boot. This ensures systems started +# before Ignition/Afterburn started logging structured data don't +# get misleading messages. Also handles the case where the journal +# gets rotated and no longer has the structured log messages. +ConditionKernelCommandLine=ignition.firstboot +# Run before user sessions to avoid reloading agetty +Before=systemd-user-sessions.service + +[Service] +Type=oneshot +ProtectHome=read-only +ExecStart=/usr/libexec/coreos-check-ssh-keys +RemainAfterExit=yes +[Install] +WantedBy=multi-user.target diff --git a/overlay.d/15fcos/usr/libexec/coreos-check-cgroups b/overlay.d/15fcos/usr/libexec/coreos-check-cgroups new file mode 100755 index 0000000..39a68b7 --- /dev/null +++ b/overlay.d/15fcos/usr/libexec/coreos-check-cgroups @@ -0,0 +1,25 @@ +#!/usr/bin/bash +# This script checks if the system is still using cgroups v1 +# and prints a message to the serial console. + +# Change the output color to yellow +warn=$(echo -e '\033[0;33m') +# No color +nc=$(echo -e '\033[0m') + +motd_path=/run/motd.d/30_cgroupsv1_warning.motd + +cat << EOF > "${motd_path}" +${warn} +############################################################################ +WARNING: This system is using cgroups v1. For increased reliability +it is strongly recommended to migrate this system and your workloads +to use cgroups v2. For instructions on how to adjust kernel arguments +to use cgroups v2, see: +https://docs.fedoraproject.org/en-US/fedora-coreos/kernel-args/ + +To disable this warning, use: +sudo systemctl disable coreos-check-cgroups.service +############################################################################ +${nc} +EOF diff --git a/overlay.d/15fcos/usr/libexec/coreos-check-ssh-keys b/overlay.d/15fcos/usr/libexec/coreos-check-ssh-keys new file mode 100755 index 0000000..7a7bc35 --- /dev/null +++ b/overlay.d/15fcos/usr/libexec/coreos-check-ssh-keys @@ -0,0 +1,46 @@ +#!/usr/bin/bash +# This script will print a message in the serial console +# if no ssh keys were added by Ignition/Afterburn. +main() { + # Change the output color to yellow + warn='\033[0;33m' + # No color + nc='\033[0m' + + # See https://github.com/coreos/ignition/pull/964 for the MESSAGE_ID + # source. It will track the authorized-ssh-keys entries in journald + # provided via Ignition. + ignitionusers=$( + journalctl -o json-pretty MESSAGE_ID=225067b87bbd4a0cb6ab151f82fa364b | \ + jq -r '.MESSAGE' | \ + xargs -I{} echo "Ignition: {}") + + # See https://github.com/coreos/afterburn/pull/397 for the MESSAGE_ID + # source. It will track the authorized-ssh-keys entries in journald + # provided via Afterburn. + afterburnusers=$( + journalctl -o json-pretty MESSAGE_ID=0f7d7a502f2d433caa1323440a6b4190 | \ + jq -r '.MESSAGE' | \ + xargs -I{} echo "Afterburn: {}") + + output='' + if [ -n "$ignitionusers" ]; then + output+="$ignitionusers" + fi + if [ -n "$afterburnusers" ]; then + # add newline if needed + if [ -n "$output" ]; then + output+=$'\n' + fi + output+="$afterburnusers" + fi + + if [ -n "$output" ]; then + echo "$output" > /etc/issue.d/30_ssh_authorized_keys.issue + else + echo -e "${warn}No SSH authorized keys provided by Ignition or Afterburn${nc}" \ + > /etc/issue.d/30_ssh_authorized_keys.issue + fi +} + +main diff --git a/overlay.d/20platform-chrony/statoverride b/overlay.d/20platform-chrony/statoverride new file mode 100644 index 0000000..27a95af --- /dev/null +++ b/overlay.d/20platform-chrony/statoverride @@ -0,0 +1,2 @@ +# Config file for overriding permission bits on overlay files/dirs +# Format: = diff --git a/overlay.d/20platform-chrony/usr/lib/systemd/system-generators/coreos-platform-chrony b/overlay.d/20platform-chrony/usr/lib/systemd/system-generators/coreos-platform-chrony new file mode 100755 index 0000000..a87f656 --- /dev/null +++ b/overlay.d/20platform-chrony/usr/lib/systemd/system-generators/coreos-platform-chrony @@ -0,0 +1,99 @@ +#!/bin/bash +set -euo pipefail +# Configuring the timeserver for the platform is often handled +# by pre-baking a config into a particular image for a platform, but +# that doesn't work for us because we have a single update stream. Hence +# this generator dynamically inspects the platform and reconfigures chrony. +# +# AWS: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/set-time.html +# Azure: https://docs.microsoft.com/en-us/azure/virtual-machines/linux/time-sync +# GCP: https://cloud.google.com/compute/docs/instances/managing-instances#configure-ntp +# +# Originally spawned from discussion in https://github.com/openshift/installer/pull/3513 + +# Generators don't have logging right now +# https://github.com/systemd/systemd/issues/15638 +exec 1>/dev/kmsg; exec 2>&1 + +self=$(basename $0) +confpath=/run/coreos-platform-chrony.conf + +# Yeah this isn't a completely accurate kernel argument parser but +# we don't have one shared across shell services at the moment. +platform="$(grep -Eo ' ignition.platform.id=[a-z]+' /proc/cmdline | cut -f 2 -d =)" +case "${platform}" in + azure|azurestack|aws|gcp) ;; # OK, this is a platform we know how to support + *) exit 0 ;; +esac + +# Exit early if we have already been run once +if [[ -f "${confpath}" ]]; then + echo "$self: ${confpath} already exists; skipping" + exit 0 +fi + +# Exit early if chrony configuration as been changed from the image default +if ! cmp {/usr,}/etc/chrony.conf >/dev/null; then + echo "$self: /etc/chrony.conf is modified; not changing the default" + exit 0 +fi + +# If not set already (by host customization or this script), set +# PEERNTP=no so that DHCP-provided NTP servers are not added to chrony. +# By doing this we assume the better NTP server choice is the +# platform-provided link-local NTP server rather than others from DHCP. +# TODO: once https://bugzilla.redhat.com/show_bug.cgi?id=1828434 is +# resolved, this won't be required. +if [ ! -e /etc/sysconfig/network ] || ! grep -q "PEERNTP" /etc/sysconfig/network; then + cat <> /etc/sysconfig/network +# PEERNTP=no is automatically added by default when a platform-provided time +# source is available, but this behavior may be overridden through an Ignition +# config specifying PEERNTP=yes. See https://github.com/coreos/fedora-coreos-config/pull/412. +PEERNTP=no +EOF +fi + +(echo "# Generated by $self - do not edit directly" + sed -e s,'^makestep,#makestep,' -e s,'^pool,#pool,' -e s,'^leapsectz,#leapsectz,' < /etc/chrony.conf +cat < "${confpath}" +case "${platform}" in + azure | azurestack) + # the /dev/ptp_hyperv symlink is created by: + # https://github.com/systemd/systemd/blob/e67a5c14f0345f5ac456cfa109324dd9e70114d3/rules.d/50-udev-default.rules.in#L106 + (echo '# See also https://docs.microsoft.com/en-us/azure/virtual-machines/linux/time-sync' + echo 'refclock PHC /dev/ptp_hyperv poll 3 dpoll -2 offset 0' + echo 'leapsectz right/UTC' + ) >> "${confpath}" ;; + aws) + (echo '# See also https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/set-time.html' + echo 'server 169.254.169.123 prefer iburst minpoll 4 maxpoll 4' + ) >> "${confpath}" ;; + gcp) + (echo '# See also https://cloud.google.com/compute/docs/instances/managing-instances#configure-ntp' + echo '# and https://cloud.google.com/compute/docs/images/configuring-imported-images' + echo 'server metadata.google.internal prefer iburst' + ) >> "${confpath}" ;; + *) echo "should not be reached" 1>&2; exit 1 ;; +esac +# Policy doesn't allow chronyd to read run_t +chcon --reference=/etc/chrony.conf "${confpath}" + +UNIT_DIR="${1:-/tmp}" + +unitconfpath="${UNIT_DIR}/chronyd.service.d/coreos-platform-chrony.conf" +mkdir -p $(dirname "${unitconfpath}") +cat >"${unitconfpath}" << EOF +[Service] +ExecStart= +ExecStart=/usr/sbin/chronyd -f ${confpath} \$OPTIONS +EOF + +echo "$self: Updated chrony to use ${platform} configuration ${confpath}" diff --git a/overlay.d/README.md b/overlay.d/README.md new file mode 100644 index 0000000..384112f --- /dev/null +++ b/overlay.d/README.md @@ -0,0 +1,43 @@ +05core +----- + +This overlay matches `fedora-coreos-base.yaml`; core Ignition+ostree bits. + +08nouveau +--------- + +Blacklist the nouveau driver because it causes issues with some NVidia GPUs in EC2, +and we don't have a use case for FCOS with nouveau. + +"Cannot boot an p3.2xlarge instance with RHCOS (g3.4xlarge is working)" +https://bugzilla.redhat.com/show_bug.cgi?id=1700056 + +09misc +------ + +Warning about `/etc/sysconfig`. + +14NetworkManager-plugins +------------------------ + +Disables the Red Hat Linux legacy `ifcfg` format. + +15fcos +------ + +Things that are more closely "Fedora CoreOS": + +* disable password logins by default over SSH +* enable SSH keys written by Ignition and Afterburn +* branding (MOTD) +* enable services by default (fedora-coreos-pinger) +* display warnings on the console if no ignition config was provided or no ssh + key found. + +20platform-chrony +----------------- + +Add static chrony configuration for NTP servers provided on platforms +such as `azure`, `aws`, `gcp`. The chrony config for these NTP servers +should override other chrony configuration (e.g. DHCP-provided) +configuration. diff --git a/rocky.repo b/rocky.repo new file mode 100644 index 0000000..a383f01 --- /dev/null +++ b/rocky.repo @@ -0,0 +1,26 @@ +[appstream] +name=Rocky Linux $releasever - AppStream +mirrorlist=https://mirrors.rockylinux.org/mirrorlist?arch=$basearch&repo=AppStream-$releasever +#baseurl=http://dl.rockylinux.org/$contentdir/$releasever/AppStream/$basearch/os/ +gpgcheck=1 +enabled=1 +countme=1 +gpgkey=file:///usr/share/distribution-gpg-keys/rocky/RPM-GPG-KEY-Rocky-$releasever + +[baseos] +name=Rocky Linux $releasever - BaseOS +mirrorlist=https://mirrors.rockylinux.org/mirrorlist?arch=$basearch&repo=BaseOS-$releasever +#baseurl=http://dl.rockylinux.org/$contentdir/$releasever/BaseOS/$basearch/os/ +gpgcheck=1 +enabled=1 +countme=1 +gpgkey=file:///usr/share/distribution-gpg-keys/rocky/RPM-GPG-KEY-Rocky-$releasever + +[extras] +name=Rocky Linux $releasever - Extras +mirrorlist=https://mirrors.rockylinux.org/mirrorlist?arch=$basearch&repo=extras-$releasever +#baseurl=http://dl.rockylinux.org/$contentdir/$releasever/extras/$basearch/os/ +gpgcheck=1 +enabled=1 +countme=1 +gpgkey=file:///usr/share/distribution-gpg-keys/rocky/RPM-GPG-KEY-Rocky-$releasever