Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build ZFS sysext with each release #1742

Merged
merged 19 commits into from
Mar 13, 2024
Merged

Build ZFS sysext with each release #1742

merged 19 commits into from
Mar 13, 2024

Conversation

jepio
Copy link
Member

@jepio jepio commented Mar 11, 2024

Build ZFS sysext with each release

Add a ZFS sysext that is built with every Flatcar release and can be enabled through the /etc/flatcar/enabled-sysext.conf mechanism that @pothos added. Since it provides a kernel module, it is tightly coupled to the Flatcar release. To solve issues with etc configs and udev rules needing to be run after the sysext is loaded, I created a tmpfiles.d that sets up the required symlinks and ordering between sysext.service and udev.service.

Following @pothos advice, i've added a step for building the sysexts after the image build. This DEFAULT_SYSEXTS can be extended to add more sysexts.

There are also some other improvements that I've added:

  • sysext building can happen in parallel
  • SOURCE_DATE_EPOCH is set for sysext build. I've taken the timestamp of the /usr/lib/os-release file as the source of the timestamp.
  • coreos-kernel now provides a better module build environment in /lib/modules/.../build so that the ZFS mod can be built and which should simplify building nvidia-drivers.
  • app-alternatives/awk is now pulled into the image instead of gawk.
  • update_ebuild --portage=rsync now works for eclasses

Pulls in this:

How to use

(still need to try the end to end flow once this is on bincache)

./build_image
./build_image sysext
scp flatcar-zfs.raw flatcar:/etc/extensions/

[ describe what reviewers need to do in order to validate this PR ]

Testing done

[Describe the testing you have done before submitting this PR. Please include both the commands you issued as well as the output you got.]

  • Changelog entries added in the respective changelog/ directory (user-facing change, bug fix, security fix, update)
  • Inspected CI output for image differences: /boot and /usr size, packages, list files for any missing binaries, kernel modules, config files, kernel modules, etc.

@jepio jepio requested a review from a team March 11, 2024 10:32
@pothos
Copy link
Member

pothos commented Mar 11, 2024

Overall this looks very nice :)
For release publishing we already have the required logic in download_payloads and generate_payload so I hope that it works smooth and we don't run into bugs while we exercise this path for the first time.

Copy link

github-actions bot commented Mar 11, 2024

jepio added 13 commits March 11, 2024 11:57
This function is meant to prebuild certain sysexts to be released along
with each release. These will not be built into the image, but instead
can be fetched by the user on demand.

The command to build sysexts would be:

  ./build_image prod sysext

Signed-off-by: Jeremi Piotrowski <[email protected]>
by skipping the check for an existing image directory if we're not
building an image. This makes './build_image sysext' work.

Signed-off-by: Jeremi Piotrowski <[email protected]>
For eclasses we need to skip the mkdir and trailing slash.

Signed-off-by: Jeremi Piotrowski <[email protected]>
build/source, which is accidentally an empty directory, needs to be a
symlink so that Gentoo kmod ebuilds can build when setting
KERNEL_DIR=/lib/modules/.../build. They detect the proper layout with
the symlink.

The other issue is building the Nvidia driver with
SYSSRC=/lib/modules/.../build. This works on Ubuntu but fails on
Flatcar. Ubuntus build directory contains symlinks to includes from the
source tree so recreate the same layout.

Signed-off-by: Jeremi Piotrowski <[email protected]>
We explicitly install gawk but our profile explicitly forces the gawk
useflag for app-alternatives/awk.  Some packages, like zfs, depend on
app-alternatives/awk and it also installs the awk -> gawk that the gawk
ebuild creates through pkg_postinst. So switch to app-alternatives/awk
to make the implementation cleaner.

Signed-off-by: Jeremi Piotrowski <[email protected]>
and a package.provided entry for a dependency that we don't need.

Signed-off-by: Jeremi Piotrowski <[email protected]>
From Gentoo commit df182f2891606e757be3e8406a69f4a0e53ee324. Also import
dist-kernel-utils.eclass.

Signed-off-by: Jeremi Piotrowski <[email protected]>
The zfs-kmod ebuild needs KERNEL_DIR to point to the correct
/lib/modules directory.

The zfs ebuild installs two systemd unit masks to /usr/lib/systemd which
result in "dangling symlink" errors during the image build. These
systemd unit masks are only necessary for old Ubuntu systems that have
sysv-init-systemd compat wrappers.

Signed-off-by: Jeremi Piotrowski <[email protected]>
We need zfs build as a board package so that we can provide a zfs
sysext.

Signed-off-by: Jeremi Piotrowski <[email protected]>
There are two challenges with the sysext: it needs config files in /etc
and it needs udev rules for mounting during boot to work. The etc files
are placed in the standard flatcar etc overlay path but the overlay is
mounted from the initrd. So instead, we create a tmpfiles.d rule that
symlinks the best important files over. For the udev issue, we create a
drop-in in /etc that ensures udev runs after systemd-sysext.

We also can't rely on systemd presets to work, so instead parse the
preset file and statically create the service dependencies. For the
primary zfs.target we rely on an Upholds entry. Users can still disabled
unwanted services if they want.

We also removed unnecessary files:
- development files
- initramfs related scripts

Signed-off-by: Jeremi Piotrowski <[email protected]>
Signed-off-by: Jeremi Piotrowski <[email protected]>
This allows it to be sourced from other scripts and used e.g. in
generating an image changes summary.

Signed-off-by: Jeremi Piotrowski <[email protected]>
@jepio
Copy link
Member Author

jepio commented Mar 11, 2024

Had to force push because i forgot to add zfs to board-packages.

Gentoo's linux-info.eclass tries to check the kernel version by
including /lib/modules/.../source/Makefile and printing $(VERSION).  It
unsets ARCH= before doing this (no clue why) which works with a full
source tree but not with our minimized one. To fix this we need to
archive arch/x86/Makefile also for arm64.

Signed-off-by: Jeremi Piotrowski <[email protected]>
@jepio
Copy link
Member Author

jepio commented Mar 12, 2024

@pothos: still need to fix something in bootengine and this looks slightly weird:

core@localhost ~ $ systemd-sysext status
HIERARCHY EXTENSIONS         SINCE
/opt      none               -
/usr      containerd-flatcar Tue 2024-03-12 08:30:52 UTC
          docker-flatcar
          flatcar-zfs
          oem-qemu

@jepio
Copy link
Member Author

jepio commented Mar 12, 2024

This is my test butane json:

variant: flatcar
version: 1.0.0
storage:
  files:
  - path: /etc/flatcar/enabled-sysext.conf
    contents:
      inline: |
        zfs
  directories:
  - path: /etc/flatcar/sysext
systemd:
  units:
  - name: zpool-create.service
    enabled: true
    contents: |
      [Unit]
      ConditionFirstBoot=1
      Before=first-boot-complete.target
      Wants=first-boot-complete.target

      [Service]
      ExecStart=zpool create tank /dev/vdb

      [Install]
      WantedBy=multi-user.target

Fix a missing mkdir of /sysroot/etc/flatcar/sysext from the initrd before
attempting to move sysext files there. Also explicitly omit dracut zfs module
from initrd generation.

Signed-off-by: Jeremi Piotrowski <[email protected]>
@jepio
Copy link
Member Author

jepio commented Mar 13, 2024

@pothos want to have this in the nearest alpha?

@pothos
Copy link
Member

pothos commented Mar 13, 2024

Would be good because the bootengine PR is already merged

@jepio
Copy link
Member Author

jepio commented Mar 13, 2024

@pothos pushed a changelog, if you have a suggestion you can commit it directly.

@sayanchowdhury lets merge this before building alpha.

@pothos pothos merged commit e586791 into main Mar 13, 2024
1 check failed
@pothos pothos deleted the jepio/zfs-sysext branch March 13, 2024 22:24
@pothos
Copy link
Member

pothos commented Mar 13, 2024

Thanks a lot 🚀

@abuisine
Copy link

Cool to see this upstreamed !

@jepio
Copy link
Member Author

jepio commented Mar 22, 2024

Cool to see this upstreamed !

hey @abuisine, I was planning to write you to see if it works for your usecase. Still need to add docs, but mantle contains the test case we now have in our CI infra with butane examples, see here:
https://github.com/flatcar/mantle/blob/flatcar-master/kola/tests/sysext/zfs.go#L19-L116

@abuisine
Copy link

We'll make a bunch of tests next week for sure, will keep you posted

@coreyjewett
Copy link

Thanks @jepio! I was previously using the enix modules, but never got them to work right at boot. I switched to the alpha channel and 3913.0.0 loaded my pool as expected right after reboot. 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants