From 86a1f73170647d89fde981ef592739af31d5fe07 Mon Sep 17 00:00:00 2001
From: Omer Tuchfeld <omer@tuchfeld.dev>
Date: Tue, 10 Dec 2024 21:13:52 +0100
Subject: [PATCH] donotmerge: IBX changes

Some (trash, temporary) changes I had to perform on bootc to get IBX to work

- `./Containerfile` builds a bootable image from an existing normal IBX seed
- `./build_seed.sh` is just a helper script

To install on recipient

```
sudo podman run --privileged --env RUST_LOG=trace -v /var/lib/containers/storage:/var/lib/containers/storage --pid=host -it quay.io/your/seed:image bootc install to-existing-root --acknowledge-destructive --stateroot foo
```

This PR only exists to start discussions around concrete issues, it's not meant to be merged.
---
 .dockerignore      |  2 ++
 Containerfile      | 26 ++++++++++++++++++
 Makefile           |  4 +--
 build_seed.sh      |  9 ++++++
 hack/Containerfile |  6 ++--
 lib/src/install.rs | 68 +++-------------------------------------------
 6 files changed, 46 insertions(+), 69 deletions(-)
 create mode 100644 Containerfile
 create mode 100755 build_seed.sh

diff --git a/.dockerignore b/.dockerignore
index 697adc052..4c029068b 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -4,3 +4,5 @@ target
 # These directories don't contribute to our container build
 docs/
 plans/
+Containerfile
+build_seed.sh
diff --git a/Containerfile b/Containerfile
new file mode 100644
index 000000000..b3279d72d
--- /dev/null
+++ b/Containerfile
@@ -0,0 +1,26 @@
+FROM quay.io/centos/centos:stream9 as build
+COPY hack/build.sh /build.sh
+RUN /build.sh && rm -v /build.sh
+COPY . /build
+WORKDIR /build
+RUN mkdir -p /build/target/dev-rootfs  # This can hold arbitrary extra content
+# See https://www.reddit.com/r/rust/comments/126xeyx/exploring_the_problem_of_faster_cargo_docker/
+# We aren't using the full recommendations there, just the simple bits.
+RUN --mount=type=cache,target=/build/target --mount=type=cache,target=/var/roothome make test-bin-archive && mkdir -p /out && cp target/bootc.tar /out
+RUN mkdir -p /build/target/dev-rootfs  # This can hold arbitrary extra content
+
+FROM quay.io/otuchfel/ostbackup:serv1 as seed
+
+# ____________________________________________________________________________
+
+FROM quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:5b1124faf4b73753b4679085604dd8cb810c4a7a2e659978f5c80183bb165f94
+
+LABEL com.openshift.lifecycle-agent.seed_format_version=3
+
+RUN mkdir -p /usr/lib/bootc/install
+RUN echo -e '[install.filesystem.root]\ntype = "xfs"' > /usr/lib/bootc/install/00-bootc.toml
+
+COPY --from=seed --exclude=ostree.tgz / /var/tmp/seed
+
+COPY --from=build /out/bootc.tar /tmp
+RUN tar -C / -xvf /tmp/bootc.tar && rm -vrf /tmp/*
diff --git a/Makefile b/Makefile
index 1a96f63a8..efc65f73d 100644
--- a/Makefile
+++ b/Makefile
@@ -39,10 +39,10 @@ install-all: install install-ostree-hooks
 	install -D -m 0755 target/release/tests-integration $(DESTDIR)$(prefix)/bin/bootc-integration-tests 
 
 bin-archive: all
-	$(MAKE) install DESTDIR=tmp-install && $(TAR_REPRODUCIBLE) --zstd -C tmp-install -cf target/bootc.tar.zst . && rm tmp-install -rf
+	$(MAKE) install DESTDIR=tmp-install && $(TAR_REPRODUCIBLE) -C tmp-install -cf target/bootc.tar . && rm tmp-install -rf
 
 test-bin-archive: all
-	$(MAKE) install-all DESTDIR=tmp-install && $(TAR_REPRODUCIBLE) --zstd -C tmp-install -cf target/bootc.tar.zst . && rm tmp-install -rf
+	$(MAKE) install-all DESTDIR=tmp-install && $(TAR_REPRODUCIBLE) -C tmp-install -cf target/bootc.tar . && rm tmp-install -rf
 
 test-tmt:
 	cargo xtask test-tmt
diff --git a/build_seed.sh b/build_seed.sh
new file mode 100755
index 000000000..4f113a9f4
--- /dev/null
+++ b/build_seed.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+SCRIPT_DIR=$(dirname $0)
+
+cd $SCRIPT_DIR
+
+podman build -t bootcseed -f Containerfile .
+podman tag bootcseed:latest quay.io/otuchfel/bootc:seed
+podman push quay.io/otuchfel/bootc:seed
diff --git a/hack/Containerfile b/hack/Containerfile
index 50f88ff90..d7453a6f2 100644
--- a/hack/Containerfile
+++ b/hack/Containerfile
@@ -14,7 +14,7 @@ WORKDIR /build
 RUN mkdir -p /build/target/dev-rootfs  # This can hold arbitrary extra content
 # See https://www.reddit.com/r/rust/comments/126xeyx/exploring_the_problem_of_faster_cargo_docker/
 # We aren't using the full recommendations there, just the simple bits.
-RUN --mount=type=cache,target=/build/target --mount=type=cache,target=/var/roothome make test-bin-archive && mkdir -p /out && cp target/bootc.tar.zst /out
+RUN --mount=type=cache,target=/build/target --mount=type=cache,target=/var/roothome make test-bin-archive && mkdir -p /out && cp target/bootc.tar /out
 
 FROM $base
 # We support e.g. adding cloud-init
@@ -26,8 +26,8 @@ COPY hack/install-test-configs/* /usr/lib/bootc/install/
 # And some test kargs
 COPY hack/test-kargs /usr/lib/bootc/kargs.d/
 # Inject our built code
-COPY --from=build /out/bootc.tar.zst /tmp
-RUN tar -C / --zstd -xvf /tmp/bootc.tar.zst && rm -vrf /tmp/*
+COPY --from=build /out/bootc.tar /tmp
+RUN tar -C / -xvf /tmp/bootc.tar && rm -vrf /tmp/*
 # Also copy over arbitrary bits from the target root
 COPY --from=build /build/target/dev-rootfs/ /
 # Test our own linting
diff --git a/lib/src/install.rs b/lib/src/install.rs
index 548c3e8d3..dd8d14b1d 100644
--- a/lib/src/install.rs
+++ b/lib/src/install.rs
@@ -334,7 +334,7 @@ pub(crate) struct SourceInfo {
     /// The digest to use for pulls
     pub(crate) digest: Option<String>,
     /// Whether or not SELinux appears to be enabled in the source commit
-    pub(crate) selinux: bool,
+    pub(crate) _selinux: bool,
     /// Whether the source is available in the host mount namespace
     pub(crate) in_host_mountns: bool,
 }
@@ -585,7 +585,7 @@ impl SourceInfo {
         Ok(Self {
             imageref,
             digest,
-            selinux,
+            _selinux: selinux,
             in_host_mountns,
         })
     }
@@ -946,7 +946,7 @@ pub(crate) fn reexecute_self_for_selinux_if_needed(
     override_disable_selinux: bool,
 ) -> Result<SELinuxFinalState> {
     // If the target state has SELinux enabled, we need to check the host state.
-    if srcdata.selinux {
+    if false {
         let host_selinux = crate::lsm::selinux_enabled()?;
         tracing::debug!("Target has SELinux, host={host_selinux}");
         let r = if override_disable_selinux {
@@ -1031,66 +1031,6 @@ fn ensure_var() -> Result<()> {
     Ok(())
 }
 
-/// We want to have proper /tmp and /var/tmp without requiring the caller to set them up
-/// in advance by manually specifying them via `podman run -v /tmp:/tmp` etc.
-/// Unfortunately, it's quite complex right now to "gracefully" dynamically reconfigure
-/// the mount setup for a container.  See https://brauner.io/2023/02/28/mounting-into-mount-namespaces.html
-/// So the brutal hack we do here is to rely on the fact that we're running in the host
-/// pid namespace, and so the magic link for /proc/1/root will escape our mount namespace.
-/// We can't bind mount though - we need to symlink it so that each calling process
-/// will traverse the link.
-#[context("Linking tmp mounts to host")]
-pub(crate) fn setup_tmp_mounts() -> Result<()> {
-    let st = rustix::fs::statfs("/tmp")?;
-    if st.f_type == libc::TMPFS_MAGIC {
-        tracing::trace!("Already have tmpfs /tmp")
-    } else {
-        // Note we explicitly also don't want a "nosuid" tmp, because that
-        // suppresses our install_t transition
-        Task::new("Mounting tmpfs /tmp", "mount")
-            .args(["tmpfs", "-t", "tmpfs", "/tmp"])
-            .quiet()
-            .run()?;
-    }
-
-    // Point our /var/tmp at the host, via the /proc/1/root magic link
-    for path in ["/var/tmp"].map(Utf8Path::new) {
-        if path.try_exists()? {
-            let st = rustix::fs::statfs(path.as_std_path()).context(path)?;
-            if st.f_type != libc::OVERLAYFS_SUPER_MAGIC {
-                tracing::trace!("Already have {path} with f_type={}", st.f_type);
-                continue;
-            }
-        }
-        let target = format!("/proc/1/root/{path}");
-        let tmp = format!("{path}.tmp");
-        // Ensure idempotence in case we're re-executed
-        if path.is_symlink() {
-            continue;
-        }
-        tracing::debug!("Retargeting {path} to host");
-        if path.try_exists()? {
-            std::os::unix::fs::symlink(&target, &tmp)
-                .with_context(|| format!("Symlinking {target} to {tmp}"))?;
-            let cwd = rustix::fs::CWD;
-            rustix::fs::renameat_with(
-                cwd,
-                path.as_os_str(),
-                cwd,
-                &tmp,
-                rustix::fs::RenameFlags::EXCHANGE,
-            )
-            .with_context(|| format!("Exchanging {path} <=> {tmp}"))?;
-            std::fs::rename(&tmp, format!("{path}.old"))
-                .with_context(|| format!("Renaming old {tmp}"))?;
-        } else {
-            std::os::unix::fs::symlink(&target, path)
-                .with_context(|| format!("Symlinking {target} to {path}"))?;
-        };
-    }
-    Ok(())
-}
-
 /// By default, podman/docker etc. when passed `--privileged` mount `/sys` as read-only,
 /// but non-recursively.  We selectively grab sub-filesystems that we need.
 #[context("Ensuring sys mount {fspath} {fstype}")]
@@ -1222,7 +1162,7 @@ async fn prepare_install(
     crate::mount::ensure_mirrored_host_mount("/dev")?;
     crate::mount::ensure_mirrored_host_mount("/var/lib/containers")?;
     ensure_var()?;
-    setup_tmp_mounts()?;
+    // setup_tmp_mounts()?;
     // Allocate a temporary directory we can use in various places to avoid
     // creating multiple.
     let tempdir = cap_std_ext::cap_tempfile::TempDir::new(cap_std::ambient_authority())?;