2017.4-1 -- new upstream version

This commit is contained in:
Jonathan Lebon 2017-04-13 14:03:33 -04:00
parent 794d0df4b7
commit 27df6f91b6
6 changed files with 7 additions and 1006 deletions

1
.gitignore vendored
View File

@ -46,3 +46,4 @@
/rpm-ostree-2017.1.tar.xz
/rpm-ostree-2017.2.tar.xz
/rpm-ostree-2017.3.tar.xz
/rpm-ostree-2017.4.tar.xz

View File

@ -1,279 +0,0 @@
From 62a93c78500edd9c67b2300cba1134b373138258 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Thu, 16 Mar 2017 11:29:21 -0400
Subject: [PATCH] postprocess: Handle f26 /etc/nsswitch.conf configuration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
F26 put sss first, which broke our regexp. When we switch to sysusers, man it'll
be nice to dump ♲ this.
Closes: https://github.com/projectatomic/rpm-ostree/issues/685
Closes: #686
Approved by: jlebon
---
Makefile-tests.am | 5 ++
src/libpriv/rpmostree-postprocess.c | 95 +++++++++++++++++++++++++++++--------
src/libpriv/rpmostree-postprocess.h | 5 ++
tests/check/postprocess.c | 93 ++++++++++++++++++++++++++++++++++++
4 files changed, 179 insertions(+), 19 deletions(-)
create mode 100644 tests/check/postprocess.c
diff --git a/Makefile-tests.am b/Makefile-tests.am
index ab9f9cc..b173877 100644
--- a/Makefile-tests.am
+++ b/Makefile-tests.am
@@ -75,6 +75,10 @@ tests_check_cache_branch_to_nevra_CPPFLAGS = $(AM_CPPFLAGS) -I $(srcdir)/src/lib
tests_check_cache_branch_to_nevra_CFLAGS = $(AM_CFLAGS) $(PKGDEP_RPMOSTREE_CFLAGS)
tests_check_cache_branch_to_nevra_LDADD = $(PKGDEP_RPMOSTREE_LIBS) librpmostreepriv.la
+tests_check_postprocess_CPPFLAGS = $(AM_CPPFLAGS) -I $(srcdir)/src/libpriv -I $(srcdir)/libglnx
+tests_check_postprocess_CFLAGS = $(AM_CFLAGS) $(PKGDEP_RPMOSTREE_CFLAGS)
+tests_check_postprocess_LDADD = $(PKGDEP_RPMOSTREE_LIBS) librpmostreepriv.la
+
tests/check/test-compose.sh: tests/common/compose/test-repo.repo
tests/check/test-ucontainer.sh: tests/common/compose/test-repo.repo
@@ -82,6 +86,7 @@ tests/check/test-ucontainer.sh: tests/common/compose/test-repo.repo
uninstalled_test_programs = \
tests/check/jsonutil \
tests/check/cache_branch_to_nevra \
+ tests/check/postprocess \
$(NULL)
uninstalled_test_scripts = \
diff --git a/src/libpriv/rpmostree-postprocess.c b/src/libpriv/rpmostree-postprocess.c
index dce8ddc..cff6e8d 100644
--- a/src/libpriv/rpmostree-postprocess.c
+++ b/src/libpriv/rpmostree-postprocess.c
@@ -512,34 +512,91 @@ rpmostree_prepare_rootfs_get_sepolicy (int dfd,
return ret;
}
-static gboolean
-replace_nsswitch (int dfd,
- GCancellable *cancellable,
- GError **error)
+static char *
+replace_nsswitch_string (const char *buf,
+ GError **error)
{
- g_autofree char *nsswitch_contents = NULL;
- g_autofree char *new_nsswitch_contents = NULL;
+ gboolean is_passwd;
+ gboolean is_group;
+
+ is_passwd = g_str_has_prefix (buf, "passwd:");
+ is_group = g_str_has_prefix (buf, "group:");
+
+ if (!(is_passwd || is_group))
+ return g_strdup (buf);
+
+ const char *colon = strchr (buf, ':');
+ g_assert (colon);
+
+ g_autoptr(GString) retbuf = g_string_new ("");
+ /* Insert the prefix */
+ g_string_append_len (retbuf, buf, (colon - buf) + 1);
+
+ /* Now parse the elements and try to insert `altfiles`
+ * after `files`.
+ */
+ g_auto(GStrv) elts = g_strsplit_set (colon + 1, " \t", -1);
+ gboolean inserted = FALSE;
+ for (char **iter = elts; iter && *iter; iter++)
+ {
+ const char *v = *iter;
+ if (!*v)
+ continue;
+ /* Already have altfiles? We're done */
+ if (strcmp (v, "altfiles") == 0)
+ return g_strdup (buf);
+ /* We prefer `files altfiles` */
+ else if (!inserted && strcmp (v, "files") == 0)
+ {
+ g_string_append (retbuf, " files altfiles");
+ inserted = TRUE;
+ }
+ else
+ {
+ g_string_append_c (retbuf, ' ');
+ g_string_append (retbuf, v);
+ }
+ }
+ /* Last ditch effort if we didn't find `files` */
+ if (!inserted)
+ g_string_append (retbuf, " altfiles");
+ return g_string_free (g_steal_pointer (&retbuf), FALSE);
+}
- static gsize regex_initialized;
- static GRegex *passwd_regex;
+char *
+rpmostree_postprocess_replace_nsswitch (const char *buf,
+ GError **error)
+{
+ g_autoptr(GString) new_buf = g_string_new ("");
- if (g_once_init_enter (&regex_initialized))
+ g_auto(GStrv) lines = g_strsplit (buf, "\n", -1);
+ for (char **iter = lines; iter && *iter; iter++)
{
- passwd_regex = g_regex_new ("^(passwd|group):\\s+files(.*)$",
- G_REGEX_MULTILINE, 0, NULL);
- g_assert (passwd_regex);
- g_once_init_leave (&regex_initialized, 1);
+ const char *line = *iter;
+ g_autofree char *replaced_line = replace_nsswitch_string (line, error);
+ if (!replaced_line)
+ return NULL;
+ g_string_append (new_buf, replaced_line);
+ if (*(iter+1))
+ g_string_append_c (new_buf, '\n');
}
+ return g_string_free (g_steal_pointer (&new_buf), FALSE);
+}
+
- nsswitch_contents = glnx_file_get_contents_utf8_at (dfd, "etc/nsswitch.conf", NULL,
- cancellable, error);
+static gboolean
+replace_nsswitch (int dfd,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_autofree char *nsswitch_contents =
+ glnx_file_get_contents_utf8_at (dfd, "etc/nsswitch.conf", NULL,
+ cancellable, error);
if (!nsswitch_contents)
return FALSE;
- new_nsswitch_contents = g_regex_replace (passwd_regex,
- nsswitch_contents, -1, 0,
- "\\1: files altfiles\\2",
- 0, error);
+ g_autofree char *new_nsswitch_contents =
+ rpmostree_postprocess_replace_nsswitch (nsswitch_contents, error);
if (!new_nsswitch_contents)
return FALSE;
diff --git a/src/libpriv/rpmostree-postprocess.h b/src/libpriv/rpmostree-postprocess.h
index a270c98..1c972ac 100644
--- a/src/libpriv/rpmostree-postprocess.h
+++ b/src/libpriv/rpmostree-postprocess.h
@@ -23,6 +23,11 @@
#include <ostree.h>
#include "rpmostree-json-parsing.h"
+/* "public" for unit tests */
+char *
+rpmostree_postprocess_replace_nsswitch (const char *buf,
+ GError **error);
+
gboolean
rpmostree_treefile_postprocessing (int rootfs_fd,
GFile *context_directory,
diff --git a/tests/check/postprocess.c b/tests/check/postprocess.c
new file mode 100644
index 0000000..135be94
--- /dev/null
+++ b/tests/check/postprocess.c
@@ -0,0 +1,93 @@
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib-unix.h>
+#include "libglnx.h"
+#include "rpmostree-postprocess.h"
+
+typedef struct {
+ const char *input;
+ const char *output;
+} AltfilesTest;
+
+static AltfilesTest altfiles_tests[] = {
+ {
+ /* F25 */
+ .input = "# An nsswitch.conf\n" \
+ "\npasswd: files sss\n" \
+ "\ngroup: files sss\n" \
+ "\nhosts: files mdns4_minimal [NOTFOUND=return] dns myhostname\n",
+ .output = "# An nsswitch.conf\n" \
+ "\npasswd: files altfiles sss\n" \
+ "\ngroup: files altfiles sss\n" \
+ "\nhosts: files mdns4_minimal [NOTFOUND=return] dns myhostname\n"
+ },
+ {
+ /* F26 */
+ .input = "# An nsswitch.conf\n" \
+ "\npasswd: sss files systemd\n" \
+ "\ngroup: sss files systemd\n" \
+ "\nhosts: files mdns4_minimal [NOTFOUND=return] dns myhostname\n",
+ .output = "# An nsswitch.conf\n" \
+ "\npasswd: sss files altfiles systemd\n" \
+ "\ngroup: sss files altfiles systemd\n" \
+ "\nhosts: files mdns4_minimal [NOTFOUND=return] dns myhostname\n"
+ },
+ {
+ /* Already have altfiles, input/output identical */
+ .input = "# An nsswitch.conf\n" \
+ "\npasswd: sss files altfiles systemd\n" \
+ "\ngroup: sss files altfiles systemd\n" \
+ "\nhosts: files mdns4_minimal [NOTFOUND=return] dns myhostname\n",
+ .output = "# An nsswitch.conf\n" \
+ "\npasswd: sss files altfiles systemd\n" \
+ "\ngroup: sss files altfiles systemd\n" \
+ "\nhosts: files mdns4_minimal [NOTFOUND=return] dns myhostname\n",
+ },
+ {
+ /* Test having `files` as a substring */
+ .input = "# An nsswitch.conf\n" \
+ "\npasswd: sss foofiles files systemd\n" \
+ "\ngroup: sss foofiles files systemd\n" \
+ "\nhosts: files mdns4_minimal [NOTFOUND=return] dns myhostname\n",
+ .output = "# An nsswitch.conf\n" \
+ "\npasswd: sss foofiles files altfiles systemd\n" \
+ "\ngroup: sss foofiles files altfiles systemd\n" \
+ "\nhosts: files mdns4_minimal [NOTFOUND=return] dns myhostname\n",
+ }
+};
+
+static void
+test_postprocess_altfiles (void)
+{
+ g_autoptr(GError) local_error = NULL;
+ GError **error = &local_error;
+
+ for (guint i = 0; i < G_N_ELEMENTS(altfiles_tests); i++)
+ {
+ AltfilesTest *test = &altfiles_tests[i];
+ g_autofree char *newbuf = rpmostree_postprocess_replace_nsswitch (test->input, error);
+
+ if (!newbuf)
+ goto out;
+
+ g_assert_cmpstr (newbuf, ==, test->output);
+ }
+
+ out:
+ g_assert_no_error (local_error);
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/altfiles", test_postprocess_altfiles);
+
+ return g_test_run ();
+}
--
2.9.3

View File

@ -1,100 +0,0 @@
From 9d294d5a394dfd7d6da37333616ed441dbe7103f Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Thu, 6 Apr 2017 17:45:54 -0400
Subject: [PATCH] treecompose: Prepare device API mounts
This gives scripts access to e.g. `/dev/urandom`. Short term
hack until we implement https://github.com/projectatomic/rpm-ostree/issues/729
The reason we don't need to explicitly clean these up before committing is right
now for treecompose we only lift `/usr` from the RPM content, so we don't run
into ostree refusing to commit devices.
Closes: https://github.com/projectatomic/rpm-ostree/issues/727
---
src/app/rpmostree-compose-builtin-tree.c | 50 +++++++++++++++++++++++++++++++-
1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/src/app/rpmostree-compose-builtin-tree.c b/src/app/rpmostree-compose-builtin-tree.c
index da6ea3b..6cff913 100644
--- a/src/app/rpmostree-compose-builtin-tree.c
+++ b/src/app/rpmostree-compose-builtin-tree.c
@@ -214,11 +214,56 @@ set_keyfile_string_array_from_json (GKeyFile *keyfile,
return ret;
}
+/* Prpare /dev in the target root with the API devices. TODO:
+ * Delete this when we implement https://github.com/projectatomic/rpm-ostree/issues/729
+ */
+static gboolean
+libcontainer_prep_dev (int rootfs_dfd,
+ GError **error)
+{
+
+ glnx_fd_close int src_fd = openat (AT_FDCWD, "/dev", O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY);
+ if (src_fd == -1)
+ return glnx_throw_errno (error);
+
+ if (mkdirat (rootfs_dfd, "dev", 0755) != 0)
+ {
+ if (errno != ENOENT)
+ return glnx_throw_errno (error);
+ }
+
+ glnx_fd_close int dest_fd = openat (rootfs_dfd, "dev", O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY);
+ if (dest_fd == -1)
+ return glnx_throw_errno (error);
+
+ static const char *const devnodes[] = { "null", "zero", "full", "random", "urandom", "tty" };
+ for (guint i = 0; i < G_N_ELEMENTS (devnodes); i++)
+ {
+ const char *nodename = devnodes[i];
+ struct stat stbuf;
+ if (fstatat (src_fd, nodename, &stbuf, 0) == -1)
+ {
+ if (errno == ENOENT)
+ continue;
+ else
+ glnx_throw_errno (error);
+ }
+
+ if (mknodat (dest_fd, nodename, stbuf.st_mode, stbuf.st_rdev) != 0)
+ return glnx_throw_errno (error);
+ if (fchmodat (dest_fd, nodename, stbuf.st_mode, 0) != 0)
+ return glnx_throw_errno (error);
+ }
+
+ return TRUE;
+}
+
static gboolean
install_packages_in_root (RpmOstreeTreeComposeContext *self,
RpmOstreeContext *ctx,
JsonObject *treedata,
GFile *yumroot,
+ int rootfs_dfd,
char **packages,
gboolean *out_unmodified,
char **out_new_inputhash,
@@ -406,6 +451,9 @@ install_packages_in_root (RpmOstreeTreeComposeContext *self,
glnx_console_lock (&console);
+ if (!libcontainer_prep_dev (rootfs_dfd, error))
+ goto out;
+
if (!dnf_transaction_commit (dnf_context_get_transaction (hifctx),
dnf_context_get_goal (hifctx),
hifstate,
@@ -915,7 +963,7 @@ rpmostree_compose_builtin_tree (int argc,
{ gboolean unmodified = FALSE;
- if (!install_packages_in_root (self, corectx, treefile, yumroot,
+ if (!install_packages_in_root (self, corectx, treefile, yumroot, rootfs_fd,
(char**)packages->pdata,
opt_force_nocache ? NULL : &unmodified,
&new_inputhash,
--
2.9.3

View File

@ -1,620 +0,0 @@
From cea2812fc01f8e37a6cdee3abcff511f2554703a Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Mon, 6 Mar 2017 14:17:06 -0500
Subject: [PATCH 1/5] Allow and start using C99 declaration-after-statement
The equivalent of https://github.com/ostreedev/ostree/pull/718
but for this codebase.
I just picked one example at random, there's plenty of others, but I don't want
to do any kind of tree-wide conversion since we have lots of outstanding
patches.
Closes: #664
Approved by: jlebon
---
configure.ac | 1 -
src/libpriv/rpmostree-util.c | 15 +++++----------
2 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/configure.ac b/configure.ac
index fc7d43f..c9a07b6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -44,7 +44,6 @@ CC_CHECK_FLAGS_APPEND([WARN_CFLAGS], [CFLAGS], [\
-Werror=incompatible-pointer-types \
-Werror=misleading-indentation \
-Werror=missing-include-dirs -Werror=aggregate-return \
- -Werror=declaration-after-statement \
])
AC_SUBST(WARN_CFLAGS)
diff --git a/src/libpriv/rpmostree-util.c b/src/libpriv/rpmostree-util.c
index b0aaec7..0f994e9 100644
--- a/src/libpriv/rpmostree-util.c
+++ b/src/libpriv/rpmostree-util.c
@@ -394,17 +394,14 @@ rpmostree_split_path_ptrarray_validate (const char *path,
GPtrArray **out_components,
GError **error)
{
- gboolean ret = FALSE;
- g_autoptr(GPtrArray) ret_components = NULL;
-
if (strlen (path) > PATH_MAX)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Path '%s' is too long", path);
- goto out;
+ return FALSE;
}
- ret_components = g_ptr_array_new_with_free_func (g_free);
+ g_autoptr(GPtrArray) ret_components = g_ptr_array_new_with_free_func (g_free);
do
{
@@ -426,23 +423,21 @@ rpmostree_split_path_ptrarray_validate (const char *path,
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Invalid empty component in path '%s'", path);
- goto out;
+ return FALSE;
}
if (g_str_equal (component, ".") ||
g_str_equal (component, ".."))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Invalid special element '.' or '..' in path %s", path);
- goto out;
+ return FALSE;
}
g_ptr_array_add (ret_components, (char*)g_steal_pointer (&component));
} while (path && *path);
- ret = TRUE;
*out_components = g_steal_pointer (&ret_components);
- out:
- return ret;
+ return TRUE;
}
/* Replace every occurrence of @old in @buf with @new. */
--
2.9.3
From 94e386fc86e4208dda03090f543f3e0f415d32e4 Mon Sep 17 00:00:00 2001
From: Jonathan Lebon <jlebon@redhat.com>
Date: Thu, 9 Mar 2017 16:39:03 -0500
Subject: [PATCH 2/5] status: always include the packages entries
Pull #646 introduced a subtle regression: we went from always including
a "packages" entry to only including it if there are packages present.
Albeit it's easy to guard against, though to be nice, let's make it
easier for consumers by always including it.
Reported-by: Micah Abbott <miabbott@redhat.com>
Closes: #670
Approved by: cgwalters
---
src/daemon/rpmostreed-deployment-utils.c | 15 +++++++++------
tests/vmcheck/test-layering-basic.sh | 6 ++++++
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/src/daemon/rpmostreed-deployment-utils.c b/src/daemon/rpmostreed-deployment-utils.c
index 42a990a..6961a0d 100644
--- a/src/daemon/rpmostreed-deployment-utils.c
+++ b/src/daemon/rpmostreed-deployment-utils.c
@@ -236,15 +236,18 @@ rpmostreed_deployment_generate_variant (OstreeDeployment *deployment,
}
g_variant_dict_insert (&dict, "origin", "s", refspec);
- if (g_hash_table_size (rpmostree_origin_get_packages (origin)) > 0)
- {
- g_autofree char **pkgs =
- (char**)g_hash_table_get_keys_as_array (rpmostree_origin_get_packages (origin), NULL);
- g_variant_dict_insert (&dict, "requested-packages", "^as", pkgs);
- }
+
+ g_autofree char **requested_pkgs =
+ (char**)g_hash_table_get_keys_as_array (rpmostree_origin_get_packages (origin), NULL);
+ g_variant_dict_insert (&dict, "requested-packages", "^as", requested_pkgs);
if (is_layered && g_strv_length (layered_pkgs) > 0)
g_variant_dict_insert (&dict, "packages", "^as", layered_pkgs);
+ else
+ {
+ const char *const p[] = { NULL };
+ g_variant_dict_insert (&dict, "packages", "^as", p);
+ }
if (sigs != NULL)
g_variant_dict_insert_value (&dict, "signatures", sigs);
diff --git a/tests/vmcheck/test-layering-basic.sh b/tests/vmcheck/test-layering-basic.sh
index 79e9562..ce10201 100755
--- a/tests/vmcheck/test-layering-basic.sh
+++ b/tests/vmcheck/test-layering-basic.sh
@@ -37,6 +37,12 @@ vm_assert_status_jq \
'.deployments[0]["base-checksum"]|not' \
'.deployments[0]["pending-base-checksum"]|not'
+# make sure that package-related entries are always present,
+# even when they're empty
+vm_assert_status_jq \
+ '.deployments[0]["packages"]' \
+ '.deployments[0]["requested-packages"]'
+
# Be sure an unprivileged user exists
vm_cmd getent passwd bin
if vm_cmd "runuser -u bin rpm-ostree pkg-add foo-1.0"; then
--
2.9.3
From 8df6672500c3404847b0e42e94dba076af4f5eb6 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Fri, 10 Mar 2017 09:48:03 -0500
Subject: [PATCH 3/5] bwrap: Don't use --unshare-net in nspawn by default
This will fix rpm-ostree-in-mock-in-koji. The drawback is minor: post scripts
will have network access. But we're going to be testing the no-network case in
our Docker-based builds, so that's fine.
---
scripts/bwrap-script-shell.sh | 6 +++++-
src/libpriv/rpmostree-bwrap.c | 20 +++++++++++++++++++-
2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/scripts/bwrap-script-shell.sh b/scripts/bwrap-script-shell.sh
index 98cadb6..e368869 100755
--- a/scripts/bwrap-script-shell.sh
+++ b/scripts/bwrap-script-shell.sh
@@ -6,9 +6,13 @@ shift
cd ${rootfs}
# ⚠⚠⚠ If you change this, also update src/libpriv/rpmostree-scripts.c ⚠⚠⚠
BWRAP_ARGV="--dev /dev --proc /proc --dir /tmp --chdir / \
- --unshare-pid --unshare-net --unshare-uts \
+ --unshare-pid --unshare-uts \
--unshare-ipc --unshare-cgroup-try \
"
+if ! test "${container:-}" = "systemd-nspawn"; then
+ BWRAP_ARGV="$BWRAP_ARGV --unshare-net"
+fi
+
for src in /sys/{block,bus,class,dev}; do
BWRAP_ARGV="$BWRAP_ARGV --ro-bind $src $src"
done
diff --git a/src/libpriv/rpmostree-bwrap.c b/src/libpriv/rpmostree-bwrap.c
index 9d40059..5258439 100644
--- a/src/libpriv/rpmostree-bwrap.c
+++ b/src/libpriv/rpmostree-bwrap.c
@@ -177,6 +177,22 @@ setup_rofiles_usr (RpmOstreeBwrap *bwrap,
return ret;
}
+/* nspawn by default doesn't give us CAP_NET_ADMIN; see
+ * https://pagure.io/releng/issue/6602#comment-71214
+ * https://pagure.io/koji/pull-request/344#comment-21060
+ *
+ * Theoretically we should do capable(CAP_NET_ADMIN)
+ * but that's a lot of ugly code, and the only known
+ * place we hit this right now is nspawn. Plus
+ * we want to use userns down the line anyways where
+ * we'll regain CAP_NET_ADMIN.
+ */
+static gboolean
+running_in_nspawn (void)
+{
+ return g_strcmp0 (getenv ("container"), "systemd-nspawn") == 0;
+}
+
RpmOstreeBwrap *
rpmostree_bwrap_new (int rootfs_fd,
RpmOstreeBwrapMutability mutable,
@@ -209,12 +225,14 @@ rpmostree_bwrap_new (int rootfs_fd,
* but it may need some mapping work.
*/
"--unshare-pid",
- "--unshare-net",
"--unshare-uts",
"--unshare-ipc",
"--unshare-cgroup-try",
NULL);
+ if (!running_in_nspawn ())
+ rpmostree_bwrap_append_bwrap_argv (ret, "--unshare-net", NULL);
+
for (guint i = 0; i < G_N_ELEMENTS (usr_links); i++)
{
const char *subdir = usr_links[i];
--
2.9.3
From 530d009df3afe4d769f065a2d5007e683bf81250 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Thu, 16 Mar 2017 11:29:21 -0400
Subject: [PATCH 4/5] postprocess: Handle f26 /etc/nsswitch.conf configuration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
F26 put sss first, which broke our regexp. When we switch to sysusers, man it'll
be nice to dump ♲ this.
Closes: https://github.com/projectatomic/rpm-ostree/issues/685
Closes: #686
Approved by: jlebon
---
Makefile-tests.am | 5 ++
src/libpriv/rpmostree-postprocess.c | 95 +++++++++++++++++++++++++++++--------
src/libpriv/rpmostree-postprocess.h | 5 ++
tests/check/postprocess.c | 93 ++++++++++++++++++++++++++++++++++++
4 files changed, 179 insertions(+), 19 deletions(-)
create mode 100644 tests/check/postprocess.c
diff --git a/Makefile-tests.am b/Makefile-tests.am
index 85c0fb4..a2163cf 100644
--- a/Makefile-tests.am
+++ b/Makefile-tests.am
@@ -71,12 +71,17 @@ tests_check_jsonutil_CPPFLAGS = $(AM_CPPFLAGS) -I $(srcdir)/src/libpriv -I $(src
tests_check_jsonutil_CFLAGS = $(AM_CFLAGS) $(PKGDEP_RPMOSTREE_CFLAGS)
tests_check_jsonutil_LDADD = $(PKGDEP_RPMOSTREE_LIBS) librpmostreepriv.la
+tests_check_postprocess_CPPFLAGS = $(AM_CPPFLAGS) -I $(srcdir)/src/libpriv -I $(srcdir)/libglnx
+tests_check_postprocess_CFLAGS = $(AM_CFLAGS) $(PKGDEP_RPMOSTREE_CFLAGS)
+tests_check_postprocess_LDADD = $(PKGDEP_RPMOSTREE_LIBS) librpmostreepriv.la
+
tests/check/test-compose.sh: tests/common/compose/test-repo.repo
tests/check/test-ucontainer.sh: tests/common/compose/test-repo.repo
uninstalled_test_programs = \
tests/check/jsonutil \
+ tests/check/postprocess \
$(NULL)
uninstalled_test_scripts = \
diff --git a/src/libpriv/rpmostree-postprocess.c b/src/libpriv/rpmostree-postprocess.c
index e75b010..43b1251 100644
--- a/src/libpriv/rpmostree-postprocess.c
+++ b/src/libpriv/rpmostree-postprocess.c
@@ -512,34 +512,91 @@ rpmostree_prepare_rootfs_get_sepolicy (int dfd,
return ret;
}
-static gboolean
-replace_nsswitch (int dfd,
- GCancellable *cancellable,
- GError **error)
+static char *
+replace_nsswitch_string (const char *buf,
+ GError **error)
{
- g_autofree char *nsswitch_contents = NULL;
- g_autofree char *new_nsswitch_contents = NULL;
+ gboolean is_passwd;
+ gboolean is_group;
+
+ is_passwd = g_str_has_prefix (buf, "passwd:");
+ is_group = g_str_has_prefix (buf, "group:");
+
+ if (!(is_passwd || is_group))
+ return g_strdup (buf);
+
+ const char *colon = strchr (buf, ':');
+ g_assert (colon);
+
+ g_autoptr(GString) retbuf = g_string_new ("");
+ /* Insert the prefix */
+ g_string_append_len (retbuf, buf, (colon - buf) + 1);
+
+ /* Now parse the elements and try to insert `altfiles`
+ * after `files`.
+ */
+ g_auto(GStrv) elts = g_strsplit_set (colon + 1, " \t", -1);
+ gboolean inserted = FALSE;
+ for (char **iter = elts; iter && *iter; iter++)
+ {
+ const char *v = *iter;
+ if (!*v)
+ continue;
+ /* Already have altfiles? We're done */
+ if (strcmp (v, "altfiles") == 0)
+ return g_strdup (buf);
+ /* We prefer `files altfiles` */
+ else if (!inserted && strcmp (v, "files") == 0)
+ {
+ g_string_append (retbuf, " files altfiles");
+ inserted = TRUE;
+ }
+ else
+ {
+ g_string_append_c (retbuf, ' ');
+ g_string_append (retbuf, v);
+ }
+ }
+ /* Last ditch effort if we didn't find `files` */
+ if (!inserted)
+ g_string_append (retbuf, " altfiles");
+ return g_string_free (g_steal_pointer (&retbuf), FALSE);
+}
- static gsize regex_initialized;
- static GRegex *passwd_regex;
+char *
+rpmostree_postprocess_replace_nsswitch (const char *buf,
+ GError **error)
+{
+ g_autoptr(GString) new_buf = g_string_new ("");
- if (g_once_init_enter (&regex_initialized))
+ g_auto(GStrv) lines = g_strsplit (buf, "\n", -1);
+ for (char **iter = lines; iter && *iter; iter++)
{
- passwd_regex = g_regex_new ("^(passwd|group):\\s+files(.*)$",
- G_REGEX_MULTILINE, 0, NULL);
- g_assert (passwd_regex);
- g_once_init_leave (&regex_initialized, 1);
+ const char *line = *iter;
+ g_autofree char *replaced_line = replace_nsswitch_string (line, error);
+ if (!replaced_line)
+ return NULL;
+ g_string_append (new_buf, replaced_line);
+ if (*(iter+1))
+ g_string_append_c (new_buf, '\n');
}
+ return g_string_free (g_steal_pointer (&new_buf), FALSE);
+}
+
- nsswitch_contents = glnx_file_get_contents_utf8_at (dfd, "etc/nsswitch.conf", NULL,
- cancellable, error);
+static gboolean
+replace_nsswitch (int dfd,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_autofree char *nsswitch_contents =
+ glnx_file_get_contents_utf8_at (dfd, "etc/nsswitch.conf", NULL,
+ cancellable, error);
if (!nsswitch_contents)
return FALSE;
- new_nsswitch_contents = g_regex_replace (passwd_regex,
- nsswitch_contents, -1, 0,
- "\\1: files altfiles\\2",
- 0, error);
+ g_autofree char *new_nsswitch_contents =
+ rpmostree_postprocess_replace_nsswitch (nsswitch_contents, error);
if (!new_nsswitch_contents)
return FALSE;
diff --git a/src/libpriv/rpmostree-postprocess.h b/src/libpriv/rpmostree-postprocess.h
index a270c98..1c972ac 100644
--- a/src/libpriv/rpmostree-postprocess.h
+++ b/src/libpriv/rpmostree-postprocess.h
@@ -23,6 +23,11 @@
#include <ostree.h>
#include "rpmostree-json-parsing.h"
+/* "public" for unit tests */
+char *
+rpmostree_postprocess_replace_nsswitch (const char *buf,
+ GError **error);
+
gboolean
rpmostree_treefile_postprocessing (int rootfs_fd,
GFile *context_directory,
diff --git a/tests/check/postprocess.c b/tests/check/postprocess.c
new file mode 100644
index 0000000..135be94
--- /dev/null
+++ b/tests/check/postprocess.c
@@ -0,0 +1,93 @@
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib-unix.h>
+#include "libglnx.h"
+#include "rpmostree-postprocess.h"
+
+typedef struct {
+ const char *input;
+ const char *output;
+} AltfilesTest;
+
+static AltfilesTest altfiles_tests[] = {
+ {
+ /* F25 */
+ .input = "# An nsswitch.conf\n" \
+ "\npasswd: files sss\n" \
+ "\ngroup: files sss\n" \
+ "\nhosts: files mdns4_minimal [NOTFOUND=return] dns myhostname\n",
+ .output = "# An nsswitch.conf\n" \
+ "\npasswd: files altfiles sss\n" \
+ "\ngroup: files altfiles sss\n" \
+ "\nhosts: files mdns4_minimal [NOTFOUND=return] dns myhostname\n"
+ },
+ {
+ /* F26 */
+ .input = "# An nsswitch.conf\n" \
+ "\npasswd: sss files systemd\n" \
+ "\ngroup: sss files systemd\n" \
+ "\nhosts: files mdns4_minimal [NOTFOUND=return] dns myhostname\n",
+ .output = "# An nsswitch.conf\n" \
+ "\npasswd: sss files altfiles systemd\n" \
+ "\ngroup: sss files altfiles systemd\n" \
+ "\nhosts: files mdns4_minimal [NOTFOUND=return] dns myhostname\n"
+ },
+ {
+ /* Already have altfiles, input/output identical */
+ .input = "# An nsswitch.conf\n" \
+ "\npasswd: sss files altfiles systemd\n" \
+ "\ngroup: sss files altfiles systemd\n" \
+ "\nhosts: files mdns4_minimal [NOTFOUND=return] dns myhostname\n",
+ .output = "# An nsswitch.conf\n" \
+ "\npasswd: sss files altfiles systemd\n" \
+ "\ngroup: sss files altfiles systemd\n" \
+ "\nhosts: files mdns4_minimal [NOTFOUND=return] dns myhostname\n",
+ },
+ {
+ /* Test having `files` as a substring */
+ .input = "# An nsswitch.conf\n" \
+ "\npasswd: sss foofiles files systemd\n" \
+ "\ngroup: sss foofiles files systemd\n" \
+ "\nhosts: files mdns4_minimal [NOTFOUND=return] dns myhostname\n",
+ .output = "# An nsswitch.conf\n" \
+ "\npasswd: sss foofiles files altfiles systemd\n" \
+ "\ngroup: sss foofiles files altfiles systemd\n" \
+ "\nhosts: files mdns4_minimal [NOTFOUND=return] dns myhostname\n",
+ }
+};
+
+static void
+test_postprocess_altfiles (void)
+{
+ g_autoptr(GError) local_error = NULL;
+ GError **error = &local_error;
+
+ for (guint i = 0; i < G_N_ELEMENTS(altfiles_tests); i++)
+ {
+ AltfilesTest *test = &altfiles_tests[i];
+ g_autofree char *newbuf = rpmostree_postprocess_replace_nsswitch (test->input, error);
+
+ if (!newbuf)
+ goto out;
+
+ g_assert_cmpstr (newbuf, ==, test->output);
+ }
+
+ out:
+ g_assert_no_error (local_error);
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/altfiles", test_postprocess_altfiles);
+
+ return g_test_run ();
+}
--
2.9.3
From 489b098787495cbb01c9c3243b6233b5ea04ecbc Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Thu, 6 Apr 2017 17:45:54 -0400
Subject: [PATCH 5/5] treecompose: Prepare device API mounts
This gives scripts access to e.g. `/dev/urandom`. Short term
hack until we implement https://github.com/projectatomic/rpm-ostree/issues/729
The reason we don't need to explicitly clean these up before committing is right
now for treecompose we only lift `/usr` from the RPM content, so we don't run
into ostree refusing to commit devices.
Closes: https://github.com/projectatomic/rpm-ostree/issues/727
---
src/app/rpmostree-compose-builtin-tree.c | 57 +++++++++++++++++++++++++++++++-
1 file changed, 56 insertions(+), 1 deletion(-)
diff --git a/src/app/rpmostree-compose-builtin-tree.c b/src/app/rpmostree-compose-builtin-tree.c
index 5b96349..7efe6d8 100644
--- a/src/app/rpmostree-compose-builtin-tree.c
+++ b/src/app/rpmostree-compose-builtin-tree.c
@@ -212,11 +212,63 @@ set_keyfile_string_array_from_json (GKeyFile *keyfile,
return ret;
}
+static inline gboolean
+glnx_throw_errno (GError **error)
+{
+ glnx_set_error_from_errno (error);
+ return FALSE;
+}
+
+/* Prpare /dev in the target root with the API devices. TODO:
+ * Delete this when we implement https://github.com/projectatomic/rpm-ostree/issues/729
+ */
+static gboolean
+libcontainer_prep_dev (int rootfs_dfd,
+ GError **error)
+{
+
+ glnx_fd_close int src_fd = openat (AT_FDCWD, "/dev", O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY);
+ if (src_fd == -1)
+ return glnx_throw_errno (error);
+
+ if (mkdirat (rootfs_dfd, "dev", 0755) != 0)
+ {
+ if (errno != ENOENT)
+ return glnx_throw_errno (error);
+ }
+
+ glnx_fd_close int dest_fd = openat (rootfs_dfd, "dev", O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY);
+ if (dest_fd == -1)
+ return glnx_throw_errno (error);
+
+ static const char *const devnodes[] = { "null", "zero", "full", "random", "urandom", "tty" };
+ for (guint i = 0; i < G_N_ELEMENTS (devnodes); i++)
+ {
+ const char *nodename = devnodes[i];
+ struct stat stbuf;
+ if (fstatat (src_fd, nodename, &stbuf, 0) == -1)
+ {
+ if (errno == ENOENT)
+ continue;
+ else
+ return glnx_throw_errno (error);
+ }
+
+ if (mknodat (dest_fd, nodename, stbuf.st_mode, stbuf.st_rdev) != 0)
+ return glnx_throw_errno (error);
+ if (fchmodat (dest_fd, nodename, stbuf.st_mode, 0) != 0)
+ return glnx_throw_errno (error);
+ }
+
+ return TRUE;
+}
+
static gboolean
install_packages_in_root (RpmOstreeTreeComposeContext *self,
RpmOstreeContext *ctx,
JsonObject *treedata,
GFile *yumroot,
+ int rootfs_dfd,
char **packages,
gboolean *out_unmodified,
char **out_new_inputhash,
@@ -401,6 +453,9 @@ install_packages_in_root (RpmOstreeTreeComposeContext *self,
glnx_console_lock (&console);
+ if (!libcontainer_prep_dev (rootfs_dfd, error))
+ goto out;
+
if (!dnf_transaction_commit (dnf_context_get_transaction (hifctx),
dnf_context_get_goal (hifctx),
hifstate,
@@ -886,7 +941,7 @@ rpmostree_compose_builtin_tree (int argc,
{ gboolean unmodified = FALSE;
- if (!install_packages_in_root (self, corectx, treefile, yumroot,
+ if (!install_packages_in_root (self, corectx, treefile, yumroot, rootfs_fd,
(char**)packages->pdata,
opt_force_nocache ? NULL : &unmodified,
&new_inputhash,
--
2.9.3

View File

@ -1,17 +1,13 @@
Summary: Hybrid image/package system
Name: rpm-ostree
Version: 2017.3
Release: 4%{?dist}
Version: 2017.4
Release: 1%{?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
License: LGPLv2+
URL: https://github.com/projectatomic/rpm-ostree
# git checkout 2017.3-maint
# git format-patch --stdout v2017.3..
Patch0: 2017.3-maint.patch
# We always run autogen.sh
BuildRequires: autoconf automake libtool git
# For docs
@ -134,6 +130,9 @@ python autofiles.py > files.devel \
%files devel -f files.devel
%changelog
* Thu Apr 13 2017 Jonathan Lebon <jlebon@redhat.com> - 2017.4-1
- New upstream version.
* Fri Apr 07 2017 Colin Walters <walters@verbum.org> - 2017.3-4
- Backport patch to add API devices for running on CentOS 7
https://github.com/projectatomic/rpm-ostree/issues/727

View File

@ -1 +1 @@
SHA512 (rpm-ostree-2017.3.tar.xz) = 9b6aa5a3d944e06ecc97329e7d2d7e2b89cac4e40aeea06276c23aca17afcd9eb0cefea82884cebd009e04229d759b407578a5a1898f116309fda417ea20b0aa
SHA512 (rpm-ostree-2017.4.tar.xz) = 3d042de1d0dd1ca08db4d999267a1098d1810f6779abf5b18e61c13a8db7e4b86bc3c19f7e864825f1ed2f2d7850952816bc0fb70c16cdde94180bee98c39fe4