summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <smcv@debian.org>2024-03-07 10:20:07 +0000
committerSimon McVittie <smcv@debian.org>2024-03-07 10:20:07 +0000
commit0467e5979af2c6cca0c3db04acf3c4ef15afa542 (patch)
tree8e55389097d89a79cb0bca51d96abce6d6a7de93
parent98a8642363bdc196d63344ebca626ad408720d4a (diff)
parent81d55657ac6ffdbf4ad021a987fc6dc9d0915f58 (diff)
Update upstream source from tag 'upstream/2024.4'
Update to upstream version '2024.4' with Debian dir b9e25d3c7dffe9b8ede2740a65ae4be2c3fe0679
-rw-r--r--README.md12
-rw-r--r--apidoc/html/index.html2
-rw-r--r--apidoc/html/ostree-ostree-version.html6
-rw-r--r--apidoc/version.xml2
-rwxr-xr-xconfigure24
-rw-r--r--configure.ac2
-rw-r--r--src/libostree/ostree-impl-system-generator.c51
-rw-r--r--src/libostree/ostree-sysroot-deploy.c4
-rw-r--r--src/libostree/ostree-sysroot.c3
-rw-r--r--src/libostree/ostree-version.h6
-rw-r--r--src/libotcore/otcore-prepare-root.c13
-rw-r--r--src/libotcore/otcore.h6
-rw-r--r--src/rofiles-fuse/main.c120
-rw-r--r--src/switchroot/ostree-prepare-root-static.c9
-rw-r--r--src/switchroot/ostree-prepare-root.c18
-rwxr-xr-xtests/libtest.sh31
-rw-r--r--tests/pull-test.sh6
-rwxr-xr-xtests/test-admin-deploy-var.sh2
-rwxr-xr-xtests/test-admin-gpg.sh2
-rwxr-xr-xtests/test-commit-sign.sh7
-rwxr-xr-xtests/test-composefs.sh6
-rwxr-xr-xtests/test-create-usb.sh2
-rwxr-xr-xtests/test-delta-ed25519.sh2
-rwxr-xr-xtests/test-export.sh6
-rwxr-xr-xtests/test-find-remotes.sh2
-rwxr-xr-xtests/test-gpg-signed-commit.sh5
-rw-r--r--tests/test-gpg-verify-result.c2
-rwxr-xr-xtests/test-libarchive.sh7
-rwxr-xr-xtests/test-local-pull.sh2
-rw-r--r--tests/test-otcore.c22
-rwxr-xr-xtests/test-parent.sh2
-rwxr-xr-xtests/test-pre-signed-pull.sh2
-rwxr-xr-xtests/test-pull-collections.sh6
-rwxr-xr-xtests/test-pull-contenturl.sh8
-rwxr-xr-xtests/test-pull-mirror-summary.sh4
-rwxr-xr-xtests/test-pull-repeated.sh2
-rwxr-xr-xtests/test-pull-summary-caching.sh5
-rwxr-xr-xtests/test-pull-summary-sigs.sh4
-rwxr-xr-xtests/test-rofiles-fuse.sh20
-rwxr-xr-xtests/test-signed-commit.sh2
-rwxr-xr-xtests/test-signed-pull-summary.sh4
-rwxr-xr-xtests/test-signed-pull.sh2
-rwxr-xr-xtests/test-summary-update.sh2
-rwxr-xr-xtests/test-summary-view.sh2
44 files changed, 251 insertions, 196 deletions
diff --git a/README.md b/README.md
index 8beedef6..166b33b6 100644
--- a/README.md
+++ b/README.md
@@ -63,6 +63,8 @@ The [machine-config-operator](https://github.com/openshift/machine-config-operat
manages upgrades. RHEL CoreOS is also the successor to RHEL Atomic Host, which
uses rpm-ostree as well.
+[Red Hat In-Vehicle Operating System (RHIVOS)](https://www.redhat.com/en/blog/new-standard-red-hat-vehicle-operating-system-modern-and-future-vehicles) is a derivative of CentOS Automotive Stream Distribution that uses OSTree, it's closest Fedora derivative is Fedora IoT although it was created as it's own distribution.
+
[GNOME Continuous](https://wiki.gnome.org/Projects/GnomeContinuous) is
where OSTree was born - as a high performance continuous delivery/testing
system for GNOME.
@@ -73,7 +75,10 @@ their host system as well as Flatpak.
[Liri OS](https://liri.io/download/silverblue/) has the option to install
their distribution using ostree.
-[Torizon OS](https://developer.toradex.com/torizon/torizoncore/torizoncore-technical-overview/) is a Linux distribution for embedded systems that updates via OSTree images delivered via [Uptane](https://uptane.github.io/) and [aktualizr](https://github.com/uptane/aktualizr/).
+[Torizon OS](https://developer.toradex.com/torizon/torizoncore/torizoncore-technical-overview/)
+is a Linux distribution for embedded systems that updates via OSTree images
+delivered via [Uptane](https://uptane.github.io/) and
+[aktualizr](https://github.com/uptane/aktualizr/).
## Distribution build tools
@@ -119,7 +124,10 @@ use the "libostree host system" aspects (e.g. bootloader management), just the
"git-like hardlink dedup". For example, Flatpak supports a per-user OSTree
repository.
-[aktualizr](https://github.com/uptane/aktualizr/) is an [Uptane](https://uptane.github.io/)-conformant software update client library intended for use in automotive and other security-sensitive embedded devices. It uses OSTree to manage the OS of the host device by default.
+[aktualizr](https://github.com/uptane/aktualizr/) is an
+[Uptane](https://uptane.github.io/)-conformant software update client library
+intended for use in automotive and other security-sensitive embedded devices.
+It uses OSTree to manage the OS of the host device by default.
## Language bindings
diff --git a/apidoc/html/index.html b/apidoc/html/index.html
index dab06bed..4016e664 100644
--- a/apidoc/html/index.html
+++ b/apidoc/html/index.html
@@ -14,7 +14,7 @@
<div class="titlepage">
<div>
<div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">OSTree API references</p></th></tr></table></div>
-<div><p class="releaseinfo">for OSTree 2023.8</p></div>
+<div><p class="releaseinfo">for OSTree 2024.4</p></div>
</div>
<hr>
</div>
diff --git a/apidoc/html/ostree-ostree-version.html b/apidoc/html/ostree-ostree-version.html
index 05613215..fb6d347c 100644
--- a/apidoc/html/ostree-ostree-version.html
+++ b/apidoc/html/ostree-ostree-version.html
@@ -125,7 +125,7 @@ of ostree is equal or greater than the required one.</p>
<hr>
<div class="refsect2">
<a name="OSTREE-RELEASE-VERSION:CAPS"></a><h3>OSTREE_RELEASE_VERSION</h3>
-<pre class="programlisting">#define OSTREE_RELEASE_VERSION (3)
+<pre class="programlisting">#define OSTREE_RELEASE_VERSION (4)
</pre>
<p>ostree release version component (e.g. 2 if <a class="link" href="ostree-ostree-version.html#OSTREE-VERSION:CAPS" title="OSTREE_VERSION"><code class="literal">OSTREE_VERSION</code></a> is 2017.2)</p>
<p class="since">Since: 2017.4</p>
@@ -133,7 +133,7 @@ of ostree is equal or greater than the required one.</p>
<hr>
<div class="refsect2">
<a name="OSTREE-VERSION:CAPS"></a><h3>OSTREE_VERSION</h3>
-<pre class="programlisting">#define OSTREE_VERSION (2024.3)
+<pre class="programlisting">#define OSTREE_VERSION (2024.4)
</pre>
<p>ostree version.</p>
<p class="since">Since: 2017.4</p>
@@ -141,7 +141,7 @@ of ostree is equal or greater than the required one.</p>
<hr>
<div class="refsect2">
<a name="OSTREE-VERSION-S:CAPS"></a><h3>OSTREE_VERSION_S</h3>
-<pre class="programlisting">#define OSTREE_VERSION_S "2024.3"
+<pre class="programlisting">#define OSTREE_VERSION_S "2024.4"
</pre>
<p>ostree version, encoded as a string, useful for printing and
concatenation.</p>
diff --git a/apidoc/version.xml b/apidoc/version.xml
index 992cd8bb..53bb8b10 100644
--- a/apidoc/version.xml
+++ b/apidoc/version.xml
@@ -1 +1 @@
-2023.8 \ No newline at end of file
+2024.4 \ No newline at end of file
diff --git a/configure b/configure
index d1cead19..01c31320 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for libostree 2024.3.
+# Generated by GNU Autoconf 2.71 for libostree 2024.4.
#
# Report bugs to <walters@verbum.org>.
#
@@ -621,8 +621,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='libostree'
PACKAGE_TARNAME='libostree'
-PACKAGE_VERSION='2024.3'
-PACKAGE_STRING='libostree 2024.3'
+PACKAGE_VERSION='2024.4'
+PACKAGE_STRING='libostree 2024.4'
PACKAGE_BUGREPORT='walters@verbum.org'
PACKAGE_URL=''
@@ -1611,7 +1611,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures libostree 2024.3 to adapt to many kinds of systems.
+\`configure' configures libostree 2024.4 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1682,7 +1682,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of libostree 2024.3:";;
+ short | recursive ) echo "Configuration of libostree 2024.4:";;
esac
cat <<\_ACEOF
@@ -1949,7 +1949,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-libostree configure 2024.3
+libostree configure 2024.4
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2322,7 +2322,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by libostree $as_me 2024.3, which was
+It was created by libostree $as_me 2024.4, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@@ -3599,7 +3599,7 @@ fi
# Define the identity of the package.
PACKAGE='libostree'
- VERSION='2024.3'
+ VERSION='2024.4'
# Some tools Automake needs.
@@ -6477,9 +6477,9 @@ test -n "$YACC" || YACC="yacc"
YEAR_VERSION=2024
-RELEASE_VERSION=3
+RELEASE_VERSION=4
-PACKAGE_VERSION=2024.3
+PACKAGE_VERSION=2024.4
pkglibexecdir=$libexecdir/$PACKAGE
@@ -20798,7 +20798,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by libostree $as_me 2024.3, which was
+This file was extended by libostree $as_me 2024.4, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -20866,7 +20866,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
-libostree config.status 2024.3
+libostree config.status 2024.4
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index e70ae82b..10a03383 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
AC_PREREQ([2.63])
dnl To perform a release, follow the instructions in `docs/CONTRIBUTING.md`.
m4_define([year_version], [2024])
-m4_define([release_version], [3])
+m4_define([release_version], [4])
m4_define([package_version], [year_version.release_version])
AC_INIT([libostree], [package_version], [walters@verbum.org])
is_release_build=yes
diff --git a/src/libostree/ostree-impl-system-generator.c b/src/libostree/ostree-impl-system-generator.c
index e51584cd..c5fe5032 100644
--- a/src/libostree/ostree-impl-system-generator.c
+++ b/src/libostree/ostree-impl-system-generator.c
@@ -126,10 +126,38 @@ require_internal_units (const char *normal_dir, const char *early_dir, const cha
#endif
}
+// Resolve symlink to return osname
+static gboolean
+_ostree_sysroot_parse_bootlink_aboot (const char *bootlink, char **out_osname, GError **error)
+{
+ static gsize regex_initialized;
+ static GRegex *regex;
+ g_autofree char *symlink_val = glnx_readlinkat_malloc (-1, bootlink, NULL, error);
+ if (!symlink_val)
+ return glnx_prefix_error (error, "Failed to read '%s' symlink", bootlink);
+
+ if (g_once_init_enter (&regex_initialized))
+ {
+ regex = g_regex_new ("^deploy/([^/]+)/", 0, 0, NULL);
+ g_assert (regex);
+ g_once_init_leave (&regex_initialized, 1);
+ }
+
+ g_autoptr (GMatchInfo) match = NULL;
+ if (!g_regex_match (regex, symlink_val, 0, &match))
+ return glnx_throw (error,
+ "Invalid aboot symlink in /ostree, expected symlink to resolve to "
+ "deploy/OSNAME/... instead it resolves to '%s'",
+ symlink_val);
+
+ *out_osname = g_match_info_fetch (match, 1);
+ return TRUE;
+}
+
/* Generate var.mount */
static gboolean
-fstab_generator (const char *ostree_cmdline, const char *normal_dir, const char *early_dir,
- const char *late_dir, GError **error)
+fstab_generator (const char *ostree_target, const bool is_aboot, const char *normal_dir,
+ const char *early_dir, const char *late_dir, GError **error)
{
#ifdef HAVE_LIBMOUNT
/* Not currently cancellable, but define a var in case we care later */
@@ -144,7 +172,12 @@ fstab_generator (const char *ostree_cmdline, const char *normal_dir, const char
* mounted yet.
*/
g_autofree char *stateroot = NULL;
- if (!_ostree_sysroot_parse_bootlink (ostree_cmdline, NULL, &stateroot, NULL, NULL, error))
+ if (is_aboot)
+ {
+ if (!_ostree_sysroot_parse_bootlink_aboot (ostree_target, &stateroot, error))
+ return glnx_prefix_error (error, "Parsing aboot stateroot");
+ }
+ else if (!_ostree_sysroot_parse_bootlink (ostree_target, NULL, &stateroot, NULL, NULL, error))
return glnx_prefix_error (error, "Parsing stateroot");
/* Load /etc/fstab if it exists, and look for a /var mount */
@@ -261,17 +294,21 @@ _ostree_impl_system_generator (const char *normal_dir, const char *early_dir, co
if (!cmdline)
return glnx_throw (error, "Failed to read /proc/cmdline");
- g_autofree char *ostree_cmdline = otcore_find_proc_cmdline_key (cmdline, "ostree");
+ g_autofree char *ostree_target = NULL;
+ gboolean is_aboot = false;
+ if (!otcore_get_ostree_target (cmdline, &is_aboot, &ostree_target, error))
+ return glnx_prefix_error (error, "Invalid aboot ostree target");
- /* This could happen in CoreOS live environments, where we hackily mock
+ /* If no `ostree=` karg exists, gracefully no-op.
+ * This could happen in CoreOS live environments, where we hackily mock
* the `ostree=` karg for `ostree-prepare-root.service` specifically, but
* otherwise that karg doesn't exist on the real command-line. */
- if (!ostree_cmdline)
+ if (!ostree_target)
return TRUE;
if (!require_internal_units (normal_dir, early_dir, late_dir, error))
return FALSE;
- if (!fstab_generator (ostree_cmdline, normal_dir, early_dir, late_dir, error))
+ if (!fstab_generator (ostree_target, is_aboot, normal_dir, early_dir, late_dir, error))
return FALSE;
return TRUE;
diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c
index 2ed1d214..df1254df 100644
--- a/src/libostree/ostree-sysroot-deploy.c
+++ b/src/libostree/ostree-sysroot-deploy.c
@@ -683,8 +683,10 @@ checkout_deployment_tree (OstreeSysroot *sysroot, OstreeRepo *repo, OstreeDeploy
return glnx_prefix_error (error, "Parsing prepare-root config");
// We always parse the composefs config, because we want to detect and error
// out if it's enabled, but not supported at compile time.
+ // However, we don't load the keys here, because they may not exist, such
+ // as in the initial deploy
g_autoptr (ComposefsConfig) composefs_config
- = otcore_load_composefs_config (prepare_root_config, error);
+ = otcore_load_composefs_config (prepare_root_config, FALSE, error);
if (!composefs_config)
return glnx_prefix_error (error, "Reading composefs config");
diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c
index a19b049b..5b4617fa 100644
--- a/src/libostree/ostree-sysroot.c
+++ b/src/libostree/ostree-sysroot.c
@@ -775,6 +775,9 @@ parse_deployment (OstreeSysroot *self, const char *boot_link, OstreeDeployment *
g_autofree char *osname = NULL;
g_autofree char *bootcsum = NULL;
int treebootserial = -1;
+
+ // Note is_boot should always be false here, this boot_link is taken from BLS file, not
+ // /proc/cmdline, BLS files are present in aboot images
if (!_ostree_sysroot_parse_bootlink (boot_link, &entry_boot_version, &osname, &bootcsum,
&treebootserial, error))
return FALSE;
diff --git a/src/libostree/ostree-version.h b/src/libostree/ostree-version.h
index a3fcfab4..d2cdc291 100644
--- a/src/libostree/ostree-version.h
+++ b/src/libostree/ostree-version.h
@@ -41,7 +41,7 @@
*
* Since: 2017.4
*/
-#define OSTREE_RELEASE_VERSION (3)
+#define OSTREE_RELEASE_VERSION (4)
/**
* OSTREE_VERSION
@@ -50,7 +50,7 @@
*
* Since: 2017.4
*/
-#define OSTREE_VERSION (2024.3)
+#define OSTREE_VERSION (2024.4)
/**
* OSTREE_VERSION_S:
@@ -60,7 +60,7 @@
*
* Since: 2017.4
*/
-#define OSTREE_VERSION_S "2024.3"
+#define OSTREE_VERSION_S "2024.4"
#define OSTREE_ENCODE_VERSION(year,release) \
((year) << 16 | (release))
diff --git a/src/libotcore/otcore-prepare-root.c b/src/libotcore/otcore-prepare-root.c
index 42f92c91..03575a47 100644
--- a/src/libotcore/otcore-prepare-root.c
+++ b/src/libotcore/otcore-prepare-root.c
@@ -75,7 +75,8 @@ otcore_find_proc_cmdline_key (const char *cmdline, const char *key)
//
// If invalid data is found, @error will be set.
gboolean
-otcore_get_ostree_target (const char *cmdline, char **out_target, GError **error)
+otcore_get_ostree_target (const char *cmdline, gboolean *is_aboot, char **out_target,
+ GError **error)
{
g_assert (cmdline);
g_assert (out_target && *out_target == NULL);
@@ -84,8 +85,14 @@ otcore_get_ostree_target (const char *cmdline, char **out_target, GError **error
// First, handle the Android boot case
g_autofree char *slot_suffix = otcore_find_proc_cmdline_key (cmdline, "androidboot.slot_suffix");
+ if (is_aboot)
+ *is_aboot = false;
+
if (slot_suffix)
{
+ if (is_aboot)
+ *is_aboot = true;
+
if (strcmp (slot_suffix, "_a") == 0)
{
*out_target = g_strdup (slot_a);
@@ -154,7 +161,7 @@ otcore_free_composefs_config (ComposefsConfig *config)
// Parse the [composefs] section of the prepare-root.conf.
ComposefsConfig *
-otcore_load_composefs_config (GKeyFile *config, GError **error)
+otcore_load_composefs_config (GKeyFile *config, gboolean load_keys, GError **error)
{
GLNX_AUTO_PREFIX_ERROR ("Loading composefs config", error);
@@ -178,7 +185,7 @@ otcore_load_composefs_config (GKeyFile *config, GError **error)
&ret->signature_pubkey, error))
return NULL;
- if (ret->is_signed)
+ if (ret->is_signed && load_keys)
{
ret->pubkeys = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref);
diff --git a/src/libotcore/otcore.h b/src/libotcore/otcore.h
index 5fd24ec9..fc6b81ca 100644
--- a/src/libotcore/otcore.h
+++ b/src/libotcore/otcore.h
@@ -44,7 +44,8 @@ gboolean otcore_validate_ed25519_signature (GBytes *data, GBytes *pubkey, GBytes
bool *out_valid, GError **error);
char *otcore_find_proc_cmdline_key (const char *cmdline, const char *key);
-gboolean otcore_get_ostree_target (const char *cmdline, char **out_target, GError **error);
+gboolean otcore_get_ostree_target (const char *cmdline, gboolean *is_aboot, char **out_target,
+ GError **error);
GKeyFile *otcore_load_config (int rootfs, const char *filename, GError **error);
@@ -58,7 +59,8 @@ typedef struct
void otcore_free_composefs_config (ComposefsConfig *config);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ComposefsConfig, otcore_free_composefs_config)
-ComposefsConfig *otcore_load_composefs_config (GKeyFile *config, GError **error);
+ComposefsConfig *otcore_load_composefs_config (GKeyFile *config, gboolean load_keys,
+ GError **error);
// Our directory with transient state (eventually /run/ostree-booted should be a link to
// /run/ostree/booted)
diff --git a/src/rofiles-fuse/main.c b/src/rofiles-fuse/main.c
index 937ee4a6..0c267ea9 100644
--- a/src/rofiles-fuse/main.c
+++ b/src/rofiles-fuse/main.c
@@ -33,6 +33,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
+#include <sys/sysmacros.h>
#include <sys/types.h>
#include <sys/xattr.h>
#include <unistd.h>
@@ -235,16 +236,21 @@ callback_link (const char *from, const char *to)
* return -EROFS. Otherwise return 0.
*/
static gboolean
-can_write_stbuf (const struct stat *stbuf)
+can_write_stbuf (const struct statx *stbuf)
{
/* If it's not a regular file or symlink, ostree won't hardlink it, so allow
* writes - it might be a FIFO or device that somehow
* ended up underneath our mount.
*/
- if (!(S_ISREG (stbuf->st_mode) || S_ISLNK (stbuf->st_mode)))
+ if (!(S_ISREG (stbuf->stx_mode) || S_ISLNK (stbuf->stx_mode)))
return TRUE;
+#ifdef STATX_ATTR_VERITY
+ /* Can't write to fsverity files */
+ if (stbuf->stx_attributes & STATX_ATTR_VERITY)
+ return FALSE;
+#endif
/* If the object isn't hardlinked, it's OK to write */
- if (stbuf->st_nlink <= 1)
+ if (stbuf->stx_nlink <= 1)
return TRUE;
/* Otherwise, it's a hardlinked file or symlink; it must be
* immutable.
@@ -275,18 +281,55 @@ gioerror_to_errno (GIOErrorEnum e)
}
}
-static int
-verify_write_or_copyup (const char *path, const struct stat *stbuf, gboolean *out_did_copyup)
+// The libglnx APIs take a stat buffer, so we need to be able to
+// convert from statx.
+static inline void
+statx_to_stat (const struct statx *stxbuf, struct stat *stbuf)
{
- struct stat stbuf_local;
+ stbuf->st_dev = makedev (stxbuf->stx_dev_major, stxbuf->stx_dev_minor);
+ stbuf->st_rdev = makedev (stxbuf->stx_rdev_major, stxbuf->stx_rdev_minor);
+ stbuf->st_ino = stxbuf->stx_ino;
+ stbuf->st_mode = stxbuf->stx_mode;
+ stbuf->st_nlink = stxbuf->stx_nlink;
+ stbuf->st_uid = stxbuf->stx_uid;
+ stbuf->st_gid = stxbuf->stx_gid;
+ stbuf->st_size = stxbuf->stx_size;
+ stbuf->st_blksize = stxbuf->stx_blksize;
+}
- if (out_did_copyup)
- *out_did_copyup = FALSE;
+// A copy of ostree_break_hardlink but without the check for hardlinks, which
+// is mainly relevant for regular files, where we need to handle verity.
+static gboolean
+copyup (int dfd, const char *path, const struct statx *stxbuf, GError **error)
+{
+ if (S_ISREG (stxbuf->stx_mode))
+ {
+ struct stat stbuf;
+ statx_to_stat (stxbuf, &stbuf);
+ // Note GLNX_FILE_COPY_OVERWRITE always uses O_TMPFILE+rename
+ return glnx_file_copy_at (dfd, path, &stbuf, dfd, path, GLNX_FILE_COPY_OVERWRITE, NULL,
+ error);
+ }
+ else
+ {
+ // For symlinks, we can just directly call the ostree API. This avoids
+ // more code duplication because atomically copying symlinks requires
+ // a temp-link dance.
+ return ostree_break_hardlink (dfd, path, FALSE, NULL, error);
+ }
+}
+
+static int
+verify_write_or_copyup (const char *path, const struct statx *stbuf)
+{
+ struct statx stbuf_local;
/* If a stbuf wasn't provided, gather it now */
if (!stbuf)
{
- if (fstatat (basefd, path, &stbuf_local, AT_SYMLINK_NOFOLLOW) == -1)
+ if (statx (basefd, path, AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT, STATX_BASIC_STATS,
+ &stbuf_local)
+ < 0)
{
if (errno == ENOENT)
return 0;
@@ -302,10 +345,8 @@ verify_write_or_copyup (const char *path, const struct stat *stbuf, gboolean *ou
if (opt_copyup)
{
g_autoptr (GError) tmp_error = NULL;
- if (!ostree_break_hardlink (basefd, path, FALSE, NULL, &tmp_error))
+ if (!copyup (basefd, path, stbuf, &tmp_error))
return -gioerror_to_errno ((GIOErrorEnum)tmp_error->code);
- if (out_did_copyup)
- *out_did_copyup = TRUE;
}
else
return -EROFS;
@@ -322,7 +363,7 @@ verify_write_or_copyup (const char *path, const struct stat *stbuf, gboolean *ou
do \
{ \
path = ENSURE_RELPATH (path); \
- int r = verify_write_or_copyup (path, NULL, NULL); \
+ int r = verify_write_or_copyup (path, NULL); \
if (r != 0) \
return r; \
} \
@@ -401,7 +442,7 @@ static int
do_open (const char *path, mode_t mode, struct fuse_file_info *finfo)
{
int fd;
- struct stat stbuf;
+ struct statx stbuf;
path = ENSURE_RELPATH (path);
@@ -415,53 +456,22 @@ do_open (const char *path, mode_t mode, struct fuse_file_info *finfo)
else
{
/* Write */
-
- /* We need to specially handle O_TRUNC */
- fd = openat (basefd, path, finfo->flags & ~O_TRUNC, mode);
- if (fd == -1)
- return -errno;
-
- if (fstat (fd, &stbuf) == -1)
- {
- (void)close (fd);
- return -errno;
- }
-
- gboolean did_copyup;
- int r = verify_write_or_copyup (path, &stbuf, &did_copyup);
- if (r != 0)
+ if (statx (basefd, path, AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT, STATX_BASIC_STATS, &stbuf)
+ == -1)
{
- (void)close (fd);
- return r;
- }
-
- /* In the copyup case, we need to re-open */
- if (did_copyup)
- {
- (void)close (fd);
- /* Note that unlike the initial open, we will pass through
- * O_TRUNC. More ideally in this copyup case we'd avoid copying
- * the whole file in the first place, but eh. It's not like we're
- * high performance anyways.
- */
- fd = openat (basefd, path, finfo->flags & ~(O_EXCL | O_CREAT), mode);
- if (fd == -1)
+ if (errno != ENOENT)
return -errno;
}
else
{
- /* In the non-copyup case we handle O_TRUNC here, after we've verified
- * the hardlink state above with verify_write_or_copyup().
- */
- if (finfo->flags & O_TRUNC)
- {
- if (ftruncate (fd, 0) == -1)
- {
- (void)close (fd);
- return -errno;
- }
- }
+ int r = verify_write_or_copyup (path, &stbuf);
+ if (r != 0)
+ return r;
}
+
+ fd = openat (basefd, path, finfo->flags, mode);
+ if (fd == -1)
+ return -errno;
}
finfo->fh = fd;
diff --git a/src/switchroot/ostree-prepare-root-static.c b/src/switchroot/ostree-prepare-root-static.c
index ce3340f8..3995a6f0 100644
--- a/src/switchroot/ostree-prepare-root-static.c
+++ b/src/switchroot/ostree-prepare-root-static.c
@@ -204,12 +204,11 @@ main (int argc, char *argv[])
const bool sysroot_readonly = sysroot_is_configured_ro (root_arg);
const bool sysroot_currently_writable = !path_is_on_readonly_fs (root_arg);
- /* Work-around for a kernel bug: for some reason the kernel
- * refuses switching root if any file systems are mounted
- * MS_SHARED. Hence remount them MS_PRIVATE here as a
- * work-around.
+ /* Remount root MS_PRIVATE here to avoid errors due to the kernel-enforced
+ * constraint that disallows MS_SHARED mounts to be moved.
*
- * https://bugzilla.redhat.com/show_bug.cgi?id=847418 */
+ * Kernel docs: Documentation/filesystems/sharedsubtree.txt
+ */
if (mount (NULL, "/", NULL, MS_REC | MS_PRIVATE | MS_SILENT, NULL) < 0)
err (EXIT_FAILURE, "failed to make \"/\" private mount");
diff --git a/src/switchroot/ostree-prepare-root.c b/src/switchroot/ostree-prepare-root.c
index c4e236d4..b93e05c7 100644
--- a/src/switchroot/ostree-prepare-root.c
+++ b/src/switchroot/ostree-prepare-root.c
@@ -124,7 +124,7 @@ resolve_deploy_path (const char *root_mountpoint)
g_autoptr (GError) error = NULL;
g_autofree char *ostree_target = NULL;
- if (!otcore_get_ostree_target (kernel_cmdline, &ostree_target, &error))
+ if (!otcore_get_ostree_target (kernel_cmdline, NULL, &ostree_target, &error))
errx (EXIT_FAILURE, "Failed to determine ostree target: %s", error->message);
if (!ostree_target)
errx (EXIT_FAILURE, "No ostree target found");
@@ -277,7 +277,8 @@ main (int argc, char *argv[])
// We always parse the composefs config, because we want to detect and error
// out if it's enabled, but not supported at compile time.
- g_autoptr (ComposefsConfig) composefs_config = otcore_load_composefs_config (config, &error);
+ g_autoptr (ComposefsConfig) composefs_config
+ = otcore_load_composefs_config (config, TRUE, &error);
if (!composefs_config)
errx (EXIT_FAILURE, "%s", error->message);
@@ -326,12 +327,11 @@ main (int argc, char *argv[])
g_print ("sysroot.readonly configuration value: %d (fs writable: %d)\n", (int)sysroot_readonly,
(int)sysroot_currently_writable);
- /* Work-around for a kernel bug: for some reason the kernel
- * refuses switching root if any file systems are mounted
- * MS_SHARED. Hence remount them MS_PRIVATE here as a
- * work-around.
+ /* Remount root MS_PRIVATE here to avoid errors due to the kernel-enforced
+ * constraint that disallows MS_SHARED mounts to be moved.
*
- * https://bugzilla.redhat.com/show_bug.cgi?id=847418 */
+ * Kernel docs: Documentation/filesystems/sharedsubtree.txt
+ */
if (mount (NULL, "/", NULL, MS_REC | MS_PRIVATE | MS_SILENT, NULL) < 0)
err (EXIT_FAILURE, "failed to make \"/\" private mount");
@@ -572,8 +572,10 @@ main (int argc, char *argv[])
* with ostree admin unlock --hotfix.
* Note however that root.transient as handled above is effectively a generalization of unlock
* --hotfix.
+ * Also, hotfixes are incompatible with signed composefs use for security reasons.
*/
- if (lstat (OTCORE_HOTFIX_USR_OVL_WORK, &stbuf) == 0)
+ if (lstat (OTCORE_HOTFIX_USR_OVL_WORK, &stbuf) == 0
+ && !(using_composefs && composefs_config->is_signed))
{
/* Do we have a persistent overlayfs for /usr? If so, mount it now. */
const char usr_ovl_options[]
diff --git a/tests/libtest.sh b/tests/libtest.sh
index d1c99eab..2c2a33f0 100755
--- a/tests/libtest.sh
+++ b/tests/libtest.sh
@@ -696,18 +696,20 @@ skip_without_fuse () {
[ -e /etc/mtab ] || skip "no /etc/mtab"
}
-has_gpgme () {
- local ret
+has_ostree_feature () {
+ local ret=0
+ # Note that this needs to write to a file and then grep the file, to
+ # avoid ostree --version being killed with SIGPIPE and exiting with a
+ # nonzero status under `set -o pipefail`.
${CMD_PREFIX} ostree --version > version.txt
- grep -q -e '- gpgme' version.txt
- ret=$?
+ grep -q -e "- $1\$" version.txt || ret=$?
rm -f version.txt
return ${ret}
}
-skip_without_gpgme() {
- if ! has_gpgme; then
- skip "no gpg support compiled in"
+skip_without_ostree_feature () {
+ if ! has_ostree_feature "$1"; then
+ skip "no $1 support compiled in"
fi
}
@@ -750,21 +752,6 @@ libtest_cleanup_gpg () {
}
libtest_exit_cmds+=(libtest_cleanup_gpg)
-has_sign_ed25519 () {
- local ret
- ${CMD_PREFIX} ostree --version > version.txt
- grep -q -e '- sign-ed25519' version.txt
- ret=$?
- rm -f version.txt
- return ${ret}
-}
-
-skip_without_sign_ed25519() {
- if ! has_sign_ed25519; then
- skip "no ed25519 support compiled in"
- fi
-}
-
# Keys for ed25519 signing tests
ED25519PUBLIC=
ED25519SEED=
diff --git a/tests/pull-test.sh b/tests/pull-test.sh
index f4084290..d61735a0 100644
--- a/tests/pull-test.sh
+++ b/tests/pull-test.sh
@@ -54,7 +54,7 @@ function verify_initial_contents() {
n_base_tests=35
gpg_tests=3
-if has_gpgme; then
+if has_ostree_feature gpgme; then
echo "1..$(($n_base_tests+$gpg_tests))"
else
echo "1..$((n_base_tests))"
@@ -633,7 +633,7 @@ fi
assert_file_has_content err.txt "404"
echo "ok pull repo 404"
-if has_gpgme; then
+if has_ostree_feature gpgme; then
cd ${test_tmpdir}
repo_init --set=gpg-verify=true
if ${CMD_PREFIX} ostree --repo=repo --depth=0 pull origin main 2>err.txt; then
@@ -653,7 +653,7 @@ assert_file_has_content err.txt "404"
find ostree-srv/gnomerepo/objects -name '*.dirtree.orig' | while read f; do mv ${f} $(dirname $f)/$(basename ${f} .orig); done
echo "ok pull repo 404 on dirtree object"
-if has_gpgme; then
+if has_ostree_feature gpgme; then
cd ${test_tmpdir}
repo_init --set=gpg-verify=true
${CMD_PREFIX} ostree --repo=ostree-srv/gnomerepo commit ${COMMIT_ARGS} \
diff --git a/tests/test-admin-deploy-var.sh b/tests/test-admin-deploy-var.sh
index 3079490d..fc61576f 100755
--- a/tests/test-admin-deploy-var.sh
+++ b/tests/test-admin-deploy-var.sh
@@ -21,7 +21,7 @@ set -euox pipefail
. $(dirname $0)/libtest.sh
-if ! echo "$OSTREE_FEATURES" | grep --quiet --no-messages "initial-var"; then
+if ! has_ostree_feature initial-var; then
fatal missing initial-var
fi
diff --git a/tests/test-admin-gpg.sh b/tests/test-admin-gpg.sh
index f71c306b..6283b126 100755
--- a/tests/test-admin-gpg.sh
+++ b/tests/test-admin-gpg.sh
@@ -34,7 +34,7 @@ setup_os_repository_signed () {
bootdir=${1:-usr/lib/modules/3.6.0}
oldpwd=`pwd`
- keyid="472CDAFA"
+ keyid="7FCA23D8472CDAFA"
cd ${test_tmpdir}
mkdir testos-repo
diff --git a/tests/test-commit-sign.sh b/tests/test-commit-sign.sh
index e0cea0b5..8e1ba615 100755
--- a/tests/test-commit-sign.sh
+++ b/tests/test-commit-sign.sh
@@ -21,10 +21,7 @@ set -euo pipefail
. $(dirname $0)/libtest.sh
-if ! has_gpgme; then
- echo "1..0 #SKIP no gpg support compiled in"
- exit 0
-fi
+skip_without_ostree_feature gpgme
if test -z "${OSTREE_HTTPD}"; then
echo "1..0 #SKIP no ostree-trivial-httpd"
@@ -33,7 +30,7 @@ fi
echo "1..7"
-keyid="472CDAFA"
+keyid="7FCA23D8472CDAFA"
oldpwd=`pwd`
mkdir ostree-srv
cd ostree-srv
diff --git a/tests/test-composefs.sh b/tests/test-composefs.sh
index d05579f5..f0f5cac1 100755
--- a/tests/test-composefs.sh
+++ b/tests/test-composefs.sh
@@ -19,11 +19,7 @@ set -euo pipefail
. $(dirname $0)/libtest.sh
-if ! ${CMD_PREFIX} ostree --version | grep -q -e '- composefs'; then
- echo "1..0 #SKIP no composefs support compiled in"
- exit 0
-fi
-
+skip_without_ostree_feature composefs
skip_without_user_xattrs
setup_test_repository "bare-user"
diff --git a/tests/test-create-usb.sh b/tests/test-create-usb.sh
index 016d32c7..064501fe 100755
--- a/tests/test-create-usb.sh
+++ b/tests/test-create-usb.sh
@@ -24,7 +24,7 @@ set -euo pipefail
. $(dirname $0)/libtest.sh
-skip_without_gpgme
+skip_without_ostree_feature gpgme
echo "1..5"
diff --git a/tests/test-delta-ed25519.sh b/tests/test-delta-ed25519.sh
index 9e00fdb4..9cd22286 100755
--- a/tests/test-delta-ed25519.sh
+++ b/tests/test-delta-ed25519.sh
@@ -23,7 +23,7 @@ set -euo pipefail
skip_without_user_xattrs
-skip_without_sign_ed25519
+skip_without_ostree_feature sign-ed25519
bindatafiles="bash true ostree"
diff --git a/tests/test-export.sh b/tests/test-export.sh
index 6b8de94c..23e51666 100755
--- a/tests/test-export.sh
+++ b/tests/test-export.sh
@@ -19,13 +19,9 @@
set -euo pipefail
-if ! ostree --version | grep -q -e '- libarchive'; then
- echo "1..0 #SKIP no libarchive support compiled in"
- exit 0
-fi
-
. $(dirname $0)/libtest.sh
+skip_without_ostree_feature libarchive
setup_test_repository "archive"
echo '1..6'
diff --git a/tests/test-find-remotes.sh b/tests/test-find-remotes.sh
index abcc41dc..3ec81f91 100755
--- a/tests/test-find-remotes.sh
+++ b/tests/test-find-remotes.sh
@@ -21,7 +21,7 @@ set -euo pipefail
. $(dirname $0)/libtest.sh
-skip_without_gpgme
+skip_without_ostree_feature gpgme
echo '1..1'
diff --git a/tests/test-gpg-signed-commit.sh b/tests/test-gpg-signed-commit.sh
index 7b00f9e9..d3b54332 100755
--- a/tests/test-gpg-signed-commit.sh
+++ b/tests/test-gpg-signed-commit.sh
@@ -22,10 +22,7 @@ set -euo pipefail
. $(dirname $0)/libtest.sh
-if ! has_gpgme; then
- echo "1..0 #SKIP no gpgme support compiled in"
- exit 0
-fi
+skip_without_ostree_feature gpgme
num_tests=1
diff --git a/tests/test-gpg-verify-result.c b/tests/test-gpg-verify-result.c
index e7171a89..5844c668 100644
--- a/tests/test-gpg-verify-result.c
+++ b/tests/test-gpg-verify-result.c
@@ -183,7 +183,7 @@ test_signature_lookup (TestFixture *fixture, gconstpointer user_data)
/* Lookup abbreviated key ID. */
signature_index = 999999;
signature_found
- = ostree_gpg_verify_result_lookup (fixture->result, fingerprint + 32, &signature_index);
+ = ostree_gpg_verify_result_lookup (fixture->result, fingerprint + 24, &signature_index);
g_assert_true (signature_found);
g_assert_cmpint (signature_index, ==, expected_signature_index);
diff --git a/tests/test-libarchive.sh b/tests/test-libarchive.sh
index 63175023..d9ce37b2 100755
--- a/tests/test-libarchive.sh
+++ b/tests/test-libarchive.sh
@@ -19,13 +19,10 @@
set -euo pipefail
-if ! ostree --version | grep -q -e '- libarchive'; then
- echo "1..0 #SKIP no libarchive support compiled in"
- exit 0
-fi
-
. $(dirname $0)/libtest.sh
+skip_without_ostree_feature libarchive
+
echo "1..18"
setup_test_repository "bare"
diff --git a/tests/test-local-pull.sh b/tests/test-local-pull.sh
index 79b86abc..e1b916c4 100755
--- a/tests/test-local-pull.sh
+++ b/tests/test-local-pull.sh
@@ -61,7 +61,7 @@ cmp checkout1.files checkout2.files
cmp checkout1.files checkout3.files
echo "ok checkouts same"
-if has_gpgme; then
+if has_ostree_feature gpgme; then
# These tests are needed GPG support
mkdir repo4
ostree_repo_init repo4 --mode="archive"
diff --git a/tests/test-otcore.c b/tests/test-otcore.c
index 4af575bf..2d8003e5 100644
--- a/tests/test-otcore.c
+++ b/tests/test-otcore.c
@@ -36,46 +36,46 @@ test_prepare_root_cmdline (void)
{
g_autoptr (GError) error = NULL;
g_autofree char *target = NULL;
-
static const char *notfound_cases[]
= { "", "foo", "foo=bar baz sometest", "xostree foo", "xostree=blah bar", NULL };
for (const char **iter = notfound_cases; iter && *iter; iter++)
{
const char *tcase = *iter;
- g_assert (otcore_get_ostree_target (tcase, &target, &error));
+ g_assert (otcore_get_ostree_target (tcase, NULL, &target, &error));
g_assert_no_error (error);
g_assert (target == NULL);
}
// Test the default ostree=
- g_assert (otcore_get_ostree_target ("blah baz=blah ostree=/foo/bar somearg", &target, &error));
+ g_assert (
+ otcore_get_ostree_target ("blah baz=blah ostree=/foo/bar somearg", NULL, &target, &error));
g_assert_no_error (error);
g_assert_cmpstr (target, ==, "/foo/bar");
free (g_steal_pointer (&target));
// Test android boot
- g_assert (otcore_get_ostree_target ("blah baz=blah androidboot.slot_suffix=_b somearg", &target,
- &error));
+ g_assert (otcore_get_ostree_target ("blah baz=blah androidboot.slot_suffix=_b somearg", NULL,
+ &target, &error));
g_assert_no_error (error);
g_assert_cmpstr (target, ==, "/ostree/root.b");
free (g_steal_pointer (&target));
- g_assert (otcore_get_ostree_target ("blah baz=blah androidboot.slot_suffix=_a somearg", &target,
- &error));
+ g_assert (otcore_get_ostree_target ("blah baz=blah androidboot.slot_suffix=_a somearg", NULL,
+ &target, &error));
g_assert_no_error (error);
g_assert_cmpstr (target, ==, "/ostree/root.a");
free (g_steal_pointer (&target));
// And an expected failure to parse a "c" suffix
- g_assert (!otcore_get_ostree_target ("blah baz=blah androidboot.slot_suffix=_c somearg", &target,
- &error));
+ g_assert (!otcore_get_ostree_target ("blah baz=blah androidboot.slot_suffix=_c somearg", NULL,
+ &target, &error));
g_assert (error);
g_assert (target == NULL);
g_clear_error (&error);
// And non-A/B androidboot
- g_assert (otcore_get_ostree_target ("blah baz=blah androidboot.somethingelse somearg", &target,
- &error));
+ g_assert (otcore_get_ostree_target ("blah baz=blah androidboot.somethingelse somearg", NULL,
+ &target, &error));
g_assert_no_error (error);
g_assert_cmpstr (target, ==, "/ostree/root.a");
free (g_steal_pointer (&target));
diff --git a/tests/test-parent.sh b/tests/test-parent.sh
index 4b5806c5..5a8809f8 100755
--- a/tests/test-parent.sh
+++ b/tests/test-parent.sh
@@ -23,7 +23,7 @@ set -euo pipefail
skip_without_user_xattrs
-skip_without_gpgme
+skip_without_ostree_feature gpgme
echo '1..2'
diff --git a/tests/test-pre-signed-pull.sh b/tests/test-pre-signed-pull.sh
index 2a1a1d23..0ac8e0aa 100755
--- a/tests/test-pre-signed-pull.sh
+++ b/tests/test-pre-signed-pull.sh
@@ -23,7 +23,7 @@ set -euo pipefail
echo "1..1"
-if ! has_sign_ed25519; then
+if ! has_ostree_feature sign-ed25519; then
echo "ok pre-signed pull # SKIP due ed25519 unavailability"
exit 0
fi
diff --git a/tests/test-pull-collections.sh b/tests/test-pull-collections.sh
index 1d14e5db..518545d7 100755
--- a/tests/test-pull-collections.sh
+++ b/tests/test-pull-collections.sh
@@ -33,7 +33,7 @@ do_commit() {
mkdir -p files
pushd files
local GPG_ARGS=""
- if has_gpgme; then
+ if has_ostree_feature gpgme; then
GPG_ARGS="--gpg-homedir=${TEST_GPG_KEYHOME} --gpg-sign=${TEST_GPG_KEYID_1}"
fi
${CMD_PREFIX} ostree --repo="../${repo}" commit -s "Test ${repo} commit for branch ${branch}" -b "${branch}" ${GPG_ARGS} "$@" > "../${branch}-checksum"
@@ -45,7 +45,7 @@ do_summary() {
shift 1
local GPG_ARGS=""
- if has_gpgme; then
+ if has_ostree_feature gpgme; then
GPG_ARGS="--gpg-homedir=${TEST_GPG_KEYHOME} --gpg-sign=${TEST_GPG_KEYID_1}"
fi
${CMD_PREFIX} ostree "--repo=${repo}" summary --update ${GPG_ARGS}
@@ -103,7 +103,7 @@ do_remote_add() {
shift 2
local GPG_ARGS=""
- if has_gpgme; then
+ if has_ostree_feature gpgme; then
GPG_ARGS="--gpg-import=${test_tmpdir}/gpghome/key1.asc"
fi
${CMD_PREFIX} ostree "--repo=${repo}" remote add "${remote_repo}-remote" "file://$(pwd)/${remote_repo}" "$@" ${GPG_ARGS}
diff --git a/tests/test-pull-contenturl.sh b/tests/test-pull-contenturl.sh
index d47fdfe1..63eecf72 100755
--- a/tests/test-pull-contenturl.sh
+++ b/tests/test-pull-contenturl.sh
@@ -29,7 +29,7 @@ fi
echo "1..2"
COMMIT_SIGN=""
-if has_gpgme; then
+if has_ostree_feature gpgme; then
COMMIT_SIGN="--gpg-homedir=${TEST_GPG_KEYHOME} --gpg-sign=${TEST_GPG_KEYID_1}"
fi
@@ -47,7 +47,7 @@ cp -a ${test_tmpdir}/ostree-srv ostree
# delete all the meta stuff from here
rm ostree/gnomerepo/summary
-if has_gpgme; then
+if has_ostree_feature gpgme; then
rm ostree/gnomerepo/summary.sig
find ostree/gnomerepo/objects -name '*.commitmeta' | xargs rm
fi
@@ -63,7 +63,7 @@ echo "http://127.0.0.1:${content_port}" > ${test_tmpdir}/httpd-content-address
cd ${test_tmpdir}
mkdir repo
ostree_repo_init repo
-if has_gpgme; then VERIFY=true; else VERIFY=false; fi
+if has_ostree_feature gpgme; then VERIFY=true; else VERIFY=false; fi
${CMD_PREFIX} ostree --repo=repo remote add origin \
--set=gpg-verify=$VERIFY --set=gpg-verify-summary=$VERIFY \
--contenturl=$(cat httpd-content-address)/ostree/gnomerepo \
@@ -72,7 +72,7 @@ ${CMD_PREFIX} ostree --repo=repo pull origin:main
echo "ok pull objects from contenturl"
-if ! has_gpgme; then
+if ! has_ostree_feature gpgme; then
echo "ok don't pull sigs from contenturl # SKIP not compiled with gpgme"
else
echo "ok don't pull sigs from contenturl"
diff --git a/tests/test-pull-mirror-summary.sh b/tests/test-pull-mirror-summary.sh
index 94a8c020..88a37b8a 100755
--- a/tests/test-pull-mirror-summary.sh
+++ b/tests/test-pull-mirror-summary.sh
@@ -22,7 +22,7 @@ set -euo pipefail
. $(dirname $0)/libtest.sh
COMMIT_SIGN=""
-if has_gpgme; then
+if has_ostree_feature gpgme; then
COMMIT_SIGN="--gpg-homedir=${TEST_GPG_KEYHOME} --gpg-sign=${TEST_GPG_KEYID_1}"
echo "1..5"
else
@@ -67,7 +67,7 @@ find repo/objects -name '*.filez' | while read name; do
done
echo "ok pull mirror summary"
-if ! has_gpgme; then
+if ! has_ostree_feature gpgme; then
exit 0;
fi
diff --git a/tests/test-pull-repeated.sh b/tests/test-pull-repeated.sh
index 7f724c95..b3e00742 100755
--- a/tests/test-pull-repeated.sh
+++ b/tests/test-pull-repeated.sh
@@ -22,7 +22,7 @@ set -euo pipefail
. $(dirname $0)/libtest.sh
COMMIT_SIGN=""
-if has_gpgme; then
+if has_ostree_feature gpgme; then
COMMIT_SIGN="--gpg-homedir=${TEST_GPG_KEYHOME} --gpg-sign=${TEST_GPG_KEYID_1}"
fi
diff --git a/tests/test-pull-summary-caching.sh b/tests/test-pull-summary-caching.sh
index 8c6727d0..180f671c 100755
--- a/tests/test-pull-summary-caching.sh
+++ b/tests/test-pull-summary-caching.sh
@@ -24,10 +24,7 @@ set -euo pipefail
. $(dirname $0)/libtest.sh
-if ! has_gpgme; then
- echo "1..0 #SKIP no gpg support compiled in"
- exit 0
-fi
+skip_without_ostree_feature gpgme
# Ensure repo caching is in use.
unset OSTREE_SKIP_CACHE
diff --git a/tests/test-pull-summary-sigs.sh b/tests/test-pull-summary-sigs.sh
index e1b0412e..8a5cc4fb 100755
--- a/tests/test-pull-summary-sigs.sh
+++ b/tests/test-pull-summary-sigs.sh
@@ -25,7 +25,7 @@ set -euo pipefail
unset OSTREE_SKIP_CACHE
COMMIT_SIGN=""
-if has_gpgme; then
+if has_ostree_feature gpgme; then
COMMIT_SIGN="--gpg-homedir=${TEST_GPG_KEYHOME} --gpg-sign=${TEST_GPG_KEYID_1}"
echo "1..10"
else
@@ -63,7 +63,7 @@ assert_file_has_content yet-another-copy/yet-another-hello-world "hello world ye
${CMD_PREFIX} ostree --repo=repo fsck
echo "ok pull mirror summary"
-if ! has_gpgme; then
+if ! has_ostree_feature gpgme; then
exit 0;
fi
diff --git a/tests/test-rofiles-fuse.sh b/tests/test-rofiles-fuse.sh
index a56a76c6..0ac55764 100755
--- a/tests/test-rofiles-fuse.sh
+++ b/tests/test-rofiles-fuse.sh
@@ -26,7 +26,7 @@ skip_without_user_xattrs
setup_test_repository "bare"
-echo "1..12"
+echo "1..13"
cd ${test_tmpdir}
mkdir mnt
@@ -192,3 +192,21 @@ sed -i -e s,first,second, mnt/firstfile
assert_file_has_content_literal mnt/firstfile "second"
echo "ok copyup"
+
+copyup_reset
+echo nonhardlinked > checkout-test2/nonhardlinked
+if fsverity enable checkout-test2/nonhardlinked 2>err.txt; then
+ orig_inode=$(stat -c %i checkout-test2/nonhardlinked)
+ echo "updated content" > mnt/nonhardlinked
+ new_inode=$(stat -c %i checkout-test2/nonhardlinked)
+ assert_not_streq "${orig_inode}" "${new_inode}"
+ # And via chmod
+ fsverity enable checkout-test2/nonhardlinked
+ orig_inode=$(stat -c %i checkout-test2/nonhardlinked)
+ chmod 0700 mnt/nonhardlinked
+ new_inode=$(stat -c %i checkout-test2/nonhardlinked)
+ assert_not_streq "${orig_inode}" "${new_inode}"
+ echo "ok copyup fsverity"
+else
+ skip "no fsverity support: $(cat err.txt)"
+fi \ No newline at end of file
diff --git a/tests/test-signed-commit.sh b/tests/test-signed-commit.sh
index 432687d8..cf1cd1c8 100755
--- a/tests/test-signed-commit.sh
+++ b/tests/test-signed-commit.sh
@@ -61,7 +61,7 @@ assert_file_has_content_literal err.txt ' No valid signatures found'
echo "ok dummy sig requires env"
# tests below require libsodium support
-if ! has_sign_ed25519; then
+if ! has_ostree_feature sign-ed25519; then
echo "ok Detached ed25519 signature # SKIP due libsodium unavailability"
echo "ok ed25519 signature verified # SKIP due libsodium unavailability"
echo "ok multiple signing # SKIP due libsodium unavailability"
diff --git a/tests/test-signed-pull-summary.sh b/tests/test-signed-pull-summary.sh
index d2873894..e5339078 100755
--- a/tests/test-signed-pull-summary.sh
+++ b/tests/test-signed-pull-summary.sh
@@ -52,7 +52,7 @@ do
PUBLIC_KEY="dummysign"
;;
ed25519)
- if ! has_sign_ed25519; then
+ if ! has_ostree_feature sign-ed25519; then
echo "ok ${engine} pull mirror summary # SKIP due libsodium unavailability"
echo "ok ${engine} pull with signed summary # SKIP due libsodium unavailability"
echo "ok ${engine} prune summary cache # SKIP due libsodium unavailability"
@@ -174,7 +174,7 @@ do
done
-if ! has_sign_ed25519; then
+if ! has_ostree_feature sign-ed25519; then
echo "ok ${engine} pull with signed summary remote old summary # SKIP due libsodium unavailability"
echo "ok ${engine} pull with signed summary broken cache # SKIP due libsodium unavailability"
exit 0
diff --git a/tests/test-signed-pull.sh b/tests/test-signed-pull.sh
index 5754914f..a08d3fbf 100755
--- a/tests/test-signed-pull.sh
+++ b/tests/test-signed-pull.sh
@@ -140,7 +140,7 @@ fi
assert_file_has_content err.txt 'Invalid key reference'
echo "ok remote add errs"
-if ! has_sign_ed25519; then
+if ! has_ostree_feature sign-ed25519; then
echo "ok ed25519-key pull signed commit # SKIP due libsodium unavailability"
echo "ok ed25519-key re-pull signature for stored commit # SKIP due libsodium unavailability"
echo "ok ed25519-key+file pull signed commit # SKIP due libsodium unavailability"
diff --git a/tests/test-summary-update.sh b/tests/test-summary-update.sh
index d85e9c4b..6cf5fccb 100755
--- a/tests/test-summary-update.sh
+++ b/tests/test-summary-update.sh
@@ -27,7 +27,7 @@ set -euo pipefail
echo "1..2"
COMMIT_SIGN=""
-if has_gpgme; then
+if has_ostree_feature gpgme; then
COMMIT_SIGN="--gpg-homedir=${TEST_GPG_KEYHOME} --gpg-sign=${TEST_GPG_KEYID_1}"
fi
diff --git a/tests/test-summary-view.sh b/tests/test-summary-view.sh
index 9dfc74f4..473c6db5 100755
--- a/tests/test-summary-view.sh
+++ b/tests/test-summary-view.sh
@@ -27,7 +27,7 @@ set -euo pipefail
echo "1..2"
COMMIT_SIGN=""
-if has_gpgme; then
+if has_ostree_feature gpgme; then
COMMIT_SIGN="--gpg-homedir=${TEST_GPG_KEYHOME} --gpg-sign=${TEST_GPG_KEYID_1}"
fi