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

Support custom mountpoints under /var (COMPOSER-2301) #601

Merged
merged 23 commits into from
Aug 15, 2024

Conversation

achilleas-k
Copy link
Member

This PR adds initial support for specifying custom mountpoints while creating a disk image. We define a new mountpoint policy internal to BIB, separate and more restrictive than the ostree mountpoint policies in osbuild/images. The rules are:

  1. / and /boot are supported for modifying their size.
  2. Custom mountpoints under /var that do not become symlinks to other paths are supported.
  3. /var itself is not.

The combination of 2. and 3. isn't directly supported in our policy checkers, so instead the policy in this PR initially allows for /var and its subdirectories, but then makes an explicit check that /var itself isn't in the custom filesystems in the blueprint.

Btrfs subvolumes are not supported because they are mounted with the parent disk at the location where they are created, so it is not possible to run bootc install to-filesystem with an empty root fileystem (see also osbuild/images#846). Since mountpoints cannot be created at paths that will contain data on or before first boot, a workaround for this would be to create subvolumes on first boot (manually or otherwise). We could enable this with firstboot scripts if necessary.

The discussion in #579 should provide further context for the limitations.

@achilleas-k achilleas-k force-pushed the partitions branch 3 times, most recently from 4642953 to a4ade40 Compare August 9, 2024 18:49
mvo5 added a commit to mvo5/images that referenced this pull request Aug 12, 2024
Trivial tweak for the errors returned from PathPolicies.Check()
so that they are a bit more user friendly.

See also osbuild/bootc-image-builder#601
mvo5
mvo5 previously approved these changes Aug 12, 2024
Copy link
Collaborator

@mvo5 mvo5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! This looks nice and will be a super nice feature for our users. I have some small suggestion inline mostly around the error handling/comments. It's fine to merge as is of course as my suggestions are all cosmetic.

bib/cmd/bootc-image-builder/image.go Outdated Show resolved Hide resolved
bib/cmd/bootc-image-builder/image.go Outdated Show resolved Hide resolved
bib/cmd/bootc-image-builder/image.go Show resolved Hide resolved
bib/cmd/bootc-image-builder/image.go Outdated Show resolved Hide resolved
test/test_build.py Outdated Show resolved Hide resolved
@achilleas-k
Copy link
Member Author

The error messages we test for will change once osbuild/images#853 is merged and pulled in here, but we can deal with that separately if this gets merged first.

github-merge-queue bot pushed a commit to osbuild/images that referenced this pull request Aug 12, 2024
Trivial tweak for the errors returned from PathPolicies.Check()
so that they are a bit more user friendly.

See also osbuild/bootc-image-builder#601
@achilleas-k
Copy link
Member Author

I think everything's sorted now.

@cgwalters
Copy link
Contributor

I tried to dig into this a bit but maybe I'm missing it...what's the expected UX here? What would some sample blueprints look like?

@cgwalters
Copy link
Contributor

IOW it'd be helpful I think if the PR included changes to the docs in this repo at least.

@achilleas-k
Copy link
Member Author

I've updated the README with information on the new customizations.

Copy link
Collaborator

@mvo5 mvo5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updated version and the excellent README update. It seems some unit test is failing so I won't appove just yet but it looks very close. Some small suggestions/questions inline for your consideration.

bib/cmd/bootc-image-builder/image.go Show resolved Hide resolved
bib/cmd/bootc-image-builder/image.go Outdated Show resolved Hide resolved
bib/cmd/bootc-image-builder/image.go Outdated Show resolved Hide resolved
@achilleas-k
Copy link
Member Author

It seems some unit test is failing so I won't appove just yet but it looks very close.

Yeah, I spotted those too but was waiting for the full result to address them (running locally was taking too long last night and I had to stop). I'll get to them now.

README.md Outdated Show resolved Hide resolved
@achilleas-k
Copy link
Member Author

It seems some unit test is failing so I won't appove just yet but it looks very close.

The issue was the fallback logic for the root filesystem type in cross-arch builds. I made some changes to the internal logic there, making it an error if it's not set from outside the Manifest() call. I think I prefer the explicitness.

mvo5
mvo5 previously approved these changes Aug 13, 2024
Copy link
Collaborator

@mvo5 mvo5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you

@cgwalters
Copy link
Contributor

I think this change stands alone and makes sense on its own; but we did also discuss supporting fully custom toplevel mount points like /data or whatever - is that a followup?

There's also the case for e.g. /mnt (a default empty toplevel directory)

@achilleas-k
Copy link
Member Author

I think this change stands alone and makes sense on its own; but we did also discuss supporting fully custom toplevel mount points like /data or whatever - is that a followup?

Yes, after our discussion in #579, I decided the quickest way to get something working is this. Top-level mounts will need to be handled differently (.mount units?), so once we figure all that out, we can have it work the same way for everything.

@achilleas-k
Copy link
Member Author

Needs a bit more work for fs type handling and cross-arch builds.

With the changes in 5f70417, the
minimum size for the root filesystem, calculated as double the size of
the base container, was not being considered at all—the Filesystems
property of the ManifestConfig was being ignored.
Also, the rootfs type from the container was not being applied to the
root filesystem in the base partition table.

Replace the Filesystems property with a simple RootfsMinsize to clarify
its purpose and use it to update or add to the user-defined
customizations.

Add a new function, setRootfsType(), which sets the root filesystem type
based on the rootfs option set either by the container config or the
user option.
The function replicates the checks that were moved to
TestBasePartitionTablesHaveRoot().  The checks in the test code will
catch any modifications to the static partition tables defined in code.
Running the same checks while modifying the partition table will also
catch any issues caused by the partition table being modified before the
rootfs type is applied.
@achilleas-k achilleas-k force-pushed the partitions branch 2 times, most recently from e987d13 to 7809d9b Compare August 14, 2024 13:50
@achilleas-k
Copy link
Member Author

I applied @mvo5's patch for splitting out the PT handling and adds tests.
I also rebased on main and resolved the conflicts.

@achilleas-k achilleas-k requested a review from mvo5 August 14, 2024 13:51
When setting the rootfs type, make sure it's not an empty string, which
would be invalid.
This makes it a hard requirement that the ManifestConfig.RootFSType is
set when calling manifestForDiskImage() (i.e. Manifest() with
ManifestConfig.BuildType == BuildTypeDisk).
Before this change, the RootFSType validation would set the option to an
empty string when an unsupported type was used for cross-arch builds.
This left the type for the root filesystem unchanged from the default
when generating the partition table for the manifest.
Now that the RootFSType is required, let's be explicit about what we're
doing and set it to the only (currently) supported type for cross-arch
builds: ext4.
Iterate over each Mountable in the partition table (each filesystem) and
change the filesystem type to match the rootfs, with two exceptions:
- /boot/efi is never changed
- /boot is not changed when rootfs is btrfs

Do this *after* the partition table with the customizations has been
generated, so that all filesystems in the final partition table are
properly set.

This also fixes osbuild#407.
mvo5 and others added 5 commits August 14, 2024 20:23
Small tweak to make the partition table generation eaiser to test
in a "integration" type of way and adding some tests.
Add a test that checks that filesystem customizations appear in the
manifest in the fstab stage.  Checks that:
- All filesystems, where appropriate, have the same type as the desired
  rootfs.
- All filesystems listed in the customizations appear in the fstab
  stage.
Add the same test as in the previous commit but for cross-arch
manifests.  Cross-arch builds only support ext4 filesystems.  Any
selected root fstype (whether from the container itself or from the
--rootfs option) is ignored (with a warning)
mvo5
mvo5 previously approved these changes Aug 14, 2024
Copy link
Collaborator

@mvo5 mvo5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lovely, thank you!

@mvo5 mvo5 enabled auto-merge August 14, 2024 19:19
@mvo5
Copy link
Collaborator

mvo5 commented Aug 15, 2024

It fails right now with:

____ test_image_boots[quay.io/centos-bootc/centos-bootc:stream9,raw,arm64] _____
...
            # NOTE: xfs filesystems are ~40 MiB and ext4 ~26 MiB smaller than the partition - reduce minsize by 100 MiB
            minsize -= 100 * 2 ** 20
>           assert minsize < mountpoint_sizes[mountpoint]
E           assert 3116367872 < 3094126592

test/test_build.py:483: AssertionError

in

The size comparison in the build test is bad.  Customizations control
the size of a partition but the function was comparing the usable size
of a filesystem, which can be very different.  Attempts were made to
cover the difference, by simply reducing the expected size by a fixed
amount, but were ultimately inadequate.

We can do better.
Copy link
Collaborator

@mvo5 mvo5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is fine! We could look into cleaning up the commit history a bit, but it's probably fine as is.

@achilleas-k
Copy link
Member Author

It fails right now with:

____ test_image_boots[quay.io/centos-bootc/centos-bootc:stream9,raw,arm64] _____
...
            # NOTE: xfs filesystems are ~40 MiB and ext4 ~26 MiB smaller than the partition - reduce minsize by 100 MiB
            minsize -= 100 * 2 ** 20
>           assert minsize < mountpoint_sizes[mountpoint]
E           assert 3116367872 < 3094126592

test/test_build.py:483: AssertionError

Yup, that size comparison isn't great. Was a bad idea to just take a chunk out of the expected size and call it a day. I dropped the check and we can replace it with something a little smarter (see last commit), but I think we should leave that for another PR.

The partition sizing is either way tested at the manifest level. The boot test now checks that all mountpoints exist when the system is booted.

@achilleas-k
Copy link
Member Author

Thanks, this is fine! We could look into cleaning up the commit history a bit, but it's probably fine as is.

It did get a bit long, I agree. The last commit could be squashed, but let's keep my stupid attempt at a size comparison heuristic in there for posterity.

@mvo5 mvo5 added this pull request to the merge queue Aug 15, 2024
Merged via the queue into osbuild:main with commit 2713962 Aug 15, 2024
8 of 10 checks passed
@achilleas-k achilleas-k deleted the partitions branch August 15, 2024 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants