Create /etc files, symlinks and folders if they don't exist#264
Create /etc files, symlinks and folders if they don't exist#264
Conversation
215eba3 to
23b43c9
Compare
|
@pothos: Thanks for the draft PR. I didn't know that we already had a tmpfile generator, that's why I wanted to leverage what we already had (that is - existing tmpfiles in coreos-overlay packages). But since the generator is already there and it required only a minor patching, then yeah - I think your solution sounds good too. Do you want me to take it over or you will finish it? |
Happy to collaborate, feel free to push to this branch. Currently it's not working and some debugging lays ahead ;) |
23b43c9 to
e6df177
Compare
Ok, tmpfiles with |
93a4bea to
c905135
Compare
The trim should be the last action before the image is finalized, otherwise it may not result in the minimal size.
c905135 to
4beb19b
Compare
The copy of the factory /etc in /usr/share/flatcar/etc may have dead links because the relative linking assumes to be under /TOPDIR (flatcar/scripts#264). Ignore the folder in the check for dead links, we still check the resulting /etc hierarchy created based on it.
4beb19b to
2a923a3
Compare
| # rootfs and don't rely on the new image. Not done for the developer | ||
| # container. | ||
| if [[ -n "${image_kernel}" ]]; then | ||
| sudo rm --one-file-system -rf "${root_fs_dir}/etc" "${root_fs_dir}/var" |
There was a problem hiding this comment.
Why removing var if we are not backing it up? Or maybe - why not backing up var above, like we do with etc?
jepio
left a comment
There was a problem hiding this comment.
I reviewed this, and I worry about the long term effects of shipping something like this now. If long term we want to do 3-way merge (not a fan, lots could go wrong) or the overlay solution, then there will be very different behaviors around /etc in different releases.
The other concern is: if a user wants to remove a config file, the systemd-tmpfiles definition will bring it back on next boot, which could be bad. So I feel like we should either be doing this only on first boot (completely empty filesystem), or replace the individual file definitions with:
C /etc - - - - /usr/share/flatcar/etc
(will recursively copy without dereferencing symlinks, and only if etc is missing).
| parser = optparse.OptionParser(description=__doc__) | ||
| parser.add_option('--root', help='Remove root prefix from output') | ||
| parser.add_option('--output', help='Write output to the given file') | ||
| parser.add_option('--files', default='', help='Also works on files and symlinks and uses the given path as source for copying files') |
There was a problem hiding this comment.
This flag does two things. How about splitting into two, like:
--process-files and --file-src.
There was a problem hiding this comment.
Both need to be present, or it's a no-op, that's why I bound them together into one
|
Another question: the tmpfiles stuff runs in sysroot right? Is there anything in initramfs that needs to look at /etc (i know there is a parse-etc.service), or some service that needs config files before tmpfiles runs? Anything selinux related? |
|
We already support running from an empty rootfs that gets created by Ignition, and this is tested in the
Only doing it on first boot won't work, the goal we address here is that required files get created not only on first boot but also after updates. Yes, currently a user can't remove the file, we would need the 3-way merge for that to have the old factory /etc as reference. I think depending on the file in question there are ways to disable it without removal (e.g., an empty file or a symlink to /dev/null) - in general this use case already wasn't possible anyway for the files we hardcoded to be under |
2a923a3 to
0fb9463
Compare
The existing tmpfile logic took care of folders that the ebuild keepdir directive wanted to exist on the OS. However, files and symlinks were not created, causing them to be missing if we didn't explicitly modify the ebuild files in coreos-overlay to find a solution with tmpfiles or patching the paths to /usr. Add logic to create missing files and symlinks through tmpfile directives and preserve any directory, not only the ones with the keepdir ebuild directive. Also remove any state from the rootfs to make sure that we don't rely on it when testing our images before the release. To create the files the final /etc folder is moved to /usr/share/flatcar/etc and in the future this can be used for a better logic that could take care of updating files the user didn't modify, deleting those that aren't needed anymore, and even reconciling changed files through a 3-way merge, instead of using simple tmpfile logic.
0fb9463 to
e263b4b
Compare
But the way tmpfiles works is it will only copy files over if the file is missing, not if its updated. So with updates we will only ever accumulate new files and keep all old contents. This is different to the way we currently work with read-only config files in /usr and also different to the way an overlay would work (with an overlay, config files the user doesn't modify would be updated together with the overlay).
I thought about empty files or symlinks to /dev/null, but are we sure every application will handle that correctly and not error out saying "configuration unreadable"? So this feels like we need to have a plan for where we're going first. I like the idea behind this PR but wouldn't want it to lock us into a solution that we would have to break in a couple of months again. |
|
Correct, the update under I think of this here as an interim solution that is not perfect but could help already. If we think it causes more trouble, I'm fine to skip it and go straight to a custom logic that is executed at a similar stage. |
|
I have my reservations but they are not strong enough to attempt to block this. For config file merging gentoo has two built-in tools to look at: |
|
I'm really ok to wait and go straight to the solution that covers updating files under /etc, not only creating missing files. More opinions on this @krnowak? Do you think we should take this and start dropping downstream patches? Or take it only as a safety measure and keep most downstream patches until we have a comprehensive solution? |
| sudo chroot "${root_fs_dir}" bash -c "cd /usr/share/selinux/mcs && semodule -s mcs -i *.pp" | ||
| fi | ||
|
|
||
| write_contents "${root_fs_dir}" "${BUILD_DIR}/${image_contents}" |
There was a problem hiding this comment.
@krnowak I didn't move the write_contents here with the idea that for the image contents /etc is the path that makes more sense. I'm totally fine moving this below to have the real image contents with /usr/share/…etc.
|
Thinking about this again I would say that using an overlayfs is great to sidestep the requirement of doing a 3-way comparison and operating on files but it gives us the same benefits (the content merging is probably something out of reach anyway…). |
I admit that the message is not entirely clear to me. To set up the overlayfs we will need the read-only lower directory, read-write upper directory and the merged directory. As I understand it, |
|
Create /etc files, symlinks and folders if they don't exist
The existing tmpfile logic took care of folders that the ebuild keepdir
directive wanted to exist on the OS. However, files and symlinks were
not created, causing them to be missing if we didn't explicitly modify
the ebuild files in coreos-overlay to find a solution with tmpfiles or
patching the paths to /usr.
Add logic to create missing files and symlinks through tmpfile
directives and preserve any directory, not only the ones with the
keepdir ebuild directive. Also remove any state from the rootfs to make
sure that we don't rely on it when testing our images before the
release. To create the files the final /etc folder is moved to
/usr/share/flatcar/etc and in the future this can be used for a better logic
that could take care of updating files the user didn't modify, deleting
those that aren't needed anymore, and even reconciling changed files
through a 3-way merge, instead of using simple tmpfile logic.
build_library/build_image_util.sh: move image modification before trim
The trim should be the last action before the image is finalized,
otherwise it may not result in the minimal size.
How to use
Testing done
Done here
using flatcar/mantle#316 should fix the failing tests.
Also did some manual tests of the python script and checked the generated entries in the image and the resulting files.
changelog/directory (user-facing change, bug fix, security fix, update)