mirror of
https://github.com/coreos/fedora-coreos-config.git
synced 2026-02-06 03:46:24 +01:00
Containerfile: run postprocess scripts in build stage
To have optimal layers, let's run our postprocess scripts in the build stage _before_ chunking occurs. That way, the chunking operates on the final flattened tree and we don't carry around a fat layer at the end with lots of whiteouts. For example, we nuke documentation as a postprocess script, which meant that we were actually still carrying all the docs in the lower layers. (On that topic, we should switch to `documentation: false` really.) But also e.g. we recompile the SELinux policy, edit a bunch of files, etc. This also fixes a bug in29ac01e6("Containerfile: include rechunking step"), in which I forgot to remove a `COPY` statement that copies the whole rootfs on top of the rechunked image. Ouch. This uses bwrap to run the scripts. Another way to do this of course is to go back to what we had before29ac01e6(where we copied the rootfs from the previous stage into a scratch rootfs and then ran the postprocess scripts) and _then_ rechunk. The huge advantage doing it the bwrap way is that it avoids that expensive full rootfs copy. With this change, the image size in the container-native and non-native paths are comparable.
This commit is contained in:
@@ -41,14 +41,6 @@ RUN --mount=type=bind,from=builder,target=/var/tmp \
|
||||
--mount=type=bind,target=/run/src,rw \
|
||||
rm /run/src/out.ociarchive
|
||||
|
||||
COPY --from=builder /target-rootfs/ /
|
||||
RUN <<EOF
|
||||
set -xeuo pipefail
|
||||
for script in /usr/libexec/coreos-postprocess-*; do
|
||||
$script; rm $script
|
||||
done
|
||||
EOF
|
||||
|
||||
LABEL containers.bootc=1
|
||||
LABEL ostree.bootable=1
|
||||
LABEL org.opencontainers.image.version=$VERSION
|
||||
|
||||
24
build-rootfs
24
build-rootfs
@@ -46,7 +46,7 @@ def main():
|
||||
|
||||
if version != "":
|
||||
inject_version_info(target_rootfs, manifest['mutate-os-release'], version)
|
||||
inject_postprocess_scripts(target_rootfs, manifest)
|
||||
run_postprocess_scripts(target_rootfs, manifest)
|
||||
|
||||
|
||||
def get_treefile(manifest_path):
|
||||
@@ -120,15 +120,33 @@ def inject_passwd_group(parent_dir):
|
||||
shutil.copy(os.path.join(parent_dir, 'group'), dst_group)
|
||||
|
||||
|
||||
def inject_postprocess_scripts(rootfs, manifest):
|
||||
def run_postprocess_scripts(rootfs, manifest):
|
||||
# since we have the derive-only manifest handy, just inject a script now
|
||||
# that we can execute in the second stage. we could of course use e.g.
|
||||
# bwrap to run those now, but... it's just cleaner to use multi-stage build
|
||||
# semantics
|
||||
for i, script in enumerate(manifest.get('postprocess', [])):
|
||||
with open(os.path.join(rootfs, f'usr/libexec/coreos-postprocess-{i}'), mode='w') as f:
|
||||
name = f'usr/libexec/coreos-postprocess-{i}'
|
||||
with open(os.path.join(rootfs, name), mode='w') as f:
|
||||
os.fchmod(f.fileno(), 0o755)
|
||||
f.write(script)
|
||||
bwrap(rootfs, [f'/{name}'])
|
||||
os.unlink(os.path.join(rootfs, name))
|
||||
|
||||
|
||||
# Could upstream this as e.g. `bootc-base-imagectl runroot /rootfs <cmd>` maybe?
|
||||
# But we'd need to carry it anyway at least for RHCOS 9.6.
|
||||
def bwrap(rootfs, args):
|
||||
subprocess.check_call(['bwrap',
|
||||
'--dev', '/dev', '--proc', '/proc',
|
||||
'--dir', '/tmp', '--dir', '/var', '--tmpfs', '/run',
|
||||
'--bind', '/run/.containerenv', '/run/.containerenv',
|
||||
'--bind', f'{rootfs}/usr', '/usr',
|
||||
'--bind', f'{rootfs}/etc', '/etc',
|
||||
'--symlink', '/usr/lib', '/lib',
|
||||
'--symlink', '/usr/lib64', '/lib64',
|
||||
'--symlink', '/usr/bin', '/bin',
|
||||
'--symlink', '/usr/sbin', '/sbin', '--'] + args)
|
||||
|
||||
|
||||
def get_locked_nevras():
|
||||
|
||||
Reference in New Issue
Block a user