From 59fe1d1510d77cb525b9c1b6d889886aa82cac7d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 31 Aug 2016 16:48:33 -0400 Subject: [PATCH] Backport patch for running inside mock --- ...d-a-workaround-for-Fedora-s-use-of-r.patch | 147 ++++++++++++++++++ 0001-mutate-os-release-skip-VERSION_ID.patch | 34 ---- rpm-ostree.spec | 7 +- 3 files changed, 152 insertions(+), 36 deletions(-) create mode 100644 0001-bwrap-compose-Add-a-workaround-for-Fedora-s-use-of-r.patch delete mode 100644 0001-mutate-os-release-skip-VERSION_ID.patch diff --git a/0001-bwrap-compose-Add-a-workaround-for-Fedora-s-use-of-r.patch b/0001-bwrap-compose-Add-a-workaround-for-Fedora-s-use-of-r.patch new file mode 100644 index 0000000..98b333b --- /dev/null +++ b/0001-bwrap-compose-Add-a-workaround-for-Fedora-s-use-of-r.patch @@ -0,0 +1,147 @@ +From 3ad4e6c72bb5b25745252da4fd1cab6e00827f72 Mon Sep 17 00:00:00 2001 +From: Colin Walters +Date: Mon, 15 Aug 2016 11:58:03 -0400 +Subject: [PATCH] bwrap/compose: Add a workaround for Fedora's use of + rpm-ostree-in-mock + +Decided to test this on Sunday evening. Of course it was broken =( +(Actually I tested mock-in-Docker but it should be the same) + +The core problem is that mock does `chroot()` without using `/` +as a mount point. This breaks an assumption in bwrap that it is. +Now, in theory we could move this same logic down into bwrap to +work around this situation, but for now let's hack it here. + +Mock is old, legacy container code that doesn't really do anything +in a modern way - in fact our goal should be to replace it +with a combination of rpm-ostree and bwrap. So carrying this +hack here to get us to that future should be OK for now. + +Closes: #431 +Approved by: jlebon +--- + src/app/rpmostree-compose-builtin-tree.c | 4 ++ + src/libpriv/rpmostree-bwrap.c | 81 ++++++++++++++++++++++++++++++++ + src/libpriv/rpmostree-bwrap.h | 1 + + 3 files changed, 86 insertions(+) + +diff --git a/src/app/rpmostree-compose-builtin-tree.c b/src/app/rpmostree-compose-builtin-tree.c +index 5ea1cbe..e49c5e4 100644 +--- a/src/app/rpmostree-compose-builtin-tree.c ++++ b/src/app/rpmostree-compose-builtin-tree.c +@@ -630,6 +630,10 @@ rpmostree_compose_builtin_tree (int argc, + "compose tree must presently be run as uid 0 (root)"); + goto out; + } ++ ++ /* Mock->bwrap bootstrap for Fedora */ ++ if (!rpmostree_bwrap_bootstrap_if_in_mock (error)) ++ goto out; + /* Test whether or not bwrap is going to work - we will fail inside e.g. a Docker + * container without --privileged or userns exposed. + */ +diff --git a/src/libpriv/rpmostree-bwrap.c b/src/libpriv/rpmostree-bwrap.c +index bd7c793..85e7837 100644 +--- a/src/libpriv/rpmostree-bwrap.c ++++ b/src/libpriv/rpmostree-bwrap.c +@@ -108,6 +108,87 @@ rpmostree_run_sync_fchdir_setup (char **argv_array, GSpawnFlags flags, + return TRUE; + } + ++/* mock doesn't actually use a mount namespace, and hence bwrap will ++ * fail to remount /. Work around this by doing it here. Fedora ++ * runs rpm-ostree inside of mock instead of Docker or something ++ * more modern. ++ */ ++gboolean ++rpmostree_bwrap_bootstrap_if_in_mock (GError **error) ++{ ++ const char *env_ps1 = getenv ("PS1"); ++ static const char *mock_mounted_paths[] = { "/proc", "/sys" }; ++ static const char *findmnt_argv[] = { "findmnt", "/", NULL }; ++ g_autofree char *pwd = NULL; ++ int estatus; ++ ++ if (!(env_ps1 && strstr (env_ps1, ""))) ++ return TRUE; ++ ++ /* Okay, we detected we're inside mock. Let's double check now ++ * whether or not / is already a mount point. The simplest way to ++ * do this is to execute findmnt...maybe someday we'll link to libmount ++ * but this is legacy. ++ */ ++ if (!g_spawn_sync (NULL, (char**)findmnt_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, ++ NULL, NULL, &estatus, error)) ++ { ++ g_prefix_error (error, "Executing findmnt: "); ++ return FALSE; ++ } ++ /* Did findmnt say / is a mount point? Okay, nothing to do here. */ ++ if (estatus == 0) ++ return TRUE; ++ ++ pwd = getcwd (NULL, 0); ++ ++ g_print ("Detected mock chroot without / as mount, enabling workaround.\n"); ++ if (unshare (CLONE_NEWNS) < 0) ++ { ++ glnx_set_prefix_error_from_errno (error, "%s", "unshare(CLONE_NEWNS)"); ++ return FALSE; ++ } ++ /* For reasons I don't fully understand, trying to bind mount / -> / ++ * doesn't work. We seem to hit a check in the kernel: ++ * ++ * static int do_change_type(struct path *path, int flag) ++ * { ++ * ... ++ * if (path->dentry != path->mnt->mnt_root) ++ * return -EINVAL; ++ */ ++ if (mount ("/", "/mnt", NULL, MS_MGC_VAL | MS_BIND, NULL) != 0) ++ { ++ glnx_set_prefix_error_from_errno (error, "%s", "mount(/ as bind)"); ++ return FALSE; ++ } ++ /* Now take the paths that mock mounted (that we need) and move them ++ * underneath the new rootfs mount. ++ */ ++ for (guint i = 0; i < G_N_ELEMENTS (mock_mounted_paths); i++) ++ { ++ const char *mockpath = mock_mounted_paths[i]; ++ g_autofree char *destpath = g_strconcat ("/mnt", mockpath, NULL); ++ if (mount (mockpath, destpath, NULL, MS_MGC_VAL | MS_MOVE, NULL) != 0) ++ { ++ glnx_set_prefix_error_from_errno (error, "%s", "mount(move)"); ++ return FALSE; ++ } ++ } ++ if (chroot ("/mnt") < 0) ++ { ++ glnx_set_error_from_errno (error); ++ return FALSE; ++ } ++ if (chdir (pwd) < 0) ++ { ++ glnx_set_error_from_errno (error); ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ + /* Execute /bin/true inside a bwrap container on the host */ + gboolean + rpmostree_bwrap_selftest (GError **error) +diff --git a/src/libpriv/rpmostree-bwrap.h b/src/libpriv/rpmostree-bwrap.h +index b4bb88c..b464355 100644 +--- a/src/libpriv/rpmostree-bwrap.h ++++ b/src/libpriv/rpmostree-bwrap.h +@@ -31,4 +31,5 @@ void rpmostree_ptrarray_append_strdup (GPtrArray *argv_array, ...) G_GNUC_NULL_T + gboolean rpmostree_run_sync_fchdir_setup (char **argv_array, GSpawnFlags flags, + int rootfs_fd, GError **error); + ++gboolean rpmostree_bwrap_bootstrap_if_in_mock (GError **error); + gboolean rpmostree_bwrap_selftest (GError **error); +-- +2.7.4 + diff --git a/0001-mutate-os-release-skip-VERSION_ID.patch b/0001-mutate-os-release-skip-VERSION_ID.patch deleted file mode 100644 index 147cf6f..0000000 --- a/0001-mutate-os-release-skip-VERSION_ID.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0fe12fe6a37ee98de5dec70c345d9f0479c47803 Mon Sep 17 00:00:00 2001 -From: Jonathan Lebon -Date: Wed, 17 Aug 2016 16:33:51 -0400 -Subject: [PATCH] mutate-os-release: skip VERSION_ID - -I hit this with librepo subbing out the $releasever with e.g. 7.2016.1 -when trying to pull various URLs. It should be enough for the user to -see the ostree version in VERSION and PRETTY_NAME. For applications, -there's OSTREE_VERSION if they need just that. - -Closes: #433 -Approved by: cgwalters ---- - src/libpriv/rpmostree-postprocess.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/libpriv/rpmostree-postprocess.c b/src/libpriv/rpmostree-postprocess.c -index 17ec151..d0566bd 100644 ---- a/src/libpriv/rpmostree-postprocess.c -+++ b/src/libpriv/rpmostree-postprocess.c -@@ -1380,8 +1380,9 @@ mutate_os_release (const char *contents, - if (strlen (line) == 0) - continue; - -+ /* NB: we don't mutate VERSION_ID because some libraries expect well-known -+ * values there*/ - if (g_str_has_prefix (line, "VERSION=") || \ -- g_str_has_prefix (line, "VERSION_ID=") || \ - g_str_has_prefix (line, "PRETTY_NAME=")) - { - g_autofree char *new_line = NULL; --- -2.7.4 - diff --git a/rpm-ostree.spec b/rpm-ostree.spec index ea52f5e..bfc099d 100644 --- a/rpm-ostree.spec +++ b/rpm-ostree.spec @@ -1,11 +1,11 @@ Summary: Client side upgrade program and server side compose tool Name: rpm-ostree Version: 2016.7 -Release: 2%{?dist} +Release: 3%{?dist} #VCS: https://github.com/cgwalters/rpm-ostree # This tarball is generated via "make -f Makefile.dist-packaging dist-snapshot" Source0: rpm-ostree-%{version}.tar.xz -Patch0: 0001-mutate-os-release-skip-VERSION_ID.patch +Patch0: 0001-bwrap-compose-Add-a-workaround-for-Fedora-s-use-of-r.patch License: LGPLv2+ URL: https://github.com/projectatomic/rpm-ostree # We always run autogen.sh @@ -122,6 +122,9 @@ python autofiles.py > files.devel \ %files devel -f files.devel %changelog +* Wed Aug 31 2016 Colin Walters - 2016.7-3 +- Backport patch for running inside mock + * Sat Aug 13 2016 walters@redhat.com - 2016.6-3 - New upstream version