diff --git a/Makefile-libostree-defines.am b/Makefile-libostree-defines.am
index 1531cf8c..aff7e52b 100644
--- a/Makefile-libostree-defines.am
+++ b/Makefile-libostree-defines.am
@@ -38,6 +38,12 @@ libostree_public_headers = \
src/libostree/ostree-repo-deprecated.h \
$(NULL)
+if ENABLE_EXPERIMENTAL_API
+libostree_public_headers += \
+ src/libostree/ostree-remote.h \
+ $(NULL)
+endif
+
# This one is generated via configure.ac, and the gtk-doc
# code hence needs to look in the builddir.
libostree_public_built_headers = src/libostree/ostree-version.h
diff --git a/Makefile-libostree.am b/Makefile-libostree.am
index 0a114884..7f2e2a4a 100644
--- a/Makefile-libostree.am
+++ b/Makefile-libostree.am
@@ -94,6 +94,8 @@ libostree_1_la_SOURCES = \
src/libostree/ostree-linuxfsutil.c \
src/libostree/ostree-diff.c \
src/libostree/ostree-mutable-tree.c \
+ src/libostree/ostree-remote.c \
+ src/libostree/ostree-remote-private.h \
src/libostree/ostree-repo.c \
src/libostree/ostree-repo-checkout.c \
src/libostree/ostree-repo-commit.c \
@@ -113,6 +115,7 @@ libostree_1_la_SOURCES = \
src/libostree/ostree-sysroot-cleanup.c \
src/libostree/ostree-sysroot-deploy.c \
src/libostree/ostree-sysroot-upgrader.c \
+ src/libostree/ostree-impl-system-generator.c \
src/libostree/ostree-bootconfig-parser.c \
src/libostree/ostree-deployment.c \
src/libostree/ostree-bootloader.h \
@@ -146,6 +149,11 @@ libostree_1_la_SOURCES += \
src/libostree/ostree-tls-cert-interaction.h \
$(NULL)
endif
+if !ENABLE_EXPERIMENTAL_API
+libostree_1_la_SOURCES += \
+ src/libostree/ostree-remote.h \
+ $(NULL)
+endif
libostree_1_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/bsdiff -I$(srcdir)/libglnx -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree -I$(builddir)/src/libostree \
$(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) $(OT_DEP_LZMA_CFLAGS) $(OT_DEP_ZLIB_CFLAGS) $(OT_DEP_OPENSSL_CFLAGS) \
@@ -156,7 +164,15 @@ libostree_1_la_LIBADD = libotutil.la libglnx.la libbsdiff.la libostree-kernel-ar
libostree_1_la_LIBADD += $(bupsplitpath)
EXTRA_libostree_1_la_DEPENDENCIES = $(top_srcdir)/src/libostree/libostree.sym
-EXTRA_DIST += src/libostree/libostree.sym
+EXTRA_DIST += \
+ src/libostree/libostree.sym \
+ src/libostree/libostree-experimental.sym \
+ $(NULL)
+
+if ENABLE_EXPERIMENTAL_API
+libostree_1_la_LDFLAGS += -Wl,--version-script=$(top_srcdir)/src/libostree/libostree-experimental.sym
+EXTRA_libostree_1_la_DEPENDENCIES += $(top_srcdir)/src/libostree/libostree-experimental.sym
+endif
if USE_LIBARCHIVE
libostree_1_la_CFLAGS += $(OT_DEP_LIBARCHIVE_CFLAGS)
diff --git a/Makefile-switchroot.am b/Makefile-switchroot.am
index 6fd2f820..dd24010e 100644
--- a/Makefile-switchroot.am
+++ b/Makefile-switchroot.am
@@ -27,6 +27,7 @@ ostree_prepare_root_SOURCES = \
src/switchroot/ostree-mount-util.h \
src/switchroot/ostree-prepare-root.c \
$(NULL)
+ostree_prepare_root_CPPFLAGS = $(AM_CPPFLAGS)
if BUILDOPT_USE_STATIC_COMPILER
# ostree-prepare-root can be used as init in a system without a populated /lib.
@@ -45,7 +46,6 @@ ostree-prepare-root : $(ostree_prepare_root_SOURCES)
$(STATIC_COMPILER) -o $@ -static $(ostree_prepare_root_SOURCES) $(AM_CPPFLAGS) $(AM_CFLAGS) $(DEFAULT_INCLUDES)
else
ostree_boot_PROGRAMS += ostree-prepare-root
-
ostree_prepare_root_CFLAGS = $(AM_CFLAGS) -Isrc/switchroot
endif
@@ -53,4 +53,19 @@ ostree_remount_SOURCES = \
src/switchroot/ostree-mount-util.h \
src/switchroot/ostree-remount.c \
$(NULL)
-ostree_remount_CFLAGS = $(AM_CFLAGS) -Isrc/switchroot
+ostree_remount_CPPFLAGS = $(AM_CPPFLAGS) -Isrc/switchroot
+
+# This is the "new mode" of using a generator for /var; see
+# https://github.com/ostreedev/ostree/issues/855
+if BUILDOPT_SYSTEMD_AND_LIBMOUNT
+ostree_prepare_root_CPPFLAGS += -DHAVE_SYSTEMD_AND_LIBMOUNT=1
+ostree_remount_CPPFLAGS += -DHAVE_SYSTEMD_AND_LIBMOUNT=1
+
+systemdsystemgenerator_PROGRAMS = ostree-system-generator
+GITIGNOREFILES += $(systemdsystemgenerator_PROGRAMS)
+ostree_system_generator_SOURCES = src/switchroot/ostree-mount-util.h \
+ src/switchroot/ostree-system-generator.c
+ostree_system_generator_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/libglnx -I$(srcdir)/src/libostree
+ostree_system_generator_CFLAGS = $(AM_CFLAGS) $(OT_INTERNAL_GIO_UNIX_CFLAGS)
+ostree_system_generator_LDADD = $(AM_LDFLAGS) libglnx.la libostree-1.la $(OT_INTERNAL_GIO_UNIX_LIBS)
+endif
diff --git a/Makefile-tests.am b/Makefile-tests.am
index 8389331d..89675288 100644
--- a/Makefile-tests.am
+++ b/Makefile-tests.am
@@ -34,6 +34,7 @@ TESTS_ENVIRONMENT += OT_TESTS_DEBUG=1 \
GI_TYPELIB_PATH=$$(cd $(top_builddir) && pwd)$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH} \
LD_LIBRARY_PATH=$$(cd $(top_builddir)/.libs && pwd)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}} \
PATH=$$(cd $(top_builddir)/tests && pwd):$${PATH} \
+ OSTREE_FEATURES="$(OSTREE_FEATURES)" \
$(NULL)
if BUILDOPT_ASAN
TESTS_ENVIRONMENT += OT_SKIP_READDIR_RAND=1 G_SLICE=always-malloc
@@ -42,12 +43,20 @@ endif
uninstalled_test_data = tests/ostree-symlink-stamp tests/ostree-prepare-root-symlink-stamp \
tests/ostree-remount-symlink-stamp tests/rofiles-fuse-symlink-stamp
-dist_uninstalled_test_scripts = tests/test-symbols.sh
+dist_uninstalled_test_scripts = tests/test-symbols.sh tests/coccinelle.sh
-dist_test_scripts = \
+# This logic implements ENABLE_INSTALLED_TESTS_EXCLUSIVE; see below.
+# The goal here if installed tests are enabled, we explicitly make the
+# tests *only* run installed, to avoid having to run them twice in CI.
+# This overrides the glib-tap.mk emphasis on doing both, if we'd
+# used e.g. `dist_test_scripts`.
+dist_test_scripts = $(NULL)
+test_programs = $(NULL)
+_installed_or_uninstalled_test_scripts = \
tests/test-basic.sh \
tests/test-basic-user.sh \
tests/test-basic-user-only.sh \
+ tests/test-basic-root.sh \
tests/test-pull-subpath.sh \
tests/test-archivez.sh \
tests/test-remote-add.sh \
@@ -68,7 +77,6 @@ dist_test_scripts = \
tests/test-pull-resume.sh \
tests/test-pull-repeated.sh \
tests/test-pull-untrusted.sh \
- tests/test-pull-many.sh \
tests/test-pull-override-url.sh \
tests/test-local-pull.sh \
tests/test-local-pull-depth.sh \
@@ -88,7 +96,6 @@ dist_test_scripts = \
tests/test-admin-pull-deploy-split.sh \
tests/test-admin-locking.sh \
tests/test-admin-deploy-clean.sh \
- tests/test-repo-checkout-subpath.sh \
tests/test-reset-nonlinear.sh \
tests/test-oldstyle-partial.sh \
tests/test-delta.sh \
@@ -100,23 +107,23 @@ dist_test_scripts = \
tests/test-switchroot.sh \
tests/test-pull-contenturl.sh \
tests/test-pull-mirrorlist.sh \
- tests/coccinelle.sh \
+ tests/test-summary-view.sh \
$(NULL)
if BUILDOPT_FUSE
-dist_test_scripts += tests/test-rofiles-fuse.sh
+_installed_or_uninstalled_test_scripts += tests/test-rofiles-fuse.sh
else
EXTRA_DIST += tests/test-rofiles-fuse.sh
endif
if USE_LIBSOUP
-dist_test_scripts += tests/test-remote-cookies.sh
+_installed_or_uninstalled_test_scripts += tests/test-remote-cookies.sh
endif
-# These call into gjs scripts
+# These call into gjs scripts
js_tests = tests/test-corruption.sh tests/test-pull-corruption.sh
if BUILDOPT_GJS
-dist_test_scripts += $(js_tests)
+_installed_or_uninstalled_test_scripts += $(js_tests)
else
EXTRA_DIST += $(js_tests)
endif
@@ -127,9 +134,10 @@ dist_installed_test_data = tests/archive-test.sh \
tests/basic-test.sh \
tests/pre-endian-deltas-repo-big.tar.xz \
tests/pre-endian-deltas-repo-little.tar.xz \
+ tests/libtest-core.sh \
$(NULL)
-EXTRA_DIST += tests/libtest.sh
+EXTRA_DIST += tests/libtest.sh
dist_test_extra_scripts = \
tests/bootloader-entries-crosscheck.py \
@@ -179,7 +187,7 @@ if !ENABLE_INSTALLED_TESTS
libreaddir_rand_la_LDFLAGS += -rpath $(abs_builddir)
endif
-test_programs = tests/test-varint tests/test-ot-unix-utils tests/test-bsdiff tests/test-mutable-tree \
+_installed_or_uninstalled_test_programs = tests/test-varint tests/test-ot-unix-utils tests/test-bsdiff tests/test-mutable-tree \
tests/test-keyfile-utils tests/test-ot-opt-utils tests/test-ot-tool-util \
tests/test-gpg-verify-result tests/test-checksum tests/test-lzma tests/test-rollsum \
tests/test-basic-c tests/test-sysroot-c tests/test-pull-c
@@ -188,7 +196,7 @@ test_programs = tests/test-varint tests/test-ot-unix-utils tests/test-bsdiff tes
noinst_PROGRAMS += tests/test-rollsum-cli
if USE_LIBARCHIVE
-test_programs += tests/test-libarchive-import
+_installed_or_uninstalled_test_programs += tests/test-libarchive-import
endif
common_tests_cflags = $(ostree_bin_shared_cflags) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -I$(srcdir)/libglnx
@@ -285,6 +293,17 @@ tests/%-symlink-stamp: % Makefile
ln -sf "$${real_bin}" tests/$*; \
touch $@
+# See above comment on binding the tests to be either installed or not.
+if ENABLE_INSTALLED_TESTS_EXCLUSIVE
+dist_installed_test_scripts = $(_installed_or_uninstalled_test_scripts)
+installed_test_programs = $(_installed_or_uninstalled_test_programs)
+check-local:
+ echo "NOTE: Exclusive installed tests are enabled; to run them, make install, then: gnome-desktop-testing-runner -p 0 libostree/"
+else
+dist_test_scripts += $(_installed_or_uninstalled_test_scripts)
+test_programs += $(_installed_or_uninstalled_test_programs)
+endif
+
# Unfortunately the glib test data APIs don't actually handle
# non-recursive Automake, so we change our code to canonically look
# for tests/ which is just a symlink when installed.
diff --git a/Makefile.am b/Makefile.am
index 78cd6653..53b505e3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,7 +19,7 @@ include Makefile-decls.am
shortened_sysconfdir = $$(echo "$(sysconfdir)" | sed -e 's|^$(prefix)||' -e 's|^/||')
-OSTREE_GITREV=$(shell if command -v git >/dev/null 2>&1 && test -d $(srcdir)/.git; then git describe --abbrev=42 --tags --always HEAD; fi)
+OSTREE_GITREV=$(shell cd $(srcdir) && if command -v git >/dev/null 2>&1 && test -d .git; then git describe --abbrev=42 --tags --always HEAD; fi)
ACLOCAL_AMFLAGS = -I buildutil -I libglnx ${ACLOCAL_FLAGS}
AM_CPPFLAGS += -DDATADIR='"$(datadir)"' -DLIBEXECDIR='"$(libexecdir)"' \
@@ -113,11 +113,11 @@ include Makefile-boot.am
include Makefile-man.am
release-tag:
- git tag -m "Release $(VERSION)" v$(VERSION)
+ cd $(srcdir) && git $(srcdir) tag -m "Release $(VERSION)" v$(VERSION)
embed_dependency=tar -C $(srcdir) --append --exclude='.git/*' --transform="s,^embedded-dependencies/,ostree-embeddeps-$${GITVERSION}/embedded-dependencies/," --file=$${TARFILE_TMP}
-git_version_rpm = $$(git describe | sed -e 's,-,\.,g' -e 's,^v,,')
+git_version_rpm = $$(cd $(srcdir) && git describe | sed -e 's,-,\.,g' -e 's,^v,,')
release-tarball-embedded:
set -x; \
diff --git a/Makefile.in b/Makefile.in
index d17f7720..b0d766e6 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -340,13 +340,13 @@ host_triplet = @host@
bin_PROGRAMS = ostree$(EXEEXT) $(am__EXEEXT_1)
sbin_PROGRAMS =
libexec_PROGRAMS =
-pkglibexec_PROGRAMS = $(am__EXEEXT_12)
-noinst_PROGRAMS = $(am__EXEEXT_9) tests/test-rollsum-cli$(EXEEXT)
-ostree_boot_PROGRAMS = $(am__EXEEXT_10) $(am__EXEEXT_11)
-TESTS = $(am__EXEEXT_3) $(am__EXEEXT_14) \
- $(dist_uninstalled_test_scripts) $(am__EXEEXT_6)
-installed_test_PROGRAMS = $(am__EXEEXT_8)
-check_PROGRAMS = $(am__EXEEXT_5) $(am__EXEEXT_6) $(am__EXEEXT_7)
+pkglibexec_PROGRAMS = $(am__EXEEXT_16)
+noinst_PROGRAMS = $(am__EXEEXT_13) tests/test-rollsum-cli$(EXEEXT)
+ostree_boot_PROGRAMS = $(am__EXEEXT_14) $(am__EXEEXT_15)
+TESTS = $(am__EXEEXT_6) $(am__EXEEXT_19) \
+ $(dist_uninstalled_test_scripts) $(am__EXEEXT_10)
+installed_test_PROGRAMS = $(am__EXEEXT_12)
+check_PROGRAMS = $(am__EXEEXT_9) $(am__EXEEXT_10) $(am__EXEEXT_11)
@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__append_1 = $(all_test_ltlibs)
@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__append_2 = $(all_test_programs)
@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__append_3 = $(all_test_scripts)
@@ -374,23 +374,33 @@ check_PROGRAMS = $(am__EXEEXT_5) $(am__EXEEXT_6) $(am__EXEEXT_7)
@ENABLE_INSTALLED_TESTS_TRUE@am__append_13 = $(installed_test_meta_DATA)
@ENABLE_GTK_DOC_TRUE@am__append_14 = apidoc
@ENABLE_RUST_TRUE@am__append_15 = $(srcdir)/rust/Cargo.toml $(srcdir)/rust/cargo-vendor-config
-@ENABLE_RUST_TRUE@am__append_16 = $(BUPSPLIT_RUST_SRCS)
-@ENABLE_RUST_FALSE@am__append_17 = libbupsplit.la
-@USE_LIBARCHIVE_TRUE@am__append_18 = src/libostree/ostree-libarchive-input-stream.h \
+@ENABLE_EXPERIMENTAL_API_TRUE@am__append_16 = \
+@ENABLE_EXPERIMENTAL_API_TRUE@ src/libostree/ostree-remote.h \
+@ENABLE_EXPERIMENTAL_API_TRUE@ $(NULL)
+
+@ENABLE_RUST_TRUE@am__append_17 = $(BUPSPLIT_RUST_SRCS)
+@ENABLE_RUST_FALSE@am__append_18 = libbupsplit.la
+@USE_LIBARCHIVE_TRUE@am__append_19 = src/libostree/ostree-libarchive-input-stream.h \
@USE_LIBARCHIVE_TRUE@ src/libostree/ostree-libarchive-input-stream.c \
@USE_LIBARCHIVE_TRUE@ src/libostree/ostree-libarchive-private.h \
@USE_LIBARCHIVE_TRUE@ $(NULL)
-@HAVE_LIBSOUP_CLIENT_CERTS_TRUE@am__append_19 = \
+@HAVE_LIBSOUP_CLIENT_CERTS_TRUE@am__append_20 = \
@HAVE_LIBSOUP_CLIENT_CERTS_TRUE@ src/libostree/ostree-tls-cert-interaction.c \
@HAVE_LIBSOUP_CLIENT_CERTS_TRUE@ src/libostree/ostree-tls-cert-interaction.h \
@HAVE_LIBSOUP_CLIENT_CERTS_TRUE@ $(NULL)
-@USE_LIBARCHIVE_TRUE@am__append_20 = $(OT_DEP_LIBARCHIVE_CFLAGS)
-@USE_LIBARCHIVE_TRUE@am__append_21 = $(OT_DEP_LIBARCHIVE_LIBS)
-@BUILDOPT_LIBSYSTEMD_TRUE@am__append_22 = $(LIBSYSTEMD_CFLAGS)
-@BUILDOPT_LIBSYSTEMD_TRUE@am__append_23 = $(LIBSYSTEMD_LIBS)
-@USE_CURL_OR_SOUP_TRUE@am__append_24 = \
+@ENABLE_EXPERIMENTAL_API_FALSE@am__append_21 = \
+@ENABLE_EXPERIMENTAL_API_FALSE@ src/libostree/ostree-remote.h \
+@ENABLE_EXPERIMENTAL_API_FALSE@ $(NULL)
+
+@ENABLE_EXPERIMENTAL_API_TRUE@am__append_22 = -Wl,--version-script=$(top_srcdir)/src/libostree/libostree-experimental.sym
+@ENABLE_EXPERIMENTAL_API_TRUE@am__append_23 = $(top_srcdir)/src/libostree/libostree-experimental.sym
+@USE_LIBARCHIVE_TRUE@am__append_24 = $(OT_DEP_LIBARCHIVE_CFLAGS)
+@USE_LIBARCHIVE_TRUE@am__append_25 = $(OT_DEP_LIBARCHIVE_LIBS)
+@BUILDOPT_LIBSYSTEMD_TRUE@am__append_26 = $(LIBSYSTEMD_CFLAGS)
+@BUILDOPT_LIBSYSTEMD_TRUE@am__append_27 = $(LIBSYSTEMD_LIBS)
+@USE_CURL_OR_SOUP_TRUE@am__append_28 = \
@USE_CURL_OR_SOUP_TRUE@ src/libostree/ostree-fetcher.h \
@USE_CURL_OR_SOUP_TRUE@ src/libostree/ostree-fetcher-util.h \
@USE_CURL_OR_SOUP_TRUE@ src/libostree/ostree-fetcher-util.c \
@@ -399,25 +409,25 @@ check_PROGRAMS = $(am__EXEEXT_5) $(am__EXEEXT_6) $(am__EXEEXT_7)
@USE_CURL_OR_SOUP_TRUE@ src/libostree/ostree-metalink.c \
@USE_CURL_OR_SOUP_TRUE@ $(NULL)
-@USE_CURL_TRUE@am__append_25 = src/libostree/ostree-fetcher-curl.c \
+@USE_CURL_TRUE@am__append_29 = src/libostree/ostree-fetcher-curl.c \
@USE_CURL_TRUE@ src/libostree/ostree-soup-uri.h src/libostree/ostree-soup-uri.c \
@USE_CURL_TRUE@ src/libostree/ostree-soup-form.c \
@USE_CURL_TRUE@ $(NULL)
-@USE_CURL_TRUE@am__append_26 = $(OT_DEP_CURL_CFLAGS)
-@USE_CURL_TRUE@am__append_27 = $(OT_DEP_CURL_LIBS)
-@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__append_28 = src/libostree/ostree-fetcher-soup.c
-@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__append_29 = $(OT_INTERNAL_SOUP_CFLAGS)
-@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__append_30 = $(OT_INTERNAL_SOUP_LIBS)
-@USE_LIBMOUNT_TRUE@am__append_31 = $(OT_DEP_LIBMOUNT_CFLAGS)
-@USE_LIBMOUNT_TRUE@am__append_32 = $(OT_DEP_LIBMOUNT_LIBS)
-@USE_SELINUX_TRUE@am__append_33 = $(OT_DEP_SELINUX_CFLAGS)
-@USE_SELINUX_TRUE@am__append_34 = $(OT_DEP_SELINUX_LIBS)
-@BUILDOPT_INTROSPECTION_TRUE@am__append_35 = OSTree-1.0.gir
-@BUILDOPT_INTROSPECTION_TRUE@am__append_36 = OSTree-1.0.gir
-@BUILDOPT_INTROSPECTION_TRUE@am__append_37 = OSTree-1.0.typelib
-@BUILDOPT_INTROSPECTION_TRUE@am__append_38 = $(gir_DATA) $(typelib_DATA)
-@USE_CURL_OR_SOUP_TRUE@am__append_39 = src/ostree/ot-remote-builtin-add-cookie.c \
+@USE_CURL_TRUE@am__append_30 = $(OT_DEP_CURL_CFLAGS)
+@USE_CURL_TRUE@am__append_31 = $(OT_DEP_CURL_LIBS)
+@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__append_32 = src/libostree/ostree-fetcher-soup.c
+@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__append_33 = $(OT_INTERNAL_SOUP_CFLAGS)
+@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__append_34 = $(OT_INTERNAL_SOUP_LIBS)
+@USE_LIBMOUNT_TRUE@am__append_35 = $(OT_DEP_LIBMOUNT_CFLAGS)
+@USE_LIBMOUNT_TRUE@am__append_36 = $(OT_DEP_LIBMOUNT_LIBS)
+@USE_SELINUX_TRUE@am__append_37 = $(OT_DEP_SELINUX_CFLAGS)
+@USE_SELINUX_TRUE@am__append_38 = $(OT_DEP_SELINUX_LIBS)
+@BUILDOPT_INTROSPECTION_TRUE@am__append_39 = OSTree-1.0.gir
+@BUILDOPT_INTROSPECTION_TRUE@am__append_40 = OSTree-1.0.gir
+@BUILDOPT_INTROSPECTION_TRUE@am__append_41 = OSTree-1.0.typelib
+@BUILDOPT_INTROSPECTION_TRUE@am__append_42 = $(gir_DATA) $(typelib_DATA)
+@USE_CURL_OR_SOUP_TRUE@am__append_43 = src/ostree/ot-remote-builtin-add-cookie.c \
@USE_CURL_OR_SOUP_TRUE@ src/ostree/ot-remote-builtin-delete-cookie.c \
@USE_CURL_OR_SOUP_TRUE@ src/ostree/ot-remote-builtin-list-cookies.c \
@USE_CURL_OR_SOUP_TRUE@ src/ostree/ot-remote-cookie-util.h \
@@ -425,40 +435,49 @@ check_PROGRAMS = $(am__EXEEXT_5) $(am__EXEEXT_6) $(am__EXEEXT_7)
@USE_CURL_OR_SOUP_TRUE@ $(NULL) src/ostree/ot-builtin-pull.c
# Eventually once we stop things from using this, we should support disabling this
-@USE_LIBSOUP_TRUE@am__append_40 = src/ostree/ot-builtin-trivial-httpd.c
-@USE_LIBSOUP_TRUE@am__append_41 = ostree-trivial-httpd
+@USE_LIBSOUP_TRUE@am__append_44 = src/ostree/ot-builtin-trivial-httpd.c
+@USE_LIBSOUP_TRUE@am__append_45 = ostree-trivial-httpd
# This is necessary for the cookie jar bits
-@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__append_42 = $(OT_INTERNAL_SOUP_CFLAGS)
-@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__append_43 = $(OT_INTERNAL_SOUP_LIBS)
-@USE_LIBARCHIVE_TRUE@am__append_44 = $(OT_DEP_LIBARCHIVE_CFLAGS)
-@USE_LIBARCHIVE_TRUE@am__append_45 = $(OT_DEP_LIBARCHIVE_LIBS)
-@BUILDOPT_SYSTEMD_TRUE@am__append_46 = ostree-remount
+@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__append_46 = $(OT_INTERNAL_SOUP_CFLAGS)
+@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__append_47 = $(OT_INTERNAL_SOUP_LIBS)
+@USE_LIBARCHIVE_TRUE@am__append_48 = $(OT_DEP_LIBARCHIVE_CFLAGS)
+@USE_LIBARCHIVE_TRUE@am__append_49 = $(OT_DEP_LIBARCHIVE_LIBS)
+@BUILDOPT_SYSTEMD_TRUE@am__append_50 = ostree-remount
# It is built anyway as a side-effect of having the symlink in tests/,
# and if we declare it here, it gets cleaned up properly
-@BUILDOPT_SYSTEMD_FALSE@am__append_47 = ostree-remount
-@BUILDOPT_USE_STATIC_COMPILER_FALSE@am__append_48 = ostree-prepare-root
-@BUILDOPT_FUSE_TRUE@am__append_49 = rofiles-fuse
-@BUILDOPT_ASAN_TRUE@am__append_50 = OT_SKIP_READDIR_RAND=1 G_SLICE=always-malloc
-@BUILDOPT_FUSE_TRUE@am__append_51 = tests/test-rofiles-fuse.sh
-@BUILDOPT_FUSE_FALSE@am__append_52 = tests/test-rofiles-fuse.sh
-@USE_LIBSOUP_TRUE@am__append_53 = tests/test-remote-cookies.sh
-@BUILDOPT_GJS_TRUE@am__append_54 = $(js_tests)
-@BUILDOPT_GJS_FALSE@am__append_55 = $(js_tests)
-@BUILDOPT_GJS_FALSE@am__append_56 = $(js_installed_tests)
-@ENABLE_INSTALLED_TESTS_FALSE@am__append_57 = -rpath $(abs_builddir)
-@USE_LIBARCHIVE_TRUE@am__append_58 = tests/test-libarchive-import
-@ENABLE_INSTALLED_TESTS_TRUE@am__append_59 = install-installed-tests-extra
+@BUILDOPT_SYSTEMD_FALSE@am__append_51 = ostree-remount
+@BUILDOPT_USE_STATIC_COMPILER_FALSE@am__append_52 = ostree-prepare-root
+
+# This is the "new mode" of using a generator for /var; see
+# https://github.com/ostreedev/ostree/issues/855
+@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@am__append_53 = -DHAVE_SYSTEMD_AND_LIBMOUNT=1
+@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@am__append_54 = -DHAVE_SYSTEMD_AND_LIBMOUNT=1
+@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@systemdsystemgenerator_PROGRAMS = ostree-system-generator$(EXEEXT)
+@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@am__append_55 = $(systemdsystemgenerator_PROGRAMS)
+@BUILDOPT_FUSE_TRUE@am__append_56 = rofiles-fuse
+@BUILDOPT_ASAN_TRUE@am__append_57 = OT_SKIP_READDIR_RAND=1 G_SLICE=always-malloc
+@BUILDOPT_FUSE_TRUE@am__append_58 = tests/test-rofiles-fuse.sh
+@BUILDOPT_FUSE_FALSE@am__append_59 = tests/test-rofiles-fuse.sh
+@USE_LIBSOUP_TRUE@am__append_60 = tests/test-remote-cookies.sh
+@BUILDOPT_GJS_TRUE@am__append_61 = $(js_tests)
+@BUILDOPT_GJS_FALSE@am__append_62 = $(js_tests)
+@BUILDOPT_GJS_FALSE@am__append_63 = $(js_installed_tests)
+@ENABLE_INSTALLED_TESTS_FALSE@am__append_64 = -rpath $(abs_builddir)
+@USE_LIBARCHIVE_TRUE@am__append_65 = tests/test-libarchive-import
+@ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE@am__append_66 = $(_installed_or_uninstalled_test_scripts)
+@ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE@am__append_67 = $(_installed_or_uninstalled_test_programs)
+@ENABLE_INSTALLED_TESTS_TRUE@am__append_68 = install-installed-tests-extra
# Allow the distcheck install under $prefix test to pass
-@BUILDOPT_SYSTEMD_TRUE@am__append_60 = --with-systemdsystemunitdir='$${libdir}/systemd/system'
+@BUILDOPT_SYSTEMD_TRUE@am__append_69 = --with-systemdsystemunitdir='$${libdir}/systemd/system'
# We're using the system grub2-mkconfig generator
-@BUILDOPT_BUILTIN_GRUB2_MKCONFIG_FALSE@am__append_61 = src/boot/grub2/grub2-15_ostree
-@BUILDOPT_BUILTIN_GRUB2_MKCONFIG_FALSE@am__append_62 = install-grub2-config-hook
-@BUILDOPT_FUSE_TRUE@@ENABLE_MAN_TRUE@am__append_63 = rofiles-fuse.1
-@ENABLE_MAN_TRUE@am__append_64 = $(man1_MANS) $(man5_MANS) $(man1_MANS:.1=.xml) $(man5_MANS:.5=.xml)
-@ENABLE_MAN_TRUE@am__append_65 = \
+@BUILDOPT_BUILTIN_GRUB2_MKCONFIG_FALSE@am__append_70 = src/boot/grub2/grub2-15_ostree
+@BUILDOPT_BUILTIN_GRUB2_MKCONFIG_FALSE@am__append_71 = install-grub2-config-hook
+@BUILDOPT_FUSE_TRUE@@ENABLE_MAN_TRUE@am__append_72 = rofiles-fuse.1
+@ENABLE_MAN_TRUE@am__append_73 = $(man1_MANS) $(man5_MANS) $(man1_MANS:.1=.xml) $(man5_MANS:.5=.xml)
+@ENABLE_MAN_TRUE@am__append_74 = \
@ENABLE_MAN_TRUE@ $(man1_MANS) \
@ENABLE_MAN_TRUE@ $(man5_MANS) \
@ENABLE_MAN_TRUE@ $(NULL)
@@ -480,8 +499,8 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
$(am__configure_deps) $(am__dist_gpginsttest_DATA_DIST) \
$(am__dist_gpginsttest_trusted_DATA_DIST) \
- $(am__dist_gpgvinsttest_DATA_DIST) $(libostreeinclude_HEADERS) \
- $(am__DIST_COMMON)
+ $(am__dist_gpgvinsttest_DATA_DIST) \
+ $(am__libostreeinclude_HEADERS_DIST) $(am__DIST_COMMON)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
@@ -521,8 +540,8 @@ am__installdirs = "$(DESTDIR)$(installed_testdir)" \
"$(DESTDIR)$(bindir)" "$(DESTDIR)$(installed_testdir)" \
"$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(ostree_bootdir)" \
"$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(sbindir)" \
- "$(DESTDIR)$(bindir)" "$(DESTDIR)$(dracutmoddir)" \
- "$(DESTDIR)$(installed_testdir)" \
+ "$(DESTDIR)$(systemdsystemgeneratordir)" "$(DESTDIR)$(bindir)" \
+ "$(DESTDIR)$(dracutmoddir)" "$(DESTDIR)$(installed_testdir)" \
"$(DESTDIR)$(mkinitcpioinstalldir)" \
"$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" \
"$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" \
@@ -611,6 +630,8 @@ am__libostree_1_la_SOURCES_DIST = \
src/libostree/ostree-linuxfsutil.h \
src/libostree/ostree-linuxfsutil.c src/libostree/ostree-diff.c \
src/libostree/ostree-mutable-tree.c \
+ src/libostree/ostree-remote.c \
+ src/libostree/ostree-remote-private.h \
src/libostree/ostree-repo.c \
src/libostree/ostree-repo-checkout.c \
src/libostree/ostree-repo-commit.c \
@@ -630,6 +651,7 @@ am__libostree_1_la_SOURCES_DIST = \
src/libostree/ostree-sysroot-cleanup.c \
src/libostree/ostree-sysroot-deploy.c \
src/libostree/ostree-sysroot-upgrader.c \
+ src/libostree/ostree-impl-system-generator.c \
src/libostree/ostree-bootconfig-parser.c \
src/libostree/ostree-deployment.c \
src/libostree/ostree-bootloader.h \
@@ -655,7 +677,7 @@ am__libostree_1_la_SOURCES_DIST = \
src/libostree/ostree-libarchive-private.h \
src/libostree/ostree-tls-cert-interaction.c \
src/libostree/ostree-tls-cert-interaction.h \
- src/libostree/ostree-fetcher.h \
+ src/libostree/ostree-remote.h src/libostree/ostree-fetcher.h \
src/libostree/ostree-fetcher-util.h \
src/libostree/ostree-fetcher-util.c \
src/libostree/ostree-fetcher-uri.c \
@@ -670,15 +692,16 @@ am__libostree_1_la_SOURCES_DIST = \
@USE_LIBARCHIVE_TRUE@ $(am__objects_1)
@HAVE_LIBSOUP_CLIENT_CERTS_TRUE@am__objects_3 = src/libostree/libostree_1_la-ostree-tls-cert-interaction.lo \
@HAVE_LIBSOUP_CLIENT_CERTS_TRUE@ $(am__objects_1)
-@USE_CURL_OR_SOUP_TRUE@am__objects_4 = src/libostree/libostree_1_la-ostree-fetcher-util.lo \
+@ENABLE_EXPERIMENTAL_API_FALSE@am__objects_4 = $(am__objects_1)
+@USE_CURL_OR_SOUP_TRUE@am__objects_5 = src/libostree/libostree_1_la-ostree-fetcher-util.lo \
@USE_CURL_OR_SOUP_TRUE@ src/libostree/libostree_1_la-ostree-fetcher-uri.lo \
@USE_CURL_OR_SOUP_TRUE@ src/libostree/libostree_1_la-ostree-metalink.lo \
@USE_CURL_OR_SOUP_TRUE@ $(am__objects_1)
-@USE_CURL_TRUE@am__objects_5 = src/libostree/libostree_1_la-ostree-fetcher-curl.lo \
+@USE_CURL_TRUE@am__objects_6 = src/libostree/libostree_1_la-ostree-fetcher-curl.lo \
@USE_CURL_TRUE@ src/libostree/libostree_1_la-ostree-soup-uri.lo \
@USE_CURL_TRUE@ src/libostree/libostree_1_la-ostree-soup-form.lo \
@USE_CURL_TRUE@ $(am__objects_1)
-@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__objects_6 = src/libostree/libostree_1_la-ostree-fetcher-soup.lo
+@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__objects_7 = src/libostree/libostree_1_la-ostree-fetcher-soup.lo
am_libostree_1_la_OBJECTS = \
src/libostree/libostree_1_la-ostree-async-progress.lo \
src/libostree/libostree_1_la-ostree-cmdprivate.lo \
@@ -694,6 +717,7 @@ am_libostree_1_la_OBJECTS = \
src/libostree/libostree_1_la-ostree-linuxfsutil.lo \
src/libostree/libostree_1_la-ostree-diff.lo \
src/libostree/libostree_1_la-ostree-mutable-tree.lo \
+ src/libostree/libostree_1_la-ostree-remote.lo \
src/libostree/libostree_1_la-ostree-repo.lo \
src/libostree/libostree_1_la-ostree-repo-checkout.lo \
src/libostree/libostree_1_la-ostree-repo-commit.lo \
@@ -709,6 +733,7 @@ am_libostree_1_la_OBJECTS = \
src/libostree/libostree_1_la-ostree-sysroot-cleanup.lo \
src/libostree/libostree_1_la-ostree-sysroot-deploy.lo \
src/libostree/libostree_1_la-ostree-sysroot-upgrader.lo \
+ src/libostree/libostree_1_la-ostree-impl-system-generator.lo \
src/libostree/libostree_1_la-ostree-bootconfig-parser.lo \
src/libostree/libostree_1_la-ostree-deployment.lo \
src/libostree/libostree_1_la-ostree-bootloader.lo \
@@ -722,7 +747,8 @@ am_libostree_1_la_OBJECTS = \
src/libostree/libostree_1_la-ostree-gpg-verifier.lo \
src/libostree/libostree_1_la-ostree-gpg-verify-result.lo \
$(am__objects_1) $(am__objects_2) $(am__objects_3) \
- $(am__objects_4) $(am__objects_5) $(am__objects_6)
+ $(am__objects_4) $(am__objects_5) $(am__objects_6) \
+ $(am__objects_7)
nodist_libostree_1_la_OBJECTS = \
src/libostree/libostree_1_la-ostree-enumtypes.lo \
$(am__objects_1)
@@ -785,9 +811,10 @@ libreaddir_rand_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
@ENABLE_INSTALLED_TESTS_TRUE@am_libreaddir_rand_la_rpath = -rpath \
@ENABLE_INSTALLED_TESTS_TRUE@ $(installed_testdir)
@BUILDOPT_FUSE_TRUE@am__EXEEXT_1 = rofiles-fuse$(EXEEXT)
-@USE_LIBARCHIVE_TRUE@am__EXEEXT_2 = \
+am__EXEEXT_2 =
+@USE_LIBARCHIVE_TRUE@am__EXEEXT_3 = \
@USE_LIBARCHIVE_TRUE@ tests/test-libarchive-import$(EXEEXT)
-am__EXEEXT_3 = tests/test-varint$(EXEEXT) \
+am__EXEEXT_4 = tests/test-varint$(EXEEXT) \
tests/test-ot-unix-utils$(EXEEXT) tests/test-bsdiff$(EXEEXT) \
tests/test-mutable-tree$(EXEEXT) \
tests/test-keyfile-utils$(EXEEXT) \
@@ -797,20 +824,26 @@ am__EXEEXT_3 = tests/test-varint$(EXEEXT) \
tests/test-checksum$(EXEEXT) tests/test-lzma$(EXEEXT) \
tests/test-rollsum$(EXEEXT) tests/test-basic-c$(EXEEXT) \
tests/test-sysroot-c$(EXEEXT) tests/test-pull-c$(EXEEXT) \
- $(am__EXEEXT_2)
-am__EXEEXT_4 = $(am__EXEEXT_3)
-@ENABLE_ALWAYS_BUILD_TESTS_FALSE@am__EXEEXT_5 = $(am__EXEEXT_4)
-am__EXEEXT_6 = test-libglnx-xattrs$(EXEEXT) test-libglnx-fdio$(EXEEXT) \
- test-libglnx-errors$(EXEEXT)
-@BUILDOPT_SYSTEMD_FALSE@am__EXEEXT_7 = ostree-remount$(EXEEXT)
-@ENABLE_INSTALLED_TESTS_TRUE@am__EXEEXT_8 = $(am__EXEEXT_3)
-@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__EXEEXT_9 = $(am__EXEEXT_4)
-@BUILDOPT_SYSTEMD_TRUE@am__EXEEXT_10 = ostree-remount$(EXEEXT)
-@BUILDOPT_USE_STATIC_COMPILER_FALSE@am__EXEEXT_11 = ostree-prepare-root$(EXEEXT)
-@USE_LIBSOUP_TRUE@am__EXEEXT_12 = ostree-trivial-httpd$(EXEEXT)
+ $(am__EXEEXT_3)
+@ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE@am__EXEEXT_5 = \
+@ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE@ $(am__EXEEXT_4)
+am__EXEEXT_6 = $(am__EXEEXT_2) $(am__EXEEXT_5)
+@ENABLE_INSTALLED_TESTS_EXCLUSIVE_TRUE@am__EXEEXT_7 = $(am__EXEEXT_4)
+am__EXEEXT_8 = $(am__EXEEXT_6) $(am__EXEEXT_7)
+@ENABLE_ALWAYS_BUILD_TESTS_FALSE@am__EXEEXT_9 = $(am__EXEEXT_8)
+am__EXEEXT_10 = test-libglnx-xattrs$(EXEEXT) \
+ test-libglnx-fdio$(EXEEXT) test-libglnx-errors$(EXEEXT)
+@BUILDOPT_SYSTEMD_FALSE@am__EXEEXT_11 = ostree-remount$(EXEEXT)
+@ENABLE_INSTALLED_TESTS_TRUE@am__EXEEXT_12 = $(am__EXEEXT_6) \
+@ENABLE_INSTALLED_TESTS_TRUE@ $(am__EXEEXT_7)
+@ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__EXEEXT_13 = $(am__EXEEXT_8)
+@BUILDOPT_SYSTEMD_TRUE@am__EXEEXT_14 = ostree-remount$(EXEEXT)
+@BUILDOPT_USE_STATIC_COMPILER_FALSE@am__EXEEXT_15 = ostree-prepare-root$(EXEEXT)
+@USE_LIBSOUP_TRUE@am__EXEEXT_16 = ostree-trivial-httpd$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS) $(installed_test_PROGRAMS) \
$(libexec_PROGRAMS) $(noinst_PROGRAMS) $(ostree_boot_PROGRAMS) \
- $(pkglibexec_PROGRAMS) $(sbin_PROGRAMS)
+ $(pkglibexec_PROGRAMS) $(sbin_PROGRAMS) \
+ $(systemdsystemgenerator_PROGRAMS)
am__ostree_SOURCES_DIST = src/ostree/main.c \
src/ostree/ot-builtin-admin.c src/ostree/ot-builtins.h \
src/ostree/ot-builtin-cat.c src/ostree/ot-builtin-config.c \
@@ -863,13 +896,13 @@ am__ostree_SOURCES_DIST = src/ostree/main.c \
src/ostree/ot-remote-cookie-util.c \
src/ostree/ot-builtin-pull.c \
src/ostree/ot-builtin-trivial-httpd.c
-@USE_CURL_OR_SOUP_TRUE@am__objects_7 = src/ostree/ostree-ot-remote-builtin-add-cookie.$(OBJEXT) \
+@USE_CURL_OR_SOUP_TRUE@am__objects_8 = src/ostree/ostree-ot-remote-builtin-add-cookie.$(OBJEXT) \
@USE_CURL_OR_SOUP_TRUE@ src/ostree/ostree-ot-remote-builtin-delete-cookie.$(OBJEXT) \
@USE_CURL_OR_SOUP_TRUE@ src/ostree/ostree-ot-remote-builtin-list-cookies.$(OBJEXT) \
@USE_CURL_OR_SOUP_TRUE@ src/ostree/ostree-ot-remote-cookie-util.$(OBJEXT) \
@USE_CURL_OR_SOUP_TRUE@ $(am__objects_1) \
@USE_CURL_OR_SOUP_TRUE@ src/ostree/ostree-ot-builtin-pull.$(OBJEXT)
-@USE_LIBSOUP_TRUE@am__objects_8 = src/ostree/ostree-ot-builtin-trivial-httpd.$(OBJEXT)
+@USE_LIBSOUP_TRUE@am__objects_9 = src/ostree/ostree-ot-builtin-trivial-httpd.$(OBJEXT)
am_ostree_OBJECTS = src/ostree/ostree-main.$(OBJEXT) \
src/ostree/ostree-ot-builtin-admin.$(OBJEXT) \
src/ostree/ostree-ot-builtin-cat.$(OBJEXT) \
@@ -921,7 +954,7 @@ am_ostree_OBJECTS = src/ostree/ostree-main.$(OBJEXT) \
src/ostree/ostree-ot-remote-builtin-show-url.$(OBJEXT) \
src/ostree/ostree-ot-remote-builtin-refs.$(OBJEXT) \
src/ostree/ostree-ot-remote-builtin-summary.$(OBJEXT) \
- $(am__objects_1) $(am__objects_7) $(am__objects_8)
+ $(am__objects_1) $(am__objects_8) $(am__objects_9)
ostree_OBJECTS = $(am_ostree_OBJECTS)
ostree_DEPENDENCIES = $(am__DEPENDENCIES_10) libbsdiff.la \
libostree-kernel-args.la $(am__DEPENDENCIES_1) \
@@ -942,10 +975,19 @@ am_ostree_remount_OBJECTS = \
$(am__objects_1)
ostree_remount_OBJECTS = $(am_ostree_remount_OBJECTS)
ostree_remount_LDADD = $(LDADD)
-ostree_remount_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+am__ostree_system_generator_SOURCES_DIST = \
+ src/switchroot/ostree-mount-util.h \
+ src/switchroot/ostree-system-generator.c
+@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@am_ostree_system_generator_OBJECTS = src/switchroot/ostree_system_generator-ostree-system-generator.$(OBJEXT)
+ostree_system_generator_OBJECTS = \
+ $(am_ostree_system_generator_OBJECTS)
+@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@ostree_system_generator_DEPENDENCIES = \
+@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@ libglnx.la libostree-1.la \
+@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@ $(am__DEPENDENCIES_2)
+ostree_system_generator_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
- $(ostree_remount_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \
- $@
+ $(ostree_system_generator_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
am__ostree_trivial_httpd_SOURCES_DIST = \
src/ostree/ostree-trivial-httpd.c
@USE_LIBSOUP_TRUE@am_ostree_trivial_httpd_OBJECTS = src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.$(OBJEXT)
@@ -1172,6 +1214,7 @@ SOURCES = $(libbsdiff_la_SOURCES) $(libbupsplit_la_SOURCES) \
$(libostreetest_la_SOURCES) $(libotutil_la_SOURCES) \
$(libreaddir_rand_la_SOURCES) $(ostree_SOURCES) \
$(ostree_prepare_root_SOURCES) $(ostree_remount_SOURCES) \
+ $(ostree_system_generator_SOURCES) \
$(ostree_trivial_httpd_SOURCES) $(rofiles_fuse_SOURCES) \
$(test_libglnx_errors_SOURCES) $(test_libglnx_fdio_SOURCES) \
$(test_libglnx_xattrs_SOURCES) tests/test-basic-c.c \
@@ -1192,6 +1235,7 @@ DIST_SOURCES = $(libbsdiff_la_SOURCES) \
$(libostreetest_la_SOURCES) $(libotutil_la_SOURCES) \
$(libreaddir_rand_la_SOURCES) $(am__ostree_SOURCES_DIST) \
$(ostree_prepare_root_SOURCES) $(ostree_remount_SOURCES) \
+ $(am__ostree_system_generator_SOURCES_DIST) \
$(am__ostree_trivial_httpd_SOURCES_DIST) \
$(am__rofiles_fuse_SOURCES_DIST) \
$(test_libglnx_errors_SOURCES) $(test_libglnx_fdio_SOURCES) \
@@ -1237,6 +1281,21 @@ DATA = $(dist_gpginsttest_DATA) $(dist_gpginsttest_trusted_DATA) \
$(installed_test_meta_DATA) $(mkinitcpioconf_DATA) \
$(nobase_installed_test_DATA) $(noinst_DATA) $(pkgconfig_DATA) \
$(systemdsystemunit_DATA) $(typelib_DATA)
+am__libostreeinclude_HEADERS_DIST = src/libostree/ostree.h \
+ src/libostree/ostree-async-progress.h \
+ src/libostree/ostree-autocleanups.h \
+ src/libostree/ostree-core.h \
+ src/libostree/ostree-dummy-enumtypes.h \
+ src/libostree/ostree-mutable-tree.h \
+ src/libostree/ostree-repo.h src/libostree/ostree-types.h \
+ src/libostree/ostree-repo-file.h src/libostree/ostree-diff.h \
+ src/libostree/ostree-gpg-verify-result.h \
+ src/libostree/ostree-sepolicy.h src/libostree/ostree-sysroot.h \
+ src/libostree/ostree-sysroot-upgrader.h \
+ src/libostree/ostree-deployment.h \
+ src/libostree/ostree-bootconfig-parser.h \
+ src/libostree/ostree-repo-deprecated.h \
+ src/libostree/ostree-remote.h src/libostree/ostree-version.h
HEADERS = $(libostreeinclude_HEADERS)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
@@ -1423,22 +1482,20 @@ am__set_TESTS_bases = \
bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
bases=`echo $$bases`
RECHECK_LOGS = $(TEST_LOGS)
-am__EXEEXT_13 =
-am__EXEEXT_14 = tests/test-basic.sh tests/test-basic-user.sh \
- tests/test-basic-user-only.sh tests/test-pull-subpath.sh \
- tests/test-archivez.sh tests/test-remote-add.sh \
- tests/test-remote-headers.sh tests/test-remote-gpg-import.sh \
- tests/test-commit-sign.sh tests/test-export.sh \
- tests/test-help.sh tests/test-libarchive.sh \
- tests/test-parent.sh tests/test-pull-archive-z.sh \
- tests/test-pull-commit-only.sh tests/test-pull-depth.sh \
- tests/test-pull-mirror-summary.sh \
+am__EXEEXT_17 = tests/test-basic.sh tests/test-basic-user.sh \
+ tests/test-basic-user-only.sh tests/test-basic-root.sh \
+ tests/test-pull-subpath.sh tests/test-archivez.sh \
+ tests/test-remote-add.sh tests/test-remote-headers.sh \
+ tests/test-remote-gpg-import.sh tests/test-commit-sign.sh \
+ tests/test-export.sh tests/test-help.sh \
+ tests/test-libarchive.sh tests/test-parent.sh \
+ tests/test-pull-archive-z.sh tests/test-pull-commit-only.sh \
+ tests/test-pull-depth.sh tests/test-pull-mirror-summary.sh \
tests/test-pull-large-metadata.sh tests/test-pull-metalink.sh \
tests/test-pull-summary-sigs.sh tests/test-pull-resume.sh \
tests/test-pull-repeated.sh tests/test-pull-untrusted.sh \
- tests/test-pull-many.sh tests/test-pull-override-url.sh \
- tests/test-local-pull.sh tests/test-local-pull-depth.sh \
- tests/test-gpg-signed-commit.sh \
+ tests/test-pull-override-url.sh tests/test-local-pull.sh \
+ tests/test-local-pull-depth.sh tests/test-gpg-signed-commit.sh \
tests/test-admin-upgrade-unconfigured.sh \
tests/test-admin-deploy-syslinux.sh \
tests/test-admin-deploy-2.sh tests/test-admin-deploy-karg.sh \
@@ -1452,15 +1509,17 @@ am__EXEEXT_14 = tests/test-basic.sh tests/test-basic-user.sh \
tests/test-admin-pull-deploy-commit.sh \
tests/test-admin-pull-deploy-split.sh \
tests/test-admin-locking.sh tests/test-admin-deploy-clean.sh \
- tests/test-repo-checkout-subpath.sh \
tests/test-reset-nonlinear.sh tests/test-oldstyle-partial.sh \
tests/test-delta.sh tests/test-xattrs.sh \
tests/test-auto-summary.sh tests/test-prune.sh \
tests/test-refs.sh tests/test-demo-buildsystem.sh \
tests/test-switchroot.sh tests/test-pull-contenturl.sh \
- tests/test-pull-mirrorlist.sh tests/coccinelle.sh \
- $(am__EXEEXT_13) $(am__append_51) $(am__append_53) \
- $(am__append_54)
+ tests/test-pull-mirrorlist.sh tests/test-summary-view.sh \
+ $(am__EXEEXT_2) $(am__append_58) $(am__append_60) \
+ $(am__append_61)
+@ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE@am__EXEEXT_18 = \
+@ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE@ $(am__EXEEXT_17)
+am__EXEEXT_19 = $(am__EXEEXT_2) $(am__EXEEXT_18)
TEST_SUITE_LOG = test-suite.log
TEST_EXTENSIONS = @EXEEXT@ .test
LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
@@ -1727,6 +1786,7 @@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
+systemdsystemgeneratordir = @systemdsystemgeneratordir@
systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
@@ -1746,25 +1806,26 @@ AM_CPPFLAGS = -DDATADIR='"$(datadir)"' -DLIBEXECDIR='"$(libexecdir)"' \
-DSOUP_VERSION_MAX_ALLOWED=SOUP_VERSION_2_48
AM_CFLAGS = -std=gnu99 $(WARN_CFLAGS)
AM_DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc --enable-man \
- --disable-maintainer-mode $(NULL) $(am__append_60)
+ --disable-maintainer-mode $(NULL) $(am__append_69)
SUBDIRS = . $(am__append_14)
NULL =
BUILT_SOURCES = $(nodist_libostree_1_la_SOURCES)
MANPAGES =
-CLEANFILES = $(am__append_13) $(BUILT_SOURCES) $(am__append_38) \
+CLEANFILES = $(am__append_13) $(BUILT_SOURCES) $(am__append_42) \
src/ostree/parse-datetime.c tests/libreaddir-rand.so \
tests/ostree-symlink-stamp \
tests/ostree-prepare-root-symlink-stamp \
tests/ostree-remount-symlink-stamp \
tests/rofiles-fuse-symlink-stamp tests/ostree \
tests/ostree-prepare-root tests/ostree-remount \
- tests/rofiles-fuse $(am__append_65)
+ tests/rofiles-fuse $(am__append_74)
EXTRA_DIST = $(all_dist_test_scripts) $(all_dist_test_data) autogen.sh \
COPYING README.md $(am__append_15) libglnx/README.md \
libglnx/COPYING libglnx/libglnx.m4 $(NULL) \
libglnx/Makefile-libglnx.am bsdiff/bsdiff.h bsdiff/bspatch.h \
bsdiff/LICENSE bsdiff/README.md bsdiff/Makefile-bsdiff.am \
- $(am__append_16) src/libostree/libostree.sym \
+ $(am__append_17) src/libostree/libostree.sym \
+ src/libostree/libostree-experimental.sym $(NULL) \
src/libostree/README-gpg src/libostree/bupsplit.h \
src/libostree/ostree-enumtypes.h.template \
src/libostree/ostree-enumtypes.c.template \
@@ -1772,29 +1833,29 @@ EXTRA_DIST = $(all_dist_test_scripts) $(all_dist_test_data) autogen.sh \
src/libostree/ostree-repo-deprecated.h \
src/libostree/ostree-version.h src/ostree/parse-datetime.y \
buildutil/tap-driver.sh buildutil/tap-test tests/glib.supp \
- tests/ostree.supp $(NULL) $(am__append_52) $(am__append_55) \
- tests/libtest.sh $(am__append_56) tests/libostreetest.h \
+ tests/ostree.supp $(NULL) $(am__append_59) $(am__append_62) \
+ tests/libtest.sh $(am__append_63) tests/libostreetest.h \
tests/libtest.sh tests/gpg-verify-data/README.md $(NULL) \
src/boot/dracut/module-setup.sh src/boot/dracut/ostree.conf \
src/boot/mkinitcpio/ostree \
src/boot/ostree-prepare-root.service \
src/boot/ostree-remount.service src/boot/grub2/grub2-15_ostree \
- src/boot/grub2/ostree-grub-generator $(NULL) $(am__append_64)
+ src/boot/grub2/ostree-grub-generator $(NULL) $(am__append_73)
bin_SCRIPTS =
lib_LTLIBRARIES = libostree-1.la
-pkglibexec_SCRIPTS = $(am__append_61)
+pkglibexec_SCRIPTS = $(am__append_70)
noinst_LTLIBRARIES = $(am__append_1) libglnx.la libbsdiff.la \
- libotutil.la libostree-kernel-args.la $(am__append_17) \
+ libotutil.la libostree-kernel-args.la $(am__append_18) \
libostreetest.la
privlibdir = $(pkglibdir)
privlib_LTLIBRARIES =
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = src/libostree/ostree-1.pc
-INTROSPECTION_GIRS = $(am__append_35)
+INTROSPECTION_GIRS = $(am__append_39)
girdir = $(datadir)/gir-1.0
-gir_DATA = $(am__append_36)
+gir_DATA = $(am__append_40)
typelibdir = $(libdir)/girepository-1.0
-typelib_DATA = $(am__append_37)
+typelib_DATA = $(am__append_41)
gsettings_SCHEMAS =
ostree_bootdir = $(prefix)/lib/ostree
@@ -1811,8 +1872,8 @@ TESTS_ENVIRONMENT = G_TEST_SRCDIR="$(abs_srcdir)" \
pwd)$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH} \
LD_LIBRARY_PATH=$$(cd $(top_builddir)/.libs && \
pwd)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}} PATH=$$(cd \
- $(top_builddir)/tests && pwd):$${PATH} $(NULL) \
- $(am__append_50)
+ $(top_builddir)/tests && pwd):$${PATH} \
+ OSTREE_FEATURES="$(OSTREE_FEATURES)" $(NULL) $(am__append_57)
LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/buildutil/tap-driver.sh
LOG_COMPILER = $(top_srcdir)/buildutil/tap-test
installed_test_LTLIBRARIES = $(am__append_12)
@@ -1852,13 +1913,14 @@ all_test_ltlibs = $(test_ltlibraries) $(uninstalled_test_ltlibraries) $(installe
# This initializes some more variables
# This is a special facility to chain together hooks easily
-INSTALL_DATA_HOOKS = install-mkdir-remotes-d-hook $(am__append_59) \
- $(am__append_62)
+INSTALL_DATA_HOOKS = install-mkdir-remotes-d-hook $(am__append_68) \
+ $(am__append_71)
ALL_LOCAL_RULES = tests/libreaddir-rand.so
shortened_sysconfdir = $$(echo "$(sysconfdir)" | sed -e 's|^$(prefix)||' -e 's|^/||')
-OSTREE_GITREV = $(shell if command -v git >/dev/null 2>&1 && test -d $(srcdir)/.git; then git describe --abbrev=42 --tags --always HEAD; fi)
+OSTREE_GITREV = $(shell cd $(srcdir) && if command -v git >/dev/null 2>&1 && test -d .git; then git describe --abbrev=42 --tags --always HEAD; fi)
ACLOCAL_AMFLAGS = -I buildutil -I libglnx ${ACLOCAL_FLAGS}
-GITIGNOREFILES = aclocal.m4 build-aux/ buildutil/*.m4 config.h.in gtk-doc.make
+GITIGNOREFILES = aclocal.m4 build-aux/ buildutil/*.m4 config.h.in \
+ gtk-doc.make $(am__append_55)
OT_INTERNAL_GIO_UNIX_CFLAGS = $(OT_DEP_GIO_UNIX_CFLAGS)
OT_INTERNAL_GIO_UNIX_LIBS = $(OT_DEP_GIO_UNIX_LIBS)
OT_INTERNAL_SOUP_CFLAGS = $(OT_DEP_SOUP_CFLAGS)
@@ -1954,26 +2016,21 @@ libotutil_la_SOURCES = \
libotutil_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libglnx -I$(srcdir)/src/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) $(LIBSYSTEMD_CFLAGS)
libotutil_la_LIBADD = $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) $(LIBSYSTEMD_LIBS)
-libostree_public_headers = \
- src/libostree/ostree.h \
+libostree_public_headers = src/libostree/ostree.h \
src/libostree/ostree-async-progress.h \
src/libostree/ostree-autocleanups.h \
src/libostree/ostree-core.h \
src/libostree/ostree-dummy-enumtypes.h \
src/libostree/ostree-mutable-tree.h \
- src/libostree/ostree-repo.h \
- src/libostree/ostree-types.h \
- src/libostree/ostree-repo-file.h \
- src/libostree/ostree-diff.h \
+ src/libostree/ostree-repo.h src/libostree/ostree-types.h \
+ src/libostree/ostree-repo-file.h src/libostree/ostree-diff.h \
src/libostree/ostree-gpg-verify-result.h \
- src/libostree/ostree-sepolicy.h \
- src/libostree/ostree-sysroot.h \
+ src/libostree/ostree-sepolicy.h src/libostree/ostree-sysroot.h \
src/libostree/ostree-sysroot-upgrader.h \
src/libostree/ostree-deployment.h \
src/libostree/ostree-bootconfig-parser.h \
- src/libostree/ostree-repo-deprecated.h \
- $(NULL)
-
+ src/libostree/ostree-repo-deprecated.h $(NULL) \
+ $(am__append_16)
# This one is generated via configure.ac, and the gtk-doc
# code hence needs to look in the builddir.
@@ -2018,6 +2075,8 @@ libostree_1_la_SOURCES = src/libostree/ostree-async-progress.c \
src/libostree/ostree-linuxfsutil.h \
src/libostree/ostree-linuxfsutil.c src/libostree/ostree-diff.c \
src/libostree/ostree-mutable-tree.c \
+ src/libostree/ostree-remote.c \
+ src/libostree/ostree-remote-private.h \
src/libostree/ostree-repo.c \
src/libostree/ostree-repo-checkout.c \
src/libostree/ostree-repo-commit.c \
@@ -2037,6 +2096,7 @@ libostree_1_la_SOURCES = src/libostree/ostree-async-progress.c \
src/libostree/ostree-sysroot-cleanup.c \
src/libostree/ostree-sysroot-deploy.c \
src/libostree/ostree-sysroot-upgrader.c \
+ src/libostree/ostree-impl-system-generator.c \
src/libostree/ostree-bootconfig-parser.c \
src/libostree/ostree-deployment.c \
src/libostree/ostree-bootloader.h \
@@ -2056,9 +2116,9 @@ libostree_1_la_SOURCES = src/libostree/ostree-async-progress.c \
src/libostree/ostree-gpg-verifier.h \
src/libostree/ostree-gpg-verify-result.c \
src/libostree/ostree-gpg-verify-result-private.h \
- src/libostree/ostree-autocleanups.h $(NULL) $(am__append_18) \
- $(am__append_19) $(am__append_24) $(am__append_25) \
- $(am__append_28)
+ src/libostree/ostree-autocleanups.h $(NULL) $(am__append_19) \
+ $(am__append_20) $(am__append_21) $(am__append_28) \
+ $(am__append_29) $(am__append_32)
libostree_1_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/bsdiff \
-I$(srcdir)/libglnx -I$(srcdir)/src/libotutil \
-I$(srcdir)/src/libostree -I$(builddir)/src/libostree \
@@ -2066,16 +2126,19 @@ libostree_1_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/bsdiff \
$(OT_DEP_LZMA_CFLAGS) $(OT_DEP_ZLIB_CFLAGS) \
$(OT_DEP_OPENSSL_CFLAGS) -fvisibility=hidden \
'-D_OSTREE_PUBLIC=__attribute__((visibility("default"))) \
- extern' $(am__append_20) $(am__append_22) $(am__append_26) \
- $(am__append_29) $(am__append_31) $(am__append_33)
-libostree_1_la_LDFLAGS = -version-number 1:0:0 -Bsymbolic-functions -Wl,--version-script=$(top_srcdir)/src/libostree/libostree.sym
+ extern' $(am__append_24) $(am__append_26) $(am__append_30) \
+ $(am__append_33) $(am__append_35) $(am__append_37)
+libostree_1_la_LDFLAGS = -version-number 1:0:0 -Bsymbolic-functions \
+ -Wl,--version-script=$(top_srcdir)/src/libostree/libostree.sym \
+ $(am__append_22)
libostree_1_la_LIBADD = libotutil.la libglnx.la libbsdiff.la \
libostree-kernel-args.la $(OT_INTERNAL_GIO_UNIX_LIBS) \
$(OT_INTERNAL_GPGME_LIBS) $(OT_DEP_LZMA_LIBS) \
$(OT_DEP_ZLIB_LIBS) $(OT_DEP_OPENSSL_LIBS) $(bupsplitpath) \
- $(am__append_21) $(am__append_23) $(am__append_27) \
- $(am__append_30) $(am__append_32) $(am__append_34)
-EXTRA_libostree_1_la_DEPENDENCIES = $(top_srcdir)/src/libostree/libostree.sym
+ $(am__append_25) $(am__append_27) $(am__append_31) \
+ $(am__append_34) $(am__append_36) $(am__append_38)
+EXTRA_libostree_1_la_DEPENDENCIES = \
+ $(top_srcdir)/src/libostree/libostree.sym $(am__append_23)
@BUILDOPT_INTROSPECTION_TRUE@OSTree_1_0_gir_EXPORT_PACKAGES = ostree-1
@BUILDOPT_INTROSPECTION_TRUE@OSTree_1_0_gir_INCLUDES = Gio-2.0
@BUILDOPT_INTROSPECTION_TRUE@OSTree_1_0_gir_CFLAGS = $(libostree_1_la_CFLAGS)
@@ -2133,7 +2196,7 @@ ostree_SOURCES = src/ostree/main.c src/ostree/ot-builtin-admin.c \
src/ostree/ot-remote-builtin-show-url.c \
src/ostree/ot-remote-builtin-refs.c \
src/ostree/ot-remote-builtin-summary.c $(NULL) \
- $(am__append_39) $(am__append_40)
+ $(am__append_43) $(am__append_44)
ostree_bin_shared_cflags = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree \
-I$(builddir)/src/libostree -I$(srcdir)/src/ostree -I$(srcdir)/libglnx $(OT_INTERNAL_GIO_UNIX_CFLAGS) \
-DPKGLIBEXECDIR=\"$(pkglibexecdir)\"
@@ -2141,11 +2204,11 @@ ostree_bin_shared_cflags = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/sr
ostree_bin_shared_ldadd = $(AM_LDFLAGS) libglnx.la libotutil.la libostree-1.la \
$(OT_INTERNAL_GIO_UNIX_LIBS)
-ostree_CFLAGS = $(ostree_bin_shared_cflags) $(am__append_42) \
- $(am__append_44)
+ostree_CFLAGS = $(ostree_bin_shared_cflags) $(am__append_46) \
+ $(am__append_48)
ostree_LDADD = $(ostree_bin_shared_ldadd) libbsdiff.la \
- libostree-kernel-args.la $(LIBSYSTEMD_LIBS) $(am__append_43) \
- $(am__append_45)
+ libostree-kernel-args.la $(LIBSYSTEMD_LIBS) $(am__append_47) \
+ $(am__append_49)
@USE_LIBSOUP_TRUE@ostree_trivial_httpd_SOURCES = src/ostree/ostree-trivial-httpd.c
@USE_LIBSOUP_TRUE@ostree_trivial_httpd_CFLAGS = $(ostree_bin_shared_cflags) $(OT_INTERNAL_SOUP_CFLAGS)
@USE_LIBSOUP_TRUE@ostree_trivial_httpd_LDADD = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_SOUP_LIBS)
@@ -2154,6 +2217,7 @@ ostree_prepare_root_SOURCES = \
src/switchroot/ostree-prepare-root.c \
$(NULL)
+ostree_prepare_root_CPPFLAGS = $(AM_CPPFLAGS) $(am__append_53)
# We're using our internal generator
@BUILDOPT_BUILTIN_GRUB2_MKCONFIG_TRUE@ostree_boot_SCRIPTS = src/boot/grub2/ostree-grub-generator
@@ -2174,16 +2238,32 @@ ostree_remount_SOURCES = \
src/switchroot/ostree-remount.c \
$(NULL)
-ostree_remount_CFLAGS = $(AM_CFLAGS) -Isrc/switchroot
+ostree_remount_CPPFLAGS = $(AM_CPPFLAGS) -Isrc/switchroot \
+ $(am__append_54)
+@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@ostree_system_generator_SOURCES = src/switchroot/ostree-mount-util.h \
+@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@ src/switchroot/ostree-system-generator.c
+
+@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@ostree_system_generator_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/libglnx -I$(srcdir)/src/libostree
+@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@ostree_system_generator_CFLAGS = $(AM_CFLAGS) $(OT_INTERNAL_GIO_UNIX_CFLAGS)
+@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@ostree_system_generator_LDADD = $(AM_LDFLAGS) libglnx.la libostree-1.la $(OT_INTERNAL_GIO_UNIX_LIBS)
@BUILDOPT_FUSE_TRUE@rofiles_fuse_SOURCES = src/rofiles-fuse/main.c
@BUILDOPT_FUSE_TRUE@rofiles_fuse_CFLAGS = $(AM_CFLAGS) -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 $(BUILDOPT_FUSE_CFLAGS) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -I$(srcdir)/libglnx $(NULL)
@BUILDOPT_FUSE_TRUE@rofiles_fuse_LDADD = libglnx.la $(BUILDOPT_FUSE_LIBS) $(OT_INTERNAL_GIO_UNIX_LIBS)
uninstalled_test_data = tests/ostree-symlink-stamp tests/ostree-prepare-root-symlink-stamp \
tests/ostree-remount-symlink-stamp tests/rofiles-fuse-symlink-stamp
-dist_uninstalled_test_scripts = tests/test-symbols.sh
-dist_test_scripts = tests/test-basic.sh tests/test-basic-user.sh \
- tests/test-basic-user-only.sh tests/test-pull-subpath.sh \
+dist_uninstalled_test_scripts = tests/test-symbols.sh tests/coccinelle.sh
+
+# This logic implements ENABLE_INSTALLED_TESTS_EXCLUSIVE; see below.
+# The goal here if installed tests are enabled, we explicitly make the
+# tests *only* run installed, to avoid having to run them twice in CI.
+# This overrides the glib-tap.mk emphasis on doing both, if we'd
+# used e.g. `dist_test_scripts`.
+dist_test_scripts = $(NULL) $(am__append_66)
+test_programs = $(NULL) $(am__append_67)
+_installed_or_uninstalled_test_scripts = tests/test-basic.sh \
+ tests/test-basic-user.sh tests/test-basic-user-only.sh \
+ tests/test-basic-root.sh tests/test-pull-subpath.sh \
tests/test-archivez.sh tests/test-remote-add.sh \
tests/test-remote-headers.sh tests/test-remote-gpg-import.sh \
tests/test-commit-sign.sh tests/test-export.sh \
@@ -2194,9 +2274,8 @@ dist_test_scripts = tests/test-basic.sh tests/test-basic-user.sh \
tests/test-pull-large-metadata.sh tests/test-pull-metalink.sh \
tests/test-pull-summary-sigs.sh tests/test-pull-resume.sh \
tests/test-pull-repeated.sh tests/test-pull-untrusted.sh \
- tests/test-pull-many.sh tests/test-pull-override-url.sh \
- tests/test-local-pull.sh tests/test-local-pull-depth.sh \
- tests/test-gpg-signed-commit.sh \
+ tests/test-pull-override-url.sh tests/test-local-pull.sh \
+ tests/test-local-pull-depth.sh tests/test-gpg-signed-commit.sh \
tests/test-admin-upgrade-unconfigured.sh \
tests/test-admin-deploy-syslinux.sh \
tests/test-admin-deploy-2.sh tests/test-admin-deploy-karg.sh \
@@ -2210,16 +2289,15 @@ dist_test_scripts = tests/test-basic.sh tests/test-basic-user.sh \
tests/test-admin-pull-deploy-commit.sh \
tests/test-admin-pull-deploy-split.sh \
tests/test-admin-locking.sh tests/test-admin-deploy-clean.sh \
- tests/test-repo-checkout-subpath.sh \
tests/test-reset-nonlinear.sh tests/test-oldstyle-partial.sh \
tests/test-delta.sh tests/test-xattrs.sh \
tests/test-auto-summary.sh tests/test-prune.sh \
tests/test-refs.sh tests/test-demo-buildsystem.sh \
tests/test-switchroot.sh tests/test-pull-contenturl.sh \
- tests/test-pull-mirrorlist.sh tests/coccinelle.sh $(NULL) \
- $(am__append_51) $(am__append_53) $(am__append_54)
+ tests/test-pull-mirrorlist.sh tests/test-summary-view.sh \
+ $(NULL) $(am__append_58) $(am__append_60) $(am__append_61)
-# These call into gjs scripts
+# These call into gjs scripts
js_tests = tests/test-corruption.sh tests/test-pull-corruption.sh
dist_installed_test_data = tests/archive-test.sh \
tests/pull-test.sh \
@@ -2227,6 +2305,7 @@ dist_installed_test_data = tests/archive-test.sh \
tests/basic-test.sh \
tests/pre-endian-deltas-repo-big.tar.xz \
tests/pre-endian-deltas-repo-little.tar.xz \
+ tests/libtest-core.sh \
$(NULL)
dist_test_extra_scripts = \
@@ -2259,6 +2338,9 @@ js_installed_tests = \
$(NULL)
@BUILDOPT_GJS_TRUE@dist_installed_test_scripts = $(js_installed_tests)
+
+# See above comment on binding the tests to be either installed or not.
+@ENABLE_INSTALLED_TESTS_EXCLUSIVE_TRUE@dist_installed_test_scripts = $(_installed_or_uninstalled_test_scripts)
test_ltlibraries = libreaddir-rand.la
libreaddir_rand_la_SOURCES = tests/readdir-rand.c
libreaddir_rand_la_CFLAGS = $(AM_CFLAGS) $(OT_INTERNAL_GIO_UNIX_CFLAGS)
@@ -2268,14 +2350,14 @@ libreaddir_rand_la_LIBADD = \
$(NULL)
libreaddir_rand_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version \
- $(am__append_57)
-test_programs = tests/test-varint tests/test-ot-unix-utils \
- tests/test-bsdiff tests/test-mutable-tree \
- tests/test-keyfile-utils tests/test-ot-opt-utils \
- tests/test-ot-tool-util tests/test-gpg-verify-result \
- tests/test-checksum tests/test-lzma tests/test-rollsum \
- tests/test-basic-c tests/test-sysroot-c tests/test-pull-c \
- $(am__append_58)
+ $(am__append_64)
+_installed_or_uninstalled_test_programs = tests/test-varint \
+ tests/test-ot-unix-utils tests/test-bsdiff \
+ tests/test-mutable-tree tests/test-keyfile-utils \
+ tests/test-ot-opt-utils tests/test-ot-tool-util \
+ tests/test-gpg-verify-result tests/test-checksum \
+ tests/test-lzma tests/test-rollsum tests/test-basic-c \
+ tests/test-sysroot-c tests/test-pull-c $(am__append_65)
common_tests_cflags = $(ostree_bin_shared_cflags) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -I$(srcdir)/libglnx
common_tests_ldadd = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_GIO_UNIX_LIBS)
libostreetest_la_SOURCES = tests/libostreetest.c
@@ -2327,6 +2409,7 @@ tests_test_gpg_verify_result_SOURCES = \
tests_test_gpg_verify_result_CFLAGS = $(TESTS_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS)
tests_test_gpg_verify_result_LDADD = $(TESTS_LDADD) $(OT_INTERNAL_GPGME_LIBS)
+@ENABLE_INSTALLED_TESTS_EXCLUSIVE_TRUE@installed_test_programs = $(_installed_or_uninstalled_test_programs)
# Not using $(libdir) here is intentional, dracut modules go in prefix/lib
@BUILDOPT_DRACUT_TRUE@dracutmoddir = $(prefix)/lib/dracut/modules.d/98ostree
@@ -2359,7 +2442,7 @@ tests_test_gpg_verify_result_LDADD = $(TESTS_LDADD) $(OT_INTERNAL_GPGME_LIBS)
@ENABLE_MAN_TRUE@ ostree-reset.1 ostree-rev-parse.1 \
@ENABLE_MAN_TRUE@ ostree-show.1 ostree-summary.1 \
@ENABLE_MAN_TRUE@ ostree-static-delta.1 ostree-trivial-httpd.1 \
-@ENABLE_MAN_TRUE@ $(am__append_63)
+@ENABLE_MAN_TRUE@ $(am__append_72)
@ENABLE_MAN_TRUE@man5_files = ostree.repo.5 ostree.repo-config.5
@ENABLE_MAN_TRUE@man1_MANS = $(addprefix man/,$(man1_files))
@ENABLE_MAN_TRUE@man5_MANS = $(addprefix man/,$(man5_files))
@@ -2374,7 +2457,7 @@ tests_test_gpg_verify_result_LDADD = $(TESTS_LDADD) $(OT_INTERNAL_GPGME_LIBS)
@ENABLE_MAN_TRUE@XSLTPROC_MAN = $(XSLTPROC) $(XSLTPROC_FLAGS)
embed_dependency = tar -C $(srcdir) --append --exclude='.git/*' --transform="s,^embedded-dependencies/,ostree-embeddeps-$${GITVERSION}/embedded-dependencies/," --file=$${TARFILE_TMP}
-git_version_rpm = $$(git describe | sed -e 's,-,\.,g' -e 's,^v,,')
+git_version_rpm = $$(cd $(srcdir) && git describe | sed -e 's,-,\.,g' -e 's,^v,,')
all: $(BUILT_SOURCES) config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
@@ -2653,6 +2736,9 @@ src/libostree/libostree_1_la-ostree-diff.lo: \
src/libostree/libostree_1_la-ostree-mutable-tree.lo: \
src/libostree/$(am__dirstamp) \
src/libostree/$(DEPDIR)/$(am__dirstamp)
+src/libostree/libostree_1_la-ostree-remote.lo: \
+ src/libostree/$(am__dirstamp) \
+ src/libostree/$(DEPDIR)/$(am__dirstamp)
src/libostree/libostree_1_la-ostree-repo.lo: \
src/libostree/$(am__dirstamp) \
src/libostree/$(DEPDIR)/$(am__dirstamp)
@@ -2698,6 +2784,9 @@ src/libostree/libostree_1_la-ostree-sysroot-deploy.lo: \
src/libostree/libostree_1_la-ostree-sysroot-upgrader.lo: \
src/libostree/$(am__dirstamp) \
src/libostree/$(DEPDIR)/$(am__dirstamp)
+src/libostree/libostree_1_la-ostree-impl-system-generator.lo: \
+ src/libostree/$(am__dirstamp) \
+ src/libostree/$(DEPDIR)/$(am__dirstamp)
src/libostree/libostree_1_la-ostree-bootconfig-parser.lo: \
src/libostree/$(am__dirstamp) \
src/libostree/$(DEPDIR)/$(am__dirstamp)
@@ -3145,6 +3234,55 @@ clean-sbinPROGRAMS:
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
+install-systemdsystemgeneratorPROGRAMS: $(systemdsystemgenerator_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(systemdsystemgenerator_PROGRAMS)'; test -n "$(systemdsystemgeneratordir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(systemdsystemgeneratordir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(systemdsystemgeneratordir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(systemdsystemgeneratordir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(systemdsystemgeneratordir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-systemdsystemgeneratorPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(systemdsystemgenerator_PROGRAMS)'; test -n "$(systemdsystemgeneratordir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(systemdsystemgeneratordir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(systemdsystemgeneratordir)" && rm -f $$files
+
+clean-systemdsystemgeneratorPROGRAMS:
+ @list='$(systemdsystemgenerator_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
src/ostree/$(am__dirstamp):
@$(MKDIR_P) src/ostree
@: > src/ostree/$(am__dirstamp)
@@ -3337,7 +3475,14 @@ src/switchroot/ostree_remount-ostree-remount.$(OBJEXT): \
ostree-remount$(EXEEXT): $(ostree_remount_OBJECTS) $(ostree_remount_DEPENDENCIES) $(EXTRA_ostree_remount_DEPENDENCIES)
@rm -f ostree-remount$(EXEEXT)
- $(AM_V_CCLD)$(ostree_remount_LINK) $(ostree_remount_OBJECTS) $(ostree_remount_LDADD) $(LIBS)
+ $(AM_V_CCLD)$(LINK) $(ostree_remount_OBJECTS) $(ostree_remount_LDADD) $(LIBS)
+src/switchroot/ostree_system_generator-ostree-system-generator.$(OBJEXT): \
+ src/switchroot/$(am__dirstamp) \
+ src/switchroot/$(DEPDIR)/$(am__dirstamp)
+
+ostree-system-generator$(EXEEXT): $(ostree_system_generator_OBJECTS) $(ostree_system_generator_DEPENDENCIES) $(EXTRA_ostree_system_generator_DEPENDENCIES)
+ @rm -f ostree-system-generator$(EXEEXT)
+ $(AM_V_CCLD)$(ostree_system_generator_LINK) $(ostree_system_generator_OBJECTS) $(ostree_system_generator_LDADD) $(LIBS)
src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.$(OBJEXT): \
src/ostree/$(am__dirstamp) \
src/ostree/$(DEPDIR)/$(am__dirstamp)
@@ -3768,6 +3913,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-util.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-gpg-verifier.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-gpg-verify-result.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-impl-system-generator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-libarchive-input-stream.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-linuxfsutil.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-lzma-common.Plo@am__quote@
@@ -3775,6 +3921,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-lzma-decompressor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-metalink.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-mutable-tree.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-remote.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-checkout.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-commit.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo-file-enumerator.Plo@am__quote@
@@ -3879,6 +4026,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/rofiles-fuse/$(DEPDIR)/rofiles_fuse-main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/switchroot/$(DEPDIR)/ostree_remount-ostree-remount.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/switchroot/$(DEPDIR)/ostree_system_generator-ostree-system-generator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/libostreetest_la-libostreetest.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/libreaddir_rand_la-readdir-rand.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/tests_test_basic_c-test-basic-c.Po@am__quote@
@@ -4097,6 +4245,13 @@ src/libostree/libostree_1_la-ostree-mutable-tree.lo: src/libostree/ostree-mutabl
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -c -o src/libostree/libostree_1_la-ostree-mutable-tree.lo `test -f 'src/libostree/ostree-mutable-tree.c' || echo '$(srcdir)/'`src/libostree/ostree-mutable-tree.c
+src/libostree/libostree_1_la-ostree-remote.lo: src/libostree/ostree-remote.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -MT src/libostree/libostree_1_la-ostree-remote.lo -MD -MP -MF src/libostree/$(DEPDIR)/libostree_1_la-ostree-remote.Tpo -c -o src/libostree/libostree_1_la-ostree-remote.lo `test -f 'src/libostree/ostree-remote.c' || echo '$(srcdir)/'`src/libostree/ostree-remote.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libostree/$(DEPDIR)/libostree_1_la-ostree-remote.Tpo src/libostree/$(DEPDIR)/libostree_1_la-ostree-remote.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libostree/ostree-remote.c' object='src/libostree/libostree_1_la-ostree-remote.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -c -o src/libostree/libostree_1_la-ostree-remote.lo `test -f 'src/libostree/ostree-remote.c' || echo '$(srcdir)/'`src/libostree/ostree-remote.c
+
src/libostree/libostree_1_la-ostree-repo.lo: src/libostree/ostree-repo.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -MT src/libostree/libostree_1_la-ostree-repo.lo -MD -MP -MF src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo.Tpo -c -o src/libostree/libostree_1_la-ostree-repo.lo `test -f 'src/libostree/ostree-repo.c' || echo '$(srcdir)/'`src/libostree/ostree-repo.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo.Tpo src/libostree/$(DEPDIR)/libostree_1_la-ostree-repo.Plo
@@ -4202,6 +4357,13 @@ src/libostree/libostree_1_la-ostree-sysroot-upgrader.lo: src/libostree/ostree-sy
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -c -o src/libostree/libostree_1_la-ostree-sysroot-upgrader.lo `test -f 'src/libostree/ostree-sysroot-upgrader.c' || echo '$(srcdir)/'`src/libostree/ostree-sysroot-upgrader.c
+src/libostree/libostree_1_la-ostree-impl-system-generator.lo: src/libostree/ostree-impl-system-generator.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -MT src/libostree/libostree_1_la-ostree-impl-system-generator.lo -MD -MP -MF src/libostree/$(DEPDIR)/libostree_1_la-ostree-impl-system-generator.Tpo -c -o src/libostree/libostree_1_la-ostree-impl-system-generator.lo `test -f 'src/libostree/ostree-impl-system-generator.c' || echo '$(srcdir)/'`src/libostree/ostree-impl-system-generator.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libostree/$(DEPDIR)/libostree_1_la-ostree-impl-system-generator.Tpo src/libostree/$(DEPDIR)/libostree_1_la-ostree-impl-system-generator.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libostree/ostree-impl-system-generator.c' object='src/libostree/libostree_1_la-ostree-impl-system-generator.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -c -o src/libostree/libostree_1_la-ostree-impl-system-generator.lo `test -f 'src/libostree/ostree-impl-system-generator.c' || echo '$(srcdir)/'`src/libostree/ostree-impl-system-generator.c
+
src/libostree/libostree_1_la-ostree-bootconfig-parser.lo: src/libostree/ostree-bootconfig-parser.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -MT src/libostree/libostree_1_la-ostree-bootconfig-parser.lo -MD -MP -MF src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootconfig-parser.Tpo -c -o src/libostree/libostree_1_la-ostree-bootconfig-parser.lo `test -f 'src/libostree/ostree-bootconfig-parser.c' || echo '$(srcdir)/'`src/libostree/ostree-bootconfig-parser.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootconfig-parser.Tpo src/libostree/$(DEPDIR)/libostree_1_la-ostree-bootconfig-parser.Plo
@@ -5246,32 +5408,46 @@ src/ostree/ostree-ot-builtin-trivial-httpd.obj: src/ostree/ot-builtin-trivial-ht
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_CFLAGS) $(CFLAGS) -c -o src/ostree/ostree-ot-builtin-trivial-httpd.obj `if test -f 'src/ostree/ot-builtin-trivial-httpd.c'; then $(CYGPATH_W) 'src/ostree/ot-builtin-trivial-httpd.c'; else $(CYGPATH_W) '$(srcdir)/src/ostree/ot-builtin-trivial-httpd.c'; fi`
src/switchroot/ostree_prepare_root-ostree-prepare-root.o: src/switchroot/ostree-prepare-root.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_prepare_root_CFLAGS) $(CFLAGS) -MT src/switchroot/ostree_prepare_root-ostree-prepare-root.o -MD -MP -MF src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Tpo -c -o src/switchroot/ostree_prepare_root-ostree-prepare-root.o `test -f 'src/switchroot/ostree-prepare-root.c' || echo '$(srcdir)/'`src/switchroot/ostree-prepare-root.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_prepare_root_CPPFLAGS) $(CPPFLAGS) $(ostree_prepare_root_CFLAGS) $(CFLAGS) -MT src/switchroot/ostree_prepare_root-ostree-prepare-root.o -MD -MP -MF src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Tpo -c -o src/switchroot/ostree_prepare_root-ostree-prepare-root.o `test -f 'src/switchroot/ostree-prepare-root.c' || echo '$(srcdir)/'`src/switchroot/ostree-prepare-root.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Tpo src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/switchroot/ostree-prepare-root.c' object='src/switchroot/ostree_prepare_root-ostree-prepare-root.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_prepare_root_CFLAGS) $(CFLAGS) -c -o src/switchroot/ostree_prepare_root-ostree-prepare-root.o `test -f 'src/switchroot/ostree-prepare-root.c' || echo '$(srcdir)/'`src/switchroot/ostree-prepare-root.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_prepare_root_CPPFLAGS) $(CPPFLAGS) $(ostree_prepare_root_CFLAGS) $(CFLAGS) -c -o src/switchroot/ostree_prepare_root-ostree-prepare-root.o `test -f 'src/switchroot/ostree-prepare-root.c' || echo '$(srcdir)/'`src/switchroot/ostree-prepare-root.c
src/switchroot/ostree_prepare_root-ostree-prepare-root.obj: src/switchroot/ostree-prepare-root.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_prepare_root_CFLAGS) $(CFLAGS) -MT src/switchroot/ostree_prepare_root-ostree-prepare-root.obj -MD -MP -MF src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Tpo -c -o src/switchroot/ostree_prepare_root-ostree-prepare-root.obj `if test -f 'src/switchroot/ostree-prepare-root.c'; then $(CYGPATH_W) 'src/switchroot/ostree-prepare-root.c'; else $(CYGPATH_W) '$(srcdir)/src/switchroot/ostree-prepare-root.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_prepare_root_CPPFLAGS) $(CPPFLAGS) $(ostree_prepare_root_CFLAGS) $(CFLAGS) -MT src/switchroot/ostree_prepare_root-ostree-prepare-root.obj -MD -MP -MF src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Tpo -c -o src/switchroot/ostree_prepare_root-ostree-prepare-root.obj `if test -f 'src/switchroot/ostree-prepare-root.c'; then $(CYGPATH_W) 'src/switchroot/ostree-prepare-root.c'; else $(CYGPATH_W) '$(srcdir)/src/switchroot/ostree-prepare-root.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Tpo src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/switchroot/ostree-prepare-root.c' object='src/switchroot/ostree_prepare_root-ostree-prepare-root.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_prepare_root_CFLAGS) $(CFLAGS) -c -o src/switchroot/ostree_prepare_root-ostree-prepare-root.obj `if test -f 'src/switchroot/ostree-prepare-root.c'; then $(CYGPATH_W) 'src/switchroot/ostree-prepare-root.c'; else $(CYGPATH_W) '$(srcdir)/src/switchroot/ostree-prepare-root.c'; fi`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_prepare_root_CPPFLAGS) $(CPPFLAGS) $(ostree_prepare_root_CFLAGS) $(CFLAGS) -c -o src/switchroot/ostree_prepare_root-ostree-prepare-root.obj `if test -f 'src/switchroot/ostree-prepare-root.c'; then $(CYGPATH_W) 'src/switchroot/ostree-prepare-root.c'; else $(CYGPATH_W) '$(srcdir)/src/switchroot/ostree-prepare-root.c'; fi`
src/switchroot/ostree_remount-ostree-remount.o: src/switchroot/ostree-remount.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_remount_CFLAGS) $(CFLAGS) -MT src/switchroot/ostree_remount-ostree-remount.o -MD -MP -MF src/switchroot/$(DEPDIR)/ostree_remount-ostree-remount.Tpo -c -o src/switchroot/ostree_remount-ostree-remount.o `test -f 'src/switchroot/ostree-remount.c' || echo '$(srcdir)/'`src/switchroot/ostree-remount.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_remount_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/switchroot/ostree_remount-ostree-remount.o -MD -MP -MF src/switchroot/$(DEPDIR)/ostree_remount-ostree-remount.Tpo -c -o src/switchroot/ostree_remount-ostree-remount.o `test -f 'src/switchroot/ostree-remount.c' || echo '$(srcdir)/'`src/switchroot/ostree-remount.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/switchroot/$(DEPDIR)/ostree_remount-ostree-remount.Tpo src/switchroot/$(DEPDIR)/ostree_remount-ostree-remount.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/switchroot/ostree-remount.c' object='src/switchroot/ostree_remount-ostree-remount.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_remount_CFLAGS) $(CFLAGS) -c -o src/switchroot/ostree_remount-ostree-remount.o `test -f 'src/switchroot/ostree-remount.c' || echo '$(srcdir)/'`src/switchroot/ostree-remount.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_remount_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/switchroot/ostree_remount-ostree-remount.o `test -f 'src/switchroot/ostree-remount.c' || echo '$(srcdir)/'`src/switchroot/ostree-remount.c
src/switchroot/ostree_remount-ostree-remount.obj: src/switchroot/ostree-remount.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_remount_CFLAGS) $(CFLAGS) -MT src/switchroot/ostree_remount-ostree-remount.obj -MD -MP -MF src/switchroot/$(DEPDIR)/ostree_remount-ostree-remount.Tpo -c -o src/switchroot/ostree_remount-ostree-remount.obj `if test -f 'src/switchroot/ostree-remount.c'; then $(CYGPATH_W) 'src/switchroot/ostree-remount.c'; else $(CYGPATH_W) '$(srcdir)/src/switchroot/ostree-remount.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_remount_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT src/switchroot/ostree_remount-ostree-remount.obj -MD -MP -MF src/switchroot/$(DEPDIR)/ostree_remount-ostree-remount.Tpo -c -o src/switchroot/ostree_remount-ostree-remount.obj `if test -f 'src/switchroot/ostree-remount.c'; then $(CYGPATH_W) 'src/switchroot/ostree-remount.c'; else $(CYGPATH_W) '$(srcdir)/src/switchroot/ostree-remount.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/switchroot/$(DEPDIR)/ostree_remount-ostree-remount.Tpo src/switchroot/$(DEPDIR)/ostree_remount-ostree-remount.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/switchroot/ostree-remount.c' object='src/switchroot/ostree_remount-ostree-remount.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_remount_CFLAGS) $(CFLAGS) -c -o src/switchroot/ostree_remount-ostree-remount.obj `if test -f 'src/switchroot/ostree-remount.c'; then $(CYGPATH_W) 'src/switchroot/ostree-remount.c'; else $(CYGPATH_W) '$(srcdir)/src/switchroot/ostree-remount.c'; fi`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_remount_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o src/switchroot/ostree_remount-ostree-remount.obj `if test -f 'src/switchroot/ostree-remount.c'; then $(CYGPATH_W) 'src/switchroot/ostree-remount.c'; else $(CYGPATH_W) '$(srcdir)/src/switchroot/ostree-remount.c'; fi`
+
+src/switchroot/ostree_system_generator-ostree-system-generator.o: src/switchroot/ostree-system-generator.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_system_generator_CPPFLAGS) $(CPPFLAGS) $(ostree_system_generator_CFLAGS) $(CFLAGS) -MT src/switchroot/ostree_system_generator-ostree-system-generator.o -MD -MP -MF src/switchroot/$(DEPDIR)/ostree_system_generator-ostree-system-generator.Tpo -c -o src/switchroot/ostree_system_generator-ostree-system-generator.o `test -f 'src/switchroot/ostree-system-generator.c' || echo '$(srcdir)/'`src/switchroot/ostree-system-generator.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/switchroot/$(DEPDIR)/ostree_system_generator-ostree-system-generator.Tpo src/switchroot/$(DEPDIR)/ostree_system_generator-ostree-system-generator.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/switchroot/ostree-system-generator.c' object='src/switchroot/ostree_system_generator-ostree-system-generator.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_system_generator_CPPFLAGS) $(CPPFLAGS) $(ostree_system_generator_CFLAGS) $(CFLAGS) -c -o src/switchroot/ostree_system_generator-ostree-system-generator.o `test -f 'src/switchroot/ostree-system-generator.c' || echo '$(srcdir)/'`src/switchroot/ostree-system-generator.c
+
+src/switchroot/ostree_system_generator-ostree-system-generator.obj: src/switchroot/ostree-system-generator.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_system_generator_CPPFLAGS) $(CPPFLAGS) $(ostree_system_generator_CFLAGS) $(CFLAGS) -MT src/switchroot/ostree_system_generator-ostree-system-generator.obj -MD -MP -MF src/switchroot/$(DEPDIR)/ostree_system_generator-ostree-system-generator.Tpo -c -o src/switchroot/ostree_system_generator-ostree-system-generator.obj `if test -f 'src/switchroot/ostree-system-generator.c'; then $(CYGPATH_W) 'src/switchroot/ostree-system-generator.c'; else $(CYGPATH_W) '$(srcdir)/src/switchroot/ostree-system-generator.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/switchroot/$(DEPDIR)/ostree_system_generator-ostree-system-generator.Tpo src/switchroot/$(DEPDIR)/ostree_system_generator-ostree-system-generator.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/switchroot/ostree-system-generator.c' object='src/switchroot/ostree_system_generator-ostree-system-generator.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ostree_system_generator_CPPFLAGS) $(CPPFLAGS) $(ostree_system_generator_CFLAGS) $(CFLAGS) -c -o src/switchroot/ostree_system_generator-ostree-system-generator.obj `if test -f 'src/switchroot/ostree-system-generator.c'; then $(CYGPATH_W) 'src/switchroot/ostree-system-generator.c'; else $(CYGPATH_W) '$(srcdir)/src/switchroot/ostree-system-generator.c'; fi`
src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.o: src/ostree/ostree-trivial-httpd.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_trivial_httpd_CFLAGS) $(CFLAGS) -MT src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.o -MD -MP -MF src/ostree/$(DEPDIR)/ostree_trivial_httpd-ostree-trivial-httpd.Tpo -c -o src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.o `test -f 'src/ostree/ostree-trivial-httpd.c' || echo '$(srcdir)/'`src/ostree/ostree-trivial-httpd.c
@@ -6431,6 +6607,13 @@ tests/test-basic-user-only.sh.log: tests/test-basic-user-only.sh
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/test-basic-root.sh.log: tests/test-basic-root.sh
+ @p='tests/test-basic-root.sh'; \
+ b='tests/test-basic-root.sh'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
tests/test-pull-subpath.sh.log: tests/test-pull-subpath.sh
@p='tests/test-pull-subpath.sh'; \
b='tests/test-pull-subpath.sh'; \
@@ -6571,13 +6754,6 @@ tests/test-pull-untrusted.sh.log: tests/test-pull-untrusted.sh
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
-tests/test-pull-many.sh.log: tests/test-pull-many.sh
- @p='tests/test-pull-many.sh'; \
- b='tests/test-pull-many.sh'; \
- $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
- --log-file $$b.log --trs-file $$b.trs \
- $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
- "$$tst" $(AM_TESTS_FD_REDIRECT)
tests/test-pull-override-url.sh.log: tests/test-pull-override-url.sh
@p='tests/test-pull-override-url.sh'; \
b='tests/test-pull-override-url.sh'; \
@@ -6711,13 +6887,6 @@ tests/test-admin-deploy-clean.sh.log: tests/test-admin-deploy-clean.sh
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
-tests/test-repo-checkout-subpath.sh.log: tests/test-repo-checkout-subpath.sh
- @p='tests/test-repo-checkout-subpath.sh'; \
- b='tests/test-repo-checkout-subpath.sh'; \
- $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
- --log-file $$b.log --trs-file $$b.trs \
- $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
- "$$tst" $(AM_TESTS_FD_REDIRECT)
tests/test-reset-nonlinear.sh.log: tests/test-reset-nonlinear.sh
@p='tests/test-reset-nonlinear.sh'; \
b='tests/test-reset-nonlinear.sh'; \
@@ -6795,9 +6964,9 @@ tests/test-pull-mirrorlist.sh.log: tests/test-pull-mirrorlist.sh
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
-tests/coccinelle.sh.log: tests/coccinelle.sh
- @p='tests/coccinelle.sh'; \
- b='tests/coccinelle.sh'; \
+tests/test-summary-view.sh.log: tests/test-summary-view.sh
+ @p='tests/test-summary-view.sh'; \
+ b='tests/test-summary-view.sh'; \
$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
@@ -6837,6 +7006,13 @@ tests/test-symbols.sh.log: tests/test-symbols.sh
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/coccinelle.sh.log: tests/coccinelle.sh
+ @p='tests/coccinelle.sh'; \
+ b='tests/coccinelle.sh'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
test-libglnx-xattrs.log: test-libglnx-xattrs$(EXEEXT)
@p='test-libglnx-xattrs$(EXEEXT)'; \
b='test-libglnx-xattrs'; \
@@ -7064,7 +7240,7 @@ distcleancheck: distclean
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
-@ENABLE_RUST_FALSE@check-local:
+@ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE@@ENABLE_RUST_FALSE@check-local:
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) $(check_PROGRAMS) \
$(check_SCRIPTS) $(check_DATA)
@@ -7077,7 +7253,7 @@ install-binPROGRAMS: install-libLTLIBRARIES
installdirs: installdirs-recursive
installdirs-am:
- for dir in "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(privlibdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(dracutmoddir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(mkinitcpioinstalldir)" "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(gpginsttestdir)" "$(DESTDIR)$(gpginsttest_trusteddir)" "$(DESTDIR)$(gpgvinsttestdir)" "$(DESTDIR)$(dracutconfdir)" "$(DESTDIR)$(girdir)" "$(DESTDIR)$(gpgreadmedir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(installed_test_metadir)" "$(DESTDIR)$(mkinitcpioconfdir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(systemdsystemunitdir)" "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(libostreeincludedir)"; do \
+ for dir in "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(privlibdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(systemdsystemgeneratordir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(dracutmoddir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(mkinitcpioinstalldir)" "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(gpginsttestdir)" "$(DESTDIR)$(gpginsttest_trusteddir)" "$(DESTDIR)$(gpgvinsttestdir)" "$(DESTDIR)$(dracutconfdir)" "$(DESTDIR)$(girdir)" "$(DESTDIR)$(gpgreadmedir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(installed_test_metadir)" "$(DESTDIR)$(mkinitcpioconfdir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(systemdsystemunitdir)" "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(libostreeincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: $(BUILT_SOURCES)
@@ -7143,7 +7319,8 @@ clean-am: clean-binPROGRAMS clean-checkLTLIBRARIES clean-checkPROGRAMS \
clean-libexecPROGRAMS clean-libtool clean-local \
clean-noinstLTLIBRARIES clean-noinstPROGRAMS \
clean-ostree_bootPROGRAMS clean-pkglibexecPROGRAMS \
- clean-privlibLTLIBRARIES clean-sbinPROGRAMS mostlyclean-am
+ clean-privlibLTLIBRARIES clean-sbinPROGRAMS \
+ clean-systemdsystemgeneratorPROGRAMS mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
@@ -7175,8 +7352,9 @@ install-data-am: install-dist_gpginsttestDATA \
install-mkinitcpioconfDATA install-mkinitcpioinstallSCRIPTS \
install-nobase_installed_testDATA install-ostree_bootPROGRAMS \
install-ostree_bootSCRIPTS install-pkgconfigDATA \
- install-privlibLTLIBRARIES install-systemdsystemunitDATA \
- install-typelibDATA
+ install-privlibLTLIBRARIES \
+ install-systemdsystemgeneratorPROGRAMS \
+ install-systemdsystemunitDATA install-typelibDATA
@$(NORMAL_INSTALL)
$(MAKE) $(AM_MAKEFLAGS) install-data-hook
install-dvi: install-dvi-recursive
@@ -7245,8 +7423,9 @@ uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
uninstall-ostree_bootPROGRAMS uninstall-ostree_bootSCRIPTS \
uninstall-pkgconfigDATA uninstall-pkglibexecPROGRAMS \
uninstall-pkglibexecSCRIPTS uninstall-privlibLTLIBRARIES \
- uninstall-sbinPROGRAMS uninstall-systemdsystemunitDATA \
- uninstall-typelibDATA
+ uninstall-sbinPROGRAMS \
+ uninstall-systemdsystemgeneratorPROGRAMS \
+ uninstall-systemdsystemunitDATA uninstall-typelibDATA
uninstall-man: uninstall-man1 uninstall-man5
@@ -7261,15 +7440,16 @@ uninstall-man: uninstall-man1 uninstall-man5
clean-libexecPROGRAMS clean-libtool clean-local \
clean-noinstLTLIBRARIES clean-noinstPROGRAMS \
clean-ostree_bootPROGRAMS clean-pkglibexecPROGRAMS \
- clean-privlibLTLIBRARIES clean-sbinPROGRAMS cscope \
- cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
- dist-gzip dist-hook dist-lzip dist-shar dist-tarZ dist-xz \
- dist-zip distcheck distclean distclean-compile \
- distclean-generic distclean-hdr distclean-libtool \
- distclean-tags distcleancheck distdir distuninstallcheck dvi \
- dvi-am html html-am info info-am install install-am \
- install-binPROGRAMS install-binSCRIPTS install-data \
- install-data-am install-data-hook install-dist_gpginsttestDATA \
+ clean-privlibLTLIBRARIES clean-sbinPROGRAMS \
+ clean-systemdsystemgeneratorPROGRAMS cscope cscopelist-am \
+ ctags ctags-am dist dist-all dist-bzip2 dist-gzip dist-hook \
+ dist-lzip dist-shar dist-tarZ dist-xz dist-zip distcheck \
+ distclean distclean-compile distclean-generic distclean-hdr \
+ distclean-libtool distclean-tags distcleancheck distdir \
+ distuninstallcheck dvi dvi-am html html-am info info-am \
+ install install-am install-binPROGRAMS install-binSCRIPTS \
+ install-data install-data-am install-data-hook \
+ install-dist_gpginsttestDATA \
install-dist_gpginsttest_trustedDATA \
install-dist_gpgvinsttestDATA install-dracutconfDATA \
install-dracutmodSCRIPTS install-dvi install-dvi-am \
@@ -7287,6 +7467,7 @@ uninstall-man: uninstall-man1 uninstall-man5
install-pkgconfigDATA install-pkglibexecPROGRAMS \
install-pkglibexecSCRIPTS install-privlibLTLIBRARIES \
install-ps install-ps-am install-sbinPROGRAMS install-strip \
+ install-systemdsystemgeneratorPROGRAMS \
install-systemdsystemunitDATA install-typelibDATA installcheck \
installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
@@ -7310,8 +7491,9 @@ uninstall-man: uninstall-man1 uninstall-man5
uninstall-ostree_bootPROGRAMS uninstall-ostree_bootSCRIPTS \
uninstall-pkgconfigDATA uninstall-pkglibexecPROGRAMS \
uninstall-pkglibexecSCRIPTS uninstall-privlibLTLIBRARIES \
- uninstall-sbinPROGRAMS uninstall-systemdsystemunitDATA \
- uninstall-typelibDATA
+ uninstall-sbinPROGRAMS \
+ uninstall-systemdsystemgeneratorPROGRAMS \
+ uninstall-systemdsystemunitDATA uninstall-typelibDATA
.PRECIOUS: Makefile
@@ -7376,6 +7558,8 @@ tests/%-symlink-stamp: % Makefile
fi; \
ln -sf "$${real_bin}" tests/$*; \
touch $@
+@ENABLE_INSTALLED_TESTS_EXCLUSIVE_TRUE@check-local:
+@ENABLE_INSTALLED_TESTS_EXCLUSIVE_TRUE@ echo "NOTE: Exclusive installed tests are enabled; to run them, make install, then: gnome-desktop-testing-runner -p 0 libostree/"
# Unfortunately the glib test data APIs don't actually handle
# non-recursive Automake, so we change our code to canonically look
@@ -7398,7 +7582,7 @@ tests/%-symlink-stamp: % Makefile
@ENABLE_MAN_TRUE@ $(AM_V_GEN) $(XSLTPROC_MAN) --output $@ $(XSLT_STYLESHEET) $<
release-tag:
- git tag -m "Release $(VERSION)" v$(VERSION)
+ cd $(srcdir) && git $(srcdir) tag -m "Release $(VERSION)" v$(VERSION)
release-tarball-embedded:
set -x; \
diff --git a/apidoc/Makefile.am b/apidoc/Makefile.am
index 730a4c33..f3405fb0 100644
--- a/apidoc/Makefile.am
+++ b/apidoc/Makefile.am
@@ -120,6 +120,7 @@ include $(top_srcdir)/gtk-doc.make
EXTRA_DIST += \
version.xml \
ostree-sections.txt \
+ ostree-experimental-sections.txt \
$(NULL)
-include $(top_srcdir)/git.mk
diff --git a/apidoc/Makefile.in b/apidoc/Makefile.in
index 8000f3b4..22ad83e0 100644
--- a/apidoc/Makefile.in
+++ b/apidoc/Makefile.in
@@ -130,6 +130,10 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+@ENABLE_EXPERIMENTAL_API_TRUE@am__append_1 = \
+@ENABLE_EXPERIMENTAL_API_TRUE@ src/libostree/ostree-remote.h \
+@ENABLE_EXPERIMENTAL_API_TRUE@ $(NULL)
+
subdir = apidoc
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/buildutil/attributes.m4 \
@@ -352,31 +356,26 @@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
+systemdsystemgeneratordir = @systemdsystemgeneratordir@
systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-libostree_public_headers = \
- src/libostree/ostree.h \
+libostree_public_headers = src/libostree/ostree.h \
src/libostree/ostree-async-progress.h \
src/libostree/ostree-autocleanups.h \
src/libostree/ostree-core.h \
src/libostree/ostree-dummy-enumtypes.h \
src/libostree/ostree-mutable-tree.h \
- src/libostree/ostree-repo.h \
- src/libostree/ostree-types.h \
- src/libostree/ostree-repo-file.h \
- src/libostree/ostree-diff.h \
+ src/libostree/ostree-repo.h src/libostree/ostree-types.h \
+ src/libostree/ostree-repo-file.h src/libostree/ostree-diff.h \
src/libostree/ostree-gpg-verify-result.h \
- src/libostree/ostree-sepolicy.h \
- src/libostree/ostree-sysroot.h \
+ src/libostree/ostree-sepolicy.h src/libostree/ostree-sysroot.h \
src/libostree/ostree-sysroot-upgrader.h \
src/libostree/ostree-deployment.h \
src/libostree/ostree-bootconfig-parser.h \
- src/libostree/ostree-repo-deprecated.h \
- $(NULL)
-
+ src/libostree/ostree-repo-deprecated.h $(NULL) $(am__append_1)
# This one is generated via configure.ac, and the gtk-doc
# code hence needs to look in the builddir.
@@ -499,7 +498,7 @@ SETUP_FILES = \
# This includes the standard gtk-doc make rules, copied by gtkdocize.
EXTRA_DIST = $(HTML_IMAGES) $(SETUP_FILES) version.xml \
- ostree-sections.txt $(NULL)
+ ostree-sections.txt ostree-experimental-sections.txt $(NULL)
DOC_STAMPS = setup-build.stamp scan-build.stamp sgml-build.stamp \
html-build.stamp pdf-build.stamp \
sgml.stamp html.stamp pdf.stamp
diff --git a/apidoc/html/index.html b/apidoc/html/index.html
index e8784b1e..f4d3d764 100644
--- a/apidoc/html/index.html
+++ b/apidoc/html/index.html
@@ -14,7 +14,7 @@
diff --git a/apidoc/html/ostree-Content-addressed-object-store.html b/apidoc/html/ostree-Content-addressed-object-store.html
index 0761497c..31c45644 100644
--- a/apidoc/html/ostree-Content-addressed-object-store.html
+++ b/apidoc/html/ostree-Content-addressed-object-store.html
@@ -881,7 +881,7 @@
-OstreeRepoCommitIterResult
+OstreeRepoCommitIterResult
ostree_repo_commit_traverse_iter_next ()
@@ -1044,6 +1044,18 @@
enum
+OstreeRepoResolveRevExtFlags
+
+
+enum
+OstreeRepoListRefsExtFlags
+
+
+enum
+OstreeRepoCommitState
+
+
+enum
OstreeRepoCommitFilterResult
@@ -1076,6 +1088,14 @@
enum
+OstreeRepoCommitTraverseFlags
+
+
+enum
+OstreeRepoCommitIterResult
+
+
+enum
OstreeRepoPruneFlags
@@ -1971,7 +1991,10 @@ ostree_repo_remote_fetch_summary_with_options
GError **error );
Like ostree_repo_remote_fetch_summary() , but supports an extensible set of flags.
The following are currently defined:
-
+
Parameters
@@ -2558,8 +2581,8 @@ be made to the repository.
checksum
-The checksum to point it to
-
+ The checksum to point it to.
+[nullable ]
@@ -3349,7 +3372,7 @@ is true and it does not exist.
ostree_repo_resolve_rev_ext (OstreeRepo *self ,
const char *refspec ,
gboolean allow_noent ,
- OstreeRepoResolveRevExtFlags flags ,
+ OstreeRepoResolveRevExtFlags flags ,
char **out_rev ,
GError **error );
Look up the given refspec, returning the checksum it references in
@@ -3461,7 +3484,7 @@ refspecs which have refspec_prefix
ostree_repo_list_refs_ext (OstreeRepo *self ,
const char *refspec_prefix ,
GHashTable **out_all_refs ,
- OstreeRepoListRefsExtFlags flags ,
+ OstreeRepoListRefsExtFlags flags ,
GCancellable *cancellable ,
GError **error );
If refspec_prefix
@@ -3621,11 +3644,11 @@ result in out_variant
ostree_repo_load_commit (OstreeRepo *self ,
const char *checksum ,
GVariant **out_commit ,
- OstreeRepoCommitState *out_state ,
+ OstreeRepoCommitState *out_state ,
GError **error );
A version of ostree_repo_load_variant() specialized to commits,
capable of returning extended state information. Currently
-the only extended state is OSTREE_REPO_COMMIT_STATE_PARTIAL, which
+the only extended state is OSTREE_REPO_COMMIT_STATE_PARTIAL , which
means that only a sub-path of the commit is available.
Parameters
@@ -5734,7 +5757,7 @@ ostree_repo_commit_traverse_iter_get_dir
char **out_content_checksum,
char **out_meta_checksum);
Return information on the current directory. This function may
-only be called if OSTREE_REPO_COMMIT_ITER_RESULT_DIR was returned
+only be called if OSTREE_REPO_COMMIT_ITER_RESULT_DIR was returned
from ostree_repo_commit_traverse_iter_next() .
Parameters
@@ -5778,7 +5801,7 @@ ostree_repo_commit_traverse_iter_get_file
char **out_name,
char **out_checksum);
Return information on the current file. This function may only be
-called if OSTREE_REPO_COMMIT_ITER_RESULT_FILE was returned from
+called if OSTREE_REPO_COMMIT_ITER_RESULT_FILE was returned from
ostree_repo_commit_traverse_iter_next() .
Parameters
@@ -5816,7 +5839,7 @@ ostree_repo_commit_traverse_iter_init_commit
(
OstreeRepoCommitTraverseIter *iter,
OstreeRepo *repo,
GVariant *commit,
-
OstreeRepoCommitTraverseFlags flags,
+
OstreeRepoCommitTraverseFlags flags,
GError **error);
Initialize (in place) an iterator over the root of a commit object.
@@ -5865,7 +5888,7 @@ ostree_repo_commit_traverse_iter_init_dirtree
(
OstreeRepoCommitTraverseIter *iter,
OstreeRepo *repo,
GVariant *dirtree,
-
OstreeRepoCommitTraverseFlags flags,
+
OstreeRepoCommitTraverseFlags flags,
GError **error);
Initialize (in place) an iterator over a directory tree.
@@ -5909,19 +5932,19 @@ ostree_repo_commit_traverse_iter_init_dirtree
ostree_repo_commit_traverse_iter_next ()
-
OstreeRepoCommitIterResult
+OstreeRepoCommitIterResult
ostree_repo_commit_traverse_iter_next (OstreeRepoCommitTraverseIter *iter ,
GCancellable *cancellable ,
GError **error );
Step the interator to the next item. Files will be returned first,
then subdirectories. Call this in a loop; upon encountering
-OSTREE_REPO_COMMIT_ITER_RESULT_END, there will be no more files or
-directories. If OSTREE_REPO_COMMIT_ITER_RESULT_DIR is returned,
+OSTREE_REPO_COMMIT_ITER_RESULT_END , there will be no more files or
+directories. If OSTREE_REPO_COMMIT_ITER_RESULT_DIR is returned,
then call ostree_repo_commit_traverse_iter_get_dir() to retrieve
data for that directory. Similarly, if
-OSTREE_REPO_COMMIT_ITER_RESULT_FILE is returned, call
+OSTREE_REPO_COMMIT_ITER_RESULT_FILE is returned, call
ostree_repo_commit_traverse_iter_get_file() .
-If OSTREE_REPO_COMMIT_ITER_RESULT_ERROR is returned, it is a
+
If OSTREE_REPO_COMMIT_ITER_RESULT_ERROR is returned, it is a
program error to call any further API on iter
except for
ostree_repo_commit_traverse_iter_clear() .
@@ -6314,7 +6337,7 @@ The following are currently defined:
override-commit-ids (as): Array of specific commit IDs to fetch for refs
dry-run (b): Only print information on what will be downloaded (requires static deltas)
override-url (s): Fetch objects from this URL if remote specifies no metalink in options
-
inherit-transaction (b): Don't initiate, finish or abort a transaction, usefult to do mutliple pulls in one transaction.
+
inherit-transaction (b): Don't initiate, finish or abort a transaction, usefult to do multiple pulls in one transaction.
http-headers (a(ss)): Additional headers to add to all HTTP requests
update-frequency (u): Frequency to call the async progress callback in milliseconds, if any; only values higher than 0 are valid
@@ -6882,6 +6905,10 @@ ostree_repo_regenerate_summary (
GError **error);
An OSTree repository can contain a high level "summary" file that
describes the available branches and other metadata.
+
If the timetable for making commits and updating the summary file is fairly
+regular, setting the ostree.summary.expires key in additional_metadata
+
+will aid clients in working out when to check for updates.
It is regenerated automatically after a commit if
core/commit-update-summary is set.
@@ -7099,6 +7126,67 @@ in bytes, counting only content objects.
+
enum OstreeRepoResolveRevExtFlags
+
+
+
+
+
enum OstreeRepoListRefsExtFlags
+
+
+
+
+
enum OstreeRepoCommitState
+
+
+
+
enum OstreeRepoCommitFilterResult
Members
@@ -7337,6 +7425,61 @@ as - List of pack file checksums in which this object appears
+
enum OstreeRepoCommitTraverseFlags
+
+
+
+
+
enum OstreeRepoCommitIterResult
+
+
+
+
enum OstreeRepoPruneFlags
Members
diff --git a/apidoc/html/ostree-Core-repository-independent-functions.html b/apidoc/html/ostree-Core-repository-independent-functions.html
index c4afe12a..8bf4efcf 100644
--- a/apidoc/html/ostree-Core-repository-independent-functions.html
+++ b/apidoc/html/ostree-Core-repository-independent-functions.html
@@ -2289,9 +2289,9 @@ content, the other types are metadata.
#define OSTREE_DIRMETA_GVARIANT_FORMAT G_VARIANT_TYPE (OSTREE_DIRMETA_GVARIANT_STRING)
-u - uid
-u - gid
-u - mode
+u - uid (big-endian)
+u - gid (big-endian)
+u - mode (big-endian)
a(ayay) - xattrs
@@ -2311,9 +2311,9 @@ in bare-user repositories. This allows us to store metadata information that we
can't store in the real filesystem but we can still use a regular .file object
that we can hardlink to in the case of a user-mode checkout.
-u - uid
-u - gid
-u - mode
+u - uid (big-endian)
+u - gid (big-endian)
+u - mode (big-endian)
a(ayay) - xattrs
@@ -2350,7 +2350,7 @@ that we can hardlink to in the case of a user-mode checkout.
a(say) - Related objects
s - subject
s - body
-
t - Timestamp in seconds since the epoch (UTC)
+
t - Timestamp in seconds since the epoch (UTC, big-endian)
ay - Root tree contents
ay - Root tree metadata
@@ -2370,9 +2370,21 @@ that we can hardlink to in the case of a user-mode checkout.
a(s(taya{sv})) - Map of ref name -> (latest commit size, latest commit checksum, additional metadata), sorted by ref name
a{sv} - Additional metadata, at the current time the following are defined:
-
+
+key: "ostree.static-deltas", value: a{sv}, static delta name -> 32 bytes of checksum
+key: "ostree.summary.last-modified", value: t, timestamp (seconds since
+the Unix epoch in UTC, big-endian) when the summary was last regenerated
+(similar to the HTTP Last-Modified header)
+key: "ostree.summary.expires", value: t, timestamp (seconds since the
+Unix epoch in UTC, big-endian) after which the summary is considered
+stale and should be re-downloaded if possible (similar to the HTTP
+Expires header)
+
+
The currently defined keys for the a{sv} of additional metadata for each commit are:
+
key: ostree.commit.timestamp, value: t, timestamp (seconds since the
+Unix epoch in UTC, big-endian) when the commit was committed
diff --git a/apidoc/html/ostree-Progress-notification-system-for-asynchronous-operations.html b/apidoc/html/ostree-Progress-notification-system-for-asynchronous-operations.html
index 588132f6..60efeb05 100644
--- a/apidoc/html/ostree-Progress-notification-system-for-asynchronous-operations.html
+++ b/apidoc/html/ostree-Progress-notification-system-for-asynchronous-operations.html
@@ -65,6 +65,22 @@
+void
+
+
+ostree_async_progress_get ()
+
+
+
+
+GVariant *
+
+
+ostree_async_progress_get_variant ()
+
+
+
+
guint
@@ -92,6 +108,22 @@
void
+ostree_async_progress_set ()
+
+
+
+
+void
+
+
+ostree_async_progress_set_variant ()
+
+
+
+
+void
+
+
ostree_async_progress_set_uint ()
@@ -138,6 +170,10 @@ operations to communicate back with callers. It transparently
handles thread safety, ensuring that the progress change
notification occurs in the thread-default context of the calling
operation.
+
The ostree_async_progress_get_status() and ostree_async_progress_set_status()
+methods get and set a well-known status key of type G_VARIANT_TYPE_STRING.
+This key may be accessed using the other OstreeAsyncProgress methods, but it
+must always have the correct type.
Functions
@@ -163,6 +199,141 @@ ostree_async_progress_new_and_connect (
ostree_async_progress_get_status ()
char *
ostree_async_progress_get_status (OstreeAsyncProgress *self );
+Get the human-readable status string from the OstreeAsyncProgress . This
+operation is thread-safe. The retuned value may be NULL if no status is
+set.
+This is a convenience function to get the well-known status key.
+
+
+Since: 2017.6
+
+
+
+
ostree_async_progress_get ()
+
void
+ostree_async_progress_get (OstreeAsyncProgress *self ,
+ ... );
+
Get the values corresponding to zero or more keys from the
+OstreeAsyncProgress . Each key is specified in @... as the key name, followed
+by a GVariant format string, followed by the necessary arguments for that
+format string, just as for g_variant_get(). After those arguments is the
+next key name. The varargs list must be NULL-terminated.
+
Each format string must make deep copies of its value, as the values stored
+in the OstreeAsyncProgress may be freed from another thread after this
+function returns.
+
This operation is thread-safe, and all the keys are queried atomically.
+
+
+
+
+
Since: 2017.6
+
+
+
+
ostree_async_progress_get_variant ()
+
GVariant *
+ostree_async_progress_get_variant (OstreeAsyncProgress *self ,
+ const char *key );
+
Look up a key in the OstreeAsyncProgress and return the GVariant associated
+with it. The lookup is thread-safe.
+
+
+
Since: 2017.6
+
+
+
ostree_async_progress_set ()
+
void
+ostree_async_progress_set (OstreeAsyncProgress *self ,
+ ... );
+
Set the values for zero or more keys in the OstreeAsyncProgress . Each key is
+specified in @... as the key name, followed by a GVariant format string,
+followed by the necessary arguments for that format string, just as for
+g_variant_new(). After those arguments is the next key name. The varargs list
+must be NULL-terminated.
+
g_variant_ref_sink() will be called as appropriate on the GVariant
+parameters, so they may be floating.
+
This operation is thread-safe, and all the keys are set atomically.
+
+
+
+
+
Since: 2017.6
+
+
+
+
ostree_async_progress_set_variant ()
+
void
+ostree_async_progress_set_variant (OstreeAsyncProgress *self ,
+ const char *key ,
+ GVariant *value );
+
Assign a new value
+ to the given key
+, replacing any existing value. The
+operation is thread-safe. value
+ may be a floating reference;
+g_variant_ref_sink() will be called on it.
+
Any watchers of the OstreeAsyncProgress will be notified of the change if
+value
+ differs from the existing value for key
+.
+
+
Since: 2017.6
diff --git a/apidoc/html/ostree.devhelp2 b/apidoc/html/ostree.devhelp2
index 5cbabaca..665a92b1 100644
--- a/apidoc/html/ostree.devhelp2
+++ b/apidoc/html/ostree.devhelp2
@@ -207,6 +207,9 @@
+
+
+
@@ -215,6 +218,8 @@
+
+
@@ -268,10 +273,14 @@
-
+
+
+
-
+
+
+
@@ -379,6 +388,9 @@
+
+
+
@@ -397,6 +409,11 @@
+
+
+
+
+
diff --git a/apidoc/html/reference.html b/apidoc/html/reference.html
index d0e784be..c0365130 100644
--- a/apidoc/html/reference.html
+++ b/apidoc/html/reference.html
@@ -80,6 +80,10 @@
+ostree_async_progress_get , function in Progress notification system for asynchronous operations
+
+
+
ostree_async_progress_get_status , function in Progress notification system for asynchronous operations
@@ -92,6 +96,10 @@
+ostree_async_progress_get_variant , function in Progress notification system for asynchronous operations
+
+
+
ostree_async_progress_new , function in Progress notification system for asynchronous operations
@@ -100,6 +108,10 @@
+ostree_async_progress_set , function in Progress notification system for asynchronous operations
+
+
+
ostree_async_progress_set_status , function in Progress notification system for asynchronous operations
@@ -111,6 +123,10 @@
ostree_async_progress_set_uint64 , function in
Progress notification system for asynchronous operations
+
+ostree_async_progress_set_variant , function in Progress notification system for asynchronous operations
+
+
B
OstreeBootconfigParser , struct in ostree-bootconfig-parser
@@ -598,6 +614,10 @@ OSTREE_RELEASE_VERSION, macro in ostree-version
+OstreeRepoCommitIterResult , enum in Content-addressed object store
+
+
+
OstreeRepoCommitModifier , typedef in Content-addressed object store
@@ -610,6 +630,14 @@ OSTREE_RELEASE_VERSION, macro in ostree-version
+OstreeRepoCommitState , enum in Content-addressed object store
+
+
+
+OstreeRepoCommitTraverseFlags , enum in Content-addressed object store
+
+
+
OstreeRepoFile , typedef in ostree-repo-file
@@ -618,6 +646,10 @@ OSTREE_RELEASE_VERSION, macro in ostree-version
+OstreeRepoListRefsExtFlags , enum in Content-addressed object store
+
+
+
OstreeRepoMode , enum in Content-addressed object store
@@ -634,6 +666,10 @@ OSTREE_RELEASE_VERSION, macro in ostree-version
+OstreeRepoResolveRevExtFlags , enum in Content-addressed object store
+
+
+
OstreeRepoTransactionStats , struct in Content-addressed object store
diff --git a/apidoc/ostree-experimental-sections.txt b/apidoc/ostree-experimental-sections.txt
new file mode 100644
index 00000000..790feb33
--- /dev/null
+++ b/apidoc/ostree-experimental-sections.txt
@@ -0,0 +1,6 @@
+
+ostree-remote
+OstreeRemote
+ostree_remote_ref
+ostree_remote_unref
+
diff --git a/apidoc/ostree-sections.txt b/apidoc/ostree-sections.txt
index 07dbaf1f..adc2dfd7 100644
--- a/apidoc/ostree-sections.txt
+++ b/apidoc/ostree-sections.txt
@@ -4,9 +4,13 @@ OstreeAsyncProgress
ostree_async_progress_new
ostree_async_progress_new_and_connect
ostree_async_progress_get_status
+ostree_async_progress_get
+ostree_async_progress_get_variant
ostree_async_progress_get_uint
ostree_async_progress_get_uint64
ostree_async_progress_set_status
+ostree_async_progress_set
+ostree_async_progress_set_variant
ostree_async_progress_set_uint
ostree_async_progress_set_uint64
ostree_async_progress_finish
@@ -316,11 +320,14 @@ ostree_repo_write_content_trusted
ostree_repo_write_content_async
ostree_repo_write_content_finish
ostree_repo_resolve_rev
+OstreeRepoResolveRevExtFlags
ostree_repo_resolve_rev_ext
ostree_repo_list_refs
+OstreeRepoListRefsExtFlags
ostree_repo_list_refs_ext
ostree_repo_remote_list_refs
ostree_repo_load_variant
+OstreeRepoCommitState
ostree_repo_load_commit
ostree_repo_load_variant_if_exists
ostree_repo_load_file
@@ -376,8 +383,10 @@ ostree_repo_commit_traverse_iter_cleanup
ostree_repo_commit_traverse_iter_clear
ostree_repo_commit_traverse_iter_get_dir
ostree_repo_commit_traverse_iter_get_file
+OstreeRepoCommitTraverseFlags
ostree_repo_commit_traverse_iter_init_commit
ostree_repo_commit_traverse_iter_init_dirtree
+OstreeRepoCommitIterResult
ostree_repo_commit_traverse_iter_next
OstreeRepoPruneFlags
ostree_repo_prune
diff --git a/apidoc/ostree.types b/apidoc/ostree.types
index d6bbf69d..b229e7da 100644
--- a/apidoc/ostree.types
+++ b/apidoc/ostree.types
@@ -6,6 +6,7 @@ ostree_deployment_get_type
ostree_diff_item_get_type
ostree_gpg_verify_result_get_type
ostree_mutable_tree_get_type
+ostree_remote_get_type
ostree_repo_commit_modifier_get_type
ostree_repo_devino_cache_get_type
ostree_repo_file_get_type
diff --git a/apidoc/version.xml b/apidoc/version.xml
index 719d04cc..f7cc504e 100644
--- a/apidoc/version.xml
+++ b/apidoc/version.xml
@@ -1 +1 @@
-2017.4
\ No newline at end of file
+2017.6
\ No newline at end of file
diff --git a/buildutil/glibtests.m4 b/buildutil/glibtests.m4
index 27e90246..108c8478 100644
--- a/buildutil/glibtests.m4
+++ b/buildutil/glibtests.m4
@@ -1,17 +1,21 @@
dnl GLIB_TESTS
-dnl
+dnl NOTE: this file has been modified from upstream glib; see
+dnl https://github.com/ostreedev/ostree/pull/837
AC_DEFUN([GLIB_TESTS],
[
AC_ARG_ENABLE(installed-tests,
AS_HELP_STRING([--enable-installed-tests],
[Enable installation of some test cases]),
- [case ${enableval} in
+ [enable_installed_tests=${enableval};
+ case ${enableval} in
yes) ENABLE_INSTALLED_TESTS="1" ;;
+ exclusive) ENABLE_INSTALLED_TESTS="1"; ENABLE_INSTALLED_TESTS_EXCLUSIVE=1 ;;
no) ENABLE_INSTALLED_TESTS="" ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-installed-tests]) ;;
esac])
AM_CONDITIONAL([ENABLE_INSTALLED_TESTS], test "$ENABLE_INSTALLED_TESTS" = "1")
+ AM_CONDITIONAL([ENABLE_INSTALLED_TESTS_EXCLUSIVE], test "$ENABLE_INSTALLED_TESTS_EXCLUSIVE" = "1")
AC_ARG_ENABLE(always-build-tests,
AS_HELP_STRING([--enable-always-build-tests],
[Enable always building tests during 'make all']),
diff --git a/config.h.in b/config.h.in
index 72d72cda..3cc2f9e0 100644
--- a/config.h.in
+++ b/config.h.in
@@ -3,6 +3,9 @@
/* Define if we are enabling ostree trivial-httpd entrypoint */
#undef BUILDOPT_ENABLE_TRIVIAL_HTTPD_CMDLINE
+/* Define if systemd and libmount */
+#undef BUILDOPT_LIBSYSTEMD_AND_LIBMOUNT
+
/* Define if we should avoid using O_TMPFILE */
#undef DISABLE_OTMPFILE
@@ -85,6 +88,9 @@
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR
+/* Define if experimental API should be enabled */
+#undef OSTREE_ENABLE_EXPERIMENTAL_API
+
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
diff --git a/configure b/configure
index 0a2b349e..c8350804 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.69 for libostree 2017.5.
+# Generated by GNU Autoconf 2.69 for libostree 2017.6.
#
# Report bugs to
.
#
@@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='libostree'
PACKAGE_TARNAME='libostree'
-PACKAGE_VERSION='2017.5'
-PACKAGE_STRING='libostree 2017.5'
+PACKAGE_VERSION='2017.6'
+PACKAGE_STRING='libostree 2017.6'
PACKAGE_BUGREPORT='walters@verbum.org'
PACKAGE_URL=''
@@ -635,6 +635,8 @@ ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
LTLIBOBJS
LIBOBJS
+ENABLE_EXPERIMENTAL_API_FALSE
+ENABLE_EXPERIMENTAL_API_TRUE
BUILDOPT_GJS_FALSE
BUILDOPT_GJS_TRUE
GJS
@@ -644,8 +646,11 @@ BUILDOPT_USE_STATIC_COMPILER_TRUE
GRUB2_MKCONFIG
BUILDOPT_BUILTIN_GRUB2_MKCONFIG_FALSE
BUILDOPT_BUILTIN_GRUB2_MKCONFIG_TRUE
+BUILDOPT_SYSTEMD_AND_LIBMOUNT_FALSE
+BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE
BUILDOPT_SYSTEMD_FALSE
BUILDOPT_SYSTEMD_TRUE
+systemdsystemgeneratordir
systemdsystemunitdir
BUILDOPT_LIBSYSTEMD_FALSE
BUILDOPT_LIBSYSTEMD_TRUE
@@ -758,6 +763,8 @@ installed_testdir
installed_test_metadir
ENABLE_ALWAYS_BUILD_TESTS_FALSE
ENABLE_ALWAYS_BUILD_TESTS_TRUE
+ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE
+ENABLE_INSTALLED_TESTS_EXCLUSIVE_TRUE
ENABLE_INSTALLED_TESTS_FALSE
ENABLE_INSTALLED_TESTS_TRUE
OSTREE_FEATURES
@@ -926,9 +933,11 @@ enable_rofiles_fuse
with_dracut
with_mkinitcpio
with_systemdsystemunitdir
+with_systemdsystemgeneratordir
with_builtin_grub2_mkconfig
with_grub2_mkconfig_path
with_static_compiler
+enable_experimental_api
'
ac_precious_vars='build_alias
host_alias
@@ -1513,7 +1522,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 2017.5 to adapt to many kinds of systems.
+\`configure' configures libostree 2017.6 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1583,7 +1592,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of libostree 2017.5:";;
+ short | recursive ) echo "Configuration of libostree 2017.6:";;
esac
cat <<\_ACEOF
@@ -1631,6 +1640,9 @@ Optional Features:
--enable-rust-debug Build Rust code with debugging information
[default=no]
--enable-rofiles-fuse generate rofiles-fuse helper [default=yes]
+ --enable-experimental-api
+ Enable unstable experimental API in libostree
+ [default=no]
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -1656,6 +1668,8 @@ Optional Packages:
--with-mkinitcpio Install mkinitcpio module (default: no)
--with-systemdsystemunitdir=DIR
Directory for systemd service files
+ --with-systemdsystemgeneratordir=DIR
+ Directory for systemd generators
--with-builtin-grub2-mkconfig
Use a builtin minimal grub2-mkconfig to generate a
GRUB2 configuration file (default: no)
@@ -1809,7 +1823,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-libostree configure 2017.5
+libostree configure 2017.6
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2224,7 +2238,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 2017.5, which was
+It was created by libostree $as_me 2017.6, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3091,7 +3105,7 @@ fi
# Define the identity of the package.
PACKAGE='libostree'
- VERSION='2017.5'
+ VERSION='2017.6'
# Some tools Automake needs.
@@ -5825,9 +5839,9 @@ test -n "$YACC" || YACC="yacc"
YEAR_VERSION=2017
-RELEASE_VERSION=5
+RELEASE_VERSION=6
-PACKAGE_VERSION=2017.5
+PACKAGE_VERSION=2017.6
@@ -13584,8 +13598,10 @@ OSTREE_FEATURES=""
# Check whether --enable-installed-tests was given.
if test "${enable_installed_tests+set}" = set; then :
- enableval=$enable_installed_tests; case ${enableval} in
+ enableval=$enable_installed_tests; enable_installed_tests=${enableval};
+ case ${enableval} in
yes) ENABLE_INSTALLED_TESTS="1" ;;
+ exclusive) ENABLE_INSTALLED_TESTS="1"; ENABLE_INSTALLED_TESTS_EXCLUSIVE=1 ;;
no) ENABLE_INSTALLED_TESTS="" ;;
*) as_fn_error $? "bad value ${enableval} for --enable-installed-tests" "$LINENO" 5 ;;
esac
@@ -13599,6 +13615,14 @@ else
ENABLE_INSTALLED_TESTS_FALSE=
fi
+ if test "$ENABLE_INSTALLED_TESTS_EXCLUSIVE" = "1"; then
+ ENABLE_INSTALLED_TESTS_EXCLUSIVE_TRUE=
+ ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE='#'
+else
+ ENABLE_INSTALLED_TESTS_EXCLUSIVE_TRUE='#'
+ ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE=
+fi
+
# Check whether --enable-always-build-tests was given.
if test "${enable_always_build_tests+set}" = set; then :
enableval=$enable_always_build_tests; case ${enableval} in
@@ -16820,6 +16844,20 @@ fi
systemdsystemunitdir=$with_systemdsystemunitdir
+fi
+
+# Check whether --with-systemdsystemgeneratordir was given.
+if test "${with_systemdsystemgeneratordir+set}" = set; then :
+ withval=$with_systemdsystemgeneratordir;
+else
+ with_systemdsystemgeneratordir=$($PKG_CONFIG --variable=systemdsystemgeneratordir systemd)
+fi
+
+ if test "x$with_systemdsystemgeneratordir" != "xno"; then :
+
+ systemdsystemgeneratordir=$with_systemdsystemgeneratordir
+
+
fi
fi
@@ -16831,6 +16869,19 @@ else
BUILDOPT_SYSTEMD_FALSE=
fi
+ if test x$with_systemd = xyes && test x$with_libmount = xyes; then
+ BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE=
+ BUILDOPT_SYSTEMD_AND_LIBMOUNT_FALSE='#'
+else
+ BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE='#'
+ BUILDOPT_SYSTEMD_AND_LIBMOUNT_FALSE=
+fi
+
+if test -z "$BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE"; then :
+
+$as_echo "#define BUILDOPT_LIBSYSTEMD_AND_LIBMOUNT 1" >>confdefs.h
+
+fi
# Check whether --with-builtin-grub2-mkconfig was given.
@@ -16993,6 +17044,35 @@ else
fi
+# Do we enable building experimental (non-stable) API?
+# The OSTREE_ENABLE_EXPERIMENTAL_API #define is used internally and in public
+# headers, so any consumer of libostree who wants to use experimental API must
+# #define OSTREE_ENABLE_EXPERIMENTAL_API 1
+# before including libostree headers. This means the name in the AC_DEFINE below
+# is public API.
+# Check whether --enable-experimental-api was given.
+if test "${enable_experimental_api+set}" = set; then :
+ enableval=$enable_experimental_api;
+else
+ enable_experimental_api=no
+fi
+
+if test x$enable_experimental_api = xyes; then :
+
+$as_echo "#define OSTREE_ENABLE_EXPERIMENTAL_API 1" >>confdefs.h
+
+ OSTREE_FEATURES="$OSTREE_FEATURES experimental"
+
+fi
+ if test x$enable_experimental_api = xyes; then
+ ENABLE_EXPERIMENTAL_API_TRUE=
+ ENABLE_EXPERIMENTAL_API_FALSE='#'
+else
+ ENABLE_EXPERIMENTAL_API_TRUE='#'
+ ENABLE_EXPERIMENTAL_API_FALSE=
+fi
+
+
ac_config_files="$ac_config_files Makefile apidoc/Makefile src/libostree/ostree-1.pc src/libostree/ostree-version.h"
cat >confcache <<\_ACEOF
@@ -17144,6 +17224,10 @@ if test -z "${ENABLE_INSTALLED_TESTS_TRUE}" && test -z "${ENABLE_INSTALLED_TESTS
as_fn_error $? "conditional \"ENABLE_INSTALLED_TESTS\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${ENABLE_INSTALLED_TESTS_EXCLUSIVE_TRUE}" && test -z "${ENABLE_INSTALLED_TESTS_EXCLUSIVE_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_INSTALLED_TESTS_EXCLUSIVE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
if test -z "${ENABLE_ALWAYS_BUILD_TESTS_TRUE}" && test -z "${ENABLE_ALWAYS_BUILD_TESTS_FALSE}"; then
as_fn_error $? "conditional \"ENABLE_ALWAYS_BUILD_TESTS\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -17252,6 +17336,10 @@ if test -z "${BUILDOPT_SYSTEMD_TRUE}" && test -z "${BUILDOPT_SYSTEMD_FALSE}"; th
as_fn_error $? "conditional \"BUILDOPT_SYSTEMD\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE}" && test -z "${BUILDOPT_SYSTEMD_AND_LIBMOUNT_FALSE}"; then
+ as_fn_error $? "conditional \"BUILDOPT_SYSTEMD_AND_LIBMOUNT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
if test -z "${BUILDOPT_BUILTIN_GRUB2_MKCONFIG_TRUE}" && test -z "${BUILDOPT_BUILTIN_GRUB2_MKCONFIG_FALSE}"; then
as_fn_error $? "conditional \"BUILDOPT_BUILTIN_GRUB2_MKCONFIG\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -17264,6 +17352,10 @@ if test -z "${BUILDOPT_GJS_TRUE}" && test -z "${BUILDOPT_GJS_FALSE}"; then
as_fn_error $? "conditional \"BUILDOPT_GJS\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${ENABLE_EXPERIMENTAL_API_TRUE}" && test -z "${ENABLE_EXPERIMENTAL_API_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_EXPERIMENTAL_API\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0
@@ -17661,7 +17753,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 2017.5, which was
+This file was extended by libostree $as_me 2017.6, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -17727,7 +17819,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-libostree config.status 2017.5
+libostree config.status 2017.6
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@@ -19436,10 +19528,12 @@ echo "
wrpseudo-compat: $enable_wrpseudo_compat
man pages (xsltproc): $enable_man
api docs (gtk-doc): $enable_gtk_doc
+ installed tests: $enable_installed_tests
gjs-based tests: $have_gjs
dracut: $with_dracut
mkinitcpio: $with_mkinitcpio
- Static compiler for ostree-prepare-root: $with_static_compiler"
+ Static compiler for ostree-prepare-root: $with_static_compiler
+ Experimental API $enable_experimental_api"
if test x$with_builtin_grub2_mkconfig = xyes; then :
echo " builtin grub2-mkconfig (instead of system): $with_builtin_grub2_mkconfig"
diff --git a/configure.ac b/configure.ac
index c8e02930..a6abee85 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
AC_PREREQ([2.63])
dnl If incrementing the version here, remember to update libostree.sym too
m4_define([year_version], [2017])
-m4_define([release_version], [5])
+m4_define([release_version], [6])
m4_define([package_version], [year_version.release_version])
AC_INIT([libostree], [package_version], [walters@verbum.org])
@@ -389,8 +389,19 @@ AS_IF([test "x$have_libsystemd" = "xyes"], [
AS_IF([test "x$with_systemdsystemunitdir" != "xno"], [
AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
])
+ AC_ARG_WITH([systemdsystemgeneratordir],
+ AS_HELP_STRING([--with-systemdsystemgeneratordir=DIR], [Directory for systemd generators]),
+ [],
+ [with_systemdsystemgeneratordir=$($PKG_CONFIG --variable=systemdsystemgeneratordir systemd)])
+ AS_IF([test "x$with_systemdsystemgeneratordir" != "xno"], [
+ AC_SUBST([systemdsystemgeneratordir], [$with_systemdsystemgeneratordir])
+ ])
])
AM_CONDITIONAL(BUILDOPT_SYSTEMD, test x$with_systemd = xyes)
+dnl If we have both, we use the "new /var" model with ostree-system-generator
+AM_CONDITIONAL(BUILDOPT_SYSTEMD_AND_LIBMOUNT,[test x$with_systemd = xyes && test x$with_libmount = xyes])
+AM_COND_IF(BUILDOPT_SYSTEMD_AND_LIBMOUNT,
+ AC_DEFINE([BUILDOPT_LIBSYSTEMD_AND_LIBMOUNT], 1, [Define if systemd and libmount]))
AC_ARG_WITH(builtin-grub2-mkconfig,
AS_HELP_STRING([--with-builtin-grub2-mkconfig],
@@ -429,6 +440,22 @@ AS_IF([test "x$found_introspection" = xyes && test x$using_asan != xyes], [
], [have_gjs=no])
AM_CONDITIONAL(BUILDOPT_GJS, test x$have_gjs = xyes)
+# Do we enable building experimental (non-stable) API?
+# The OSTREE_ENABLE_EXPERIMENTAL_API #define is used internally and in public
+# headers, so any consumer of libostree who wants to use experimental API must
+# #define OSTREE_ENABLE_EXPERIMENTAL_API 1
+# before including libostree headers. This means the name in the AC_DEFINE below
+# is public API.
+AC_ARG_ENABLE([experimental-api],
+ [AS_HELP_STRING([--enable-experimental-api],
+ [Enable unstable experimental API in libostree [default=no]])],,
+ [enable_experimental_api=no])
+AS_IF([test x$enable_experimental_api = xyes],
+ [AC_DEFINE([OSTREE_ENABLE_EXPERIMENTAL_API],[1],[Define if experimental API should be enabled])
+ OSTREE_FEATURES="$OSTREE_FEATURES experimental"]
+)
+AM_CONDITIONAL([ENABLE_EXPERIMENTAL_API],[test x$enable_experimental_api = xyes])
+
AC_CONFIG_FILES([
Makefile
apidoc/Makefile
@@ -457,10 +484,12 @@ echo "
wrpseudo-compat: $enable_wrpseudo_compat
man pages (xsltproc): $enable_man
api docs (gtk-doc): $enable_gtk_doc
+ installed tests: $enable_installed_tests
gjs-based tests: $have_gjs
dracut: $with_dracut
mkinitcpio: $with_mkinitcpio
- Static compiler for ostree-prepare-root: $with_static_compiler"
+ Static compiler for ostree-prepare-root: $with_static_compiler
+ Experimental API $enable_experimental_api"
AS_IF([test x$with_builtin_grub2_mkconfig = xyes], [
echo " builtin grub2-mkconfig (instead of system): $with_builtin_grub2_mkconfig"
], [
diff --git a/libglnx/glnx-dirfd.c b/libglnx/glnx-dirfd.c
index 08d90071..12b983c1 100644
--- a/libglnx/glnx-dirfd.c
+++ b/libglnx/glnx-dirfd.c
@@ -209,13 +209,12 @@ glnx_dirfd_iterator_next_dent_ensure_dtype (GLnxDirFdIterator *dfd_iter,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
struct dirent *ret_dent;
g_return_val_if_fail (out_dent, FALSE);
if (!glnx_dirfd_iterator_next_dent (dfd_iter, out_dent, cancellable, error))
- goto out;
+ return FALSE;
ret_dent = *out_dent;
@@ -226,17 +225,12 @@ glnx_dirfd_iterator_next_dent_ensure_dtype (GLnxDirFdIterator *dfd_iter,
{
struct stat stbuf;
if (TEMP_FAILURE_RETRY (fstatat (dfd_iter->fd, ret_dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW)) != 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno (error);
ret_dent->d_type = IFTODT (stbuf.st_mode);
}
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/**
@@ -348,3 +342,70 @@ glnx_mkdtempat (int dfd,
"mkstempat ran out of combinations to try.");
return FALSE;
}
+
+/**
+ * glnx_mkdtempat_open:
+ * @dfd: Directory FD
+ * @tmpl: (type filename): template directory name, last 6 characters will be replaced
+ * @mode: permissions to create the temporary directory with
+ * @out_dfd: (out caller-allocates): Return location for an FD for the new
+ * temporary directory, or `-1` on error
+ * @error: Return location for a #GError, or %NULL
+ *
+ * Similar to glnx_mkdtempat(), except it will open the resulting temporary
+ * directory and return a directory FD to it.
+ *
+ * Returns: %TRUE on success, %FALSE otherwise
+ * Since: UNRELEASED
+ */
+gboolean
+glnx_mkdtempat_open (int dfd,
+ gchar *tmpl,
+ int mode,
+ int *out_dfd,
+ GError **error)
+{
+ /* FIXME: Ideally we could use openat(O_DIRECTORY | O_CREAT | O_EXCL) here
+ * to create and open the directory atomically, but that’s not supported by
+ * current kernel versions: http://www.openwall.com/lists/oss-security/2014/11/26/14
+ * (Tested on kernel 4.10.10-200.fc25.x86_64). For the moment, accept a
+ * TOCTTOU race here. */
+ *out_dfd = -1;
+
+ if (!glnx_mkdtempat (dfd, tmpl, mode, error))
+ return FALSE;
+
+ return glnx_opendirat (dfd, tmpl, FALSE, out_dfd, error);
+}
+
+/**
+ * glnx_mkdtempat_open_in_system:
+ * @tmpl: (type filename): template directory name, last 6 characters will be replaced
+ * @mode: permissions to create the temporary directory with
+ * @out_dfd: (out caller-allocates): Return location for an FD for the new
+ * temporary directory, or `-1` on error
+ * @error: Return location for a #GError, or %NULL
+ *
+ * Similar to glnx_mkdtempat_open(), except it will use the system temporary
+ * directory (from g_get_tmp_dir()) as the parent directory to @tmpl.
+ *
+ * Returns: %TRUE on success, %FALSE otherwise
+ * Since: UNRELEASED
+ */
+gboolean
+glnx_mkdtempat_open_in_system (gchar *tmpl,
+ int mode,
+ int *out_dfd,
+ GError **error)
+{
+ glnx_fd_close int tmp_dfd = -1;
+
+ *out_dfd = -1;
+
+ if (!glnx_opendirat (-1, g_get_tmp_dir (), TRUE, &tmp_dfd, error))
+ return FALSE;
+
+ return glnx_mkdtempat_open (tmp_dfd, tmpl, mode, out_dfd, error);
+}
+
+
diff --git a/libglnx/glnx-dirfd.h b/libglnx/glnx-dirfd.h
index 3a766952..0cb79e69 100644
--- a/libglnx/glnx-dirfd.h
+++ b/libglnx/glnx-dirfd.h
@@ -88,4 +88,15 @@ gboolean glnx_mkdtempat (int dfd,
int mode,
GError **error);
+gboolean glnx_mkdtempat_open (int dfd,
+ gchar *tmpl,
+ int mode,
+ int *out_dfd,
+ GError **error);
+
+gboolean glnx_mkdtempat_open_in_system (gchar *tmpl,
+ int mode,
+ int *out_dfd,
+ GError **error);
+
G_END_DECLS
diff --git a/libglnx/glnx-errors.c b/libglnx/glnx-errors.c
index edbce205..48008733 100644
--- a/libglnx/glnx-errors.c
+++ b/libglnx/glnx-errors.c
@@ -23,6 +23,22 @@
#include
#include
+void
+glnx_real_set_prefix_error_va (GError *error,
+ const char *format,
+ va_list args)
+{
+ if (error == NULL)
+ return;
+
+ g_autofree char *old_msg = g_steal_pointer (&error->message);
+ g_autoptr(GString) buf = g_string_new ("");
+ g_string_append_vprintf (buf, format, args);
+ g_string_append (buf, ": ");
+ g_string_append (buf, old_msg);
+ error->message = g_string_free (g_steal_pointer (&buf), FALSE);
+}
+
void
glnx_real_set_prefix_error_from_errno_va (GError **error,
gint errsv,
@@ -32,13 +48,9 @@ glnx_real_set_prefix_error_from_errno_va (GError **error,
if (!error)
return;
- /* TODO - enhance GError to have a "set and take ownership" API */
- g_autoptr(GString) buf = g_string_new ("");
- g_string_append_vprintf (buf, format, args);
- g_string_append (buf, ": ");
- g_string_append (buf, g_strerror (errsv));
g_set_error_literal (error,
G_IO_ERROR,
g_io_error_from_errno (errsv),
- buf->str);
+ g_strerror (errsv));
+ glnx_real_set_prefix_error_va (*error, format, args);
}
diff --git a/libglnx/glnx-errors.h b/libglnx/glnx-errors.h
index 8f9cad81..e26a513e 100644
--- a/libglnx/glnx-errors.h
+++ b/libglnx/glnx-errors.h
@@ -30,7 +30,7 @@ G_BEGIN_DECLS
* This function returns %FALSE so it can be used conveniently in a single
* statement:
*
- * ``
+ * ```
* if (strcmp (foo, "somevalue") != 0)
* return glnx_throw (error, "key must be somevalue, not '%s'", foo);
* ```
@@ -49,13 +49,47 @@ glnx_throw (GError **error, const char *fmt, ...)
return FALSE;
}
+/* Like `glnx_throw ()`, but returns %NULL. */
+#define glnx_null_throw(error, args...) \
+ ({glnx_throw (error, args); NULL;})
+
+/* Implementation detail of glnx_throw_prefix() */
+void glnx_real_set_prefix_error_va (GError *error,
+ const char *format,
+ va_list args) G_GNUC_PRINTF (2,0);
+
+/* Prepend to @error's message by `$prefix: ` where `$prefix` is computed via
+ * printf @fmt. Returns %FALSE so it can be used conveniently in a single
+ * statement:
+ *
+ * ```
+ * if (!function_that_fails (s, error))
+ * return glnx_throw_prefix (error, "while handling '%s'", s);
+ * ```
+ * */
+static inline gboolean G_GNUC_PRINTF (2,3)
+glnx_prefix_error (GError **error, const char *fmt, ...)
+{
+ if (error == NULL)
+ return FALSE;
+
+ va_list args;
+ va_start (args, fmt);
+ glnx_real_set_prefix_error_va (*error, fmt, args);
+ va_end (args);
+ return FALSE;
+}
+
+/* Like `glnx_prefix_error ()`, but returns %NULL. */
+#define glnx_prefix_error_null(error, args...) \
+ ({glnx_prefix_error (error, args); NULL;})
/* Set @error using the value of `g_strerror (errno)`.
*
* This function returns %FALSE so it can be used conveniently in a single
* statement:
*
- * ``
+ * ```
* if (unlinkat (fd, somepathname) < 0)
* return glnx_throw_errno (error);
* ```
@@ -79,6 +113,10 @@ glnx_throw_errno (GError **error)
return FALSE;
}
+/* Like glnx_throw_errno(), but yields a NULL pointer. */
+#define glnx_null_throw_errno(error) \
+ ({glnx_throw_errno (error); NULL;})
+
/* Implementation detail of glnx_throw_errno_prefix() */
void glnx_real_set_prefix_error_from_errno_va (GError **error,
gint errsv,
@@ -108,6 +146,10 @@ glnx_throw_errno_prefix (GError **error, const char *fmt, ...)
return FALSE;
}
+/* Like glnx_throw_errno_prefix(), but yields a NULL pointer. */
+#define glnx_null_throw_errno_prefix(error, args...) \
+ ({glnx_throw_errno_prefix (error, args); NULL;})
+
/* BEGIN LEGACY APIS */
#define glnx_set_error_from_errno(error) \
@@ -117,9 +159,7 @@ glnx_throw_errno_prefix (GError **error, const char *fmt, ...)
#define glnx_set_prefix_error_from_errno(error, format, args...) \
do { \
- glnx_set_error_from_errno (error); \
- g_prefix_error (error, format, args); \
+ glnx_throw_errno_prefix (error, format, args); \
} while (0);
-
G_END_DECLS
diff --git a/libglnx/glnx-fdio.c b/libglnx/glnx-fdio.c
index 68704cb1..df4c8518 100644
--- a/libglnx/glnx-fdio.c
+++ b/libglnx/glnx-fdio.c
@@ -102,10 +102,7 @@ rename_file_noreplace_at (int olddirfd, const char *oldpath,
return TRUE;
}
else
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
+ return glnx_throw_errno (error);
}
return TRUE;
}
@@ -172,10 +169,7 @@ glnx_open_tmpfile_linkable_at (int dfd,
#if defined(O_TMPFILE) && !defined(DISABLE_OTMPFILE) && !defined(ENABLE_WRPSEUDO_COMPAT)
fd = openat (dfd, subpath, O_TMPFILE|flags, 0600);
if (fd == -1 && !(errno == ENOSYS || errno == EISDIR || errno == EOPNOTSUPP))
- {
- glnx_set_prefix_error_from_errno (error, "%s", "open(O_TMPFILE)");
- return FALSE;
- }
+ return glnx_throw_errno_prefix (error, "open(O_TMPFILE)");
if (fd != -1)
{
*out_fd = fd;
@@ -199,10 +193,7 @@ glnx_open_tmpfile_linkable_at (int dfd,
if (errno == EEXIST)
continue;
else
- {
- glnx_set_prefix_error_from_errno (error, "%s", "Creating temp file");
- return FALSE;
- }
+ return glnx_throw_errno_prefix (error, "Creating temp file");
}
else
{
@@ -246,9 +237,10 @@ glnx_link_tmpfile_at (int dfd,
*/
if (renameat (dfd, tmpfile_path, target_dfd, target) < 0)
{
+ int errsv = errno;
(void) unlinkat (dfd, tmpfile_path, 0);
- glnx_set_error_from_errno (error);
- return FALSE;
+ errno = errsv;
+ return glnx_throw_errno_prefix (error, "renameat");
}
}
else
@@ -293,10 +285,7 @@ glnx_link_tmpfile_at (int dfd,
if (errno == EEXIST)
continue;
else
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
+ return glnx_throw_errno_prefix (error, "linkat");
}
else
break;
@@ -311,9 +300,10 @@ glnx_link_tmpfile_at (int dfd,
/* This is currently the only case where we need to have
* a cleanup unlinkat() still with O_TMPFILE.
*/
+ int errsv = errno;
(void) unlinkat (target_dfd, tmpname_buf, 0);
- glnx_set_error_from_errno (error);
- return FALSE;
+ errno = errsv;
+ return glnx_throw_errno_prefix (error, "renameat");
}
}
else
@@ -323,10 +313,7 @@ glnx_link_tmpfile_at (int dfd,
if (errno == EEXIST && mode == GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST)
;
else
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
+ return glnx_throw_errno_prefix (error, "linkat");
}
}
@@ -341,49 +328,37 @@ glnx_fd_readall_malloc (int fd,
GCancellable *cancellable,
GError **error)
{
- gboolean success = FALSE;
const guint maxreadlen = 4096;
- int res;
+
struct stat stbuf;
- guint8* buf = NULL;
+ if (TEMP_FAILURE_RETRY (fstat (fd, &stbuf)) < 0)
+ return glnx_null_throw_errno (error);
+
gsize buf_allocated;
- gsize buf_size = 0;
- gssize bytes_read;
-
- do
- res = fstat (fd, &stbuf);
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (res == -1)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
-
if (S_ISREG (stbuf.st_mode) && stbuf.st_size > 0)
buf_allocated = stbuf.st_size;
else
buf_allocated = 16;
-
- buf = g_malloc (buf_allocated);
+ g_autofree guint8* buf = g_malloc (buf_allocated);
+
+ gsize buf_size = 0;
while (TRUE)
{
gsize readlen = MIN (buf_allocated - buf_size, maxreadlen);
-
- if (g_cancellable_set_error_if_cancelled (cancellable, error))
- goto out;
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
+
+ gssize bytes_read;
do
bytes_read = read (fd, buf + buf_size, readlen);
while (G_UNLIKELY (bytes_read == -1 && errno == EINTR));
if (G_UNLIKELY (bytes_read == -1))
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_null_throw_errno (error);
if (bytes_read == 0)
break;
-
+
buf_size += bytes_read;
if (buf_allocated - buf_size < maxreadlen)
buf = g_realloc (buf, buf_allocated *= 2);
@@ -396,15 +371,8 @@ glnx_fd_readall_malloc (int fd,
buf[buf_size] = '\0';
}
- success = TRUE;
- out:
- if (success)
- {
- *out_len = buf_size;
- return buf;
- }
- g_free (buf);
- return NULL;
+ *out_len = buf_size;
+ return g_steal_pointer (&buf);
}
/**
@@ -423,13 +391,10 @@ glnx_fd_readall_bytes (int fd,
GCancellable *cancellable,
GError **error)
{
- guint8 *buf;
gsize len;
-
- buf = glnx_fd_readall_malloc (fd, &len, FALSE, cancellable, error);
+ guint8 *buf = glnx_fd_readall_malloc (fd, &len, FALSE, cancellable, error);
if (!buf)
return NULL;
-
return g_bytes_new_take (buf, len);
}
@@ -451,13 +416,10 @@ glnx_fd_readall_utf8 (int fd,
GCancellable *cancellable,
GError **error)
{
- gboolean success = FALSE;
- guint8 *buf;
gsize len;
-
- buf = glnx_fd_readall_malloc (fd, &len, TRUE, cancellable, error);
+ g_autofree guint8 *buf = glnx_fd_readall_malloc (fd, &len, TRUE, cancellable, error);
if (!buf)
- goto out;
+ return FALSE;
if (!g_utf8_validate ((char*)buf, len, NULL))
{
@@ -465,19 +427,12 @@ glnx_fd_readall_utf8 (int fd,
G_IO_ERROR,
G_IO_ERROR_INVALID_DATA,
"Invalid UTF-8");
- goto out;
+ return FALSE;
}
- success = TRUE;
- out:
- if (success)
- {
- if (out_len)
- *out_len = len;
- return (char*)buf;
- }
- g_free (buf);
- return NULL;
+ if (out_len)
+ *out_len = len;
+ return (char*)g_steal_pointer (&buf);
}
/**
@@ -501,36 +456,20 @@ glnx_file_get_contents_utf8_at (int dfd,
GCancellable *cancellable,
GError **error)
{
- gboolean success = FALSE;
- glnx_fd_close int fd = -1;
- char *buf = NULL;
- gsize len;
-
dfd = glnx_dirfd_canonicalize (dfd);
- do
- fd = openat (dfd, subpath, O_RDONLY | O_NOCTTY | O_CLOEXEC);
- while (G_UNLIKELY (fd == -1 && errno == EINTR));
+ glnx_fd_close int fd = TEMP_FAILURE_RETRY (openat (dfd, subpath, O_RDONLY | O_NOCTTY | O_CLOEXEC));
if (G_UNLIKELY (fd == -1))
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_null_throw_errno_prefix (error, "open(%s)", subpath);
- buf = glnx_fd_readall_utf8 (fd, &len, cancellable, error);
+ gsize len;
+ g_autofree char *buf = glnx_fd_readall_utf8 (fd, &len, cancellable, error);
if (G_UNLIKELY(!buf))
- goto out;
-
- success = TRUE;
- out:
- if (success)
- {
- if (out_len)
- *out_len = len;
- return buf;
- }
- g_free (buf);
- return NULL;
+ return FALSE;
+
+ if (out_len)
+ *out_len = len;
+ return g_steal_pointer (&buf);
}
/**
@@ -555,25 +494,20 @@ glnx_readlinkat_malloc (int dfd,
for (;;)
{
- char *c;
+ g_autofree char *c = NULL;
ssize_t n;
c = g_malloc (l);
n = TEMP_FAILURE_RETRY (readlinkat (dfd, subpath, c, l-1));
if (n < 0)
- {
- glnx_set_error_from_errno (error);
- g_free (c);
- return FALSE;
- }
+ return glnx_null_throw_errno (error);
if ((size_t) n < l-1)
{
c[n] = 0;
- return c;
+ return g_steal_pointer (&c);
}
- g_free (c);
l *= 2;
}
@@ -590,158 +524,171 @@ copy_symlink_at (int src_dfd,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- g_autofree char *buf = NULL;
-
- buf = glnx_readlinkat_malloc (src_dfd, src_subpath, cancellable, error);
+ g_autofree char *buf = glnx_readlinkat_malloc (src_dfd, src_subpath, cancellable, error);
if (!buf)
- goto out;
+ return FALSE;
if (TEMP_FAILURE_RETRY (symlinkat (buf, dest_dfd, dest_subpath)) != 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
-
+ return glnx_throw_errno_prefix (error, "symlinkat");
+
if (!(copyflags & GLNX_FILE_COPY_NOXATTRS))
{
g_autoptr(GVariant) xattrs = NULL;
if (!glnx_dfd_name_get_all_xattrs (src_dfd, src_subpath, &xattrs,
cancellable, error))
- goto out;
+ return FALSE;
if (!glnx_dfd_name_set_all_xattrs (dest_dfd, dest_subpath, xattrs,
cancellable, error))
- goto out;
+ return FALSE;
}
-
+
if (TEMP_FAILURE_RETRY (fchownat (dest_dfd, dest_subpath,
src_stbuf->st_uid, src_stbuf->st_gid,
AT_SYMLINK_NOFOLLOW)) != 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno (error);
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
#define COPY_BUFFER_SIZE (16*1024)
-/* From systemd */
+/* Most of the code below is from systemd, but has been reindented to GNU style,
+ * and changed to use POSIX error conventions (return -1, set errno) to more
+ * conveniently fit in with the rest of libglnx.
+ */
static int btrfs_reflink(int infd, int outfd) {
- int r;
-
g_return_val_if_fail(infd >= 0, -1);
g_return_val_if_fail(outfd >= 0, -1);
- r = ioctl(outfd, BTRFS_IOC_CLONE, infd);
- if (r < 0)
- return -errno;
-
- return 0;
+ return ioctl (outfd, BTRFS_IOC_CLONE, infd);
}
-int glnx_loop_write(int fd, const void *buf, size_t nbytes) {
- const uint8_t *p = buf;
+/* Like write(), but loop until @nbytes are written, or an error
+ * occurs.
+ *
+ * On error, -1 is returned an @errno is set. NOTE: This is an
+ * API change from previous versions of this function.
+ */
+int
+glnx_loop_write(int fd, const void *buf, size_t nbytes)
+{
+ const uint8_t *p = buf;
- g_return_val_if_fail(fd >= 0, -1);
- g_return_val_if_fail(buf, -1);
+ g_return_val_if_fail(fd >= 0, -1);
+ g_return_val_if_fail(buf, -1);
- errno = 0;
+ errno = 0;
- while (nbytes > 0) {
- ssize_t k;
+ while (nbytes > 0)
+ {
+ ssize_t k;
- k = write(fd, p, nbytes);
- if (k < 0) {
- if (errno == EINTR)
- continue;
+ k = write(fd, p, nbytes);
+ if (k < 0)
+ {
+ if (errno == EINTR)
+ continue;
- return -errno;
- }
-
- if (k == 0) /* Can't really happen */
- return -EIO;
-
- p += k;
- nbytes -= k;
+ return -1;
}
- return 0;
+ if (k == 0) /* Can't really happen */
+ {
+ errno = EIO;
+ return -1;
+ }
+
+ p += k;
+ nbytes -= k;
+ }
+
+ return 0;
}
-static int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink) {
- bool try_sendfile = true;
- int r;
+/* Read from @fdf until EOF, writing to @fdt. If @try_reflink is %TRUE,
+ * attempt to use any "reflink" functionality; see e.g. https://lwn.net/Articles/331808/
+ *
+ * The file descriptor @fdf must refer to a regular file.
+ *
+ * If provided, @max_bytes specifies the maximum number of bytes to read from @fdf.
+ * On error, this function returns `-1` and @errno will be set.
+ */
+int
+glnx_regfile_copy_bytes (int fdf, int fdt, off_t max_bytes, gboolean try_reflink)
+{
+ bool try_sendfile = true;
+ int r;
- g_return_val_if_fail (fdf >= 0, -1);
- g_return_val_if_fail (fdt >= 0, -1);
-
- /* Try btrfs reflinks first. */
- if (try_reflink && max_bytes == (off_t) -1) {
- r = btrfs_reflink(fdf, fdt);
- if (r >= 0)
- return r;
- }
-
- for (;;) {
- size_t m = COPY_BUFFER_SIZE;
- ssize_t n;
-
- if (max_bytes != (off_t) -1) {
-
- if (max_bytes <= 0)
- return -EFBIG;
-
- if ((off_t) m > max_bytes)
- m = (size_t) max_bytes;
- }
-
- /* First try sendfile(), unless we already tried */
- if (try_sendfile) {
-
- n = sendfile(fdt, fdf, NULL, m);
- if (n < 0) {
- if (errno != EINVAL && errno != ENOSYS)
- return -errno;
-
- try_sendfile = false;
- /* use fallback below */
- } else if (n == 0) /* EOF */
- break;
- else if (n > 0)
- /* Succcess! */
- goto next;
- }
-
- /* As a fallback just copy bits by hand */
- {
- char buf[m];
-
- n = read(fdf, buf, m);
- if (n < 0)
- return -errno;
- if (n == 0) /* EOF */
- break;
-
- r = glnx_loop_write(fdt, buf, (size_t) n);
- if (r < 0)
- return r;
- }
-
- next:
- if (max_bytes != (off_t) -1) {
- g_assert(max_bytes >= n);
- max_bytes -= n;
- }
- }
+ g_return_val_if_fail (fdf >= 0, -1);
+ g_return_val_if_fail (fdt >= 0, -1);
+ g_return_val_if_fail (max_bytes >= -1, -1);
+ /* Try btrfs reflinks first. */
+ if (try_reflink && max_bytes == (off_t) -1)
+ {
+ r = btrfs_reflink(fdf, fdt);
+ if (r >= 0)
return 0;
+ /* Fall through */
+ }
+
+ while (TRUE)
+ {
+ size_t m = COPY_BUFFER_SIZE;
+ ssize_t n;
+
+ if (max_bytes != (off_t) -1)
+ {
+ if ((off_t) m > max_bytes)
+ m = (size_t) max_bytes;
+ }
+
+ /* First try sendfile(), unless we already tried */
+ if (try_sendfile)
+ {
+ n = sendfile (fdt, fdf, NULL, m);
+ if (n < 0)
+ {
+ if (errno != EINVAL && errno != ENOSYS)
+ return -1;
+
+ try_sendfile = false;
+ /* use fallback below */
+ }
+ else if (n == 0) /* EOF */
+ break;
+ else if (n > 0)
+ /* Succcess! */
+ goto next;
+ }
+
+ /* As a fallback just copy bits by hand */
+ { char buf[m];
+
+ n = read (fdf, buf, m);
+ if (n < 0)
+ return -1;
+ if (n == 0) /* EOF */
+ break;
+
+ if (glnx_loop_write (fdt, buf, (size_t) n) < 0)
+ return -1;
+ }
+
+ next:
+ if (max_bytes != (off_t) -1)
+ {
+ g_assert(max_bytes >= n);
+ max_bytes -= n;
+ if (max_bytes == 0)
+ break;
+ }
+ }
+
+ return 0;
}
/**
@@ -829,10 +776,9 @@ glnx_file_copy_at (int src_dfd,
goto out;
}
- r = copy_bytes (src_fd, dest_fd, (off_t) -1, TRUE);
+ r = glnx_regfile_copy_bytes (src_fd, dest_fd, (off_t) -1, TRUE);
if (r < 0)
{
- errno = -r;
glnx_set_error_from_errno (error);
goto out;
}
@@ -921,7 +867,6 @@ glnx_file_replace_contents_at (int dfd,
return glnx_file_replace_contents_with_perms_at (dfd, subpath, buf, len,
(mode_t) -1, (uid_t) -1, (gid_t) -1,
flags, cancellable, error);
-
}
/**
@@ -953,8 +898,6 @@ glnx_file_replace_contents_with_perms_at (int dfd,
int r;
char *dnbuf = strdupa (subpath);
const char *dn = dirname (dnbuf);
- g_autofree char *tmpfile_path = NULL;
- glnx_fd_close int fd = -1;
dfd = glnx_dirfd_canonicalize (dfd);
@@ -964,6 +907,8 @@ glnx_file_replace_contents_with_perms_at (int dfd,
if (mode == (mode_t) -1)
mode = 0644;
+ glnx_fd_close int fd = -1;
+ g_autofree char *tmpfile_path = NULL;
if (!glnx_open_tmpfile_linkable_at (dfd, dn, O_WRONLY | O_CLOEXEC,
&fd, &tmpfile_path,
error))
@@ -979,30 +924,22 @@ glnx_file_replace_contents_with_perms_at (int dfd,
if (r != 0)
{
errno = r;
- glnx_set_error_from_errno (error);
- return FALSE;
+ return glnx_throw_errno_prefix (error, "fallocate");
}
}
- if ((r = glnx_loop_write (fd, buf, len)) != 0)
- {
- errno = -r;
- glnx_set_error_from_errno (error);
- return FALSE;
- }
-
+ if (glnx_loop_write (fd, buf, len) < 0)
+ return glnx_throw_errno (error);
+
if (!(flags & GLNX_FILE_REPLACE_NODATASYNC))
{
struct stat stbuf;
gboolean do_sync;
-
+
if (fstatat (dfd, subpath, &stbuf, AT_SYMLINK_NOFOLLOW) != 0)
{
if (errno != ENOENT)
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
+ return glnx_throw_errno (error);
do_sync = (flags & GLNX_FILE_REPLACE_DATASYNC_NEW) > 0;
}
else
@@ -1011,27 +948,18 @@ glnx_file_replace_contents_with_perms_at (int dfd,
if (do_sync)
{
if (fdatasync (fd) != 0)
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
+ return glnx_throw_errno_prefix (error, "fdatasync");
}
}
if (uid != (uid_t) -1)
{
if (fchown (fd, uid, gid) != 0)
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
+ return glnx_throw_errno (error);
}
if (fchmod (fd, mode) != 0)
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
+ return glnx_throw_errno (error);
if (!glnx_link_tmpfile_at (dfd, GLNX_LINK_TMPFILE_REPLACE,
fd, tmpfile_path, dfd, subpath, error))
@@ -1060,10 +988,7 @@ glnx_stream_fstat (GFileDescriptorBased *stream,
int fd = g_file_descriptor_based_get_fd (stream);
if (fstat (fd, stbuf) == -1)
- {
- glnx_set_prefix_error_from_errno (error, "%s", "fstat");
- return FALSE;
- }
+ return glnx_throw_errno_prefix (error, "fstat");
return TRUE;
}
diff --git a/libglnx/glnx-fdio.h b/libglnx/glnx-fdio.h
index c3e7573c..deff22b2 100644
--- a/libglnx/glnx-fdio.h
+++ b/libglnx/glnx-fdio.h
@@ -35,6 +35,8 @@
#include
#undef basename
+#include
+
G_BEGIN_DECLS
/* Irritatingly, g_basename() which is what we want
@@ -129,6 +131,9 @@ glnx_readlinkat_malloc (int dfd,
int
glnx_loop_write (int fd, const void *buf, size_t nbytes);
+int
+glnx_regfile_copy_bytes (int fdf, int fdt, off_t max_bytes, gboolean try_reflink);
+
typedef enum {
GLNX_FILE_COPY_OVERWRITE = (1 << 0),
GLNX_FILE_COPY_NOXATTRS = (1 << 1),
@@ -155,5 +160,54 @@ int glnx_renameat2_noreplace (int olddirfd, const char *oldpath,
int glnx_renameat2_exchange (int olddirfd, const char *oldpath,
int newdirfd, const char *newpath);
+/**
+ * glnx_fstat:
+ * @fd: FD to stat
+ * @buf: (out caller-allocates): Return location for stat details
+ * @error: Return location for a #GError, or %NULL
+ *
+ * Wrapper around fstat() which adds #GError support and ensures that it retries
+ * on %EINTR.
+ *
+ * Returns: %TRUE on success, %FALSE otherwise
+ * Since: UNRELEASED
+ */
+static inline gboolean
+glnx_fstat (int fd,
+ struct stat *buf,
+ GError **error)
+{
+ if (TEMP_FAILURE_RETRY (fstat (fd, buf)) != 0)
+ return glnx_throw_errno (error);
+
+ return TRUE;
+}
+
+/**
+ * glnx_fstatat:
+ * @dfd: Directory FD to stat beneath
+ * @path: Path to stat beneath @dfd
+ * @buf: (out caller-allocates): Return location for stat details
+ * @flags: Flags to pass to fstatat()
+ * @error: Return location for a #GError, or %NULL
+ *
+ * Wrapper around fstatat() which adds #GError support and ensures that it
+ * retries on %EINTR.
+ *
+ * Returns: %TRUE on success, %FALSE otherwise
+ * Since: UNRELEASED
+ */
+static inline gboolean
+glnx_fstatat (int dfd,
+ const gchar *path,
+ struct stat *buf,
+ int flags,
+ GError **error)
+{
+ if (TEMP_FAILURE_RETRY (fstatat (dfd, path, buf, flags)) != 0)
+ return glnx_throw_errno (error);
+
+ return TRUE;
+}
G_END_DECLS
diff --git a/libglnx/glnx-local-alloc.h b/libglnx/glnx-local-alloc.h
index f628b61c..8c1914cf 100644
--- a/libglnx/glnx-local-alloc.h
+++ b/libglnx/glnx-local-alloc.h
@@ -199,9 +199,9 @@ glnx_cleanup_close_fdp (int *fdp)
int fd, errsv;
g_assert (fdp);
-
+
fd = *fdp;
- if (fd != -1)
+ if (fd >= 0)
{
errsv = errno;
(void) close (fd);
diff --git a/libglnx/glnx-lockfile.c b/libglnx/glnx-lockfile.c
index 7dd69e91..c1cfc6b2 100644
--- a/libglnx/glnx-lockfile.c
+++ b/libglnx/glnx-lockfile.c
@@ -61,7 +61,6 @@
*/
gboolean
glnx_make_lock_file(int dfd, const char *p, int operation, GLnxLockFile *out_lock, GError **error) {
- gboolean ret = FALSE;
glnx_fd_close int fd = -1;
g_autofree char *t = NULL;
int r;
@@ -89,10 +88,8 @@ glnx_make_lock_file(int dfd, const char *p, int operation, GLnxLockFile *out_loc
struct stat st;
fd = openat(dfd, p, O_CREAT|O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NOCTTY, 0600);
- if (fd < 0) {
- glnx_set_error_from_errno(error);
- goto out;
- }
+ if (fd < 0)
+ return glnx_throw_errno(error);
/* Unfortunately, new locks are not in RHEL 7.1 glibc */
#ifdef F_OFD_SETLK
@@ -107,10 +104,8 @@ glnx_make_lock_file(int dfd, const char *p, int operation, GLnxLockFile *out_loc
if (errno == EINVAL)
r = flock(fd, operation);
- if (r < 0) {
- glnx_set_error_from_errno(error);
- goto out;
- }
+ if (r < 0)
+ return glnx_throw_errno(error);
}
/* If we acquired the lock, let's check if the file
@@ -120,10 +115,8 @@ glnx_make_lock_file(int dfd, const char *p, int operation, GLnxLockFile *out_loc
* hence try again. */
r = fstat(fd, &st);
- if (r < 0) {
- glnx_set_error_from_errno(error);
- goto out;
- }
+ if (r < 0)
+ return glnx_throw_errno(error);
if (st.st_nlink > 0)
break;
@@ -142,9 +135,7 @@ glnx_make_lock_file(int dfd, const char *p, int operation, GLnxLockFile *out_loc
fd = -1;
t = NULL;
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
void glnx_release_lock_file(GLnxLockFile *f) {
diff --git a/libglnx/glnx-shutil.c b/libglnx/glnx-shutil.c
index 6ff9fa68..6a1cdd4a 100644
--- a/libglnx/glnx-shutil.c
+++ b/libglnx/glnx-shutil.c
@@ -31,14 +31,12 @@ glnx_shutil_rm_rf_children (GLnxDirFdIterator *dfd_iter,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
struct dirent *dent;
while (TRUE)
{
if (!glnx_dirfd_iterator_next_dent_ensure_dtype (dfd_iter, &dent, cancellable, error))
- goto out;
-
+ return FALSE;
if (dent == NULL)
break;
@@ -48,33 +46,25 @@ glnx_shutil_rm_rf_children (GLnxDirFdIterator *dfd_iter,
if (!glnx_dirfd_iterator_init_at (dfd_iter->fd, dent->d_name, FALSE,
&child_dfd_iter, error))
- goto out;
+ return FALSE;
if (!glnx_shutil_rm_rf_children (&child_dfd_iter, cancellable, error))
- goto out;
+ return FALSE;
if (unlinkat (dfd_iter->fd, dent->d_name, AT_REMOVEDIR) == -1)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "unlinkat");
}
else
{
if (unlinkat (dfd_iter->fd, dent->d_name, 0) == -1)
{
if (errno != ENOENT)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "unlinkat");
}
}
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/**
@@ -94,7 +84,6 @@ glnx_shutil_rm_rf_at (int dfd,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
glnx_fd_close int target_dfd = -1;
g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
@@ -114,40 +103,28 @@ glnx_shutil_rm_rf_at (int dfd,
else if (errsv == ENOTDIR || errsv == ELOOP)
{
if (unlinkat (dfd, path, 0) != 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "unlinkat");
}
else
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "open(%s)", path);
}
else
{
if (!glnx_dirfd_iterator_init_take_fd (target_dfd, &dfd_iter, error))
- goto out;
+ return FALSE;
target_dfd = -1;
if (!glnx_shutil_rm_rf_children (&dfd_iter, cancellable, error))
- goto out;
+ return FALSE;
if (unlinkat (dfd, path, AT_REMOVEDIR) == -1)
{
- int errsv = errno;
- if (errsv != ENOENT)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ if (errno != ENOENT)
+ return glnx_throw_errno_prefix (error, "unlinkat");
}
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
static gboolean
@@ -157,11 +134,10 @@ mkdir_p_at_internal (int dfd,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
gboolean did_recurse = FALSE;
if (g_cancellable_set_error_if_cancelled (cancellable, error))
- goto out;
+ return FALSE;
again:
if (mkdirat (dfd, path, mode) == -1)
@@ -179,7 +155,7 @@ mkdir_p_at_internal (int dfd,
if (!glnx_shutil_mkdir_p_at (dfd, path, mode,
cancellable, error))
- goto out;
+ return FALSE;
/* Now restore it for another mkdir attempt */
*lastslash = '/';
@@ -194,15 +170,10 @@ mkdir_p_at_internal (int dfd,
*/
}
else
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "mkdir(%s)", path);
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/**
@@ -223,26 +194,58 @@ glnx_shutil_mkdir_p_at (int dfd,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
struct stat stbuf;
char *buf;
/* Fast path stat to see whether it already exists */
if (fstatat (dfd, path, &stbuf, AT_SYMLINK_NOFOLLOW) == 0)
{
+ /* Note early return */
if (S_ISDIR (stbuf.st_mode))
- {
- ret = TRUE;
- goto out;
- }
+ return TRUE;
}
buf = strdupa (path);
if (!mkdir_p_at_internal (dfd, buf, mode, cancellable, error))
- goto out;
+ return FALSE;
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
+}
+
+/**
+ * glnx_shutil_mkdir_p_at_open:
+ * @dfd: Directory fd
+ * @path: Directory path to be created
+ * @mode: Mode for newly created directories
+ * @out_dfd: (out caller-allocates): Return location for an FD to @dfd/@path,
+ * or `-1` on error
+ * @cancellable: (nullable): Cancellable, or %NULL
+ * @error: Return location for a #GError, or %NULL
+ *
+ * Similar to glnx_shutil_mkdir_p_at(), except it opens the resulting directory
+ * and returns a directory FD to it. Currently, this is not guaranteed to be
+ * race-free.
+ *
+ * Returns: %TRUE on success, %FALSE otherwise
+ * Since: UNRELEASED
+ */
+gboolean
+glnx_shutil_mkdir_p_at_open (int dfd,
+ const char *path,
+ int mode,
+ int *out_dfd,
+ GCancellable *cancellable,
+ GError **error)
+{
+ /* FIXME: It’s not possible to eliminate the race here until
+ * openat(O_DIRECTORY | O_CREAT) works (and returns a directory rather than a
+ * file). It appears to be not supported in current kernels. (Tested with
+ * 4.10.10-200.fc25.x86_64.) */
+ *out_dfd = -1;
+
+ if (!glnx_shutil_mkdir_p_at (dfd, path, mode, cancellable, error))
+ return FALSE;
+
+ return glnx_opendirat (dfd, path, TRUE, out_dfd, error);
}
diff --git a/libglnx/glnx-shutil.h b/libglnx/glnx-shutil.h
index 8cc732c3..56a99fa2 100644
--- a/libglnx/glnx-shutil.h
+++ b/libglnx/glnx-shutil.h
@@ -37,4 +37,12 @@ glnx_shutil_mkdir_p_at (int dfd,
GCancellable *cancellable,
GError **error);
+gboolean
+glnx_shutil_mkdir_p_at_open (int dfd,
+ const char *path,
+ int mode,
+ int *out_dfd,
+ GCancellable *cancellable,
+ GError **error);
+
G_END_DECLS
diff --git a/libglnx/tests/test-libglnx-errors.c b/libglnx/tests/test-libglnx-errors.c
index 8d109cd1..721818ba 100644
--- a/libglnx/tests/test-libglnx-errors.c
+++ b/libglnx/tests/test-libglnx-errors.c
@@ -33,6 +33,19 @@ test_error_throw (void)
g_assert (!glnx_throw (&error, "foo: %s %d", "hello", 42));
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
g_assert_cmpstr (error->message, ==, "foo: hello 42");
+ g_clear_error (&error);
+
+ gpointer dummy = glnx_null_throw (&error, "literal foo");
+ g_assert (dummy == NULL);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
+ g_assert_cmpstr (error->message, ==, "literal foo");
+ g_clear_error (&error);
+
+ gpointer dummy2 = glnx_null_throw (&error, "foo: %s %d", "hola", 24);
+ g_assert (dummy2 == NULL);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
+ g_assert_cmpstr (error->message, ==, "foo: hola 24");
+ g_clear_error (&error);
}
static void
@@ -47,6 +60,9 @@ test_error_errno (void)
{
g_assert (!glnx_throw_errno (&error));
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
+ g_assert (!glnx_prefix_error (&error, "myprefix"));
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
+ g_assert (g_str_has_prefix (error->message, "myprefix: "));
g_clear_error (&error);
}
else
@@ -55,8 +71,53 @@ test_error_errno (void)
fd = open (noent_path, O_RDONLY);
if (fd < 0)
{
+ gpointer dummy = glnx_null_throw_errno (&error);
+ g_assert (dummy == NULL);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
+ dummy = glnx_prefix_error_null (&error, "myprefix");
+ g_assert (dummy == NULL);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
+ g_assert (g_str_has_prefix (error->message, "myprefix: "));
+ g_clear_error (&error);
+ }
+ else
+ g_assert_cmpint (fd, ==, -1);
+
+ fd = open (noent_path, O_RDONLY);
+ if (fd < 0)
+ {
+ g_autofree char *expected_prefix = g_strdup_printf ("Failed to open %s", noent_path);
g_assert (!glnx_throw_errno_prefix (&error, "Failed to open %s", noent_path));
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
+ g_assert (g_str_has_prefix (error->message, expected_prefix));
+ g_clear_error (&error);
+ /* And test the legacy wrapper */
+ glnx_set_prefix_error_from_errno (&error, "Failed to open %s", noent_path);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
+ g_assert (g_str_has_prefix (error->message, expected_prefix));
+ g_clear_error (&error);
+ }
+ else
+ g_assert_cmpint (fd, ==, -1);
+
+ fd = open (noent_path, O_RDONLY);
+ if (fd < 0)
+ {
+ gpointer dummy = glnx_null_throw_errno_prefix (&error, "Failed to open file");
+ g_assert (dummy == NULL);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
+ g_assert (g_str_has_prefix (error->message, "Failed to open file"));
+ g_clear_error (&error);
+ }
+ else
+ g_assert_cmpint (fd, ==, -1);
+
+ fd = open (noent_path, O_RDONLY);
+ if (fd < 0)
+ {
+ gpointer dummy = glnx_null_throw_errno_prefix (&error, "Failed to open %s", noent_path);
+ g_assert (dummy == NULL);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND);
g_assert (g_str_has_prefix (error->message, glnx_strjoina ("Failed to open ", noent_path)));
g_clear_error (&error);
}
diff --git a/libglnx/tests/test-libglnx-xattrs.c b/libglnx/tests/test-libglnx-xattrs.c
index 0b21133a..b6f0ac69 100644
--- a/libglnx/tests/test-libglnx-xattrs.c
+++ b/libglnx/tests/test-libglnx-xattrs.c
@@ -244,6 +244,21 @@ test_xattr_races (void)
if (!glnx_opendirat (AT_FDCWD, tmpdir, TRUE, &dfd, error))
goto out;
+ /* Support people building/testing on tmpfs https://github.com/flatpak/flatpak/issues/686 */
+ if (fsetxattr (dfd, "user.test", "novalue", strlen ("novalue"), 0) < 0)
+ {
+ if (errno == EOPNOTSUPP)
+ {
+ g_test_skip ("no xattr support");
+ return;
+ }
+ else
+ {
+ glnx_set_error_from_errno (error);
+ goto out;
+ }
+ }
+
for (guint i = 0; i < nprocs; i++)
{
struct XattrWorker *worker = &wdata[i];
diff --git a/man/ostree-admin-cleanup.1 b/man/ostree-admin-cleanup.1
index 4fb7bd71..50ba5195 100644
--- a/man/ostree-admin-cleanup.1
+++ b/man/ostree-admin-cleanup.1
@@ -2,7 +2,7 @@
.\" Title: ostree admin cleanup
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree admin cleanup
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-admin-config-diff.1 b/man/ostree-admin-config-diff.1
index 1891b90f..f3661b09 100644
--- a/man/ostree-admin-config-diff.1
+++ b/man/ostree-admin-config-diff.1
@@ -2,7 +2,7 @@
.\" Title: ostree admin config-diff
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/14/2017
+.\" Date: 05/17/2017
.\" Manual: ostree admin config-diff
.\" Source: OSTree
.\" Language: English
@@ -37,9 +37,9 @@ ostree-admin-config-diff \- Diff current /etc configuration versus default
Prints the differences between the current /etc directory and the default configuration in /usr/etc\&. Newly added files (present in /etc but not in /usr/etc) will be prefixed with \*(AqA\*(Aq\&. Modified files will be prefixed with \*(AqM\*(Aq, and deleted files with \*(AqD\*(Aq\&.
.SH "OPTIONS"
.PP
-\fB\-\-os\fR="OSNAME"
+\fB\-\-os\fR="STATEROOT"
.RS 4
-Use a different operating system root than the current one\&.
+Use a different operating system stateroot than the current one\&.
.RE
.SH "EXAMPLE"
.PP
diff --git a/man/ostree-admin-config-diff.xml b/man/ostree-admin-config-diff.xml
index 69209e49..256b02fe 100644
--- a/man/ostree-admin-config-diff.xml
+++ b/man/ostree-admin-config-diff.xml
@@ -66,10 +66,10 @@ Boston, MA 02111-1307, USA.
- --os ="OSNAME"
+ --os ="STATEROOT"
- Use a different operating system root than the current one.
+ Use a different operating system stateroot than the current one.
diff --git a/man/ostree-admin-deploy.1 b/man/ostree-admin-deploy.1
index 838aa181..0c07738e 100644
--- a/man/ostree-admin-deploy.1
+++ b/man/ostree-admin-deploy.1
@@ -2,7 +2,7 @@
.\" Title: ostree admin deploy
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/14/2017
+.\" Date: 05/17/2017
.\" Manual: ostree admin deploy
.\" Source: OSTree
.\" Language: English
@@ -37,7 +37,7 @@ ostree-admin-deploy \- Checkout a revision as the new default deployment
Takes a commit or revision REFSPEC, and queues the new deployment as default upon reboot\&.
.SH "OPTIONS"
.PP
-\fB\-\-os\fR="OSNAME"
+\fB\-\-os\fR="STATEROOT"
.RS 4
Use a different operating system root than the current one\&.
.RE
diff --git a/man/ostree-admin-deploy.xml b/man/ostree-admin-deploy.xml
index ef96203c..347a4ba9 100644
--- a/man/ostree-admin-deploy.xml
+++ b/man/ostree-admin-deploy.xml
@@ -66,7 +66,7 @@ Boston, MA 02111-1307, USA.
- --os ="OSNAME"
+ --os ="STATEROOT"
Use a different operating system root than the current one.
diff --git a/man/ostree-admin-init-fs.1 b/man/ostree-admin-init-fs.1
index 785f55ef..fcb7302f 100644
--- a/man/ostree-admin-init-fs.1
+++ b/man/ostree-admin-init-fs.1
@@ -2,7 +2,7 @@
.\" Title: ostree admin init-fs
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree admin init-fs
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-admin-instutil.1 b/man/ostree-admin-instutil.1
index f6c90952..cc0f52b7 100644
--- a/man/ostree-admin-instutil.1
+++ b/man/ostree-admin-instutil.1
@@ -2,7 +2,7 @@
.\" Title: ostree admin instutil
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree admin instutil
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-admin-os-init.1 b/man/ostree-admin-os-init.1
index 5b14d45f..4f2f7cbe 100644
--- a/man/ostree-admin-os-init.1
+++ b/man/ostree-admin-os-init.1
@@ -2,7 +2,7 @@
.\" Title: ostree admin os-init
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/14/2017
+.\" Date: 05/17/2017
.\" Manual: ostree admin os-init
.\" Source: OSTree
.\" Language: English
@@ -31,21 +31,21 @@
ostree-admin-os-init \- Initialize empty state for a given operating system
.SH "SYNOPSIS"
.HP \w'\fBostree\ admin\ os\-init\fR\ 'u
-\fBostree admin os\-init\fR {OSNAME}
+\fBostree admin os\-init\fR {STATEROOT}
.SH "DESCRIPTION"
.PP
-Initializes an new state for an operating system\&. Ensures that the core subdirectories of /var (/tmp, /lib, /run, and /lock) exist and initialize the given OSNAME as OSTree root\&. Each deployment location is comprised of a single shared
+Initializes an new stateroot (AKA "osname") for an operating system\&. Ensures that the core subdirectories of /var (/tmp, /lib, /run, and /lock) exist and initialize the given STATEROOT as OSTree stateroot\&. Each deployment location is comprised of a single shared
var
and a set of deployments (chroots)\&.
.SH "EXAMPLE"
.PP
-\fB$ ostree admin os\-init gnome\-ostree\fR
+\fB$ ostree admin os\-init exampleos\fR
.sp
.if n \{\
.RS 4
.\}
.nf
- ostree/deploy/gnome\-ostree initialized as OSTree root
+ ostree/deploy/exampleos initialized as OSTree root
.fi
.if n \{\
diff --git a/man/ostree-admin-os-init.xml b/man/ostree-admin-os-init.xml
index 77bd126a..10f02ad6 100644
--- a/man/ostree-admin-os-init.xml
+++ b/man/ostree-admin-os-init.xml
@@ -49,7 +49,7 @@ Boston, MA 02111-1307, USA.
- ostree admin os-init OSNAME
+ ostree admin os-init STATEROOT
@@ -57,15 +57,19 @@ Boston, MA 02111-1307, USA.
Description
- Initializes an new state for an operating system. Ensures that the core subdirectories of /var (/tmp, /lib, /run, and /lock) exist and initialize the given OSNAME as OSTree root. Each deployment location is comprised of a single shared var and a set of deployments (chroots).
+ Initializes an new stateroot (AKA "osname") for an operating system.
+ Ensures that the core subdirectories of /var (/tmp, /lib, /run, and
+ /lock) exist and initialize the given STATEROOT as OSTree stateroot.
+ Each deployment location is comprised of a single shared
+ var and a set of deployments (chroots).
Example
- $ ostree admin os-init gnome-ostree
+ $ ostree admin os-init exampleos
- ostree/deploy/gnome-ostree initialized as OSTree root
+ ostree/deploy/exampleos initialized as OSTree root
diff --git a/man/ostree-admin-set-origin.1 b/man/ostree-admin-set-origin.1
index fe1db02d..33d6720f 100644
--- a/man/ostree-admin-set-origin.1
+++ b/man/ostree-admin-set-origin.1
@@ -2,7 +2,7 @@
.\" Title: ostree admin set-origin
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree admin set-origin
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-admin-status.1 b/man/ostree-admin-status.1
index 5a14d3e5..9ac88f20 100644
--- a/man/ostree-admin-status.1
+++ b/man/ostree-admin-status.1
@@ -2,7 +2,7 @@
.\" Title: ostree admin status
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree admin status
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-admin-switch.1 b/man/ostree-admin-switch.1
index 1df9f953..f7761162 100644
--- a/man/ostree-admin-switch.1
+++ b/man/ostree-admin-switch.1
@@ -2,7 +2,7 @@
.\" Title: ostree admin switch
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/14/2017
+.\" Date: 05/17/2017
.\" Manual: ostree admin switch
.\" Source: OSTree
.\" Language: English
@@ -38,7 +38,7 @@ Choose a different REF forom the current remote to track\&. This is the ref that
\fBostree admin upgrade\fR\&. Like an upgrade, the operating system state will be preserved\&.
.SH "OPTIONS"
.PP
-\fB\-\-os\fR="OSNAME"
+\fB\-\-os\fR="STATEROOT"
.RS 4
Use a different operating system root than the current one\&.
.RE
diff --git a/man/ostree-admin-switch.xml b/man/ostree-admin-switch.xml
index 8072d6b9..86f9be40 100644
--- a/man/ostree-admin-switch.xml
+++ b/man/ostree-admin-switch.xml
@@ -66,7 +66,7 @@ Boston, MA 02111-1307, USA.
- --os ="OSNAME"
+ --os ="STATEROOT"
Use a different operating system root than the current one.
diff --git a/man/ostree-admin-undeploy.1 b/man/ostree-admin-undeploy.1
index 88a7ba41..5a0253f2 100644
--- a/man/ostree-admin-undeploy.1
+++ b/man/ostree-admin-undeploy.1
@@ -2,7 +2,7 @@
.\" Title: ostree admin undeploy
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree admin undeploy
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-admin-unlock.1 b/man/ostree-admin-unlock.1
index 68145e27..141656c5 100644
--- a/man/ostree-admin-unlock.1
+++ b/man/ostree-admin-unlock.1
@@ -2,7 +2,7 @@
.\" Title: ostree admin unlock
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree admin unlock
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-admin-upgrade.1 b/man/ostree-admin-upgrade.1
index 768f24ef..50734f26 100644
--- a/man/ostree-admin-upgrade.1
+++ b/man/ostree-admin-upgrade.1
@@ -2,7 +2,7 @@
.\" Title: ostree admin upgrade
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/14/2017
+.\" Date: 05/17/2017
.\" Manual: ostree admin upgrade
.\" Source: OSTree
.\" Language: English
@@ -40,7 +40,7 @@ and
\fB\-\-deploy\-only\fR\&.
.SH "OPTIONS"
.PP
-\fB\-\-os\fR="OSNAME"
+\fB\-\-os\fR="STATEROOT"
.RS 4
Use a different operating system root than the current one\&.
.RE
diff --git a/man/ostree-admin-upgrade.xml b/man/ostree-admin-upgrade.xml
index 7766c66e..51900b85 100644
--- a/man/ostree-admin-upgrade.xml
+++ b/man/ostree-admin-upgrade.xml
@@ -69,7 +69,7 @@ Boston, MA 02111-1307, USA.
- --os ="OSNAME"
+ --os ="STATEROOT"
Use a different operating system root than the current one.
diff --git a/man/ostree-admin.1 b/man/ostree-admin.1
index 2de6a630..4f149829 100644
--- a/man/ostree-admin.1
+++ b/man/ostree-admin.1
@@ -2,7 +2,7 @@
.\" Title: ostree admin
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree admin
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-cat.1 b/man/ostree-cat.1
index c068668a..c771a90a 100644
--- a/man/ostree-cat.1
+++ b/man/ostree-cat.1
@@ -2,7 +2,7 @@
.\" Title: ostree cat
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree cat
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-checkout.1 b/man/ostree-checkout.1
index 80420983..44dc90a8 100644
--- a/man/ostree-checkout.1
+++ b/man/ostree-checkout.1
@@ -2,7 +2,7 @@
.\" Title: ostree checkout
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree checkout
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-checksum.1 b/man/ostree-checksum.1
index 7d2d56bc..fa8abeaf 100644
--- a/man/ostree-checksum.1
+++ b/man/ostree-checksum.1
@@ -2,7 +2,7 @@
.\" Title: ostree checksum
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree checksum
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-commit.1 b/man/ostree-commit.1
index d3ce3286..0bc038db 100644
--- a/man/ostree-commit.1
+++ b/man/ostree-commit.1
@@ -2,7 +2,7 @@
.\" Title: ostree commit
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree commit
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-config.1 b/man/ostree-config.1
index 2a820647..9e927d46 100644
--- a/man/ostree-config.1
+++ b/man/ostree-config.1
@@ -2,7 +2,7 @@
.\" Title: ostree config
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree config
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-diff.1 b/man/ostree-diff.1
index d91442ab..abbb8b80 100644
--- a/man/ostree-diff.1
+++ b/man/ostree-diff.1
@@ -2,7 +2,7 @@
.\" Title: ostree diff
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/11/2017
+.\" Date: 05/17/2017
.\" Manual: ostree diff
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-export.1 b/man/ostree-export.1
index b642a026..f40c257e 100644
--- a/man/ostree-export.1
+++ b/man/ostree-export.1
@@ -2,7 +2,7 @@
.\" Title: ostree export
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree export
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-fsck.1 b/man/ostree-fsck.1
index c7cf826b..6ee29ddd 100644
--- a/man/ostree-fsck.1
+++ b/man/ostree-fsck.1
@@ -2,7 +2,7 @@
.\" Title: ostree fsck
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree fsck
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-gpg-sign.1 b/man/ostree-gpg-sign.1
index 150e488a..621af5cb 100644
--- a/man/ostree-gpg-sign.1
+++ b/man/ostree-gpg-sign.1
@@ -2,7 +2,7 @@
.\" Title: ostree gpg-sign
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree gpg-sign
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-init.1 b/man/ostree-init.1
index 303f9ebe..8a33ac92 100644
--- a/man/ostree-init.1
+++ b/man/ostree-init.1
@@ -2,7 +2,7 @@
.\" Title: ostree init
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree init
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-log.1 b/man/ostree-log.1
index 8b6bbb50..5dee34cd 100644
--- a/man/ostree-log.1
+++ b/man/ostree-log.1
@@ -2,7 +2,7 @@
.\" Title: ostree log
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree log
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-ls.1 b/man/ostree-ls.1
index 9488f2a4..aefbb97c 100644
--- a/man/ostree-ls.1
+++ b/man/ostree-ls.1
@@ -2,7 +2,7 @@
.\" Title: ostree ls
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree ls
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-prune.1 b/man/ostree-prune.1
index d474c1cf..30a42239 100644
--- a/man/ostree-prune.1
+++ b/man/ostree-prune.1
@@ -2,7 +2,7 @@
.\" Title: ostree prune
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree prune
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-pull-local.1 b/man/ostree-pull-local.1
index af5e740c..9abae9a9 100644
--- a/man/ostree-pull-local.1
+++ b/man/ostree-pull-local.1
@@ -2,7 +2,7 @@
.\" Title: ostree pull-local
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree pull-local
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-pull.1 b/man/ostree-pull.1
index 17d9fcbd..ff57eb3c 100644
--- a/man/ostree-pull.1
+++ b/man/ostree-pull.1
@@ -2,7 +2,7 @@
.\" Title: ostree pull
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree pull
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-refs.1 b/man/ostree-refs.1
index 0734d0f2..7898ba25 100644
--- a/man/ostree-refs.1
+++ b/man/ostree-refs.1
@@ -2,7 +2,7 @@
.\" Title: ostree refs
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree refs
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-remote.1 b/man/ostree-remote.1
index 20278e44..eb9cbd55 100644
--- a/man/ostree-remote.1
+++ b/man/ostree-remote.1
@@ -2,7 +2,7 @@
.\" Title: ostree remote
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree remote
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-reset.1 b/man/ostree-reset.1
index b009d9e9..b2ce450b 100644
--- a/man/ostree-reset.1
+++ b/man/ostree-reset.1
@@ -2,7 +2,7 @@
.\" Title: ostree reset
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree reset
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-rev-parse.1 b/man/ostree-rev-parse.1
index 3da7374b..78af805b 100644
--- a/man/ostree-rev-parse.1
+++ b/man/ostree-rev-parse.1
@@ -2,7 +2,7 @@
.\" Title: ostree rev-parse
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree rev-parse
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-show.1 b/man/ostree-show.1
index 5fb6c675..ef36f4a2 100644
--- a/man/ostree-show.1
+++ b/man/ostree-show.1
@@ -2,7 +2,7 @@
.\" Title: ostree show
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree show
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-static-delta.1 b/man/ostree-static-delta.1
index 5d2ed8e9..660983ff 100644
--- a/man/ostree-static-delta.1
+++ b/man/ostree-static-delta.1
@@ -2,7 +2,7 @@
.\" Title: ostree static-delta
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree static-delta
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-summary.1 b/man/ostree-summary.1
index 6e258f0b..6f2b1622 100644
--- a/man/ostree-summary.1
+++ b/man/ostree-summary.1
@@ -2,7 +2,7 @@
.\" Title: ostree summary
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree summary
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree-trivial-httpd.1 b/man/ostree-trivial-httpd.1
index a6a7cafe..9a021cc9 100644
--- a/man/ostree-trivial-httpd.1
+++ b/man/ostree-trivial-httpd.1
@@ -2,7 +2,7 @@
.\" Title: ostree trivial-httpd
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree trivial-httpd
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree.1 b/man/ostree.1
index 6c58dccc..58434378 100644
--- a/man/ostree.1
+++ b/man/ostree.1
@@ -2,7 +2,7 @@
.\" Title: ostree
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/14/2017
+.\" Date: 05/17/2017
.\" Manual: ostree
.\" Source: OSTree
.\" Language: English
@@ -37,8 +37,10 @@ ostree \- Manage multiple bootable versioned filesystem trees
OSTree is a tool for managing multiple bootable versioned filesystem trees, or just "tree" for short\&. In the OSTree model, operating systems no longer live in the physical "/" root directory\&. Instead, they parallel install to the new toplevel
/ostree
directory\&. Each installed system gets its own
-/ostree/deploy/\fIosname\fR
-directory\&.
+/ostree/deploy/\fIstateroot\fR
+directory\&. (stateroot
+is the newer term for
+osname)\&.
.PP
Unlike
rpm
diff --git a/man/ostree.repo-config.5 b/man/ostree.repo-config.5
index 7d84d39b..de7302a3 100644
--- a/man/ostree.repo-config.5
+++ b/man/ostree.repo-config.5
@@ -2,7 +2,7 @@
.\" Title: ostree.repo-config
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree.repo-config
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree.repo.5 b/man/ostree.repo.5
index 9d630fa1..07f0d904 100644
--- a/man/ostree.repo.5
+++ b/man/ostree.repo.5
@@ -2,7 +2,7 @@
.\" Title: ostree.repo
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: ostree.repo
.\" Source: OSTree
.\" Language: English
diff --git a/man/ostree.xml b/man/ostree.xml
index e31d58b2..940d81d7 100644
--- a/man/ostree.xml
+++ b/man/ostree.xml
@@ -65,8 +65,9 @@ Boston, MA 02111-1307, USA.
Instead, they parallel install to the new toplevel
/ostree directory. Each
installed system gets its own
- /ostree/deploy/osname
- directory.
+ /ostree/deploy/stateroot
+ directory. (stateroot is the
+ newer term for osname ).
Unlike rpm or
diff --git a/man/rofiles-fuse.1 b/man/rofiles-fuse.1
index 4c6de299..59591a05 100644
--- a/man/rofiles-fuse.1
+++ b/man/rofiles-fuse.1
@@ -2,7 +2,7 @@
.\" Title: rofiles-fuse
.\" Author: Colin Walters
.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 04/05/2017
+.\" Date: 05/17/2017
.\" Manual: rofiles-fuse
.\" Source: rofiles-fuse
.\" Language: English
diff --git a/src/libostree/libostree-experimental.sym b/src/libostree/libostree-experimental.sym
new file mode 100644
index 00000000..e2ab4ea8
--- /dev/null
+++ b/src/libostree/libostree-experimental.sym
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 2017 Endless Mobile, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * - Philip Withnall
+ */
+
+/* Symbols in this file are added to the build if OSTree is configured with
+ * --enable-experimental-api. They are not stable or officially supported, and
+ * might disappear or change in future releases. */
+
+LIBOSTREE_2017.6_EXPERIMENTAL {
+global:
+ ostree_remote_ref;
+ ostree_remote_unref;
+} LIBOSTREE_2017.6;
diff --git a/src/libostree/libostree.sym b/src/libostree/libostree.sym
index d9339bf2..e2a7c3d9 100644
--- a/src/libostree/libostree.sym
+++ b/src/libostree/libostree.sym
@@ -389,17 +389,24 @@ global:
ostree_sysroot_write_deployments_with_options;
} LIBOSTREE_2017.3;
+LIBOSTREE_2017.6 {
+global:
+ ostree_async_progress_get;
+ ostree_async_progress_set;
+ ostree_async_progress_get_variant;
+ ostree_async_progress_set_variant;
+} LIBOSTREE_2017.4;
+
/* NOTE NOTE NOTE
* Versions above here are released. Only add symbols below this line.
* NOTE NOTE NOTE
*/
-/* Uncomment when adding the first new symbol */
/*
LIBOSTREE_2017.$NEWVERSION {
global:
someostree_symbol_deleteme;
-} LIBOSTREE_2017.4;
+} LIBOSTREE_2017.6;
*/
/* Stub section for the stable release *after* this development one; don't
diff --git a/src/libostree/ostree-1.pc.in b/src/libostree/ostree-1.pc.in
index d777c597..9a4debce 100644
--- a/src/libostree/ostree-1.pc.in
+++ b/src/libostree/ostree-1.pc.in
@@ -2,6 +2,7 @@ prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
+features=@OSTREE_FEATURES@
Name: OSTree
Description: Git for operating system binaries
diff --git a/src/libostree/ostree-async-progress.c b/src/libostree/ostree-async-progress.c
index 0851fd86..b879559e 100644
--- a/src/libostree/ostree-async-progress.c
+++ b/src/libostree/ostree-async-progress.c
@@ -22,6 +22,8 @@
#include "ostree-async-progress.h"
+#include "libglnx.h"
+
/**
* SECTION:ostree-async-progress
* @title: Progress notification system for asynchronous operations
@@ -37,14 +39,13 @@
* handles thread safety, ensuring that the progress change
* notification occurs in the thread-default context of the calling
* operation.
+ *
+ * The ostree_async_progress_get_status() and ostree_async_progress_set_status()
+ * methods get and set a well-known `status` key of type %G_VARIANT_TYPE_STRING.
+ * This key may be accessed using the other #OstreeAsyncProgress methods, but it
+ * must always have the correct type.
*/
-#if GLIB_SIZEOF_VOID_P == 8
-#define _OSTREE_HAVE_LP64 1
-#else
-#define _OSTREE_HAVE_LP64 0
-#endif
-
enum {
CHANGED,
LAST_SIGNAL
@@ -59,12 +60,9 @@ struct OstreeAsyncProgress
GMutex lock;
GMainContext *maincontext;
GSource *idle_source;
- GHashTable *uint_values;
- GHashTable *uint64_values;
+ GHashTable *values; /* (element-type uint GVariant) */
gboolean dead;
-
- char *status;
};
G_DEFINE_TYPE (OstreeAsyncProgress, ostree_async_progress, G_TYPE_OBJECT)
@@ -79,9 +77,7 @@ ostree_async_progress_finalize (GObject *object)
g_mutex_clear (&self->lock);
g_clear_pointer (&self->maincontext, g_main_context_unref);
g_clear_pointer (&self->idle_source, g_source_unref);
- g_hash_table_unref (self->uint_values);
- g_hash_table_unref (self->uint64_values);
- g_free (self->status);
+ g_hash_table_unref (self->values);
G_OBJECT_CLASS (ostree_async_progress_parent_class)->finalize (object);
}
@@ -114,46 +110,115 @@ ostree_async_progress_init (OstreeAsyncProgress *self)
{
g_mutex_init (&self->lock);
self->maincontext = g_main_context_ref_thread_default ();
- self->uint_values = g_hash_table_new (NULL, NULL);
-#if _OSTREE_HAVE_LP64
- self->uint64_values = g_hash_table_new (NULL, NULL);
-#else
- self->uint64_values = g_hash_table_new_full (NULL, NULL,
- NULL, g_free);
-#endif
+ self->values = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_variant_unref);
+}
+
+/**
+ * ostree_async_progress_get_variant:
+ * @self: an #OstreeAsyncProgress
+ * @key: a key to look up
+ *
+ * Look up a key in the #OstreeAsyncProgress and return the #GVariant associated
+ * with it. The lookup is thread-safe.
+ *
+ * Returns: (transfer full) (nullable): value for the given @key, or %NULL if
+ * it was not set
+ * Since: 2017.6
+ */
+GVariant *
+ostree_async_progress_get_variant (OstreeAsyncProgress *self,
+ const char *key)
+{
+ GVariant *rval;
+
+ g_return_val_if_fail (OSTREE_IS_ASYNC_PROGRESS (self), NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ g_mutex_lock (&self->lock);
+ rval = g_hash_table_lookup (self->values, GUINT_TO_POINTER (g_quark_from_string (key)));
+ if (rval != NULL)
+ g_variant_ref (rval);
+ g_mutex_unlock (&self->lock);
+
+ return rval;
}
guint
ostree_async_progress_get_uint (OstreeAsyncProgress *self,
const char *key)
{
- guint rval;
- g_mutex_lock (&self->lock);
- rval = GPOINTER_TO_UINT (g_hash_table_lookup (self->uint_values,
- GUINT_TO_POINTER (g_quark_from_string (key))));
- g_mutex_unlock (&self->lock);
- return rval;
+ g_autoptr(GVariant) rval = ostree_async_progress_get_variant (self, key);
+ return (rval != NULL) ? g_variant_get_uint32 (rval) : 0;
}
guint64
ostree_async_progress_get_uint64 (OstreeAsyncProgress *self,
const char *key)
{
-#if _OSTREE_HAVE_LP64
- guint64 rval;
+ g_autoptr(GVariant) rval = ostree_async_progress_get_variant (self, key);
+ return (rval != NULL) ? g_variant_get_uint64 (rval) : 0;
+}
+
+/**
+ * ostree_async_progress_get:
+ * @self: an #OstreeAsyncProgress
+ * @...: key name, format string, #GVariant return locations, …, followed by %NULL
+ *
+ * Get the values corresponding to zero or more keys from the
+ * #OstreeAsyncProgress. Each key is specified in @... as the key name, followed
+ * by a #GVariant format string, followed by the necessary arguments for that
+ * format string, just as for g_variant_get(). After those arguments is the
+ * next key name. The varargs list must be %NULL-terminated.
+ *
+ * Each format string must make deep copies of its value, as the values stored
+ * in the #OstreeAsyncProgress may be freed from another thread after this
+ * function returns.
+ *
+ * This operation is thread-safe, and all the keys are queried atomically.
+ *
+ * |[
+ * guint32 outstanding_fetches;
+ * guint64 bytes_received;
+ * g_autofree gchar *status = NULL;
+ * g_autoptr(GVariant) refs_variant = NULL;
+ *
+ * ostree_async_progress_get (progress,
+ * "outstanding-fetches", "u", &outstanding_fetches,
+ * "bytes-received", "t", &bytes_received,
+ * "status", "s", &status,
+ * "refs", "@a{ss}", &refs_variant,
+ * NULL);
+ * ]|
+ *
+ * Since: 2017.6
+ */
+void
+ostree_async_progress_get (OstreeAsyncProgress *self,
+ ...)
+{
+ va_list ap;
+ const char *key, *format_string;
+
g_mutex_lock (&self->lock);
- rval = (guint64) g_hash_table_lookup (self->uint64_values, GUINT_TO_POINTER (g_quark_from_string (key)));
+ va_start (ap, self);
+
+ for (key = va_arg (ap, const char *), format_string = va_arg (ap, const char *);
+ key != NULL;
+ key = va_arg (ap, const char *), format_string = va_arg (ap, const char *))
+ {
+ GVariant *variant;
+
+ g_assert (format_string != NULL);
+
+ variant = g_hash_table_lookup (self->values, GUINT_TO_POINTER (g_quark_from_string (key)));
+ g_assert (variant != NULL);
+ g_assert (g_variant_check_format_string (variant, format_string, TRUE));
+
+ g_variant_get_va (variant, format_string, NULL, &ap);
+ }
+
+ va_end (ap);
g_mutex_unlock (&self->lock);
- return rval;
-#else
- guint64 *rval;
- g_mutex_lock (&self->lock);
- rval = g_hash_table_lookup (self->uint64_values, (gpointer)g_quark_from_string (key));
- g_mutex_unlock (&self->lock);
- if (rval)
- return *rval;
- return 0;
-#endif
}
static gboolean
@@ -180,50 +245,162 @@ ensure_callback_locked (OstreeAsyncProgress *self)
g_source_attach (self->idle_source, self->maincontext);
}
+/**
+ * ostree_async_progress_set_status:
+ * @self: an #OstreeAsyncProgress
+ * @status: (nullable): new status string, or %NULL to clear the status
+ *
+ * Set the human-readable status string for the #OstreeAsyncProgress. This
+ * operation is thread-safe. %NULL may be passed to clear the status.
+ *
+ * This is a convenience function to set the well-known `status` key.
+ *
+ * Since: 2017.6
+ */
void
ostree_async_progress_set_status (OstreeAsyncProgress *self,
const char *status)
{
- g_mutex_lock (&self->lock);
- if (!self->dead)
- {
- g_free (self->status);
- self->status = g_strdup (status);
- ensure_callback_locked (self);
- }
- g_mutex_unlock (&self->lock);
+ ostree_async_progress_set_variant (self, "status",
+ g_variant_new_string ((status != NULL) ? status : ""));
}
+/**
+ * ostree_async_progress_get_status:
+ * @self: an #OstreeAsyncProgress
+ *
+ * Get the human-readable status string from the #OstreeAsyncProgress. This
+ * operation is thread-safe. The retuned value may be %NULL if no status is
+ * set.
+ *
+ * This is a convenience function to get the well-known `status` key.
+ *
+ * Returns: (transfer full) (nullable): the current status, or %NULL if none is set
+ * Since: 2017.6
+ */
char *
ostree_async_progress_get_status (OstreeAsyncProgress *self)
{
- char *ret;
- g_mutex_lock (&self->lock);
- ret = g_strdup (self->status);
- g_mutex_unlock (&self->lock);
- return ret;
+ g_autoptr(GVariant) rval = ostree_async_progress_get_variant (self, "status");
+ const gchar *status = (rval != NULL) ? g_variant_get_string (rval, NULL) : NULL;
+ if (status != NULL && *status == '\0')
+ status = NULL;
+ return g_strdup (status);
}
-static void
-update_key (OstreeAsyncProgress *self,
- GHashTable *hash,
- const char *key,
- gpointer value)
+/**
+ * ostree_async_progress_set:
+ * @self: an #OstreeAsyncProgress
+ * @...: key name, format string, #GVariant parameters, …, followed by %NULL
+ *
+ * Set the values for zero or more keys in the #OstreeAsyncProgress. Each key is
+ * specified in @... as the key name, followed by a #GVariant format string,
+ * followed by the necessary arguments for that format string, just as for
+ * g_variant_new(). After those arguments is the next key name. The varargs list
+ * must be %NULL-terminated.
+ *
+ * g_variant_ref_sink() will be called as appropriate on the #GVariant
+ * parameters, so they may be floating.
+ *
+ * This operation is thread-safe, and all the keys are set atomically.
+ *
+ * |[
+ * guint32 outstanding_fetches = 15;
+ * guint64 bytes_received = 1000;
+ *
+ * ostree_async_progress_set (progress,
+ * "outstanding-fetches", "u", outstanding_fetches,
+ * "bytes-received", "t", bytes_received,
+ * "status", "s", "Updated status",
+ * "refs", "@a{ss}", g_variant_new_parsed ("@a{ss} {}"),
+ * NULL);
+ * ]|
+ *
+ * Since: 2017.6
+ */
+void
+ostree_async_progress_set (OstreeAsyncProgress *self,
+ ...)
{
- gpointer orig_value;
- gpointer qkey = GUINT_TO_POINTER (g_quark_from_string (key));
+ va_list ap;
+ const char *key, *format_string;
+ gboolean changed;
g_mutex_lock (&self->lock);
if (self->dead)
goto out;
- if (g_hash_table_lookup_extended (hash, qkey, NULL, &orig_value))
+ changed = FALSE;
+
+ va_start (ap, self);
+
+ for (key = va_arg (ap, const char *), format_string = va_arg (ap, const char *);
+ key != NULL;
+ key = va_arg (ap, const char *), format_string = va_arg (ap, const char *))
{
- if (orig_value == value)
+ GVariant *orig_value;
+ g_autoptr(GVariant) new_value = NULL;
+ gpointer qkey = GUINT_TO_POINTER (g_quark_from_string (key));
+
+ new_value = g_variant_ref_sink (g_variant_new_va (format_string, NULL, &ap));
+
+ if (g_hash_table_lookup_extended (self->values, qkey, NULL, (gpointer *) &orig_value) &&
+ g_variant_equal (orig_value, new_value))
+ continue;
+
+ g_hash_table_replace (self->values, qkey, g_steal_pointer (&new_value));
+ changed = TRUE;
+ }
+
+ va_end (ap);
+
+ if (changed)
+ ensure_callback_locked (self);
+
+out:
+ g_mutex_unlock (&self->lock);
+}
+
+/**
+ * ostree_async_progress_set_variant:
+ * @self: an #OstreeAsyncProgress
+ * @key: a key to set
+ * @value: the value to assign to @key
+ *
+ * Assign a new @value to the given @key, replacing any existing value. The
+ * operation is thread-safe. @value may be a floating reference;
+ * g_variant_ref_sink() will be called on it.
+ *
+ * Any watchers of the #OstreeAsyncProgress will be notified of the change if
+ * @value differs from the existing value for @key.
+ *
+ * Since: 2017.6
+ */
+void
+ostree_async_progress_set_variant (OstreeAsyncProgress *self,
+ const char *key,
+ GVariant *value)
+{
+ GVariant *orig_value;
+ g_autoptr(GVariant) new_value = g_variant_ref_sink (value);
+ gpointer qkey = GUINT_TO_POINTER (g_quark_from_string (key));
+
+ g_return_if_fail (OSTREE_IS_ASYNC_PROGRESS (self));
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (value != NULL);
+
+ g_mutex_lock (&self->lock);
+
+ if (self->dead)
+ goto out;
+
+ if (g_hash_table_lookup_extended (self->values, qkey, NULL, (gpointer *) &orig_value))
+ {
+ if (g_variant_equal (orig_value, new_value))
goto out;
}
- g_hash_table_replace (hash, qkey, value);
+ g_hash_table_replace (self->values, qkey, g_steal_pointer (&new_value));
ensure_callback_locked (self);
out:
@@ -235,7 +412,7 @@ ostree_async_progress_set_uint (OstreeAsyncProgress *self,
const char *key,
guint value)
{
- update_key (self, self->uint_values, key, GUINT_TO_POINTER (value));
+ ostree_async_progress_set_variant (self, key, g_variant_new_uint32 (value));
}
void
@@ -243,18 +420,7 @@ ostree_async_progress_set_uint64 (OstreeAsyncProgress *self,
const char *key,
guint64 value)
{
- gpointer valuep;
-
-#if _OSTREE_HAVE_LP64
- valuep = (gpointer)value;
-#else
- {
- guint64 *boxed = g_malloc (sizeof (guint64));
- *boxed = value;
- valuep = boxed;
- }
-#endif
- update_key (self, self->uint64_values, key, valuep);
+ ostree_async_progress_set_variant (self, key, g_variant_new_uint64 (value));
}
/**
diff --git a/src/libostree/ostree-async-progress.h b/src/libostree/ostree-async-progress.h
index ae0e5faa..55ac591c 100644
--- a/src/libostree/ostree-async-progress.h
+++ b/src/libostree/ostree-async-progress.h
@@ -53,17 +53,28 @@ OstreeAsyncProgress *ostree_async_progress_new_and_connect (void (*changed) (Ost
_OSTREE_PUBLIC
char *ostree_async_progress_get_status (OstreeAsyncProgress *self);
+_OSTREE_PUBLIC
+void ostree_async_progress_get (OstreeAsyncProgress *self,
+ ...) G_GNUC_NULL_TERMINATED;
+
_OSTREE_PUBLIC
guint ostree_async_progress_get_uint (OstreeAsyncProgress *self,
const char *key);
_OSTREE_PUBLIC
guint64 ostree_async_progress_get_uint64 (OstreeAsyncProgress *self,
const char *key);
+_OSTREE_PUBLIC
+GVariant *ostree_async_progress_get_variant (OstreeAsyncProgress *self,
+ const char *key);
_OSTREE_PUBLIC
void ostree_async_progress_set_status (OstreeAsyncProgress *self,
const char *status);
+_OSTREE_PUBLIC
+void ostree_async_progress_set (OstreeAsyncProgress *self,
+ ...) G_GNUC_NULL_TERMINATED;
+
_OSTREE_PUBLIC
void ostree_async_progress_set_uint (OstreeAsyncProgress *self,
const char *key,
@@ -72,6 +83,10 @@ _OSTREE_PUBLIC
void ostree_async_progress_set_uint64 (OstreeAsyncProgress *self,
const char *key,
guint64 value);
+_OSTREE_PUBLIC
+void ostree_async_progress_set_variant (OstreeAsyncProgress *self,
+ const char *key,
+ GVariant *value);
_OSTREE_PUBLIC
void ostree_async_progress_finish (OstreeAsyncProgress *self);
diff --git a/src/libostree/ostree-autocleanups.h b/src/libostree/ostree-autocleanups.h
index f030b50e..1fdb50ad 100644
--- a/src/libostree/ostree-autocleanups.h
+++ b/src/libostree/ostree-autocleanups.h
@@ -59,6 +59,10 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeSysrootUpgrader, g_object_unref)
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (OstreeRepoCommitTraverseIter, ostree_repo_commit_traverse_iter_clear)
+#ifdef OSTREE_ENABLE_EXPERIMENTAL_API
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRemote, ostree_remote_unref)
+#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */
+
#endif
G_END_DECLS
diff --git a/src/libostree/ostree-bootconfig-parser.c b/src/libostree/ostree-bootconfig-parser.c
index 8031334e..a7c473dd 100644
--- a/src/libostree/ostree-bootconfig-parser.c
+++ b/src/libostree/ostree-bootconfig-parser.c
@@ -79,23 +79,18 @@ ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- g_autofree char *contents = NULL;
- char **lines = NULL;
- char **iter = NULL;
-
g_return_val_if_fail (!self->parsed, FALSE);
- contents = glnx_file_get_contents_utf8_at (dfd, path, NULL, cancellable, error);
+ g_autofree char *contents = glnx_file_get_contents_utf8_at (dfd, path, NULL, cancellable, error);
if (!contents)
- goto out;
+ return FALSE;
- lines = g_strsplit (contents, "\n", -1);
- for (iter = lines; *iter; iter++)
+ g_auto(GStrv) lines = g_strsplit (contents, "\n", -1);
+ for (char **iter = lines; *iter; iter++)
{
const char *line = *iter;
char *keyname = "";
-
+
if (g_ascii_isalpha (*line))
{
char **items = NULL;
@@ -115,11 +110,8 @@ ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self,
}
self->parsed = TRUE;
-
- ret = TRUE;
- out:
- g_strfreev (lines);
- return ret;
+
+ return TRUE;
}
gboolean
@@ -166,16 +158,10 @@ ostree_bootconfig_parser_write_at (OstreeBootconfigParser *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- GHashTableIter hashiter;
- gpointer hashkey, hashvalue;
- GString *buf = g_string_new ("");
- guint i;
- g_autoptr(GHashTable) written_overrides = NULL;
+ g_autoptr(GString) buf = g_string_new ("");
+ g_autoptr(GHashTable) written_overrides = g_hash_table_new (g_str_hash, g_str_equal);
- written_overrides = g_hash_table_new (g_str_hash, g_str_equal);
-
- for (i = 0; i < self->lines->len; i++)
+ for (guint i = 0; i < self->lines->len; i++)
{
GVariant *linedata = self->lines->pdata[i];
const char *key;
@@ -197,6 +183,8 @@ ostree_bootconfig_parser_write_at (OstreeBootconfigParser *self,
}
}
+ GHashTableIter hashiter;
+ gpointer hashkey, hashvalue;
g_hash_table_iter_init (&hashiter, self->options);
while (g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue))
{
@@ -208,15 +196,11 @@ ostree_bootconfig_parser_write_at (OstreeBootconfigParser *self,
if (!glnx_file_replace_contents_at (dfd, path, (guint8*)buf->str, buf->len,
GLNX_FILE_REPLACE_NODATASYNC,
cancellable, error))
- goto out;
+ return FALSE;
- ret = TRUE;
- out:
- if (buf)
- g_string_free (buf, TRUE);
- return ret;
+ return TRUE;
}
-
+
gboolean
ostree_bootconfig_parser_write (OstreeBootconfigParser *self,
GFile *output,
diff --git a/src/libostree/ostree-bootloader-grub2.c b/src/libostree/ostree-bootloader-grub2.c
index 2cd02287..63e4b968 100644
--- a/src/libostree/ostree-bootloader-grub2.c
+++ b/src/libostree/ostree-bootloader-grub2.c
@@ -148,7 +148,7 @@ _ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot
GError **error)
{
gboolean ret = FALSE;
- GString *output = g_string_new ("");
+ g_autoptr(GString) output = g_string_new ("");
g_autoptr(GOutputStream) out_stream = NULL;
g_autoptr(GPtrArray) loader_configs = NULL;
guint i;
@@ -260,8 +260,6 @@ _ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot
ret = TRUE;
out:
- if (output)
- g_string_free (output, TRUE);
return ret;
}
diff --git a/src/libostree/ostree-cmdprivate.c b/src/libostree/ostree-cmdprivate.c
index 4367b497..bade7431 100644
--- a/src/libostree/ostree-cmdprivate.c
+++ b/src/libostree/ostree-cmdprivate.c
@@ -45,6 +45,7 @@ const OstreeCmdPrivateVTable *
ostree_cmd__private__ (void)
{
static OstreeCmdPrivateVTable table = {
+ _ostree_impl_system_generator,
impl_ostree_generate_grub2_config,
_ostree_repo_static_delta_dump,
_ostree_repo_static_delta_query_exists,
diff --git a/src/libostree/ostree-cmdprivate.h b/src/libostree/ostree-cmdprivate.h
index 8d1c653e..63c427cd 100644
--- a/src/libostree/ostree-cmdprivate.h
+++ b/src/libostree/ostree-cmdprivate.h
@@ -24,7 +24,10 @@
G_BEGIN_DECLS
+gboolean _ostree_impl_system_generator (const char *ostree_cmdline, const char *normal_dir, const char *early_dir, const char *late_dir, GError **error);
+
typedef struct {
+ gboolean (* ostree_system_generator) (const char *ostree_cmdline, const char *normal_dir, const char *early_dir, const char *late_dir, GError **error);
gboolean (* ostree_generate_grub2_config) (OstreeSysroot *sysroot, int bootversion, int target_fd, GCancellable *cancellable, GError **error);
gboolean (* ostree_static_delta_dump) (OstreeRepo *repo, const char *delta_id, GCancellable *cancellable, GError **error);
gboolean (* ostree_static_delta_query_exists) (OstreeRepo *repo, const char *delta_id, gboolean *out_exists, GCancellable *cancellable, GError **error);
diff --git a/src/libostree/ostree-core-private.h b/src/libostree/ostree-core-private.h
index a66a068f..72b88aba 100644
--- a/src/libostree/ostree-core-private.h
+++ b/src/libostree/ostree-core-private.h
@@ -90,6 +90,14 @@ _ostree_make_temporary_symlink_at (int tmp_dirfd,
GFileInfo * _ostree_header_gfile_info_new (mode_t mode, uid_t uid, gid_t gid);
+static inline void
+_ostree_checksum_inplace_from_bytes_v (GVariant *csum_v, char *buf)
+{
+ const guint8*csum = ostree_checksum_bytes_peek (csum_v);
+ g_assert (csum);
+ ostree_checksum_inplace_from_bytes (csum, buf);
+}
+
/* XX/checksum-2.extension, but let's just use 256 for a
* bit of overkill.
*/
diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c
index bab2ab33..7d2ed3c6 100644
--- a/src/libostree/ostree-core.c
+++ b/src/libostree/ostree-core.c
@@ -579,57 +579,45 @@ ostree_content_stream_parse (gboolean compressed,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
guint32 archive_header_size;
guchar dummy[4];
gsize bytes_read;
- g_autoptr(GInputStream) ret_input = NULL;
- g_autoptr(GFileInfo) ret_file_info = NULL;
- g_autoptr(GVariant) ret_xattrs = NULL;
- g_autoptr(GVariant) file_header = NULL;
- g_autofree guchar *buf = NULL;
if (!g_input_stream_read_all (input,
&archive_header_size, 4, &bytes_read,
cancellable, error))
- goto out;
+ return FALSE;
archive_header_size = GUINT32_FROM_BE (archive_header_size);
if (archive_header_size > input_length)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "File header size %u exceeds size %" G_GUINT64_FORMAT,
- (guint)archive_header_size, input_length);
- goto out;
- }
- if (archive_header_size == 0)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "File header size is zero");
- goto out;
- }
+ return glnx_throw (error, "File header size %u exceeds size %" G_GUINT64_FORMAT,
+ (guint)archive_header_size, input_length);
+ else if (archive_header_size == 0)
+ return glnx_throw (error, "File header size is zero");
/* Skip over padding */
if (!g_input_stream_read_all (input,
dummy, 4, &bytes_read,
cancellable, error))
- goto out;
+ return FALSE;
- buf = g_malloc (archive_header_size);
+ g_autofree guchar *buf = g_malloc (archive_header_size);
if (!g_input_stream_read_all (input, buf, archive_header_size, &bytes_read,
cancellable, error))
- goto out;
- file_header = g_variant_new_from_data (compressed ? _OSTREE_ZLIB_FILE_HEADER_GVARIANT_FORMAT : _OSTREE_FILE_HEADER_GVARIANT_FORMAT,
- buf, archive_header_size, trusted,
- g_free, buf);
+ return FALSE;
+ g_autoptr(GVariant) file_header =
+ g_variant_new_from_data (compressed ? _OSTREE_ZLIB_FILE_HEADER_GVARIANT_FORMAT : _OSTREE_FILE_HEADER_GVARIANT_FORMAT,
+ buf, archive_header_size, trusted,
+ g_free, buf);
buf = NULL;
-
+ g_autoptr(GFileInfo) ret_file_info = NULL;
+ g_autoptr(GVariant) ret_xattrs = NULL;
if (compressed)
{
if (!zlib_file_header_parse (file_header,
out_file_info ? &ret_file_info : NULL,
out_xattrs ? &ret_xattrs : NULL,
error))
- goto out;
+ return FALSE;
}
else
{
@@ -637,11 +625,12 @@ ostree_content_stream_parse (gboolean compressed,
out_file_info ? &ret_file_info : NULL,
out_xattrs ? &ret_xattrs : NULL,
error))
- goto out;
+ return FALSE;
if (ret_file_info)
g_file_info_set_size (ret_file_info, input_length - archive_header_size - 8);
}
-
+
+ g_autoptr(GInputStream) ret_input = NULL;
if (g_file_info_get_file_type (ret_file_info) == G_FILE_TYPE_REGULAR
&& out_input)
{
@@ -658,12 +647,10 @@ ostree_content_stream_parse (gboolean compressed,
ret_input = g_object_ref (input);
}
- ret = TRUE;
ot_transfer_out_value (out_input, &ret_input);
ot_transfer_out_value (out_file_info, &ret_file_info);
ot_transfer_out_value (out_xattrs, &ret_xattrs);
- out:
- return ret;
+ return TRUE;
}
/**
@@ -820,43 +807,39 @@ ostree_checksum_file (GFile *f,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- g_autoptr(GFileInfo) file_info = NULL;
- g_autoptr(GInputStream) in = NULL;
- g_autoptr(GVariant) xattrs = NULL;
- g_autofree guchar *ret_csum = NULL;
-
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return FALSE;
- file_info = g_file_query_info (f, OSTREE_GIO_FAST_QUERYINFO,
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
- cancellable, error);
+ g_autoptr(GFileInfo) file_info =
+ g_file_query_info (f, OSTREE_GIO_FAST_QUERYINFO,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ cancellable, error);
if (!file_info)
- goto out;
+ return FALSE;
+ g_autoptr(GInputStream) in = NULL;
if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
{
in = (GInputStream*)g_file_read (f, cancellable, error);
if (!in)
- goto out;
+ return FALSE;
}
+ g_autoptr(GVariant) xattrs = NULL;
if (objtype == OSTREE_OBJECT_TYPE_FILE)
{
if (!glnx_dfd_name_get_all_xattrs (AT_FDCWD, gs_file_get_path_cached (f),
&xattrs, cancellable, error))
- goto out;
+ return FALSE;
}
+ g_autofree guchar *ret_csum = NULL;
if (!ostree_checksum_file_from_input (file_info, xattrs, in, objtype,
&ret_csum, cancellable, error))
- goto out;
+ return FALSE;
- ret = TRUE;
ot_transfer_out_value(out_csum, &ret_csum);
- out:
- return ret;
+ return TRUE;
}
typedef struct {
@@ -1623,27 +1606,21 @@ file_header_parse (GVariant *metadata,
GVariant **out_xattrs,
GError **error)
{
- gboolean ret = FALSE;
guint32 uid, gid, mode, rdev;
const char *symlink_target;
- g_autoptr(GFileInfo) ret_file_info = NULL;
g_autoptr(GVariant) ret_xattrs = NULL;
g_variant_get (metadata, "(uuuu&s@a(ayay))",
&uid, &gid, &mode, &rdev,
&symlink_target, &ret_xattrs);
if (rdev != 0)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Corrupted archive file; invalid rdev %u", GUINT32_FROM_BE (rdev));
- goto out;
- }
+ return glnx_throw (error, "Corrupted archive file; invalid rdev %u", GUINT32_FROM_BE (rdev));
uid = GUINT32_FROM_BE (uid);
gid = GUINT32_FROM_BE (gid);
mode = GUINT32_FROM_BE (mode);
- ret_file_info = _ostree_header_gfile_info_new (mode, uid, gid);
+ g_autoptr(GFileInfo) ret_file_info = _ostree_header_gfile_info_new (mode, uid, gid);
if (S_ISREG (mode))
{
@@ -1655,16 +1632,12 @@ file_header_parse (GVariant *metadata,
}
else
{
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Corrupted archive file; invalid mode %u", mode);
- goto out;
+ return glnx_throw (error, "Corrupted archive file; invalid mode %u", mode);
}
- ret = TRUE;
ot_transfer_out_value(out_file_info, &ret_file_info);
ot_transfer_out_value(out_xattrs, &ret_xattrs);
- out:
- return ret;
+ return TRUE;
}
/*
@@ -1683,28 +1656,21 @@ zlib_file_header_parse (GVariant *metadata,
GVariant **out_xattrs,
GError **error)
{
- gboolean ret = FALSE;
guint64 size;
guint32 uid, gid, mode, rdev;
const char *symlink_target;
- g_autoptr(GFileInfo) ret_file_info = NULL;
g_autoptr(GVariant) ret_xattrs = NULL;
g_variant_get (metadata, "(tuuuu&s@a(ayay))", &size,
&uid, &gid, &mode, &rdev,
&symlink_target, &ret_xattrs);
if (rdev != 0)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Corrupted archive file; invalid rdev %u", GUINT32_FROM_BE (rdev));
- goto out;
- }
+ return glnx_throw (error, "Corrupted archive file; invalid rdev %u", GUINT32_FROM_BE (rdev));
uid = GUINT32_FROM_BE (uid);
gid = GUINT32_FROM_BE (gid);
mode = GUINT32_FROM_BE (mode);
- ret_file_info = _ostree_header_gfile_info_new (mode, uid, gid);
-
+ g_autoptr(GFileInfo) ret_file_info = _ostree_header_gfile_info_new (mode, uid, gid);
g_file_info_set_size (ret_file_info, GUINT64_FROM_BE (size));
if (S_ISREG (mode))
@@ -1717,16 +1683,12 @@ zlib_file_header_parse (GVariant *metadata,
}
else
{
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Corrupted archive file; invalid mode %u", mode);
- goto out;
+ return glnx_throw (error, "Corrupted archive file; invalid mode %u", mode);
}
- ret = TRUE;
ot_transfer_out_value(out_file_info, &ret_file_info);
ot_transfer_out_value(out_xattrs, &ret_xattrs);
- out:
- return ret;
+ return TRUE;
}
/**
@@ -1829,34 +1791,30 @@ gboolean
ostree_validate_structureof_commit (GVariant *commit,
GError **error)
{
- gboolean ret = FALSE;
- g_autoptr(GVariant) parent_csum_v = NULL;
- g_autoptr(GVariant) content_csum_v = NULL;
- g_autoptr(GVariant) metadata_csum_v = NULL;
- gsize n_elts;
-
if (!validate_variant (commit, OSTREE_COMMIT_GVARIANT_FORMAT, error))
- goto out;
+ return FALSE;
+ g_autoptr(GVariant) parent_csum_v = NULL;
g_variant_get_child (commit, 1, "@ay", &parent_csum_v);
+ gsize n_elts;
(void) g_variant_get_fixed_array (parent_csum_v, &n_elts, 1);
if (n_elts > 0)
{
if (!ostree_validate_structureof_csum_v (parent_csum_v, error))
- goto out;
+ return FALSE;
}
+ g_autoptr(GVariant) content_csum_v = NULL;
g_variant_get_child (commit, 6, "@ay", &content_csum_v);
if (!ostree_validate_structureof_csum_v (content_csum_v, error))
- goto out;
+ return FALSE;
+ g_autoptr(GVariant) metadata_csum_v = NULL;
g_variant_get_child (commit, 7, "@ay", &metadata_csum_v);
if (!ostree_validate_structureof_csum_v (metadata_csum_v, error))
- goto out;
+ return FALSE;
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/**
@@ -1873,14 +1831,13 @@ gboolean
ostree_validate_structureof_dirtree (GVariant *dirtree,
GError **error)
{
- gboolean ret = FALSE;
const char *filename;
g_autoptr(GVariant) content_csum_v = NULL;
g_autoptr(GVariant) meta_csum_v = NULL;
- GVariantIter *contents_iter = NULL;
+ g_autoptr(GVariantIter) contents_iter = NULL;
if (!validate_variant (dirtree, OSTREE_TREE_GVARIANT_FORMAT, error))
- goto out;
+ return FALSE;
g_variant_get_child (dirtree, 0, "a(say)", &contents_iter);
@@ -1888,10 +1845,13 @@ ostree_validate_structureof_dirtree (GVariant *dirtree,
&filename, &content_csum_v))
{
if (!ot_util_filename_validate (filename, error))
- goto out;
+ return FALSE;
if (!ostree_validate_structureof_csum_v (content_csum_v, error))
- goto out;
+ return FALSE;
}
+ /* Note we only use autoptr in case we broke out of the loop early;
+ * g_variant_iter_loop() has special semantics.
+ */
content_csum_v = NULL;
g_variant_iter_free (contents_iter);
@@ -1901,68 +1861,49 @@ ostree_validate_structureof_dirtree (GVariant *dirtree,
&filename, &content_csum_v, &meta_csum_v))
{
if (!ot_util_filename_validate (filename, error))
- goto out;
+ return FALSE;
if (!ostree_validate_structureof_csum_v (content_csum_v, error))
- goto out;
+ return FALSE;
if (!ostree_validate_structureof_csum_v (meta_csum_v, error))
- goto out;
+ return FALSE;
}
content_csum_v = NULL;
meta_csum_v = NULL;
- ret = TRUE;
- out:
- if (contents_iter)
- g_variant_iter_free (contents_iter);
- return ret;
+ return TRUE;
}
static gboolean
validate_stat_mode_perms (guint32 mode,
GError **error)
{
- gboolean ret = FALSE;
guint32 otherbits = (~S_IFMT & ~S_IRWXU & ~S_IRWXG & ~S_IRWXO &
~S_ISUID & ~S_ISGID & ~S_ISVTX);
if (mode & otherbits)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Invalid mode %u; invalid bits in mode", mode);
- goto out;
- }
+ return glnx_throw (error, "Invalid mode %u; invalid bits in mode", mode);
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/**
* ostree_validate_structureof_file_mode:
* @mode: A Unix filesystem mode
* @error: Error
- *
+ *
* Returns: %TRUE if @mode represents a valid file type and permissions
*/
gboolean
ostree_validate_structureof_file_mode (guint32 mode,
GError **error)
{
- gboolean ret = FALSE;
-
if (!(S_ISREG (mode) || S_ISLNK (mode)))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Invalid file metadata mode %u; not a valid file type", mode);
- goto out;
- }
+ return glnx_throw (error, "Invalid file metadata mode %u; not a valid file type", mode);
if (!validate_stat_mode_perms (mode, error))
- goto out;
+ return FALSE;
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/**
@@ -1978,28 +1919,21 @@ gboolean
ostree_validate_structureof_dirmeta (GVariant *dirmeta,
GError **error)
{
- gboolean ret = FALSE;
guint32 mode;
if (!validate_variant (dirmeta, OSTREE_DIRMETA_GVARIANT_FORMAT, error))
- goto out;
+ return FALSE;
g_variant_get_child (dirmeta, 2, "u", &mode);
mode = GUINT32_FROM_BE (mode);
if (!S_ISDIR (mode))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Invalid directory metadata mode %u; not a directory", mode);
- goto out;
- }
+ return glnx_throw (error, "Invalid directory metadata mode %u; not a directory", mode);
if (!validate_stat_mode_perms (mode, error))
- goto out;
+ return FALSE;
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/**
diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h
index b25112db..c530cea3 100644
--- a/src/libostree/ostree-core.h
+++ b/src/libostree/ostree-core.h
@@ -104,9 +104,9 @@ typedef enum {
/**
* OSTREE_DIRMETA_GVARIANT_FORMAT:
*
- * - u - uid
- * - u - gid
- * - u - mode
+ * - u - uid (big-endian)
+ * - u - gid (big-endian)
+ * - u - mode (big-endian)
* - a(ayay) - xattrs
*/
#define OSTREE_DIRMETA_GVARIANT_STRING "(uuua(ayay))"
@@ -120,9 +120,9 @@ typedef enum {
* can't store in the real filesystem but we can still use a regular .file object
* that we can hardlink to in the case of a user-mode checkout.
*
- * - u - uid
- * - u - gid
- * - u - mode
+ * - u - uid (big-endian)
+ * - u - gid (big-endian)
+ * - u - mode (big-endian)
* - a(ayay) - xattrs
*/
#define OSTREE_FILEMETA_GVARIANT_STRING "(uuua(ayay))"
@@ -145,7 +145,7 @@ typedef enum {
* - a(say) - Related objects
* - s - subject
* - s - body
- * - t - Timestamp in seconds since the epoch (UTC)
+ * - t - Timestamp in seconds since the epoch (UTC, big-endian)
* - ay - Root tree contents
* - ay - Root tree metadata
*/
@@ -158,6 +158,17 @@ typedef enum {
* - a(s(taya{sv})) - Map of ref name -> (latest commit size, latest commit checksum, additional metadata), sorted by ref name
* - a{sv} - Additional metadata, at the current time the following are defined:
* - key: "ostree.static-deltas", value: a{sv}, static delta name -> 32 bytes of checksum
+ * - key: "ostree.summary.last-modified", value: t, timestamp (seconds since
+ * the Unix epoch in UTC, big-endian) when the summary was last regenerated
+ * (similar to the HTTP `Last-Modified` header)
+ * - key: "ostree.summary.expires", value: t, timestamp (seconds since the
+ * Unix epoch in UTC, big-endian) after which the summary is considered
+ * stale and should be re-downloaded if possible (similar to the HTTP
+ * `Expires` header)
+ *
+ * The currently defined keys for the `a{sv}` of additional metadata for each commit are:
+ * - key: `ostree.commit.timestamp`, value: `t`, timestamp (seconds since the
+ * Unix epoch in UTC, big-endian) when the commit was committed
*/
#define OSTREE_SUMMARY_GVARIANT_STRING "(a(s(taya{sv}))a{sv})"
#define OSTREE_SUMMARY_GVARIANT_FORMAT G_VARIANT_TYPE (OSTREE_SUMMARY_GVARIANT_STRING)
diff --git a/src/libostree/ostree-deployment.c b/src/libostree/ostree-deployment.c
index 67e896bf..8bdc9b57 100644
--- a/src/libostree/ostree-deployment.c
+++ b/src/libostree/ostree-deployment.c
@@ -39,6 +39,12 @@ ostree_deployment_get_bootcsum (OstreeDeployment *self)
return self->bootcsum;
}
+/*
+ * ostree_deployment_get_osname:
+ * @self: Deployemnt
+ *
+ * Returns: The "stateroot" name, also known as an "osname"
+ */
const char *
ostree_deployment_get_osname (OstreeDeployment *self)
{
diff --git a/src/libostree/ostree-diff.c b/src/libostree/ostree-diff.c
index b428fb44..f21b0302 100644
--- a/src/libostree/ostree-diff.c
+++ b/src/libostree/ostree-diff.c
@@ -35,9 +35,7 @@ get_file_checksum (OstreeDiffFlags flags,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
g_autofree char *ret_checksum = NULL;
- g_autofree guchar *csum = NULL;
if (OSTREE_IS_REPO_FILE (f))
{
@@ -52,27 +50,26 @@ get_file_checksum (OstreeDiffFlags flags,
{
if (!glnx_dfd_name_get_all_xattrs (AT_FDCWD, gs_file_get_path_cached (f),
&xattrs, cancellable, error))
- goto out;
+ return FALSE;
}
if (g_file_info_get_file_type (f_info) == G_FILE_TYPE_REGULAR)
{
in = (GInputStream*)g_file_read (f, cancellable, error);
if (!in)
- goto out;
+ return FALSE;
}
+ g_autofree guchar *csum = NULL;
if (!ostree_checksum_file_from_input (f_info, xattrs, in,
OSTREE_OBJECT_TYPE_FILE,
&csum, cancellable, error))
- goto out;
+ return FALSE;
ret_checksum = ostree_checksum_from_bytes (csum);
}
- ret = TRUE;
ot_transfer_out_value(out_checksum, &ret_checksum);
- out:
- return ret;
+ return TRUE;
}
OstreeDiffItem *
@@ -130,28 +127,22 @@ diff_files (OstreeDiffFlags flags,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
g_autofree char *checksum_a = NULL;
g_autofree char *checksum_b = NULL;
- OstreeDiffItem *ret_item = NULL;
-
if (!get_file_checksum (flags, a, a_info, &checksum_a, cancellable, error))
- goto out;
+ return FALSE;
if (!get_file_checksum (flags, b, b_info, &checksum_b, cancellable, error))
- goto out;
+ return FALSE;
+ g_autoptr(OstreeDiffItem) ret_item = NULL;
if (strcmp (checksum_a, checksum_b) != 0)
{
ret_item = diff_item_new (a, a_info, b, b_info,
checksum_a, checksum_b);
}
- ret = TRUE;
ot_transfer_out_value(out_item, &ret_item);
- out:
- if (ret_item)
- ostree_diff_item_unref (ret_item);
- return ret;
+ return TRUE;
}
static gboolean
@@ -160,47 +151,38 @@ diff_add_dir_recurse (GFile *d,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- GError *temp_error = NULL;
- g_autoptr(GFileEnumerator) dir_enum = NULL;
- g_autoptr(GFile) child = NULL;
- g_autoptr(GFileInfo) child_info = NULL;
-
- dir_enum = g_file_enumerate_children (d, OSTREE_GIO_FAST_QUERYINFO,
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
- cancellable,
- error);
+ g_autoptr(GFileEnumerator) dir_enum =
+ g_file_enumerate_children (d, OSTREE_GIO_FAST_QUERYINFO,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ cancellable,
+ error);
if (!dir_enum)
- goto out;
+ return FALSE;
- while ((child_info = g_file_enumerator_next_file (dir_enum, cancellable, &temp_error)) != NULL)
+ while (TRUE)
{
+ GFileInfo *child_info;
const char *name;
+ if (!g_file_enumerator_iterate (dir_enum, &child_info, NULL,
+ cancellable, error))
+ return FALSE;
+ if (child_info == NULL)
+ break;
+
name = g_file_info_get_name (child_info);
- g_clear_object (&child);
- child = g_file_get_child (d, name);
-
+ g_autoptr(GFile) child = g_file_get_child (d, name);
g_ptr_array_add (added, g_object_ref (child));
if (g_file_info_get_file_type (child_info) == G_FILE_TYPE_DIRECTORY)
{
if (!diff_add_dir_recurse (child, added, cancellable, error))
- goto out;
+ return FALSE;
}
-
- g_clear_object (&child_info);
- }
- if (temp_error != NULL)
- {
- g_propagate_error (error, temp_error);
- goto out;
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/**
diff --git a/src/libostree/ostree-fetcher-curl.c b/src/libostree/ostree-fetcher-curl.c
index 829f4447..f6893fd0 100644
--- a/src/libostree/ostree-fetcher-curl.c
+++ b/src/libostree/ostree-fetcher-curl.c
@@ -272,7 +272,7 @@ ensure_tmpfile (FetcherRequest *req, GError **error)
if (req->out_tmpfile_fd == -1)
{
if (!glnx_open_tmpfile_linkable_at (req->fetcher->tmpdir_dfd, ".",
- O_WRONLY, &req->out_tmpfile_fd,
+ O_WRONLY | O_CLOEXEC, &req->out_tmpfile_fd,
&req->out_tmpfile,
error))
return FALSE;
diff --git a/src/libostree/ostree-gpg-verifier.c b/src/libostree/ostree-gpg-verifier.c
index eda05e9a..59028821 100644
--- a/src/libostree/ostree-gpg-verifier.c
+++ b/src/libostree/ostree-gpg-verifier.c
@@ -116,7 +116,7 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
if (result == NULL)
goto out;
- if (!ot_gpgme_ctx_tmp_home_dir (result->context, NULL,
+ if (!ot_gpgme_ctx_tmp_home_dir (result->context,
&tmp_dir, &target_stream,
cancellable, error))
goto out;
diff --git a/src/libostree/ostree-gpg-verify-result.c b/src/libostree/ostree-gpg-verify-result.c
index 73fbfeed..cd709b7c 100644
--- a/src/libostree/ostree-gpg-verify-result.c
+++ b/src/libostree/ostree-gpg-verify-result.c
@@ -562,6 +562,14 @@ ostree_gpg_verify_result_describe_variant (GVariant *variant,
key_id = (len > 16) ? fingerprint + len - 16 : fingerprint;
date_time_utc = g_date_time_new_from_unix_utc (timestamp);
+ if (date_time_utc == NULL)
+ {
+ g_string_append_printf (output_buffer,
+ "Can't check signature: timestamp %" G_GINT64_FORMAT " is invalid\n",
+ timestamp);
+ return;
+ }
+
date_time_local = g_date_time_to_local (date_time_utc);
formatted_date_time = g_date_time_format (date_time_local, "%c");
@@ -606,6 +614,14 @@ ostree_gpg_verify_result_describe_variant (GVariant *variant,
if (exp_timestamp > 0)
{
date_time_utc = g_date_time_new_from_unix_utc (exp_timestamp);
+ if (date_time_utc == NULL)
+ {
+ g_string_append_printf (output_buffer,
+ "Signature expiry timestamp (%" G_GINT64_FORMAT ") is invalid\n",
+ exp_timestamp);
+ return;
+ }
+
date_time_local = g_date_time_to_local (date_time_utc);
formatted_date_time = g_date_time_format (date_time_local, "%c");
diff --git a/src/libostree/ostree-impl-system-generator.c b/src/libostree/ostree-impl-system-generator.c
new file mode 100644
index 00000000..72f52bc5
--- /dev/null
+++ b/src/libostree/ostree-impl-system-generator.c
@@ -0,0 +1,229 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2017 Colin Walters
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include
+#include
+#include
+#include
+#ifdef HAVE_LIBMOUNT
+#include
+#endif
+#include
+#include "otutil.h"
+
+#include "ostree.h"
+#include "ostree-core-private.h"
+#include "ostree-cmdprivate.h"
+
+#ifdef HAVE_LIBMOUNT
+typedef FILE OtLibMountFile;
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtLibMountFile, endmntent);
+
+/* Taken from systemd path-util.c */
+static bool
+is_path (const char *p)
+{
+ return !!strchr (p, '/');
+}
+
+/* Taken from systemd path-util.c */
+static char*
+path_kill_slashes (char *path)
+{
+ char *f, *t;
+ bool slash = false;
+
+ /* Removes redundant inner and trailing slashes. Modifies the
+ * passed string in-place.
+ *
+ * For example: ///foo///bar/ becomes /foo/bar
+ */
+
+ for (f = path, t = path; *f; f++)
+ {
+ if (*f == '/')
+ {
+ slash = true;
+ continue;
+ }
+
+ if (slash)
+ {
+ slash = false;
+ *(t++) = '/';
+ }
+
+ *(t++) = *f;
+ }
+
+ /* Special rule, if we are talking of the root directory, a
+ trailing slash is good */
+
+ if (t == path && slash)
+ *(t++) = '/';
+
+ *t = 0;
+ return path;
+}
+
+/* Written by ostree-sysroot-deploy.c. We parse out the stateroot here since we
+ * need to know it to mount /var. Unfortunately we can't easily use the
+ * libostree API to find the booted deployment since /boot might not have been
+ * mounted yet.
+ */
+static char *
+stateroot_from_ostree_cmdline (const char *ostree_cmdline,
+ GError **error)
+{
+ static GRegex *regex;
+ static gsize regex_initialized;
+ if (g_once_init_enter (®ex_initialized))
+ {
+ regex = g_regex_new ("^/ostree/boot.[01]/([^/]+)/", 0, 0, NULL);
+ g_assert (regex);
+ g_once_init_leave (®ex_initialized, 1);
+ }
+
+ g_autoptr(GMatchInfo) match = NULL;
+ if (!g_regex_match (regex, ostree_cmdline, 0, &match))
+ return glnx_null_throw (error, "Failed to parse %s", ostree_cmdline);
+
+ return g_match_info_fetch (match, 1);
+}
+#endif
+
+/* Implementation of ostree-system-generator */
+gboolean
+_ostree_impl_system_generator (const char *ostree_cmdline,
+ 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 */
+ GCancellable *cancellable = NULL;
+ /* Some path constants to avoid typos */
+ static const char fstab_path[] = "/etc/fstab";
+ static const char var_path[] = "/var";
+
+ /* ostree-prepare-root was patched to write the stateroot to this file */
+ g_autofree char *stateroot = stateroot_from_ostree_cmdline (ostree_cmdline, error);
+ if (!stateroot)
+ return FALSE;
+
+ /* Load /etc/fstab if it exists, and look for a /var mount */
+ g_autoptr(OtLibMountFile) fstab = setmntent (fstab_path, "re");
+ gboolean found_var_mnt = FALSE;
+ if (!fstab)
+ {
+ if (errno != ENOENT)
+ return glnx_throw_errno_prefix (error, "Reading %s", fstab_path);
+ }
+ else
+ {
+ /* Parse it */
+ struct mntent *me;
+ while ((me = getmntent (fstab)))
+ {
+ g_autofree char *where = g_strdup (me->mnt_dir);
+ if (is_path (where))
+ path_kill_slashes (where);
+
+ /* We're only looking for /var here */
+ if (strcmp (where, var_path) != 0)
+ continue;
+
+ found_var_mnt = TRUE;
+ break;
+ }
+ }
+
+ /* If we found /var, we're done */
+ if (found_var_mnt)
+ return TRUE;
+
+ /* Prepare to write to the output unit dir; we use the "normal" dir
+ * that overrides /usr, but not /etc.
+ */
+ glnx_fd_close int normal_dir_dfd = -1;
+ if (!glnx_opendirat (AT_FDCWD, normal_dir, TRUE, &normal_dir_dfd, error))
+ return FALSE;
+
+ /* Generate our bind mount unit */
+ const char *stateroot_var_path = glnx_strjoina ("/sysroot/ostree/deploy/", stateroot, "/var");
+
+ glnx_fd_close int tmpfd = -1;
+ g_autofree char *tmppath = NULL;
+ if (!glnx_open_tmpfile_linkable_at (normal_dir_dfd, ".", O_WRONLY | O_CLOEXEC,
+ &tmpfd, &tmppath, error))
+ return FALSE;
+ g_autoptr(GOutputStream) outstream = g_unix_output_stream_new (tmpfd, FALSE);
+ gsize bytes_written;
+ /* This code is inspired by systemd's fstab-generator.c.
+ *
+ * Note that our unit doesn't run if systemd.volatile is enabled;
+ * see https://github.com/ostreedev/ostree/pull/856
+ */
+ if (!g_output_stream_printf (outstream, &bytes_written, cancellable, error,
+ "##\n# Automatically generated by ostree-system-generator\n##\n\n"
+ "[Unit]\n"
+ "Documentation=man:ostree(1)\n"
+ "ConditionKernelCommandLine=!systemd.volatile\n"
+ /* We need /sysroot mounted writable first */
+ "After=ostree-remount.service\n"
+ "Before=local-fs.target\n"
+ "\n"
+ "[Mount]\n"
+ "Where=%s\n"
+ "What=%s\n"
+ "Options=bind\n",
+ var_path,
+ stateroot_var_path))
+ return FALSE;
+ if (!g_output_stream_flush (outstream, cancellable, error))
+ return FALSE;
+ g_clear_object (&outstream);
+ /* It should be readable */
+ if (fchmod (tmpfd, 0644) < 0)
+ return glnx_throw_errno_prefix (error, "fchmod");
+ /* Error out if somehow it already exists, that'll help us debug conflicts */
+ if (!glnx_link_tmpfile_at (normal_dir_dfd, GLNX_LINK_TMPFILE_NOREPLACE,
+ tmpfd, tmppath, normal_dir_dfd,
+ "var.mount", error))
+ return FALSE;
+
+ /* And ensure it's required; newer systemd will auto-inject fs dependencies
+ * via RequiresMountsFor and the like, but on older versions (e.g. CentOS) we
+ * need this. It's what the fstab generator does. And my mother always said,
+ * listen to the fstab generator.
+ */
+ if (!glnx_shutil_mkdir_p_at (normal_dir_dfd, "local-fs.target.requires", 0755, cancellable, error))
+ return FALSE;
+ if (symlinkat ("../var.mount", normal_dir_dfd, "local-fs.target.requires/var.mount") < 0)
+ return glnx_throw_errno_prefix (error, "symlinkat");
+
+ return TRUE;
+#else
+ return glnx_throw (error, "Not implemented");
+#endif
+}
diff --git a/src/libostree/ostree-remote-private.h b/src/libostree/ostree-remote-private.h
new file mode 100644
index 00000000..e207ed4c
--- /dev/null
+++ b/src/libostree/ostree-remote-private.h
@@ -0,0 +1,59 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright © 2011 Colin Walters
+ * Copyright © 2015 Red Hat, Inc.
+ * Copyright © 2017 Endless Mobile, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * - Colin Walters
+ * - Philip Withnall
+ */
+
+#pragma once
+
+#include
+#include
+#include
+
+#include "libglnx.h"
+#include "ostree-remote.h"
+#include "ostree-types.h"
+
+G_BEGIN_DECLS
+
+struct OstreeRemote {
+ volatile int ref_count;
+ char *name;
+ char *group; /* group name in options */
+ char *keyring; /* keyring name (NAME.trustedkeys.gpg) */
+ GFile *file; /* NULL if remote defined in repo/config */
+ GKeyFile *options;
+};
+
+G_GNUC_INTERNAL
+OstreeRemote *ostree_remote_new (void);
+
+G_GNUC_INTERNAL
+OstreeRemote *ostree_remote_new_from_keyfile (GKeyFile *keyfile,
+ const gchar *group);
+
+#if (defined(OSTREE_COMPILATION) || GLIB_CHECK_VERSION(2, 44, 0)) && !defined(OSTREE_ENABLE_EXPERIMENTAL_API)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRemote, ostree_remote_unref)
+#endif
+
+G_END_DECLS
diff --git a/src/libostree/ostree-remote.c b/src/libostree/ostree-remote.c
new file mode 100644
index 00000000..86fae8d8
--- /dev/null
+++ b/src/libostree/ostree-remote.c
@@ -0,0 +1,150 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright © 2011 Colin Walters
+ * Copyright © 2015 Red Hat, Inc.
+ * Copyright © 2017 Endless Mobile, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * - Colin Walters
+ * - Philip Withnall
+ */
+
+#include "config.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#include "ostree-remote.h"
+#include "ostree-remote-private.h"
+#include "ot-keyfile-utils.h"
+
+/**
+ * SECTION:remote
+ *
+ * The #OstreeRemote structure represents the configuration for a single remote
+ * repository. Currently, all configuration is handled internally, and
+ * #OstreeRemote objects are represented by their textual name handle, or by an
+ * opaque pointer (which can be reference counted if needed).
+ *
+ * #OstreeRemote provides configuration for accessing a remote, but does not
+ * provide the results of accessing a remote, such as information about what
+ * refs are currently on a remote, or the commits they currently point to. Use
+ * #OstreeRepo in combination with an #OstreeRemote to query that information.
+ *
+ * Since: 2017.6
+ */
+
+OstreeRemote *
+ostree_remote_new (void)
+{
+ OstreeRemote *remote;
+
+ remote = g_slice_new0 (OstreeRemote);
+ remote->ref_count = 1;
+ remote->options = g_key_file_new ();
+
+ return remote;
+}
+
+OstreeRemote *
+ostree_remote_new_from_keyfile (GKeyFile *keyfile,
+ const gchar *group)
+{
+ g_autoptr(GMatchInfo) match = NULL;
+ OstreeRemote *remote;
+
+ static gsize regex_initialized;
+ static GRegex *regex;
+
+ if (g_once_init_enter (®ex_initialized))
+ {
+ regex = g_regex_new ("^remote \"(.+)\"$", 0, 0, NULL);
+ g_assert (regex);
+ g_once_init_leave (®ex_initialized, 1);
+ }
+
+ /* Sanity check */
+ g_return_val_if_fail (g_key_file_has_group (keyfile, group), NULL);
+
+ /* If group name doesn't fit the pattern, fail. */
+ if (!g_regex_match (regex, group, 0, &match))
+ return NULL;
+
+ remote = ostree_remote_new ();
+ remote->name = g_match_info_fetch (match, 1);
+ remote->group = g_strdup (group);
+ remote->keyring = g_strdup_printf ("%s.trustedkeys.gpg", remote->name);
+
+ ot_keyfile_copy_group (keyfile, remote->options, group);
+
+ return remote;
+}
+
+/**
+ * ostree_remote_ref:
+ * @remote: an #OstreeRemote
+ *
+ * Increase the reference count on the given @remote.
+ *
+ * Returns: (transfer full): a copy of @remote, for convenience
+ * Since: 2017.6
+ */
+OstreeRemote *
+ostree_remote_ref (OstreeRemote *remote)
+{
+ gint refcount;
+ g_return_val_if_fail (remote != NULL, NULL);
+ refcount = g_atomic_int_add (&remote->ref_count, 1);
+ g_assert (refcount > 0);
+ return remote;
+}
+
+/**
+ * ostree_remote_unref:
+ * @remote: (transfer full): an #OstreeRemote
+ *
+ * Decrease the reference count on the given @remote and free it if the
+ * reference count reaches 0.
+ *
+ * Since: 2017.6
+ */
+void
+ostree_remote_unref (OstreeRemote *remote)
+{
+ g_return_if_fail (remote != NULL);
+ g_return_if_fail (remote->ref_count > 0);
+
+ if (g_atomic_int_dec_and_test (&remote->ref_count))
+ {
+ g_clear_pointer (&remote->name, g_free);
+ g_clear_pointer (&remote->group, g_free);
+ g_clear_pointer (&remote->keyring, g_free);
+ g_clear_object (&remote->file);
+ g_clear_pointer (&remote->options, g_key_file_free);
+ g_slice_free (OstreeRemote, remote);
+ }
+}
+
+#ifdef OSTREE_ENABLE_EXPERIMENTAL_API
+G_DEFINE_BOXED_TYPE(OstreeRemote, ostree_remote,
+ ostree_remote_ref,
+ ostree_remote_unref);
+#endif
diff --git a/src/libostree/ostree-remote.h b/src/libostree/ostree-remote.h
new file mode 100644
index 00000000..8e96213c
--- /dev/null
+++ b/src/libostree/ostree-remote.h
@@ -0,0 +1,63 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright © 2011 Colin Walters
+ * Copyright © 2015 Red Hat, Inc.
+ * Copyright © 2017 Endless Mobile, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * - Colin Walters
+ * - Philip Withnall
+ */
+
+#pragma once
+
+#include
+#include
+#include
+
+#include "ostree-types.h"
+
+G_BEGIN_DECLS
+
+/**
+ * OstreeRemote:
+ *
+ * This represents the configuration for a single remote repository. Currently,
+ * remotes can only be passed around as (reference counted) opaque handles. In
+ * future, more API may be added to create and interrogate them.
+ *
+ * Since: 2016.7
+ */
+#ifndef OSTREE_ENABLE_EXPERIMENTAL_API
+/* This is in ostree-types.h otherwise */
+typedef struct OstreeRemote OstreeRemote;
+#endif
+
+#ifdef OSTREE_ENABLE_EXPERIMENTAL_API
+_OSTREE_PUBLIC
+GType ostree_remote_get_type (void) G_GNUC_CONST;
+#else
+#ifndef __GI_SCANNER__
+_OSTREE_PUBLIC
+OstreeRemote *ostree_remote_ref (OstreeRemote *remote);
+_OSTREE_PUBLIC
+void ostree_remote_unref (OstreeRemote *remote);
+#endif /* GI_SCANNER */
+#endif
+
+G_END_DECLS
diff --git a/src/libostree/ostree-repo-checkout.c b/src/libostree/ostree-repo-checkout.c
index 71511824..f6e91498 100644
--- a/src/libostree/ostree-repo-checkout.c
+++ b/src/libostree/ostree-repo-checkout.c
@@ -29,11 +29,25 @@
#include "otutil.h"
#include "ostree-repo-file.h"
+#include "ostree-sepolicy-private.h"
#include "ostree-core-private.h"
#include "ostree-repo-private.h"
#define WHITEOUT_PREFIX ".wh."
+/* Per-checkout call state/caching */
+typedef struct {
+ GString *selabel_path_buf;
+} CheckoutState;
+
+static void
+checkout_state_clear (CheckoutState *state)
+{
+ if (state->selabel_path_buf)
+ g_string_free (state->selabel_path_buf, TRUE);
+}
+G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(CheckoutState, checkout_state_clear);
+
static gboolean
checkout_object_for_uncompressed_cache (OstreeRepo *self,
const char *loose_path,
@@ -42,64 +56,48 @@ checkout_object_for_uncompressed_cache (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- g_autofree char *temp_filename = NULL;
- g_autoptr(GOutputStream) temp_out = NULL;
- glnx_fd_close int fd = -1;
- int res;
- guint32 file_mode;
-
/* Don't make setuid files in uncompressed cache */
- file_mode = g_file_info_get_attribute_uint32 (src_info, "unix::mode");
+ guint32 file_mode = g_file_info_get_attribute_uint32 (src_info, "unix::mode");
file_mode &= ~(S_ISUID|S_ISGID);
+ glnx_fd_close int fd = -1;
+ g_autofree char *temp_filename = NULL;
if (!glnx_open_tmpfile_linkable_at (self->tmp_dir_fd, ".", O_WRONLY | O_CLOEXEC,
&fd, &temp_filename,
error))
- goto out;
- temp_out = g_unix_output_stream_new (fd, FALSE);
+ return FALSE;
+ g_autoptr(GOutputStream) temp_out = g_unix_output_stream_new (fd, FALSE);
if (g_output_stream_splice (temp_out, content, 0, cancellable, error) < 0)
- goto out;
+ return FALSE;
if (!g_output_stream_flush (temp_out, cancellable, error))
- goto out;
+ return FALSE;
if (!self->disable_fsync)
{
- do
- res = fsync (fd);
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (G_UNLIKELY (res == -1))
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ if (TEMP_FAILURE_RETRY (fsync (fd)) < 0)
+ return glnx_throw_errno (error);
}
if (!g_output_stream_close (temp_out, cancellable, error))
- goto out;
+ return FALSE;
if (fchmod (fd, file_mode) < 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno (error);
if (!_ostree_repo_ensure_loose_objdir_at (self->uncompressed_objects_dir_fd,
loose_path,
cancellable, error))
- goto out;
+ return FALSE;
if (!glnx_link_tmpfile_at (self->tmp_dir_fd, GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST,
fd, temp_filename,
self->uncompressed_objects_dir_fd, loose_path,
error))
- goto out;
+ return FALSE;
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
static gboolean
@@ -112,209 +110,151 @@ fsync_is_enabled (OstreeRepo *self,
static gboolean
write_regular_file_content (OstreeRepo *self,
OstreeRepoCheckoutAtOptions *options,
- GOutputStream *output,
+ int outfd,
GFileInfo *file_info,
GVariant *xattrs,
GInputStream *input,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
const OstreeRepoCheckoutMode mode = options->mode;
- int fd;
- int res;
+ g_autoptr(GOutputStream) outstream = NULL;
- if (g_output_stream_splice (output, input, 0,
- cancellable, error) < 0)
- goto out;
+ if (G_IS_FILE_DESCRIPTOR_BASED (input))
+ {
+ int infd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*) input);
+ guint64 len = g_file_info_get_size (file_info);
- if (!g_output_stream_flush (output, cancellable, error))
- goto out;
+ if (glnx_regfile_copy_bytes (infd, outfd, (off_t)len, TRUE) < 0)
+ return glnx_throw_errno_prefix (error, "regfile copy");
+ }
+ else
+ {
+ outstream = g_unix_output_stream_new (outfd, FALSE);
+ if (g_output_stream_splice (outstream, input, 0,
+ cancellable, error) < 0)
+ return FALSE;
- fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)output);
+ if (!g_output_stream_flush (outstream, cancellable, error))
+ return FALSE;
+ }
if (mode != OSTREE_REPO_CHECKOUT_MODE_USER)
{
- do
- res = fchown (fd,
- g_file_info_get_attribute_uint32 (file_info, "unix::uid"),
- g_file_info_get_attribute_uint32 (file_info, "unix::gid"));
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (G_UNLIKELY (res == -1))
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ if (TEMP_FAILURE_RETRY (fchown (outfd, g_file_info_get_attribute_uint32 (file_info, "unix::uid"),
+ g_file_info_get_attribute_uint32 (file_info, "unix::gid"))) < 0)
+ return glnx_throw_errno (error);
+
+ if (TEMP_FAILURE_RETRY (fchmod (outfd, g_file_info_get_attribute_uint32 (file_info, "unix::mode"))) < 0)
+ return glnx_throw_errno (error);
- do
- res = fchmod (fd, g_file_info_get_attribute_uint32 (file_info, "unix::mode"));
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (G_UNLIKELY (res == -1))
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
-
if (xattrs)
{
- if (!glnx_fd_set_all_xattrs (fd, xattrs, cancellable, error))
- goto out;
+ if (!glnx_fd_set_all_xattrs (outfd, xattrs, cancellable, error))
+ return FALSE;
}
}
-
+
if (fsync_is_enabled (self, options))
{
- if (fsync (fd) == -1)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ if (fsync (outfd) == -1)
+ return glnx_throw_errno (error);
}
-
- if (!g_output_stream_close (output, cancellable, error))
- goto out;
- ret = TRUE;
- out:
- return ret;
-}
-
-static gboolean
-checkout_file_from_input_at (OstreeRepo *self,
- OstreeRepoCheckoutAtOptions *options,
- GFileInfo *file_info,
- GVariant *xattrs,
- GInputStream *input,
- int destination_dfd,
- const char *destination_name,
- GCancellable *cancellable,
- GError **error)
-{
- gboolean ret = FALSE;
- int res;
-
- if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_SYMBOLIC_LINK)
+ if (outstream)
{
- do
- res = symlinkat (g_file_info_get_symlink_target (file_info),
- destination_dfd, destination_name);
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (res == -1)
- {
- if (errno == EEXIST && options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES)
- {
- ret = TRUE;
- goto out;
- }
- else
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
- }
-
- if (options->mode != OSTREE_REPO_CHECKOUT_MODE_USER)
- {
- if (G_UNLIKELY (fchownat (destination_dfd, destination_name,
- g_file_info_get_attribute_uint32 (file_info, "unix::uid"),
- g_file_info_get_attribute_uint32 (file_info, "unix::gid"),
- AT_SYMLINK_NOFOLLOW) == -1))
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
-
- if (xattrs)
- {
- if (!glnx_dfd_name_set_all_xattrs (destination_dfd, destination_name,
- xattrs, cancellable, error))
- goto out;
- }
- }
+ if (!g_output_stream_close (outstream, cancellable, error))
+ return FALSE;
}
- else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
- {
- g_autoptr(GOutputStream) temp_out = NULL;
- int fd;
- guint32 file_mode;
- file_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
- /* Don't make setuid files on checkout when we're doing --user */
- if (options->mode == OSTREE_REPO_CHECKOUT_MODE_USER)
- file_mode &= ~(S_ISUID|S_ISGID);
-
- do
- fd = openat (destination_dfd, destination_name, O_WRONLY | O_CREAT | O_EXCL, file_mode);
- while (G_UNLIKELY (fd == -1 && errno == EINTR));
- if (fd == -1)
- {
- if (errno == EEXIST && options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES)
- {
- ret = TRUE;
- goto out;
- }
- glnx_set_error_from_errno (error);
- goto out;
- }
- temp_out = g_unix_output_stream_new (fd, TRUE);
- fd = -1; /* Transfer ownership */
-
- if (!write_regular_file_content (self, options, temp_out, file_info, xattrs, input,
- cancellable, error))
- goto out;
- }
- else
- g_assert_not_reached ();
-
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/*
- * This function creates a file under a temporary name, then rename()s
- * it into place. This implements union-like behavior.
+ * Create a copy of a file, supporting optional union/add behavior.
*/
static gboolean
-checkout_file_unioning_from_input_at (OstreeRepo *repo,
- OstreeRepoCheckoutAtOptions *options,
- GFileInfo *file_info,
- GVariant *xattrs,
- GInputStream *input,
- int destination_dfd,
- const char *destination_name,
- GCancellable *cancellable,
- GError **error)
+create_file_copy_from_input_at (OstreeRepo *repo,
+ OstreeRepoCheckoutAtOptions *options,
+ CheckoutState *state,
+ GFileInfo *file_info,
+ GVariant *xattrs,
+ GInputStream *input,
+ int destination_dfd,
+ const char *destination_name,
+ GCancellable *cancellable,
+ GError **error)
{
- gboolean ret = FALSE;
g_autofree char *temp_filename = NULL;
+ const gboolean union_mode = options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES;
+ const gboolean add_mode = options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES;
+ const gboolean sepolicy_enabled = options->sepolicy && !repo->disable_xattrs;
+ g_autoptr(GVariant) modified_xattrs = NULL;
+
+ /* If we're doing SELinux labeling, prepare it */
+ if (sepolicy_enabled)
+ {
+ /* If doing sepolicy path-based labeling, we don't want to set the
+ * security.selinux attr via the generic xattr paths in either the symlink
+ * or regfile cases, so filter it out.
+ */
+ modified_xattrs = _ostree_filter_selinux_xattr (xattrs);
+ xattrs = modified_xattrs;
+ }
if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_SYMBOLIC_LINK)
{
- if (!_ostree_make_temporary_symlink_at (destination_dfd,
- g_file_info_get_symlink_target (file_info),
- &temp_filename,
- cancellable, error))
- goto out;
-
- if (xattrs)
+ g_auto(OstreeSepolicyFsCreatecon) fscreatecon = { 0, };
+
+ if (sepolicy_enabled)
{
- if (!glnx_dfd_name_set_all_xattrs (destination_dfd, temp_filename,
- xattrs, cancellable, error))
- goto out;
+ /* For symlinks, since we don't have O_TMPFILE, we use setfscreatecon() */
+ if (!_ostree_sepolicy_preparefscreatecon (&fscreatecon, options->sepolicy,
+ state->selabel_path_buf->str,
+ g_file_info_get_attribute_uint32 (file_info, "unix::mode"),
+ error))
+ return FALSE;
}
- if (G_UNLIKELY (renameat (destination_dfd, temp_filename,
- destination_dfd, destination_name) == -1))
+
+ if (symlinkat (g_file_info_get_symlink_target (file_info),
+ destination_dfd, destination_name) < 0)
{
- glnx_set_error_from_errno (error);
- goto out;
+ /* Handle union/add behaviors if we get EEXIST */
+ if (errno == EEXIST && union_mode)
+ {
+ /* Unioning? Let's unlink and try again */
+ (void) unlinkat (destination_dfd, destination_name, 0);
+ if (symlinkat (g_file_info_get_symlink_target (file_info),
+ destination_dfd, destination_name) < 0)
+ return glnx_throw_errno (error);
+ }
+ else if (errno == EEXIST && add_mode)
+ /* Note early return - we don't want to set the xattrs below */
+ return TRUE;
+ else
+ return glnx_throw_errno (error);
+ }
+
+ /* Process ownership and xattrs now that we made the link */
+ if (options->mode != OSTREE_REPO_CHECKOUT_MODE_USER)
+ {
+ if (TEMP_FAILURE_RETRY (fchownat (destination_dfd, destination_name,
+ g_file_info_get_attribute_uint32 (file_info, "unix::uid"),
+ g_file_info_get_attribute_uint32 (file_info, "unix::gid"),
+ AT_SYMLINK_NOFOLLOW)) == -1)
+ return glnx_throw_errno_prefix (error, "fchownat");
+
+ if (xattrs != NULL &&
+ !glnx_dfd_name_set_all_xattrs (destination_dfd, destination_name,
+ xattrs, cancellable, error))
+ return FALSE;
}
}
else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
{
glnx_fd_close int temp_fd = -1;
- g_autoptr(GOutputStream) temp_out = NULL;
guint32 file_mode;
+ GLnxLinkTmpfileReplaceMode replace_mode;
file_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
/* Don't make setuid files on checkout when we're doing --user */
@@ -324,25 +264,42 @@ checkout_file_unioning_from_input_at (OstreeRepo *repo,
if (!glnx_open_tmpfile_linkable_at (destination_dfd, ".", O_WRONLY | O_CLOEXEC,
&temp_fd, &temp_filename,
error))
- goto out;
- temp_out = g_unix_output_stream_new (temp_fd, FALSE);
+ return FALSE;
- if (!write_regular_file_content (repo, options, temp_out, file_info, xattrs, input,
+ if (sepolicy_enabled)
+ {
+ g_autofree char *label = NULL;
+ if (!ostree_sepolicy_get_label (options->sepolicy,
+ state->selabel_path_buf->str,
+ g_file_info_get_attribute_uint32 (file_info, "unix::mode"),
+ &label, cancellable, error))
+ return FALSE;
+ if (fsetxattr (temp_fd, "security.selinux", label, strlen (label), 0) < 0)
+ return glnx_throw_errno_prefix (error, "Setting security.selinux");
+ }
+
+ if (!write_regular_file_content (repo, options, temp_fd, file_info, xattrs, input,
cancellable, error))
- goto out;
+ return FALSE;
- if (!glnx_link_tmpfile_at (destination_dfd, GLNX_LINK_TMPFILE_REPLACE,
+ /* The add/union/none behaviors map directly to GLnxLinkTmpfileReplaceMode */
+ if (add_mode)
+ replace_mode = GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST;
+ else if (union_mode)
+ replace_mode = GLNX_LINK_TMPFILE_REPLACE;
+ else
+ replace_mode = GLNX_LINK_TMPFILE_NOREPLACE;
+
+ if (!glnx_link_tmpfile_at (destination_dfd, replace_mode,
temp_fd, temp_filename, destination_dfd,
destination_name,
error))
- goto out;
+ return FALSE;
}
else
g_assert_not_reached ();
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
typedef enum {
@@ -386,7 +343,7 @@ checkout_file_hardlink (OstreeRepo *self,
ret_result = HARDLINK_RESULT_SKIP_EXISTED;
}
else if (errno == EEXIST && options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES)
- {
+ {
/* Idiocy, from man rename(2)
*
* "If oldpath and newpath are existing hard links referring to
@@ -400,9 +357,7 @@ checkout_file_hardlink (OstreeRepo *self,
}
else
{
- g_prefix_error (error, "Hardlinking %s to %s: ", loose_path, destination_name);
- glnx_set_error_from_errno (error);
- return FALSE;
+ return glnx_throw_errno_prefix (error, "Hardlinking %s to %s", loose_path, destination_name);
}
if (out_result)
@@ -413,29 +368,26 @@ checkout_file_hardlink (OstreeRepo *self,
static gboolean
checkout_one_file_at (OstreeRepo *repo,
OstreeRepoCheckoutAtOptions *options,
- GFile *source,
- GFileInfo *source_info,
+ CheckoutState *state,
+ const char *checksum,
int destination_dfd,
const char *destination_name,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- const char *checksum;
- gboolean is_symlink;
- gboolean is_bare_user_symlink = FALSE;
- gboolean can_cache;
gboolean need_copy = TRUE;
+ gboolean is_bare_user_symlink = FALSE;
char loose_path_buf[_OSTREE_LOOSE_PATH_MAX];
- g_autoptr(GInputStream) input = NULL;
- g_autoptr(GVariant) xattrs = NULL;
- gboolean is_whiteout;
- is_symlink = g_file_info_get_file_type (source_info) == G_FILE_TYPE_SYMBOLIC_LINK;
- checksum = ostree_repo_file_get_checksum ((OstreeRepoFile*)source);
+ /* FIXME - avoid the GFileInfo here */
+ g_autoptr(GFileInfo) source_info = NULL;
+ if (!ostree_repo_load_file (repo, checksum, NULL, &source_info, NULL,
+ cancellable, error))
+ return FALSE;
- is_whiteout = !is_symlink && options->process_whiteouts &&
- g_str_has_prefix (destination_name, WHITEOUT_PREFIX);
+ const gboolean is_symlink = (g_file_info_get_file_type (source_info) == G_FILE_TYPE_SYMBOLIC_LINK);
+ const gboolean is_whiteout = (!is_symlink && options->process_whiteouts &&
+ g_str_has_prefix (destination_name, WHITEOUT_PREFIX));
/* First, see if it's a Docker whiteout,
* https://github.com/docker/docker/blob/1a714e76a2cb9008cd19609059e9988ff1660b78/pkg/archive/whiteouts.go
@@ -445,20 +397,16 @@ checkout_one_file_at (OstreeRepo *repo,
const char *name = destination_name + (sizeof (WHITEOUT_PREFIX) - 1);
if (!name[0])
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Invalid empty whiteout '%s'", name);
- goto out;
- }
+ return glnx_throw (error, "Invalid empty whiteout '%s'", name);
g_assert (name[0] != '/'); /* Sanity */
if (!glnx_shutil_rm_rf_at (destination_dfd, name, cancellable, error))
- goto out;
+ return FALSE;
need_copy = FALSE;
}
- else
+ else if (!options->force_copy)
{
HardlinkResult hardlink_res = HARDLINK_RESULT_NOT_SUPPORTED;
/* Try to do a hardlink first, if it's a regular file. This also
@@ -496,13 +444,10 @@ checkout_one_file_at (OstreeRepo *repo,
* special exception for bare-user symlinks.
*/
if (options->no_copy_fallback && !is_hardlinkable && !is_bare_user_symlink)
- {
- glnx_throw (error,
- repo_is_usermode ?
- "User repository mode requires user checkout mode to hardlink" :
- "Bare repository mode cannot hardlink in user checkout mode");
- goto out;
- }
+ return glnx_throw (error,
+ repo_is_usermode ?
+ "User repository mode requires user checkout mode to hardlink" :
+ "Bare repository mode cannot hardlink in user checkout mode");
/* But only under these conditions */
if (is_bare || is_archive_z2_with_cache)
@@ -516,24 +461,21 @@ checkout_one_file_at (OstreeRepo *repo,
destination_dfd, destination_name,
TRUE, &hardlink_res,
cancellable, error))
- goto out;
+ return FALSE;
if (hardlink_res == HARDLINK_RESULT_LINKED && options->devino_to_csum_cache)
{
struct stat stbuf;
OstreeDevIno *key;
-
+
if (TEMP_FAILURE_RETRY (fstatat (destination_dfd, destination_name, &stbuf, AT_SYMLINK_NOFOLLOW)) != 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
-
+ return glnx_throw_errno (error);
+
key = g_new (OstreeDevIno, 1);
key->dev = stbuf.st_dev;
key->ino = stbuf.st_ino;
memcpy (key->checksum, checksum, OSTREE_SHA256_STRING_LEN+1);
-
+
g_hash_table_add ((GHashTable*)options->devino_to_csum_cache, key);
}
@@ -546,8 +488,11 @@ checkout_one_file_at (OstreeRepo *repo,
need_copy = (hardlink_res == HARDLINK_RESULT_NOT_SUPPORTED);
}
- can_cache = (options->enable_uncompressed_cache
- && repo->enable_uncompressed_cache);
+ const gboolean can_cache = (options->enable_uncompressed_cache
+ && repo->enable_uncompressed_cache);
+
+ g_autoptr(GInputStream) input = NULL;
+ g_autoptr(GVariant) xattrs = NULL;
/* Ok, if we're archive-z2 and we didn't find an object, uncompress
* it now, stick it in the cache, and then hardlink to that.
@@ -560,10 +505,10 @@ checkout_one_file_at (OstreeRepo *repo,
&& options->mode == OSTREE_REPO_CHECKOUT_MODE_USER)
{
HardlinkResult hardlink_res = HARDLINK_RESULT_NOT_SUPPORTED;
-
+
if (!ostree_repo_load_file (repo, checksum, &input, NULL, NULL,
cancellable, error))
- goto out;
+ return FALSE;
/* Overwrite any parent repo from earlier */
_ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_FILE, OSTREE_REPO_MODE_BARE);
@@ -571,11 +516,8 @@ checkout_one_file_at (OstreeRepo *repo,
if (!checkout_object_for_uncompressed_cache (repo, loose_path_buf,
source_info, input,
cancellable, error))
- {
- g_prefix_error (error, "Unpacking loose object %s: ", checksum);
- goto out;
- }
-
+ return glnx_prefix_error (error, "Unpacking loose object %s", checksum);
+
g_clear_object (&input);
/* Store the 2-byte objdir prefix (e.g. e3) in a set. The basic
@@ -607,10 +549,7 @@ checkout_one_file_at (OstreeRepo *repo,
destination_dfd, destination_name,
FALSE, &hardlink_res,
cancellable, error))
- {
- g_prefix_error (error, "Using new cached uncompressed hardlink of %s to %s: ", checksum, destination_name);
- goto out;
- }
+ return glnx_prefix_error (error, "Using new cached uncompressed hardlink of %s to %s", checksum, destination_name);
need_copy = (hardlink_res == HARDLINK_RESULT_NOT_SUPPORTED);
}
@@ -627,47 +566,28 @@ checkout_one_file_at (OstreeRepo *repo,
g_assert (is_bare_user_symlink);
if (!ostree_repo_load_file (repo, checksum, &input, NULL, &xattrs,
cancellable, error))
- goto out;
+ return FALSE;
- if (options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES)
- {
- if (!checkout_file_unioning_from_input_at (repo, options, source_info, xattrs, input,
- destination_dfd,
- destination_name,
- cancellable, error))
- {
- g_prefix_error (error, "Union checkout of %s to %s: ", checksum, destination_name);
- goto out;
- }
- }
- else
- {
- if (!checkout_file_from_input_at (repo, options, source_info, xattrs, input,
- destination_dfd,
- destination_name,
- cancellable, error))
- {
- g_prefix_error (error, "Checkout of %s to %s: ", checksum, destination_name);
- goto out;
- }
- }
+ if (!create_file_copy_from_input_at (repo, options, state, source_info, xattrs, input,
+ destination_dfd, destination_name,
+ cancellable, error))
+ return glnx_prefix_error (error, "Copy checkout of %s to %s", checksum, destination_name);
if (input)
{
if (!g_input_stream_close (input, cancellable, error))
- goto out;
+ return FALSE;
}
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/*
* checkout_tree_at:
* @self: Repo
* @mode: Options controlling all files
+ * @state: Any state we're carrying through
* @overwrite_mode: Whether or not to overwrite files
* @destination_parent_fd: Place tree here
* @destination_name: Use this name for tree
@@ -680,6 +600,192 @@ checkout_one_file_at (OstreeRepo *repo,
* relative @destination_name, located by @destination_parent_fd.
*/
static gboolean
+checkout_tree_at_recurse (OstreeRepo *self,
+ OstreeRepoCheckoutAtOptions *options,
+ CheckoutState *state,
+ int destination_parent_fd,
+ const char *destination_name,
+ const char *dirtree_checksum,
+ const char *dirmeta_checksum,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean did_exist = FALSE;
+ const gboolean sepolicy_enabled = options->sepolicy && !self->disable_xattrs;
+ g_autoptr(GVariant) dirtree = NULL;
+ g_autoptr(GVariant) dirmeta = NULL;
+ g_autoptr(GVariant) xattrs = NULL;
+ g_autoptr(GVariant) modified_xattrs = NULL;
+
+ if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_DIR_TREE,
+ dirtree_checksum, &dirtree, error))
+ return FALSE;
+ if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_DIR_META,
+ dirmeta_checksum, &dirmeta, error))
+ return FALSE;
+
+ /* Parse OSTREE_OBJECT_TYPE_DIR_META */
+ guint32 uid, gid, mode;
+ g_variant_get (dirmeta, "(uuu@a(ayay))",
+ &uid, &gid, &mode,
+ options->mode != OSTREE_REPO_CHECKOUT_MODE_USER ? &xattrs : NULL);
+ uid = GUINT32_FROM_BE (uid);
+ gid = GUINT32_FROM_BE (gid);
+ mode = GUINT32_FROM_BE (mode);
+
+ /* First, make the directory. Push a new scope in case we end up using
+ * setfscreatecon().
+ */
+ {
+ g_auto(OstreeSepolicyFsCreatecon) fscreatecon = { 0, };
+
+ /* If we're doing SELinux labeling, prepare it */
+ if (sepolicy_enabled)
+ {
+ /* We'll set the xattr via setfscreatecon(), so don't do it via generic xattrs below. */
+ modified_xattrs = _ostree_filter_selinux_xattr (xattrs);
+ xattrs = modified_xattrs;
+
+ if (!_ostree_sepolicy_preparefscreatecon (&fscreatecon, options->sepolicy,
+ state->selabel_path_buf->str,
+ mode, error))
+ return FALSE;
+ }
+
+ /* Create initially with mode 0700, then chown/chmod only when we're
+ * done. This avoids anyone else being able to operate on partially
+ * constructed dirs.
+ */
+ if (TEMP_FAILURE_RETRY (mkdirat (destination_parent_fd, destination_name, 0700)) < 0)
+ {
+ if (errno == EEXIST &&
+ (options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES
+ || options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES))
+ did_exist = TRUE;
+ else
+ return glnx_throw_errno (error);
+ }
+ }
+
+ glnx_fd_close int destination_dfd = -1;
+ if (!glnx_opendirat (destination_parent_fd, destination_name, TRUE,
+ &destination_dfd, error))
+ return FALSE;
+
+ struct stat repo_dfd_stat;
+ if (fstat (self->repo_dir_fd, &repo_dfd_stat) < 0)
+ return glnx_throw_errno (error);
+ struct stat destination_stat;
+ if (fstat (destination_dfd, &destination_stat) < 0)
+ return glnx_throw_errno (error);
+
+ if (options->no_copy_fallback && repo_dfd_stat.st_dev != destination_stat.st_dev)
+ return glnx_throw (error, "Unable to do hardlink checkout across devices (src=%"G_GUINT64_FORMAT" destination=%"G_GUINT64_FORMAT")",
+ (guint64)repo_dfd_stat.st_dev, (guint64)destination_stat.st_dev);
+
+ /* Set the xattrs if we created the dir */
+ if (!did_exist && xattrs)
+ {
+ if (!glnx_fd_set_all_xattrs (destination_dfd, xattrs, cancellable, error))
+ return FALSE;
+ }
+
+ GString *selabel_path_buf = state->selabel_path_buf;
+ /* Process files in this subdir */
+ { g_autoptr(GVariant) dir_file_contents = g_variant_get_child_value (dirtree, 0);
+ GVariantIter viter;
+ g_variant_iter_init (&viter, dir_file_contents);
+ const char *fname;
+ g_autoptr(GVariant) contents_csum_v = NULL;
+ while (g_variant_iter_loop (&viter, "(&s@ay)", &fname, &contents_csum_v))
+ {
+ const size_t namelen = strlen (fname);
+ if (selabel_path_buf)
+ g_string_append_len (selabel_path_buf, fname, namelen);
+
+ char tmp_checksum[OSTREE_SHA256_STRING_LEN+1];
+ _ostree_checksum_inplace_from_bytes_v (contents_csum_v, tmp_checksum);
+
+ if (!checkout_one_file_at (self, options, state,
+ tmp_checksum,
+ destination_dfd, fname,
+ cancellable, error))
+ return FALSE;
+
+ if (selabel_path_buf)
+ g_string_truncate (selabel_path_buf, selabel_path_buf->len - namelen);
+ }
+ contents_csum_v = NULL; /* iter_loop freed it */
+ }
+
+ /* Process subdirectories */
+ { g_autoptr(GVariant) dir_subdirs = g_variant_get_child_value (dirtree, 1);
+ const char *dname;
+ g_autoptr(GVariant) subdirtree_csum_v = NULL;
+ g_autoptr(GVariant) subdirmeta_csum_v = NULL;
+ GVariantIter viter;
+ g_variant_iter_init (&viter, dir_subdirs);
+ while (g_variant_iter_loop (&viter, "(&s@ay@ay)", &dname,
+ &subdirtree_csum_v, &subdirmeta_csum_v))
+ {
+ const size_t namelen = strlen (dname);
+ if (selabel_path_buf)
+ {
+ g_string_append_len (selabel_path_buf, dname, namelen);
+ g_string_append_c (selabel_path_buf, '/');
+ }
+
+ char subdirtree_checksum[OSTREE_SHA256_STRING_LEN+1];
+ _ostree_checksum_inplace_from_bytes_v (subdirtree_csum_v, subdirtree_checksum);
+ char subdirmeta_checksum[OSTREE_SHA256_STRING_LEN+1];
+ _ostree_checksum_inplace_from_bytes_v (subdirmeta_csum_v, subdirmeta_checksum);
+ if (!checkout_tree_at_recurse (self, options, state,
+ destination_dfd, dname,
+ subdirtree_checksum, subdirmeta_checksum,
+ cancellable, error))
+ return FALSE;
+
+ if (selabel_path_buf)
+ g_string_truncate (selabel_path_buf, selabel_path_buf->len - namelen);
+ }
+ }
+
+ /* We do fchmod/fchown last so that no one else could access the
+ * partially created directory and change content we're laying out.
+ */
+ if (!did_exist)
+ {
+ if (TEMP_FAILURE_RETRY (fchmod (destination_dfd, mode)) < 0)
+ return glnx_throw_errno (error);
+ }
+
+ if (!did_exist && options->mode != OSTREE_REPO_CHECKOUT_MODE_USER)
+ {
+ if (TEMP_FAILURE_RETRY (fchown (destination_dfd, uid, gid)) < 0)
+ return glnx_throw_errno (error);
+ }
+
+ /* Set directory mtime to OSTREE_TIMESTAMP, so that it is constant for all checkouts.
+ * Must be done after setting permissions and creating all children.
+ */
+ if (!did_exist)
+ {
+ const struct timespec times[2] = { { OSTREE_TIMESTAMP, UTIME_OMIT }, { OSTREE_TIMESTAMP, 0} };
+ if (TEMP_FAILURE_RETRY (futimens (destination_dfd, times)) < 0)
+ return glnx_throw_errno (error);
+ }
+
+ if (fsync_is_enabled (self, options))
+ {
+ if (fsync (destination_dfd) == -1)
+ return glnx_throw_errno (error);
+ }
+
+ return TRUE;
+}
+
+/* Begin a checkout process */
+static gboolean
checkout_tree_at (OstreeRepo *self,
OstreeRepoCheckoutAtOptions *options,
int destination_parent_fd,
@@ -689,179 +795,75 @@ checkout_tree_at (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- gboolean did_exist = FALSE;
- glnx_fd_close int destination_dfd = -1;
- int res;
- struct stat repo_dfd_stat;
- struct stat destination_stat;
- g_autoptr(GVariant) xattrs = NULL;
- g_autoptr(GFileEnumerator) dir_enum = NULL;
-
- /* Create initially with mode 0700, then chown/chmod only when we're
- * done. This avoids anyone else being able to operate on partially
- * constructed dirs.
- */
- do
- res = mkdirat (destination_parent_fd, destination_name, 0700);
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (res == -1)
+ g_auto(CheckoutState) state = { 0, };
+ // If SELinux labeling is enabled, we need to keep track of the full path string
+ if (options->sepolicy)
{
- if (errno == EEXIST &&
- (options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES
- || options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES))
- did_exist = TRUE;
- else
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
- }
-
- if (!glnx_opendirat (destination_parent_fd, destination_name, TRUE,
- &destination_dfd, error))
- goto out;
-
- if (fstat (self->repo_dir_fd, &repo_dfd_stat) < 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
- if (fstat (destination_dfd, &destination_stat) < 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
-
- if (options->no_copy_fallback && repo_dfd_stat.st_dev != destination_stat.st_dev)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Unable to do hardlink checkout across devices (src=%"G_GUINT64_FORMAT" destination=%"G_GUINT64_FORMAT")",
- (guint64)repo_dfd_stat.st_dev, (guint64)destination_stat.st_dev);
- goto out;
- }
-
- /* Set the xattrs now, so any derived labeling works */
- if (!did_exist && options->mode != OSTREE_REPO_CHECKOUT_MODE_USER)
- {
- if (!ostree_repo_file_get_xattrs (source, &xattrs, NULL, error))
- goto out;
-
- if (xattrs)
- {
- if (!glnx_fd_set_all_xattrs (destination_dfd, xattrs, cancellable, error))
- goto out;
- }
+ GString *buf = g_string_new (options->sepolicy_prefix ?: options->subpath);
+ g_assert_cmpint (buf->len, >, 0);
+ // Ensure it ends with /
+ if (buf->str[buf->len-1] != '/')
+ g_string_append_c (buf, '/');
+ state.selabel_path_buf = buf;
+
+ /* Otherwise it'd just be corrupting things, and there's no use case */
+ g_assert (options->force_copy);
}
+ /* Special case handling for subpath of a non-directory */
if (g_file_info_get_file_type (source_info) != G_FILE_TYPE_DIRECTORY)
{
- ret = checkout_one_file_at (self, options,
- (GFile *) source,
- source_info,
- destination_dfd,
- g_file_info_get_name (source_info),
- cancellable, error);
- goto out;
- }
- dir_enum = g_file_enumerate_children ((GFile*)source,
- OSTREE_GIO_FAST_QUERYINFO,
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
- cancellable,
- error);
- if (!dir_enum)
- goto out;
-
- while (TRUE)
- {
- GFileInfo *file_info;
- GFile *src_child;
- const char *name;
-
- if (!g_file_enumerator_iterate (dir_enum, &file_info, &src_child,
- cancellable, error))
- goto out;
- if (file_info == NULL)
- break;
-
- name = g_file_info_get_name (file_info);
-
- if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
+ /* For backwards compat reasons, we do a mkdir() here. However, as a
+ * special case to allow callers to directly check out files without an
+ * intermediate root directory, we will skip mkdirat() if
+ * `destination_name` == `.`, since obviously the current directory
+ * exists.
+ */
+ int destination_dfd = destination_parent_fd;
+ glnx_fd_close int destination_dfd_owned = -1;
+ if (strcmp (destination_name, ".") != 0)
{
- if (!checkout_tree_at (self, options,
- destination_dfd, name,
- (OstreeRepoFile*)src_child, file_info,
- cancellable, error))
- goto out;
- }
- else
- {
- if (!checkout_one_file_at (self, options,
- src_child, file_info,
- destination_dfd, name,
- cancellable, error))
- goto out;
+ if (mkdirat (destination_parent_fd, destination_name, 0700) < 0
+ && errno != EEXIST)
+ return glnx_throw_errno_prefix (error, "mkdirat");
+ if (!glnx_opendirat (destination_parent_fd, destination_name, TRUE,
+ &destination_dfd_owned, error))
+ return FALSE;
+ destination_dfd = destination_dfd_owned;
}
+ return checkout_one_file_at (self, options, &state,
+ ostree_repo_file_get_checksum (source),
+ destination_dfd,
+ g_file_info_get_name (source_info),
+ cancellable, error);
}
- /* We do fchmod/fchown last so that no one else could access the
- * partially created directory and change content we're laying out.
+ /* Cache any directory metadata we read during this operation;
+ * see commit b7afe91e21143d7abb0adde440683a52712aa246
*/
- if (!did_exist)
- {
- do
- res = fchmod (destination_dfd,
- g_file_info_get_attribute_uint32 (source_info, "unix::mode"));
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (G_UNLIKELY (res == -1))
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
- }
+ g_auto(OstreeRepoMemoryCacheRef) memcache_ref;
+ _ostree_repo_memory_cache_ref_init (&memcache_ref, self);
- if (!did_exist && options->mode != OSTREE_REPO_CHECKOUT_MODE_USER)
- {
- do
- res = fchown (destination_dfd,
- g_file_info_get_attribute_uint32 (source_info, "unix::uid"),
- g_file_info_get_attribute_uint32 (source_info, "unix::gid"));
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (G_UNLIKELY (res == -1))
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
- }
+ g_assert_cmpint (g_file_info_get_file_type (source_info), ==, G_FILE_TYPE_DIRECTORY);
+ const char *dirtree_checksum = ostree_repo_file_tree_get_contents_checksum (source);
+ const char *dirmeta_checksum = ostree_repo_file_tree_get_metadata_checksum (source);
+ return checkout_tree_at_recurse (self, options, &state, destination_parent_fd,
+ destination_name,
+ dirtree_checksum, dirmeta_checksum,
+ cancellable, error);
+}
- /* Set directory mtime to OSTREE_TIMESTAMP, so that it is constant for all checkouts.
- * Must be done after setting permissions and creating all children.
- */
- if (!did_exist)
- {
- const struct timespec times[2] = { { OSTREE_TIMESTAMP, UTIME_OMIT }, { OSTREE_TIMESTAMP, 0} };
- do
- res = futimens (destination_dfd, times);
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (G_UNLIKELY (res == -1))
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
- }
+static void
+canonicalize_options (OstreeRepo *self,
+ OstreeRepoCheckoutAtOptions *options)
+{
+ /* Canonicalize subpath to / */
+ if (!options->subpath)
+ options->subpath = "/";
- if (fsync_is_enabled (self, options))
- {
- if (fsync (destination_dfd) == -1)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
- }
-
- ret = TRUE;
- out:
- return ret;
+ /* Force USER mode for BARE_USER_ONLY always - nothing else makes sense */
+ if (ostree_repo_get_mode (self) == OSTREE_REPO_MODE_BARE_USER_ONLY)
+ options->mode = OSTREE_REPO_CHECKOUT_MODE_USER;
}
/**
@@ -891,14 +893,11 @@ ostree_repo_checkout_tree (OstreeRepo *self,
GError **error)
{
OstreeRepoCheckoutAtOptions options = { 0, };
-
- if (ostree_repo_get_mode (self) == OSTREE_REPO_MODE_BARE_USER_ONLY)
- mode = OSTREE_REPO_CHECKOUT_MODE_USER;
-
options.mode = mode;
options.overwrite_mode = overwrite_mode;
/* Backwards compatibility */
options.enable_uncompressed_cache = TRUE;
+ canonicalize_options (self, &options);
return checkout_tree_at (self, &options,
AT_FDCWD, gs_file_get_path_cached (destination),
@@ -992,9 +991,10 @@ ostree_repo_checkout_at (OstreeRepo *self,
/* Make a copy so we can modify the options */
real_options = *options;
options = &real_options;
+ canonicalize_options (self, options);
- if (ostree_repo_get_mode (self) == OSTREE_REPO_MODE_BARE_USER_ONLY)
- options->mode = OSTREE_REPO_CHECKOUT_MODE_USER;
+ g_return_val_if_fail (!(options->force_copy && options->no_copy_fallback), FALSE);
+ g_return_val_if_fail (!options->sepolicy || options->force_copy, FALSE);
g_autoptr(GFile) commit_root = (GFile*) _ostree_repo_file_new_for_commit (self, commit, error);
if (!commit_root)
@@ -1004,7 +1004,8 @@ ostree_repo_checkout_at (OstreeRepo *self,
return FALSE;
g_autoptr(GFile) target_dir = NULL;
- if (options->subpath && strcmp (options->subpath, "/") != 0)
+
+ if (strcmp (options->subpath, "/") != 0)
target_dir = g_file_get_child (commit_root, options->subpath);
else
target_dir = g_object_ref (commit_root);
@@ -1111,7 +1112,7 @@ ostree_repo_checkout_gc (OstreeRepo *self,
glnx_set_error_from_errno (error);
return FALSE;
}
-
+
if (stbuf.st_nlink == 1)
{
if (unlinkat (dfd_iter.fd, dent->d_name, 0) != 0)
diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c
index 45577373..ce45a911 100644
--- a/src/libostree/ostree-repo-commit.c
+++ b/src/libostree/ostree-repo-commit.c
@@ -433,7 +433,7 @@ add_size_index_to_metadata (OstreeRepo *self,
{
guint8 csum[OSTREE_SHA256_DIGEST_LEN];
const char *e_checksum = sorted_keys->pdata[i];
- GString *buffer = g_string_new (NULL);
+ g_autoptr(GString) buffer = g_string_new (NULL);
ostree_checksum_inplace_to_bytes (e_checksum, csum);
g_string_append_len (buffer, (char*)csum, sizeof (csum));
@@ -444,7 +444,6 @@ add_size_index_to_metadata (OstreeRepo *self,
g_variant_builder_add (&index_builder, "@ay",
ot_gvariant_new_bytearray ((guint8*)buffer->str, buffer->len));
- g_string_free (buffer, TRUE);
}
g_variant_builder_add (builder, "{sv}", "ostree.sizes",
@@ -459,29 +458,19 @@ add_size_index_to_metadata (OstreeRepo *self,
}
static gboolean
-fallocate_stream (GFileDescriptorBased *stream,
- goffset size,
- GCancellable *cancellable,
- GError **error)
+ot_fallocate (int fd, goffset size, GError **error)
{
- gboolean ret = FALSE;
- int fd = g_file_descriptor_based_get_fd (stream);
+ if (size == 0)
+ return TRUE;
- if (size > 0)
+ int r = posix_fallocate (fd, 0, size);
+ if (r != 0)
{
- int r = posix_fallocate (fd, 0, size);
- if (r != 0)
- {
- /* posix_fallocate is a weird deviation from errno standards */
- errno = r;
- glnx_set_error_from_errno (error);
- goto out;
- }
+ /* posix_fallocate is a weird deviation from errno standards */
+ errno = r;
+ return glnx_throw_errno_prefix (error, "fallocate");
}
-
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
gboolean
@@ -511,11 +500,10 @@ _ostree_repo_open_content_bare (OstreeRepo *self,
&fd, &temp_filename, error))
goto out;
- ret_stream = g_unix_output_stream_new (fd, TRUE);
-
- if (!fallocate_stream ((GFileDescriptorBased*)ret_stream, content_len,
- cancellable, error))
+ if (!ot_fallocate (fd, content_len, error))
goto out;
+
+ ret_stream = g_unix_output_stream_new (fd, TRUE);
}
ret = TRUE;
@@ -570,7 +558,6 @@ create_regular_tmpfile_linkable_with_content (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- g_autoptr(GOutputStream) temp_out = NULL;
glnx_fd_close int temp_fd = -1;
g_autofree char *temp_filename = NULL;
@@ -578,20 +565,27 @@ create_regular_tmpfile_linkable_with_content (OstreeRepo *self,
&temp_fd, &temp_filename,
error))
return FALSE;
- temp_out = g_unix_output_stream_new (temp_fd, FALSE);
- if (!fallocate_stream ((GFileDescriptorBased*)temp_out, length,
- cancellable, error))
+ if (!ot_fallocate (temp_fd, length, error))
return FALSE;
- if (g_output_stream_splice (temp_out, input, 0,
- cancellable, error) < 0)
- return FALSE;
- if (fchmod (temp_fd, 0644) < 0)
+ if (G_IS_FILE_DESCRIPTOR_BASED (input))
{
- glnx_set_error_from_errno (error);
- return FALSE;
+ int infd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*) input);
+ if (glnx_regfile_copy_bytes (infd, temp_fd, (off_t)length, TRUE) < 0)
+ return glnx_throw_errno_prefix (error, "regfile copy");
}
+ else
+ {
+ g_autoptr(GOutputStream) temp_out = g_unix_output_stream_new (temp_fd, FALSE);
+ if (g_output_stream_splice (temp_out, input, 0,
+ cancellable, error) < 0)
+ return FALSE;
+ }
+
+ if (fchmod (temp_fd, 0644) < 0)
+ return glnx_throw_errno_prefix (error, "fchmod");
+
*out_fd = temp_fd; temp_fd = -1;
*out_path = g_steal_pointer (&temp_filename);
return TRUE;
@@ -608,7 +602,8 @@ write_object (OstreeRepo *self,
GError **error)
{
gboolean ret = FALSE;
- const char *actual_checksum;
+ const char *actual_checksum = NULL;
+ g_autofree char *actual_checksum_owned = NULL;
gboolean do_commit;
OstreeRepoMode repo_mode;
g_autofree char *temp_filename = NULL;
@@ -773,7 +768,7 @@ write_object (OstreeRepo *self,
actual_checksum = expected_checksum;
else
{
- actual_checksum = ot_checksum_instream_get_string (checksum_input);
+ actual_checksum = actual_checksum_owned = ot_checksum_instream_get_string (checksum_input);
if (expected_checksum && strcmp (actual_checksum, expected_checksum) != 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
@@ -1306,7 +1301,7 @@ ensure_txn_refs (OstreeRepo *self)
* ostree_repo_transaction_set_refspec:
* @self: An #OstreeRepo
* @refspec: The refspec to write
- * @checksum: The checksum to point it to
+ * @checksum: (nullable): The checksum to point it to
*
* Like ostree_repo_transaction_set_ref(), but takes concatenated
* @refspec format as input instead of separate remote and name
@@ -1329,7 +1324,7 @@ ostree_repo_transaction_set_refspec (OstreeRepo *self,
* @self: An #OstreeRepo
* @remote: (allow-none): A remote for the ref
* @ref: The ref to write
- * @checksum: The checksum to point it to
+ * @checksum: (nullable): The checksum to point it to
*
* If @checksum is not %NULL, then record it as the target of ref named
* @ref; if @remote is provided, the ref will appear to originate from that
@@ -2014,13 +2009,13 @@ ostree_repo_read_commit_detached_metadata (OstreeRepo *self,
!ot_util_variant_map_at (self->commit_stagedir_fd, buf,
G_VARIANT_TYPE ("a{sv}"),
OT_VARIANT_MAP_ALLOW_NOENT | OT_VARIANT_MAP_TRUSTED, &ret_metadata, error))
- return g_prefix_error (error, "Unable to read existing detached metadata: "), FALSE;
+ return glnx_prefix_error (error, "Unable to read existing detached metadata");
if (ret_metadata == NULL &&
!ot_util_variant_map_at (self->objects_dir_fd, buf,
G_VARIANT_TYPE ("a{sv}"),
OT_VARIANT_MAP_ALLOW_NOENT | OT_VARIANT_MAP_TRUSTED, &ret_metadata, error))
- return g_prefix_error (error, "Unable to read existing detached metadata: "), FALSE;
+ return glnx_prefix_error (error, "Unable to read existing detached metadata");
if (ret_metadata == NULL && self->parent_repo)
return ostree_repo_read_commit_detached_metadata (self->parent_repo,
diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h
index b1a58d61..2a518d4f 100644
--- a/src/libostree/ostree-repo-private.h
+++ b/src/libostree/ostree-repo-private.h
@@ -21,6 +21,7 @@
#pragma once
#include "ostree-repo.h"
+#include "ostree-remote-private.h"
#include "libglnx.h"
G_BEGIN_DECLS
@@ -43,6 +44,14 @@ G_BEGIN_DECLS
* */
#define _OSTREE_MAX_OUTSTANDING_WRITE_REQUESTS 16
+/* Well-known keys for the additional metadata field in a summary file. */
+#define OSTREE_SUMMARY_LAST_MODIFIED "ostree.summary.last-modified"
+#define OSTREE_SUMMARY_EXPIRES "ostree.summary.expires"
+
+/* Well-known keys for the additional metadata field in a commit in a ref entry
+ * in a summary file. */
+#define OSTREE_COMMIT_TIMESTAMP "ostree.commit.timestamp"
+
typedef enum {
OSTREE_REPO_TEST_ERROR_PRE_COMMIT = (1 << 0)
} OstreeRepoTestErrorFlags;
@@ -78,7 +87,6 @@ struct OstreeRepo {
GFile *repodir;
int repo_dir_fd;
- GFile *tmp_dir;
int tmp_dir_fd;
int cache_dir_fd;
char *cache_dir;
@@ -92,8 +100,9 @@ struct OstreeRepo {
OstreeRepoTransactionStats txn_stats;
GMutex cache_lock;
- GPtrArray *cached_meta_indexes;
- GPtrArray *cached_content_indexes;
+ guint dirmeta_cache_refcount;
+ /* char * checksum → GVariant * for dirmeta objects, used in the checkout path */
+ GHashTable *dirmeta_cache;
gboolean inited;
gboolean writable;
@@ -128,6 +137,24 @@ typedef struct {
char checksum[OSTREE_SHA256_STRING_LEN+1];
} OstreeDevIno;
+/* A MemoryCacheRef is an in-memory cache of objects (currently just DIRMETA). This can
+ * be used when performing an operation that traverses a repository in someway. Currently,
+ * the primary use case is ostree_repo_checkout_at() avoiding lots of duplicate dirmeta
+ * lookups.
+ */
+typedef struct {
+ OstreeRepo *repo;
+} OstreeRepoMemoryCacheRef;
+
+
+void
+_ostree_repo_memory_cache_ref_init (OstreeRepoMemoryCacheRef *state,
+ OstreeRepo *repo);
+
+void
+_ostree_repo_memory_cache_ref_destroy (OstreeRepoMemoryCacheRef *state);
+G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(OstreeRepoMemoryCacheRef, _ostree_repo_memory_cache_ref_destroy);
+
#define OSTREE_REPO_TMPDIR_STAGING "staging-"
#define OSTREE_REPO_TMPDIR_FETCHER "fetcher-"
@@ -324,4 +351,16 @@ gboolean
_ostree_repo_update_mtime (OstreeRepo *self,
GError **error);
+void
+_ostree_repo_add_remote (OstreeRepo *self,
+ OstreeRemote *remote);
+OstreeRemote *
+_ostree_repo_get_remote (OstreeRepo *self,
+ const char *name,
+ GError **error);
+OstreeRemote *
+_ostree_repo_get_remote_inherited (OstreeRepo *self,
+ const char *name,
+ GError **error);
+
G_END_DECLS
diff --git a/src/libostree/ostree-repo-prune.c b/src/libostree/ostree-repo-prune.c
index 1b2a8257..bf0a2530 100644
--- a/src/libostree/ostree-repo-prune.c
+++ b/src/libostree/ostree-repo-prune.c
@@ -42,21 +42,14 @@ prune_commitpartial_file (OstreeRepo *repo,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
g_autofree char *path = _ostree_get_commitpartial_path (checksum);
-
if (unlinkat (repo->repo_dir_fd, path, 0) != 0)
{
if (errno != ENOENT)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "unlinkat");
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
static gboolean
@@ -67,7 +60,6 @@ maybe_prune_loose_object (OtPruneData *data,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
g_autoptr(GVariant) key = NULL;
key = ostree_object_name_serialize (checksum, objtype);
@@ -83,16 +75,16 @@ maybe_prune_loose_object (OtPruneData *data,
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
{
if (!prune_commitpartial_file (data->repo, checksum, cancellable, error))
- goto out;
+ return FALSE;
}
if (!ostree_repo_query_object_storage_size (data->repo, objtype, checksum,
&storage_size, cancellable, error))
- goto out;
+ return FALSE;
if (!ostree_repo_delete_object (data->repo, objtype, checksum,
cancellable, error))
- goto out;
+ return FALSE;
data->freed_bytes += storage_size;
}
@@ -111,9 +103,7 @@ maybe_prune_loose_object (OtPruneData *data,
data->n_reachable_content++;
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
static gboolean
@@ -121,25 +111,17 @@ _ostree_repo_prune_tmp (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
- glnx_fd_close int fd = -1;
-
if (self->cache_dir_fd == -1)
return TRUE;
- fd = glnx_opendirat_with_errno (self->cache_dir_fd, _OSTREE_SUMMARY_CACHE_DIR, FALSE);
- if (fd < 0)
- {
- if (errno == ENOENT)
- ret = TRUE;
- else
- glnx_set_error_from_errno (error);
- goto out;
- }
-
- if (!glnx_dirfd_iterator_init_take_fd (dup (fd), &dfd_iter, error))
- goto out;
+ g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
+ gboolean exists;
+ if (!ot_dfd_iter_init_allow_noent (self->cache_dir_fd, _OSTREE_SUMMARY_CACHE_DIR,
+ &dfd_iter, &exists, error))
+ return FALSE;
+ /* Note early return */
+ if (!exists)
+ return TRUE;
while (TRUE)
{
@@ -148,8 +130,7 @@ _ostree_repo_prune_tmp (OstreeRepo *self,
struct dirent *dent;
if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error))
- goto out;
-
+ return FALSE;
if (dent == NULL)
break;
@@ -166,18 +147,12 @@ _ostree_repo_prune_tmp (OstreeRepo *self,
if (has_sig_suffix)
dent->d_name[len - 4] = '.';
- if (unlinkat (fd, dent->d_name, 0) < 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ if (unlinkat (dfd_iter.fd, dent->d_name, 0) < 0)
+ return glnx_throw_errno_prefix (error, "unlinkat");
}
}
- ret = TRUE;
-
- out:
- return ret;
+ return TRUE;
}
@@ -198,22 +173,17 @@ ostree_repo_prune_static_deltas (OstreeRepo *self, const char *commit,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
g_autoptr(GPtrArray) deltas = NULL;
- guint i;
-
if (!ostree_repo_list_static_delta_names (self, &deltas,
cancellable, error))
- goto out;
+ return FALSE;
- for (i = 0; i < deltas->len; i++)
+ for (guint i = 0; i < deltas->len; i++)
{
const char *deltaname = deltas->pdata[i];
const char *dash = strchr (deltaname, '-');
const char *to = NULL;
- gboolean have_commit;
g_autofree char *from = NULL;
- g_autofree char *deltadir = NULL;
if (!dash)
{
@@ -232,26 +202,24 @@ ostree_repo_prune_static_deltas (OstreeRepo *self, const char *commit,
}
else
{
+ gboolean have_commit;
if (!ostree_repo_has_object (self, OSTREE_OBJECT_TYPE_COMMIT,
to, &have_commit,
cancellable, error))
- goto out;
+ return FALSE;
if (have_commit)
continue;
}
g_debug ("Trying to prune static delta %s", deltaname);
- deltadir = _ostree_get_relative_static_delta_path (from, to, NULL);
-
+ g_autofree char *deltadir = _ostree_get_relative_static_delta_path (from, to, NULL);
if (!glnx_shutil_rm_rf_at (self->repo_dir_fd, deltadir,
- cancellable, error))
- goto out;
+ cancellable, error))
+ return FALSE;
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
static gboolean
@@ -264,13 +232,14 @@ repo_prune_internal (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
GHashTableIter hash_iter;
gpointer key, value;
OtPruneData data = { 0, };
data.repo = self;
- data.reachable = g_hash_table_ref (options->reachable);
+ /* We unref this when we're done */
+ g_autoptr(GHashTable) reachable_owned = g_hash_table_ref (options->reachable);
+ data.reachable = reachable_owned;
g_hash_table_iter_init (&hash_iter, objects);
while (g_hash_table_iter_next (&hash_iter, &key, &value))
@@ -289,24 +258,20 @@ repo_prune_internal (OstreeRepo *self,
if (!maybe_prune_loose_object (&data, options->flags, checksum, objtype,
cancellable, error))
- goto out;
+ return FALSE;
}
if (!ostree_repo_prune_static_deltas (self, NULL, cancellable, error))
- goto out;
+ return FALSE;
if (!_ostree_repo_prune_tmp (self, cancellable, error))
- goto out;
+ return FALSE;
- ret = TRUE;
*out_objects_total = (data.n_reachable_meta + data.n_unreachable_meta +
data.n_reachable_content + data.n_unreachable_content);
*out_objects_pruned = (data.n_unreachable_meta + data.n_unreachable_content);
*out_pruned_object_size_total = data.freed_bytes;
- out:
- if (data.reachable)
- g_hash_table_unref (data.reachable);
- return ret;
+ return TRUE;
}
/**
diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c
index a7a3a5b0..f1dae995 100644
--- a/src/libostree/ostree-repo-pull.c
+++ b/src/libostree/ostree-repo-pull.c
@@ -68,6 +68,7 @@ typedef struct {
gboolean gpg_verify;
gboolean require_static_deltas;
+ gboolean disable_static_deltas;
gboolean gpg_verify_summary;
gboolean has_tombstone_commits;
@@ -210,38 +211,38 @@ update_progress (gpointer user_data)
n_scanned_metadata = pull_data->n_scanned_metadata;
start_time = pull_data->start_time;
- ostree_async_progress_set_uint (pull_data->progress, "outstanding-fetches", outstanding_fetches);
- ostree_async_progress_set_uint (pull_data->progress, "outstanding-writes", outstanding_writes);
- ostree_async_progress_set_uint (pull_data->progress, "fetched", fetched);
- ostree_async_progress_set_uint (pull_data->progress, "requested", requested);
- ostree_async_progress_set_uint (pull_data->progress, "scanning", g_queue_is_empty (&pull_data->scan_object_queue) ? 0 : 1);
- ostree_async_progress_set_uint (pull_data->progress, "scanned-metadata", n_scanned_metadata);
- ostree_async_progress_set_uint64 (pull_data->progress, "bytes-transferred", bytes_transferred);
- ostree_async_progress_set_uint64 (pull_data->progress, "start-time", start_time);
-
- /* Deltas */
- ostree_async_progress_set_uint (pull_data->progress, "fetched-delta-parts",
- pull_data->n_fetched_deltaparts);
- ostree_async_progress_set_uint (pull_data->progress, "total-delta-parts",
- pull_data->n_total_deltaparts);
- ostree_async_progress_set_uint (pull_data->progress, "fetched-delta-fallbacks",
- pull_data->n_fetched_deltapart_fallbacks);
- ostree_async_progress_set_uint (pull_data->progress, "total-delta-fallbacks",
- pull_data->n_total_delta_fallbacks);
- ostree_async_progress_set_uint64 (pull_data->progress, "fetched-delta-part-size",
- pull_data->fetched_deltapart_size);
- ostree_async_progress_set_uint64 (pull_data->progress, "total-delta-part-size",
- pull_data->total_deltapart_size);
- ostree_async_progress_set_uint64 (pull_data->progress, "total-delta-part-usize",
- pull_data->total_deltapart_usize);
- ostree_async_progress_set_uint (pull_data->progress, "total-delta-superblocks",
- pull_data->static_delta_superblocks->len);
-
- /* We fetch metadata before content. These allow us to report metadata fetch progress specifically. */
- ostree_async_progress_set_uint (pull_data->progress, "outstanding-metadata-fetches", pull_data->n_outstanding_metadata_fetches);
- ostree_async_progress_set_uint (pull_data->progress, "metadata-fetched", pull_data->n_fetched_metadata);
-
- ostree_async_progress_set_status (pull_data->progress, NULL);
+ ostree_async_progress_set (pull_data->progress,
+ "outstanding-fetches", "u", outstanding_fetches,
+ "outstanding-writes", "u", outstanding_writes,
+ "fetched", "u", fetched,
+ "requested", "u", requested,
+ "scanning", "u", g_queue_is_empty (&pull_data->scan_object_queue) ? 0 : 1,
+ "scanned-metadata", "u", n_scanned_metadata,
+ "bytes-transferred", "t", bytes_transferred,
+ "start-time", "t", start_time,
+ /* Deltas */
+ "fetched-delta-parts",
+ "u", pull_data->n_fetched_deltaparts,
+ "total-delta-parts",
+ "u", pull_data->n_total_deltaparts,
+ "fetched-delta-fallbacks",
+ "u", pull_data->n_fetched_deltapart_fallbacks,
+ "total-delta-fallbacks",
+ "u", pull_data->n_total_delta_fallbacks,
+ "fetched-delta-part-size",
+ "t", pull_data->fetched_deltapart_size,
+ "total-delta-part-size",
+ "t", pull_data->total_deltapart_size,
+ "total-delta-part-usize",
+ "t", pull_data->total_deltapart_usize,
+ "total-delta-superblocks",
+ "u", pull_data->static_delta_superblocks->len,
+ /* We fetch metadata before content. These allow us to report metadata fetch progress specifically. */
+ "outstanding-metadata-fetches", "u", pull_data->n_outstanding_metadata_fetches,
+ "metadata-fetched", "u", pull_data->n_fetched_metadata,
+ /* Overall status. */
+ "status", "s", "",
+ NULL);
if (pull_data->dry_run)
pull_data->dry_run_emitted_progress = TRUE;
@@ -436,32 +437,22 @@ fetch_mirrored_uri_contents_utf8_sync (OstreeFetcher *fetcher,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
g_autoptr(GBytes) bytes = NULL;
- g_autofree char *ret_contents = NULL;
- gsize len;
-
if (!_ostree_fetcher_mirrored_request_to_membuf (fetcher, mirrorlist,
filename, TRUE, FALSE,
&bytes,
OSTREE_MAX_METADATA_SIZE,
cancellable, error))
- goto out;
+ return FALSE;
- ret_contents = g_bytes_unref_to_data (bytes, &len);
- bytes = NULL;
+ gsize len;
+ g_autofree char *ret_contents = g_bytes_unref_to_data (g_steal_pointer (&bytes), &len);
if (!g_utf8_validate (ret_contents, -1, NULL))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Invalid UTF-8");
- goto out;
- }
+ return glnx_throw (error, "Invalid UTF-8");
- ret = TRUE;
ot_transfer_out_value (out_contents, &ret_contents);
- out:
- return ret;
+ return TRUE;
}
static gboolean
@@ -484,16 +475,11 @@ write_commitpartial_for (OtPullData *pull_data,
GError **error)
{
g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (checksum);
- glnx_fd_close int fd = -1;
-
- fd = openat (pull_data->repo->repo_dir_fd, commitpartial_path, O_EXCL | O_CREAT | O_WRONLY | O_CLOEXEC | O_NOCTTY, 0644);
+ glnx_fd_close int fd = openat (pull_data->repo->repo_dir_fd, commitpartial_path, O_EXCL | O_CREAT | O_WRONLY | O_CLOEXEC | O_NOCTTY, 0644);
if (fd == -1)
{
if (errno != EEXIST)
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
+ return glnx_throw_errno_prefix (error, "open(%s)", commitpartial_path);
}
return TRUE;
}
@@ -554,15 +540,12 @@ pull_matches_subdir (OtPullData *pull_data,
const char *basename,
gboolean basename_is_dir)
{
- int i;
- g_autofree char *file = NULL;
-
if (pull_data->dirs == NULL)
return TRUE;
- file = g_strconcat (path, basename, NULL);
+ g_autofree char *file = g_strconcat (path, basename, NULL);
- for (i = 0; i < pull_data->dirs->len; i++)
+ for (guint i = 0; i < pull_data->dirs->len; i++)
{
const char *pull_dir = g_ptr_array_index (pull_data->dirs, i);
if (matches_pull_dir (file, pull_dir, basename_is_dir))
@@ -580,30 +563,18 @@ scan_dirtree_object (OtPullData *pull_data,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- int i, n;
- g_autoptr(GVariant) tree = NULL;
- g_autoptr(GVariant) files_variant = NULL;
- g_autoptr(GVariant) dirs_variant = NULL;
- const char *dirname = NULL;
-
if (recursion_depth > OSTREE_MAX_RECURSION)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Exceeded maximum recursion");
- goto out;
- }
+ return glnx_throw (error, "Exceeded maximum recursion");
+ g_autoptr(GVariant) tree = NULL;
if (!ostree_repo_load_variant (pull_data->repo, OSTREE_OBJECT_TYPE_DIR_TREE, checksum,
&tree, error))
- goto out;
+ return FALSE;
/* PARSE OSTREE_SERIALIZED_TREE_VARIANT */
- files_variant = g_variant_get_child_value (tree, 0);
- dirs_variant = g_variant_get_child_value (tree, 1);
-
- n = g_variant_n_children (files_variant);
- for (i = 0; i < n; i++)
+ g_autoptr(GVariant) files_variant = g_variant_get_child_value (tree, 0);
+ const guint n = g_variant_n_children (files_variant);
+ for (guint i = 0; i < n; i++)
{
const char *filename;
gboolean file_is_stored;
@@ -613,7 +584,7 @@ scan_dirtree_object (OtPullData *pull_data,
g_variant_get_child (files_variant, i, "(&s@ay)", &filename, &csum);
if (!ot_util_filename_validate (filename, error))
- goto out;
+ return FALSE;
/* Skip files if we're traversing a request only directory, unless it exactly
* matches the path */
@@ -624,14 +595,14 @@ scan_dirtree_object (OtPullData *pull_data,
if (!ostree_repo_has_object (pull_data->repo, OSTREE_OBJECT_TYPE_FILE, file_checksum,
&file_is_stored, cancellable, error))
- goto out;
+ return FALSE;
if (!file_is_stored && pull_data->remote_repo_local)
{
if (!ostree_repo_import_object_from_with_trust (pull_data->repo, pull_data->remote_repo_local,
OSTREE_OBJECT_TYPE_FILE, file_checksum, !pull_data->is_untrusted,
cancellable, error))
- goto out;
+ return FALSE;
}
else if (!file_is_stored && !g_hash_table_lookup (pull_data->requested_content, file_checksum))
{
@@ -641,44 +612,38 @@ scan_dirtree_object (OtPullData *pull_data,
}
}
- n = g_variant_n_children (dirs_variant);
-
- for (i = 0; i < n; i++)
+ g_autoptr(GVariant) dirs_variant = g_variant_get_child_value (tree, 1);
+ const guint m = g_variant_n_children (dirs_variant);
+ for (guint i = 0; i < m; i++)
{
+ const char *dirname = NULL;
g_autoptr(GVariant) tree_csum = NULL;
g_autoptr(GVariant) meta_csum = NULL;
- const guchar *tree_csum_bytes;
- const guchar *meta_csum_bytes;
- g_autofree char *subpath = NULL;
-
g_variant_get_child (dirs_variant, i, "(&s@ay@ay)",
&dirname, &tree_csum, &meta_csum);
if (!ot_util_filename_validate (dirname, error))
- goto out;
+ return FALSE;
if (!pull_matches_subdir (pull_data, path, dirname, TRUE))
continue;
- tree_csum_bytes = ostree_checksum_bytes_peek_validate (tree_csum, error);
+ const guchar *tree_csum_bytes = ostree_checksum_bytes_peek_validate (tree_csum, error);
if (tree_csum_bytes == NULL)
- goto out;
+ return FALSE;
- meta_csum_bytes = ostree_checksum_bytes_peek_validate (meta_csum, error);
+ const guchar *meta_csum_bytes = ostree_checksum_bytes_peek_validate (meta_csum, error);
if (meta_csum_bytes == NULL)
- goto out;
-
- subpath = g_strconcat (path, dirname, "/", NULL);
+ return FALSE;
+ g_autofree char *subpath = g_strconcat (path, dirname, "/", NULL);
queue_scan_one_metadata_object_c (pull_data, tree_csum_bytes,
OSTREE_OBJECT_TYPE_DIR_TREE, subpath, recursion_depth + 1);
queue_scan_one_metadata_object_c (pull_data, meta_csum_bytes,
OSTREE_OBJECT_TYPE_DIR_META, subpath, recursion_depth + 1);
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
static gboolean
@@ -688,27 +653,21 @@ fetch_ref_contents (OtPullData *pull_data,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
+ g_autofree char *filename = g_build_filename ("refs", "heads", ref, NULL);
g_autofree char *ret_contents = NULL;
- g_autofree char *filename = NULL;
-
- filename = g_build_filename ("refs", "heads", ref, NULL);
-
if (!fetch_mirrored_uri_contents_utf8_sync (pull_data->fetcher,
pull_data->meta_mirrorlist,
filename, &ret_contents,
cancellable, error))
- goto out;
+ return FALSE;
g_strchomp (ret_contents);
if (!ostree_validate_checksum_string (ret_contents, error))
- goto out;
+ return FALSE;
- ret = TRUE;
ot_transfer_out_value (out_contents, &ret_contents);
- out:
- return ret;
+ return TRUE;
}
static gboolean
@@ -718,34 +677,23 @@ lookup_commit_checksum_from_summary (OtPullData *pull_data,
gsize *out_size,
GError **error)
{
- gboolean ret = FALSE;
g_autoptr(GVariant) refs = g_variant_get_child_value (pull_data->summary, 0);
- g_autoptr(GVariant) refdata = NULL;
- g_autoptr(GVariant) reftargetdata = NULL;
+ int i;
+ if (!ot_variant_bsearch_str (refs, ref, &i))
+ return glnx_throw (error, "No such branch '%s' in repository summary", ref);
+
+ g_autoptr(GVariant) refdata = g_variant_get_child_value (refs, i);
+ g_autoptr(GVariant) reftargetdata = g_variant_get_child_value (refdata, 1);
guint64 commit_size;
g_autoptr(GVariant) commit_csum_v = NULL;
- int i;
-
- if (!ot_variant_bsearch_str (refs, ref, &i))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "No such branch '%s' in repository summary",
- ref);
- goto out;
- }
-
- refdata = g_variant_get_child_value (refs, i);
- reftargetdata = g_variant_get_child_value (refdata, 1);
g_variant_get (reftargetdata, "(t@ay@a{sv})", &commit_size, &commit_csum_v, NULL);
if (!ostree_validate_structureof_csum_v (commit_csum_v, error))
- goto out;
+ return FALSE;
- ret = TRUE;
*out_checksum = ostree_checksum_from_bytes_v (commit_csum_v);
*out_size = commit_size;
- out:
- return ret;
+ return TRUE;
}
static void
@@ -771,7 +719,7 @@ content_fetch_on_write_complete (GObject *object,
g_autofree char *checksum = NULL;
g_autofree char *checksum_obj = NULL;
- if (!ostree_repo_write_content_finish ((OstreeRepo*)object, result,
+ if (!ostree_repo_write_content_finish ((OstreeRepo*)object, result,
&csum, error))
goto out;
@@ -1879,10 +1827,15 @@ process_one_static_delta (OtPullData *pull_data,
/* Loop over the static delta data we got from the summary,
* and find the newest commit for @out_from_revision that
* goes to @to_revision.
+ *
+ * Additionally, @out_have_scratch_delta will be set to %TRUE
+ * if there is a %NULL → @to_revision delta, also known as
+ * a "from scratch" delta.
*/
static gboolean
get_best_static_delta_start_for (OtPullData *pull_data,
const char *to_revision,
+ gboolean *out_have_scratch_delta,
char **out_from_revision,
GCancellable *cancellable,
GError **error)
@@ -1897,6 +1850,8 @@ get_best_static_delta_start_for (OtPullData *pull_data,
g_assert (pull_data->summary_deltas_checksums != NULL);
g_hash_table_iter_init (&hiter, pull_data->summary_deltas_checksums);
+ *out_have_scratch_delta = FALSE;
+
/* Loop over all deltas known from the summary file,
* finding ones which go to to_revision */
while (g_hash_table_iter_next (&hiter, &hkey, &hvalue))
@@ -1915,6 +1870,8 @@ get_best_static_delta_start_for (OtPullData *pull_data,
if (cur_from_rev)
g_ptr_array_add (candidates, g_steal_pointer (&cur_from_rev));
+ else
+ *out_have_scratch_delta = TRUE;
}
/* Loop over our candidates, find the newest one */
@@ -1963,6 +1920,16 @@ typedef struct {
char *to_revision;
} FetchDeltaSuperData;
+static void
+set_required_deltas_error (GError **error,
+ const char *from_revision,
+ const char *to_revision)
+{
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Static deltas required, but none found for %s to %s",
+ from_revision, to_revision);
+}
+
static void
on_superblock_fetched (GObject *src,
GAsyncResult *res,
@@ -1984,14 +1951,11 @@ on_superblock_fetched (GObject *src,
{
if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
goto out;
-
g_clear_error (&local_error);
if (pull_data->require_static_deltas)
{
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Static deltas required, but none found for %s to %s",
- from_revision, to_revision);
+ set_required_deltas_error (error, from_revision, to_revision);
goto out;
}
@@ -2442,11 +2406,15 @@ repo_remote_fetch_summary (OstreeRepo *self,
g_autoptr(GMainContext) mainctx = NULL;
gboolean ret = FALSE;
gboolean from_cache = FALSE;
- g_autofree char *url_override = NULL;
+ const char *url_override = NULL;
+ g_autoptr(GVariant) extra_headers = NULL;
g_autoptr(GPtrArray) mirrorlist = NULL;
if (options)
- (void) g_variant_lookup (options, "override-url", "&s", &url_override);
+ {
+ (void) g_variant_lookup (options, "override-url", "&s", &url_override);
+ (void) g_variant_lookup (options, "http-headers", "@a(ss)", &extra_headers);
+ }
mainctx = g_main_context_new ();
g_main_context_push_thread_default (mainctx);
@@ -2455,6 +2423,9 @@ repo_remote_fetch_summary (OstreeRepo *self,
if (fetcher == NULL)
goto out;
+ if (extra_headers)
+ _ostree_fetcher_set_extra_headers (fetcher, extra_headers);
+
{
g_autofree char *url_string = NULL;
if (metalink_url_string)
@@ -2566,6 +2537,117 @@ reinitialize_fetcher (OtPullData *pull_data, const char *remote_name, GError **e
return TRUE;
}
+/* Start a request for a static delta */
+static void
+initiate_delta_request (OtPullData *pull_data,
+ const char *from_revision,
+ const char *to_revision)
+{
+ g_autofree char *delta_name =
+ _ostree_get_relative_static_delta_superblock_path (from_revision, to_revision);
+ FetchDeltaSuperData *fdata = g_new0(FetchDeltaSuperData, 1);
+ fdata->pull_data = pull_data;
+ fdata->from_revision = g_strdup (from_revision);
+ fdata->to_revision = g_strdup (to_revision);
+
+ _ostree_fetcher_request_to_membuf (pull_data->fetcher,
+ pull_data->content_mirrorlist,
+ delta_name, 0,
+ OSTREE_MAX_METADATA_SIZE,
+ 0, pull_data->cancellable,
+ on_superblock_fetched, fdata);
+ pull_data->n_outstanding_metadata_fetches++;
+ pull_data->n_requested_metadata++;
+}
+
+/* @ref - Optional ref name
+ * @to_revision: Target commit revision we want to fetch
+ *
+ * Start a request for either a ref or a commit. In the
+ * ref case, we know both the name and the target commit.
+ *
+ * This function primarily handles the semantics around
+ * `disable_static_deltas` and `require_static_deltas`.
+ */
+static gboolean
+initiate_request (OtPullData *pull_data,
+ const char *ref,
+ const char *to_revision,
+ GError **error)
+{
+ g_autofree char *delta_from_revision = NULL;
+
+ /* Are deltas disabled? OK, just start an object fetch and be done */
+ if (pull_data->disable_static_deltas)
+ {
+ queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, 0);
+ return TRUE;
+ }
+
+ /* If we have a summary, we can use the newer logic */
+ if (pull_data->summary)
+ {
+ gboolean have_scratch_delta = FALSE;
+
+ /* Look for a delta to @to_revision in the summary data */
+ if (!get_best_static_delta_start_for (pull_data, to_revision,
+ &have_scratch_delta, &delta_from_revision,
+ pull_data->cancellable, error))
+ return FALSE;
+
+ if (delta_from_revision) /* Did we find a delta FROM commit? */
+ initiate_delta_request (pull_data, delta_from_revision, to_revision);
+ else if (have_scratch_delta) /* No delta FROM, do we have a scratch? */
+ initiate_delta_request (pull_data, NULL, to_revision);
+ else if (pull_data->require_static_deltas) /* No deltas found; are they required? */
+ {
+ set_required_deltas_error (error, ref, to_revision);
+ return FALSE;
+ }
+ else /* No deltas, fall back to object fetches. */
+ queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, 0);
+ }
+ else if (ref != NULL)
+ {
+ /* Are we doing a delta via a ref? In that case we can fall back to the older
+ * logic of just using the current tip of the ref as a delta FROM source. */
+ if (!ostree_repo_resolve_rev (pull_data->repo, ref, TRUE,
+ &delta_from_revision, error))
+ return FALSE;
+
+ /* Determine whether the from revision we have is partial; this
+ * can happen if e.g. one uses `ostree pull --commit-metadata-only`.
+ * This mirrors the logic in get_best_static_delta_start_for().
+ */
+ if (delta_from_revision)
+ {
+ OstreeRepoCommitState from_commitstate;
+
+ if (!ostree_repo_load_commit (pull_data->repo, delta_from_revision, NULL,
+ &from_commitstate, error))
+ return FALSE;
+
+ /* Was it partial? Then we can't use it. */
+ if (commitstate_is_partial (pull_data, from_commitstate))
+ g_clear_pointer (&delta_from_revision, g_free);
+ }
+
+ /* This is similar to the below, except we *might* use the previous
+ * commit, or we might do a scratch delta first.
+ */
+ initiate_delta_request (pull_data, delta_from_revision ?: NULL, to_revision);
+ }
+ else
+ {
+ /* Legacy path without a summary file - let's try a scratch delta, if that
+ * doesn't work, it'll drop down to object requests.
+ */
+ initiate_delta_request (pull_data, NULL, to_revision);
+ }
+
+ return TRUE;
+}
+
/* ------------------------------------------------------------------------------------------
* Below is the libsoup-invariant API; these should match
* the stub functions in the #else clause
@@ -2597,7 +2679,7 @@ reinitialize_fetcher (OtPullData *pull_data, const char *remote_name, GError **e
* * override-commit-ids (as): Array of specific commit IDs to fetch for refs
* * dry-run (b): Only print information on what will be downloaded (requires static deltas)
* * override-url (s): Fetch objects from this URL if remote specifies no metalink in options
- * * inherit-transaction (b): Don't initiate, finish or abort a transaction, usefult to do mutliple pulls in one transaction.
+ * * inherit-transaction (b): Don't initiate, finish or abort a transaction, usefult to do multiple pulls in one transaction.
* * http-headers (a(ss)): Additional headers to add to all HTTP requests
* * update-frequency (u): Frequency to call the async progress callback in milliseconds, if any; only values higher than 0 are valid
*/
@@ -2631,7 +2713,6 @@ ostree_repo_pull_with_options (OstreeRepo *self,
g_autofree char **refs_to_fetch = NULL;
g_autofree char **override_commit_ids = NULL;
GSource *update_timeout = NULL;
- gboolean disable_static_deltas = FALSE;
gboolean opt_gpg_verify_set = FALSE;
gboolean opt_gpg_verify_summary_set = FALSE;
const char *url_override = NULL;
@@ -2653,7 +2734,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
opt_gpg_verify_summary_set =
g_variant_lookup (options, "gpg-verify-summary", "b", &pull_data->gpg_verify_summary);
(void) g_variant_lookup (options, "depth", "i", &pull_data->maxdepth);
- (void) g_variant_lookup (options, "disable-static-deltas", "b", &disable_static_deltas);
+ (void) g_variant_lookup (options, "disable-static-deltas", "b", &pull_data->disable_static_deltas);
(void) g_variant_lookup (options, "require-static-deltas", "b", &pull_data->require_static_deltas);
(void) g_variant_lookup (options, "override-commit-ids", "^a&s", &override_commit_ids);
(void) g_variant_lookup (options, "dry-run", "b", &pull_data->dry_run);
@@ -2673,7 +2754,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
for (i = 0; dirs_to_pull != NULL && dirs_to_pull[i] != NULL; i++)
g_return_val_if_fail (dirs_to_pull[i][0] == '/', FALSE);
- g_return_val_if_fail (!(disable_static_deltas && pull_data->require_static_deltas), FALSE);
+ g_return_val_if_fail (!(pull_data->disable_static_deltas && pull_data->require_static_deltas), FALSE);
/* We only do dry runs with static deltas, because we don't really have any
* in-advance information for bare fetches.
@@ -2952,7 +3033,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
* exact object files are copied.
*/
if (pull_data->remote_repo_local && !pull_data->require_static_deltas)
- disable_static_deltas = TRUE;
+ pull_data->disable_static_deltas = TRUE;
/* We can't use static deltas if pulling into an archive-z2 repo. */
if (self->mode == OSTREE_REPO_MODE_ARCHIVE_Z2)
@@ -2963,13 +3044,13 @@ ostree_repo_pull_with_options (OstreeRepo *self,
"Can't use static deltas in an archive repo");
goto out;
}
- disable_static_deltas = TRUE;
+ pull_data->disable_static_deltas = TRUE;
}
/* It's not efficient to use static deltas if all we want is the commit
* metadata. */
if (pull_data->is_commit_only)
- disable_static_deltas = TRUE;
+ pull_data->disable_static_deltas = TRUE;
pull_data->static_delta_superblocks = g_ptr_array_new_with_free_func ((GDestroyNotify)g_variant_unref);
@@ -3239,78 +3320,23 @@ ostree_repo_pull_with_options (OstreeRepo *self,
if (pull_data->legacy_transaction_resuming)
g_debug ("resuming legacy transaction");
+ /* Initiate requests for explicit commit revisions */
g_hash_table_iter_init (&hash_iter, commits_to_fetch);
while (g_hash_table_iter_next (&hash_iter, &key, &value))
{
const char *commit = value;
- queue_scan_one_metadata_object (pull_data, commit, OSTREE_OBJECT_TYPE_COMMIT, NULL, 0);
+ if (!initiate_request (pull_data, NULL, commit, error))
+ goto out;
}
+ /* Initiate requests for refs */
g_hash_table_iter_init (&hash_iter, requested_refs_to_fetch);
while (g_hash_table_iter_next (&hash_iter, &key, &value))
{
- g_autofree char *from_revision = NULL;
const char *ref = key;
const char *to_revision = value;
- gboolean have_valid_from_commit = TRUE;
-
- /* If we have a summary, find the latest local commit we have
- * to use as a from revision for static deltas.
- */
- if (pull_data->summary)
- {
- if (!get_best_static_delta_start_for (pull_data, to_revision, &from_revision,
- cancellable, error))
- goto out;
- }
- else
- {
- if (!ostree_repo_resolve_rev (pull_data->repo, ref, TRUE,
- &from_revision, error))
- goto out;
-
- /* Determine whether the from revision we have is partial; this
- * can happen if e.g. one uses `ostree pull --commit-metadata-only`.
- * This mirrors the logic in get_best_static_delta_start_for().
- */
- if (from_revision)
- {
- OstreeRepoCommitState from_commitstate;
-
- if (!ostree_repo_load_commit (pull_data->repo, from_revision, NULL,
- &from_commitstate, error))
- goto out;
-
- /* Was it partial? OK, we can't use it. */
- if (commitstate_is_partial (pull_data, from_commitstate))
- have_valid_from_commit = FALSE;
- }
- }
-
- if (!disable_static_deltas &&
- have_valid_from_commit &&
- (from_revision == NULL || g_strcmp0 (from_revision, to_revision) != 0))
- {
- g_autofree char *delta_name =
- _ostree_get_relative_static_delta_superblock_path (from_revision, to_revision);
- FetchDeltaSuperData *fdata = g_new0(FetchDeltaSuperData, 1);
- fdata->pull_data = pull_data;
- fdata->from_revision = g_strdup (from_revision);
- fdata->to_revision = g_strdup (to_revision);
-
- _ostree_fetcher_request_to_membuf (pull_data->fetcher,
- pull_data->content_mirrorlist,
- delta_name, 0,
- OSTREE_MAX_METADATA_SIZE,
- 0, pull_data->cancellable,
- on_superblock_fetched, fdata);
- pull_data->n_outstanding_metadata_fetches++;
- pull_data->n_requested_metadata++;
- }
- else
- {
- queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, 0);
- }
+ if (!initiate_request (pull_data, ref, to_revision, error))
+ goto out;
}
if (pull_data->progress)
@@ -3402,8 +3428,11 @@ ostree_repo_pull_with_options (OstreeRepo *self,
bytes_transferred = _ostree_fetcher_bytes_transferred (pull_data->fetcher);
if (bytes_transferred > 0 && pull_data->progress)
{
- guint shift;
- GString *buf = g_string_new ("");
+ guint shift;
+ g_autoptr(GString) buf = g_string_new ("");
+
+ /* Ensure the rest of the progress keys are set appropriately. */
+ update_progress (pull_data);
if (bytes_transferred < 1024)
shift = 1;
@@ -3424,7 +3453,6 @@ ostree_repo_pull_with_options (OstreeRepo *self,
(guint) ((end_time - pull_data->start_time) / G_USEC_PER_SEC));
ostree_async_progress_set_status (pull_data->progress, buf->str);
- g_string_free (buf, TRUE);
}
/* iterate over commits fetched and delete any commitpartial files */
@@ -3510,6 +3538,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
* The following are currently defined:
*
* - override-url (s): Fetch summary from this URL if remote specifies no metalink in options
+ * - http-headers (a(ss)): Additional headers to add to all HTTP requests
*
* Returns: %TRUE on success, %FALSE on failure
*/
diff --git a/src/libostree/ostree-repo-static-delta-core.c b/src/libostree/ostree-repo-static-delta-core.c
index 21ed081d..3a14f8bb 100644
--- a/src/libostree/ostree-repo-static-delta-core.c
+++ b/src/libostree/ostree-repo-static-delta-core.c
@@ -73,99 +73,89 @@ ostree_repo_list_static_delta_names (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- g_autoptr(GPtrArray) ret_deltas = NULL;
- glnx_fd_close int dfd = -1;
+ g_autoptr(GPtrArray) ret_deltas = g_ptr_array_new_with_free_func (g_free);
- ret_deltas = g_ptr_array_new_with_free_func (g_free);
-
- dfd = glnx_opendirat_with_errno (self->repo_dir_fd, "deltas", TRUE);
- if (dfd < 0)
+ g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
+ gboolean exists;
+ if (!ot_dfd_iter_init_allow_noent (self->repo_dir_fd, "deltas", &dfd_iter,
+ &exists, error))
+ return FALSE;
+ if (!exists)
{
- if (errno != ENOENT)
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
+ /* Note early return */
+ ot_transfer_out_value (out_deltas, &ret_deltas);
+ return TRUE;
}
- else
- {
- g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
- if (!glnx_dirfd_iterator_init_take_fd (dfd, &dfd_iter, error))
+ while (TRUE)
+ {
+ g_auto(GLnxDirFdIterator) sub_dfd_iter = { 0, };
+ struct dirent *dent;
+
+ if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
+ return FALSE;
+ if (dent == NULL)
+ break;
+ if (dent->d_type != DT_DIR)
+ continue;
+
+ if (!glnx_dirfd_iterator_init_at (dfd_iter.fd, dent->d_name, FALSE,
+ &sub_dfd_iter, error))
return FALSE;
- dfd = -1;
while (TRUE)
{
- g_auto(GLnxDirFdIterator) sub_dfd_iter = { 0, };
- struct dirent *dent;
+ struct dirent *sub_dent;
+ const char *name1;
+ const char *name2;
+ g_autofree char *superblock_subpath = NULL;
+ struct stat stbuf;
- if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
+ if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&sub_dfd_iter, &sub_dent,
+ cancellable, error))
return FALSE;
- if (dent == NULL)
+ if (sub_dent == NULL)
break;
if (dent->d_type != DT_DIR)
continue;
- if (!glnx_dirfd_iterator_init_at (dfd_iter.fd, dent->d_name, FALSE,
- &sub_dfd_iter, error))
- return FALSE;
+ name1 = dent->d_name;
+ name2 = sub_dent->d_name;
- while (TRUE)
+ superblock_subpath = g_strconcat (name2, "/superblock", NULL);
+ if (fstatat (sub_dfd_iter.fd, superblock_subpath, &stbuf, 0) < 0)
{
- struct dirent *sub_dent;
- const char *name1;
- const char *name2;
- g_autofree char *superblock_subpath = NULL;
- struct stat stbuf;
-
- if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&sub_dfd_iter, &sub_dent,
- cancellable, error))
- return FALSE;
- if (sub_dent == NULL)
- break;
- if (dent->d_type != DT_DIR)
- continue;
-
- name1 = dent->d_name;
- name2 = sub_dent->d_name;
-
- superblock_subpath = g_strconcat (name2, "/superblock", NULL);
- if (fstatat (sub_dfd_iter.fd, superblock_subpath, &stbuf, 0) < 0)
+ if (errno != ENOENT)
{
- if (errno != ENOENT)
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
+ glnx_set_error_from_errno (error);
+ return FALSE;
}
- else
- {
- g_autofree char *buf = g_strconcat (name1, name2, NULL);
- GString *out = g_string_new ("");
- char checksum[OSTREE_SHA256_STRING_LEN+1];
- guchar csum[OSTREE_SHA256_DIGEST_LEN];
- const char *dash = strchr (buf, '-');
+ }
+ else
+ {
+ g_autofree char *buf = g_strconcat (name1, name2, NULL);
+ GString *out = g_string_new ("");
+ char checksum[OSTREE_SHA256_STRING_LEN+1];
+ guchar csum[OSTREE_SHA256_DIGEST_LEN];
+ const char *dash = strchr (buf, '-');
- ostree_checksum_b64_inplace_to_bytes (buf, csum);
+ ostree_checksum_b64_inplace_to_bytes (buf, csum);
+ ostree_checksum_inplace_from_bytes (csum, checksum);
+ g_string_append (out, checksum);
+ if (dash)
+ {
+ g_string_append_c (out, '-');
+ ostree_checksum_b64_inplace_to_bytes (dash+1, csum);
ostree_checksum_inplace_from_bytes (csum, checksum);
g_string_append (out, checksum);
- if (dash)
- {
- g_string_append_c (out, '-');
- ostree_checksum_b64_inplace_to_bytes (dash+1, csum);
- ostree_checksum_inplace_from_bytes (csum, checksum);
- g_string_append (out, checksum);
- }
-
- g_ptr_array_add (ret_deltas, g_string_free (out, FALSE));
}
+
+ g_ptr_array_add (ret_deltas, g_string_free (out, FALSE));
}
}
}
- if (out_deltas)
- *out_deltas = g_steal_pointer (&ret_deltas);
+ ot_transfer_out_value (out_deltas, &ret_deltas);
return TRUE;
}
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index c8a12543..2ef64ec0 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -32,6 +32,7 @@
#include
#include "ostree-core-private.h"
+#include "ostree-remote-private.h"
#include "ostree-repo-private.h"
#include "ostree-repo-file.h"
#include "ostree-repo-file-enumerator.h"
@@ -104,94 +105,10 @@ G_DEFINE_TYPE (OstreeRepo, ostree_repo, G_TYPE_OBJECT)
#define SYSCONF_REMOTES SHORTENED_SYSCONFDIR "/ostree/remotes.d"
-typedef struct {
- volatile int ref_count;
- char *name;
- char *group; /* group name in options */
- char *keyring; /* keyring name (NAME.trustedkeys.gpg) */
- GFile *file; /* NULL if remote defined in repo/config */
- GKeyFile *options;
-} OstreeRemote;
-
-static OstreeRemote *
-ost_remote_new (void)
-{
- OstreeRemote *remote;
-
- remote = g_slice_new0 (OstreeRemote);
- remote->ref_count = 1;
- remote->options = g_key_file_new ();
-
- return remote;
-}
-
-static OstreeRemote *
-ost_remote_new_from_keyfile (GKeyFile *keyfile,
- const gchar *group)
-{
- g_autoptr(GMatchInfo) match = NULL;
- OstreeRemote *remote;
-
- static gsize regex_initialized;
- static GRegex *regex;
-
- if (g_once_init_enter (®ex_initialized))
- {
- regex = g_regex_new ("^remote \"(.+)\"$", 0, 0, NULL);
- g_assert (regex);
- g_once_init_leave (®ex_initialized, 1);
- }
-
- /* Sanity check */
- g_return_val_if_fail (g_key_file_has_group (keyfile, group), NULL);
-
- /* If group name doesn't fit the pattern, fail. */
- if (!g_regex_match (regex, group, 0, &match))
- return NULL;
-
- remote = ost_remote_new ();
- remote->name = g_match_info_fetch (match, 1);
- remote->group = g_strdup (group);
- remote->keyring = g_strdup_printf ("%s.trustedkeys.gpg", remote->name);
-
- ot_keyfile_copy_group (keyfile, remote->options, group);
-
- return remote;
-}
-
-static OstreeRemote *
-ost_remote_ref (OstreeRemote *remote)
-{
- gint refcount;
- g_return_val_if_fail (remote != NULL, NULL);
- refcount = g_atomic_int_add (&remote->ref_count, 1);
- g_assert (refcount > 0);
- return remote;
-}
-
-static void
-ost_remote_unref (OstreeRemote *remote)
-{
- g_return_if_fail (remote != NULL);
- g_return_if_fail (remote->ref_count > 0);
-
- if (g_atomic_int_dec_and_test (&remote->ref_count))
- {
- g_clear_pointer (&remote->name, g_free);
- g_clear_pointer (&remote->group, g_free);
- g_clear_pointer (&remote->keyring, g_free);
- g_clear_object (&remote->file);
- g_clear_pointer (&remote->options, g_key_file_free);
- g_slice_free (OstreeRemote, remote);
- }
-}
-
-G_DEFINE_AUTOPTR_CLEANUP_FUNC(OstreeRemote, ost_remote_unref)
-
-static OstreeRemote *
-ost_repo_get_remote (OstreeRepo *self,
- const char *name,
- GError **error)
+OstreeRemote *
+_ostree_repo_get_remote (OstreeRepo *self,
+ const char *name,
+ GError **error)
{
OstreeRemote *remote = NULL;
@@ -202,7 +119,7 @@ ost_repo_get_remote (OstreeRepo *self,
remote = g_hash_table_lookup (self->remotes, name);
if (remote != NULL)
- ost_remote_ref (remote);
+ ostree_remote_ref (remote);
else
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"Remote \"%s\" not found", name);
@@ -212,19 +129,19 @@ ost_repo_get_remote (OstreeRepo *self,
return remote;
}
-static OstreeRemote *
-ost_repo_get_remote_inherited (OstreeRepo *self,
- const char *name,
- GError **error)
+OstreeRemote *
+_ostree_repo_get_remote_inherited (OstreeRepo *self,
+ const char *name,
+ GError **error)
{
g_autoptr(OstreeRemote) remote = NULL;
g_autoptr(GError) temp_error = NULL;
- remote = ost_repo_get_remote (self, name, &temp_error);
+ remote = _ostree_repo_get_remote (self, name, &temp_error);
if (remote == NULL)
{
if (self->parent_repo != NULL)
- return ost_repo_get_remote_inherited (self->parent_repo, name, error);
+ return _ostree_repo_get_remote_inherited (self->parent_repo, name, error);
g_propagate_error (error, g_steal_pointer (&temp_error));
return NULL;
@@ -233,9 +150,9 @@ ost_repo_get_remote_inherited (OstreeRepo *self,
return g_steal_pointer (&remote);
}
-static void
-ost_repo_add_remote (OstreeRepo *self,
- OstreeRemote *remote)
+void
+_ostree_repo_add_remote (OstreeRepo *self,
+ OstreeRemote *remote)
{
g_return_if_fail (self != NULL);
g_return_if_fail (remote != NULL);
@@ -243,7 +160,7 @@ ost_repo_add_remote (OstreeRepo *self,
g_mutex_lock (&self->remotes_lock);
- g_hash_table_replace (self->remotes, remote->name, ost_remote_ref (remote));
+ g_hash_table_replace (self->remotes, remote->name, ostree_remote_ref (remote));
g_mutex_unlock (&self->remotes_lock);
}
@@ -308,7 +225,7 @@ ostree_repo_get_remote_option (OstreeRepo *self,
return TRUE;
}
- remote = ost_repo_get_remote (self, remote_name, &temp_error);
+ remote = _ostree_repo_get_remote (self, remote_name, &temp_error);
if (remote != NULL)
{
value = g_key_file_get_string (remote->options, remote->group, option_name, &temp_error);
@@ -385,7 +302,7 @@ ostree_repo_get_remote_list_option (OstreeRepo *self,
return TRUE;
}
- remote = ost_repo_get_remote (self, remote_name, &temp_error);
+ remote = _ostree_repo_get_remote (self, remote_name, &temp_error);
if (remote != NULL)
{
value = g_key_file_get_string_list (remote->options,
@@ -461,7 +378,7 @@ ostree_repo_get_remote_boolean_option (OstreeRepo *self,
return TRUE;
}
- remote = ost_repo_get_remote (self, remote_name, &temp_error);
+ remote = _ostree_repo_get_remote (self, remote_name, &temp_error);
if (remote != NULL)
{
value = g_key_file_get_boolean (remote->options, remote->group, option_name, &temp_error);
@@ -517,7 +434,6 @@ ostree_repo_finalize (GObject *object)
(void) close (self->commit_stagedir_fd);
g_free (self->commit_stagedir_name);
glnx_release_lock_file (&self->commit_stagedir_lock);
- g_clear_object (&self->tmp_dir);
if (self->tmp_dir_fd != -1)
(void) close (self->tmp_dir_fd);
if (self->cache_dir_fd != -1)
@@ -536,10 +452,9 @@ ostree_repo_finalize (GObject *object)
if (self->config)
g_key_file_free (self->config);
g_clear_pointer (&self->txn_refs, g_hash_table_destroy);
- g_clear_pointer (&self->cached_meta_indexes, (GDestroyNotify) g_ptr_array_unref);
- g_clear_pointer (&self->cached_content_indexes, (GDestroyNotify) g_ptr_array_unref);
g_clear_error (&self->writable_error);
g_clear_pointer (&self->object_sizes, (GDestroyNotify) g_hash_table_unref);
+ g_clear_pointer (&self->dirmeta_cache, (GDestroyNotify) g_hash_table_unref);
g_mutex_clear (&self->cache_lock);
g_mutex_clear (&self->txn_stats_lock);
@@ -606,8 +521,6 @@ ostree_repo_constructed (GObject *object)
g_assert (self->repodir != NULL);
- self->tmp_dir = g_file_resolve_relative_path (self->repodir, "tmp");
-
/* Ensure the "sysroot-path" property is set. */
if (self->sysroot_dir == NULL)
self->sysroot_dir = g_object_ref (_ostree_get_default_sysroot_path ());
@@ -696,7 +609,7 @@ ostree_repo_init (OstreeRepo *self)
self->remotes = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) NULL,
- (GDestroyNotify) ost_remote_unref);
+ (GDestroyNotify) ostree_remote_unref);
g_mutex_init (&self->remotes_lock);
self->repo_dir_fd = -1;
@@ -956,7 +869,7 @@ impl_repo_remote_add (OstreeRepo *self,
if (strchr (name, '/') != NULL)
return glnx_throw (error, "Invalid character '/' in remote name: %s", name);
- g_autoptr(OstreeRemote) remote = ost_repo_get_remote (self, name, NULL);
+ g_autoptr(OstreeRemote) remote = _ostree_repo_get_remote (self, name, NULL);
if (remote != NULL && if_not_exists)
{
/* Note early return */
@@ -969,7 +882,7 @@ impl_repo_remote_add (OstreeRepo *self,
name, remote->file ? gs_file_get_path_cached (remote->file) : "(in config)");
}
- remote = ost_remote_new ();
+ remote = ostree_remote_new ();
remote->name = g_strdup (name);
remote->group = g_strdup_printf ("remote \"%s\"", name);
remote->keyring = g_strdup_printf ("%s.trustedkeys.gpg", name);
@@ -1040,7 +953,7 @@ impl_repo_remote_add (OstreeRepo *self,
return FALSE;
}
- ost_repo_add_remote (self, remote);
+ _ostree_repo_add_remote (self, remote);
return TRUE;
}
@@ -1091,7 +1004,7 @@ impl_repo_remote_delete (OstreeRepo *self,
g_autoptr(OstreeRemote) remote = NULL;
if (if_exists)
{
- remote = ost_repo_get_remote (self, name, NULL);
+ remote = _ostree_repo_get_remote (self, name, NULL);
if (!remote)
{
/* Note early return */
@@ -1099,7 +1012,7 @@ impl_repo_remote_delete (OstreeRepo *self,
}
}
else
- remote = ost_repo_get_remote (self, name, error);
+ remote = _ostree_repo_get_remote (self, name, error);
if (remote == NULL)
return FALSE;
@@ -1402,7 +1315,6 @@ ostree_repo_remote_gpg_import (OstreeRepo *self,
ot_auto_gpgme_data gpgme_data_t data_buffer = NULL;
gpgme_import_result_t import_result;
gpgme_import_status_t import_status;
- const char *tmp_dir = NULL;
g_autofree char *source_tmp_dir = NULL;
g_autofree char *target_tmp_dir = NULL;
glnx_fd_close int target_temp_fd = -1;
@@ -1410,27 +1322,17 @@ ostree_repo_remote_gpg_import (OstreeRepo *self,
struct stat stbuf;
gpgme_error_t gpg_error;
gboolean ret = FALSE;
+ const GLnxFileCopyFlags copyflags = self->disable_xattrs ? GLNX_FILE_COPY_NOXATTRS : 0;
g_return_val_if_fail (OSTREE_IS_REPO (self), FALSE);
g_return_val_if_fail (name != NULL, FALSE);
/* First make sure the remote name is valid. */
- remote = ost_repo_get_remote_inherited (self, name, error);
+ remote = _ostree_repo_get_remote_inherited (self, name, error);
if (remote == NULL)
goto out;
- /* Use OstreeRepo's "tmp" directory so the keyring files remain
- * under one mount point. Necessary for renameat() below. */
-
- /* XXX This produces a path under "/proc/self/fd/" which won't
- * work in a child process so I had to resort to the GFile.
- * I was trying to avoid the GFile so we can get rid of it.
- *
- * tmp_dir = glnx_fdrel_abspath (self->repo_dir_fd, "tmp");
- */
- tmp_dir = gs_file_get_path_cached (self->tmp_dir);
-
/* Prepare the source GPGME context. If reading GPG keys from an input
* stream, point the OpenPGP engine at a temporary directory and import
* the keys to a new pubring.gpg file. If the key data format is ASCII
@@ -1444,7 +1346,7 @@ ostree_repo_remote_gpg_import (OstreeRepo *self,
{
data_buffer = ot_gpgme_data_input (source_stream);
- if (!ot_gpgme_ctx_tmp_home_dir (source_context, tmp_dir, &source_tmp_dir,
+ if (!ot_gpgme_ctx_tmp_home_dir (source_context, &source_tmp_dir,
NULL, cancellable, error))
{
g_prefix_error (error, "Unable to configure context: ");
@@ -1527,7 +1429,7 @@ ostree_repo_remote_gpg_import (OstreeRepo *self,
goto out;
/* No need for an output stream since we copy in a pubring.gpg. */
- if (!ot_gpgme_ctx_tmp_home_dir (target_context, tmp_dir, &target_tmp_dir,
+ if (!ot_gpgme_ctx_tmp_home_dir (target_context, &target_tmp_dir,
NULL, cancellable, error))
{
g_prefix_error (error, "Unable to configure context: ");
@@ -1542,10 +1444,9 @@ ostree_repo_remote_gpg_import (OstreeRepo *self,
if (fstatat (self->repo_dir_fd, remote->keyring, &stbuf, AT_SYMLINK_NOFOLLOW) == 0)
{
- GLnxFileCopyFlags copyflags = self->disable_xattrs ? GLNX_FILE_COPY_NOXATTRS : 0;
if (!glnx_file_copy_at (self->repo_dir_fd, remote->keyring,
- &stbuf, target_temp_fd, "pubring.gpg", copyflags,
- cancellable, error))
+ &stbuf, target_temp_fd, "pubring.gpg",
+ copyflags, cancellable, error))
{
g_prefix_error (error, "Unable to copy remote's keyring: ");
goto out;
@@ -1627,13 +1528,11 @@ ostree_repo_remote_gpg_import (OstreeRepo *self,
/* Import successful; replace the remote's old keyring with the
* updated keyring in the target context's temporary directory. */
-
- if (renameat (target_temp_fd, "pubring.gpg",
- self->repo_dir_fd, remote->keyring) == -1)
- {
- glnx_set_prefix_error_from_errno (error, "%s", "Unable to rename keyring");
- goto out;
- }
+ if (!glnx_file_copy_at (target_temp_fd, "pubring.gpg", NULL,
+ self->repo_dir_fd, remote->keyring,
+ copyflags | GLNX_FILE_COPY_OVERWRITE,
+ cancellable, error))
+ goto out;
if (out_imported != NULL)
*out_imported = (guint) import_result->imported;
@@ -1642,7 +1541,7 @@ ostree_repo_remote_gpg_import (OstreeRepo *self,
out:
if (remote != NULL)
- ost_remote_unref (remote);
+ ostree_remote_unref (remote);
if (source_tmp_dir != NULL)
(void) glnx_shutil_rm_rf_at (AT_FDCWD, source_tmp_dir, NULL, NULL);
@@ -1875,7 +1774,7 @@ add_remotes_from_keyfile (OstreeRepo *self,
{
OstreeRemote *remote;
- remote = ost_remote_new_from_keyfile (keyfile, groups[ii]);
+ remote = ostree_remote_new_from_keyfile (keyfile, groups[ii]);
if (remote != NULL)
{
@@ -1906,7 +1805,7 @@ add_remotes_from_keyfile (OstreeRepo *self,
out:
while (!g_queue_is_empty (&queue))
- ost_remote_unref (g_queue_pop_head (&queue));
+ ostree_remote_unref (g_queue_pop_head (&queue));
g_mutex_unlock (&self->remotes_lock);
@@ -2365,39 +2264,41 @@ ostree_repo_get_parent (OstreeRepo *self)
static gboolean
list_loose_objects_at (OstreeRepo *self,
GHashTable *inout_objects,
- const char *prefix,
int dfd,
+ const char *prefix,
const char *commit_starting_with,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- DIR *d = NULL;
- struct dirent *dent;
GVariant *key, *value;
- d = fdopendir (dfd);
- if (!d)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
+ gboolean exists;
+ if (!ot_dfd_iter_init_allow_noent (dfd, prefix, &dfd_iter, &exists, error))
+ return FALSE;
+ /* Note early return */
+ if (!exists)
+ return TRUE;
- while ((dent = readdir (d)) != NULL)
+ while (TRUE)
{
+ struct dirent *dent;
+
+ if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error))
+ return FALSE;
+ if (dent == NULL)
+ break;
+
const char *name = dent->d_name;
- const char *dot;
- OstreeObjectType objtype;
- char buf[OSTREE_SHA256_STRING_LEN+1];
-
if (strcmp (name, ".") == 0 ||
strcmp (name, "..") == 0)
continue;
- dot = strrchr (name, '.');
+ const char *dot = strrchr (name, '.');
if (!dot)
continue;
+ OstreeObjectType objtype;
if ((self->mode == OSTREE_REPO_MODE_ARCHIVE_Z2
&& strcmp (dot, ".filez") == 0) ||
((_ostree_repo_mode_is_bare (self->mode))
@@ -2415,6 +2316,8 @@ list_loose_objects_at (OstreeRepo *self,
if ((dot - name) != 62)
continue;
+ char buf[OSTREE_SHA256_STRING_LEN+1];
+
memcpy (buf, prefix, 2);
memcpy (buf + 2, name, 62);
buf[sizeof(buf)-1] = '\0';
@@ -2441,11 +2344,7 @@ list_loose_objects_at (OstreeRepo *self,
g_variant_ref_sink (value));
}
- ret = TRUE;
- out:
- if (d)
- (void) closedir (d);
- return ret;
+ return TRUE;
}
static gboolean
@@ -2455,28 +2354,17 @@ list_loose_objects (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- guint c;
- int dfd = -1;
static const gchar hexchars[] = "0123456789abcdef";
- for (c = 0; c < 256; c++)
+ for (guint c = 0; c < 256; c++)
{
char buf[3];
buf[0] = hexchars[c >> 4];
buf[1] = hexchars[c & 0xF];
buf[2] = '\0';
- dfd = ot_opendirat (self->objects_dir_fd, buf, FALSE);
- if (dfd == -1)
- {
- if (errno == ENOENT)
- continue;
- else
- return glnx_throw_errno (error);
- }
- /* Takes ownership of dfd */
- if (!list_loose_objects_at (self, inout_objects, buf, dfd,
- commit_starting_with,
- cancellable, error))
+ if (!list_loose_objects_at (self, inout_objects, self->objects_dir_fd, buf,
+ commit_starting_with,
+ cancellable, error))
return FALSE;
}
@@ -2502,6 +2390,26 @@ load_metadata_internal (OstreeRepo *self,
g_return_val_if_fail (OSTREE_OBJECT_TYPE_IS_META (objtype), FALSE);
+ /* Special caching for dirmeta objects, since they're commonly referenced many
+ * times.
+ */
+ const gboolean is_dirmeta_cachable =
+ (objtype == OSTREE_OBJECT_TYPE_DIR_META && out_variant && !out_stream);
+ if (is_dirmeta_cachable)
+ {
+ GMutex *lock = &self->cache_lock;
+ g_mutex_lock (lock);
+ GVariant *cache_hit = NULL;
+ /* Look it up, if we have a cache */
+ if (self->dirmeta_cache)
+ cache_hit = g_hash_table_lookup (self->dirmeta_cache, sha256);
+ if (cache_hit)
+ *out_variant = g_variant_ref (cache_hit);
+ g_mutex_unlock (lock);
+ if (cache_hit)
+ return TRUE;
+ }
+
_ostree_loose_path (loose_path_buf, sha256, objtype, self->mode);
if (!ot_openat_ignore_enoent (self->objects_dir_fd, loose_path_buf, &fd,
@@ -2547,6 +2455,16 @@ load_metadata_internal (OstreeRepo *self,
data, TRUE);
g_variant_ref_sink (ret_variant);
}
+
+ /* Now, let's put it in the cache */
+ if (is_dirmeta_cachable)
+ {
+ GMutex *lock = &self->cache_lock;
+ g_mutex_lock (lock);
+ if (self->dirmeta_cache)
+ g_hash_table_replace (self->dirmeta_cache, g_strdup (sha256), g_variant_ref (ret_variant));
+ g_mutex_unlock (lock);
+ }
}
else if (out_stream)
{
@@ -2584,27 +2502,19 @@ query_info_for_bare_content_object (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
struct stat stbuf;
- int res;
- g_autoptr(GFileInfo) ret_info = NULL;
- do
- res = fstatat (self->objects_dir_fd, loose_path_buf, &stbuf, AT_SYMLINK_NOFOLLOW);
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (res == -1)
+ if (TEMP_FAILURE_RETRY (fstatat (self->objects_dir_fd, loose_path_buf, &stbuf, AT_SYMLINK_NOFOLLOW)) < 0)
{
if (errno == ENOENT)
{
*out_info = NULL;
- ret = TRUE;
- goto out;
+ return TRUE;
}
- glnx_set_error_from_errno (error);
- goto out;
+ return glnx_throw_errno (error);
}
- ret_info = _ostree_header_gfile_info_new (stbuf.st_mode, stbuf.st_uid, stbuf.st_gid);
+ g_autoptr(GFileInfo) ret_info = _ostree_header_gfile_info_new (stbuf.st_mode, stbuf.st_uid, stbuf.st_gid);
if (S_ISREG (stbuf.st_mode))
{
@@ -2614,20 +2524,13 @@ query_info_for_bare_content_object (OstreeRepo *self,
{
if (!ot_readlinkat_gfile_info (self->objects_dir_fd, loose_path_buf,
ret_info, cancellable, error))
- goto out;
+ return FALSE;
}
else
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Not a regular file or symlink: %s", loose_path_buf);
- goto out;
- }
+ return glnx_throw (error, "Not a regular file or symlink: %s", loose_path_buf);
- ret = TRUE;
- if (out_info)
- *out_info = g_steal_pointer (&ret_info);
- out:
- return ret;
+ ot_transfer_out_value (out_info, &ret_info);
+ return TRUE;
}
static GVariant *
@@ -2705,16 +2608,14 @@ ostree_repo_load_file (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
gboolean found = FALSE;
- OstreeRepoMode repo_mode;
g_autoptr(GInputStream) ret_input = NULL;
g_autoptr(GFileInfo) ret_file_info = NULL;
g_autoptr(GVariant) ret_xattrs = NULL;
+
+ OstreeRepoMode repo_mode = ostree_repo_get_mode (self);
+
char loose_path_buf[_OSTREE_LOOSE_PATH_MAX];
-
- repo_mode = ostree_repo_get_mode (self);
-
_ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_FILE, repo_mode);
if (repo_mode == OSTREE_REPO_MODE_ARCHIVE_Z2)
@@ -2725,29 +2626,29 @@ ostree_repo_load_file (OstreeRepo *self,
if (!ot_openat_ignore_enoent (self->objects_dir_fd, loose_path_buf, &fd,
error))
- goto out;
+ return FALSE;
if (fd < 0 && self->commit_stagedir_fd != -1)
{
if (!ot_openat_ignore_enoent (self->commit_stagedir_fd, loose_path_buf, &fd,
error))
- goto out;
+ return FALSE;
}
if (fd != -1)
{
tmp_stream = g_unix_input_stream_new (fd, TRUE);
fd = -1; /* Transfer ownership */
-
+
if (!glnx_stream_fstat ((GFileDescriptorBased*) tmp_stream, &stbuf,
error))
- goto out;
-
+ return FALSE;
+
if (!ostree_content_stream_parse (TRUE, tmp_stream, stbuf.st_size, TRUE,
out_input ? &ret_input : NULL,
&ret_file_info, &ret_xattrs,
cancellable, error))
- goto out;
+ return FALSE;
found = TRUE;
}
@@ -2757,7 +2658,7 @@ ostree_repo_load_file (OstreeRepo *self,
if (!query_info_for_bare_content_object (self, loose_path_buf,
&ret_file_info,
cancellable, error))
- goto out;
+ return FALSE;
if (ret_file_info)
{
@@ -2770,10 +2671,17 @@ ostree_repo_load_file (OstreeRepo *self,
g_autoptr(GBytes) bytes = NULL;
glnx_fd_close int fd = -1;
- bytes = ot_lgetxattrat (self->objects_dir_fd, loose_path_buf,
- "user.ostreemeta", error);
+ /* In bare-user, symlinks are stored as regular files, so we just
+ * always do an open, then query the user.ostreemeta xattr for
+ * more information.
+ */
+ fd = openat (self->objects_dir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
+ if (fd < 0)
+ return glnx_throw_errno (error);
+
+ bytes = glnx_fgetxattr_bytes (fd, "user.ostreemeta", error);
if (bytes == NULL)
- goto out;
+ return FALSE;
metadata = g_variant_new_from_bytes (OSTREE_FILEMETA_GVARIANT_FORMAT,
bytes, FALSE);
@@ -2783,21 +2691,6 @@ ostree_repo_load_file (OstreeRepo *self,
mode = g_file_info_get_attribute_uint32 (ret_file_info, "unix::mode");
- /* Optimize this so that we only open the file if we
- * need to; symlinks contain their content, and we only
- * open regular files if the caller has requested an
- * input stream.
- */
- if (S_ISLNK (mode) || out_input)
- {
- fd = openat (self->objects_dir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
- if (fd < 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
- }
-
if (S_ISREG (mode) && out_input)
{
g_assert (fd != -1);
@@ -2818,7 +2711,7 @@ ostree_repo_load_file (OstreeRepo *self,
if (!g_input_stream_read_all (target_input, targetbuf, sizeof (targetbuf),
&target_size, cancellable, error))
- goto out;
+ return FALSE;
g_file_info_set_symlink_target (ret_file_info, targetbuf);
}
@@ -2838,10 +2731,7 @@ ostree_repo_load_file (OstreeRepo *self,
{
fd = openat (self->objects_dir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
if (fd < 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno (error);
ret_input = g_unix_input_stream_new (fd, TRUE);
fd = -1; /* Transfer ownership */
@@ -2865,10 +2755,7 @@ ostree_repo_load_file (OstreeRepo *self,
fd = openat (self->objects_dir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
if (fd < 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno (error);
if (out_xattrs)
{
@@ -2876,7 +2763,7 @@ ostree_repo_load_file (OstreeRepo *self,
ret_xattrs = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0));
else if (!glnx_fd_get_all_xattrs (fd, &ret_xattrs,
cancellable, error))
- goto out;
+ return FALSE;
}
if (out_input)
@@ -2893,7 +2780,7 @@ ostree_repo_load_file (OstreeRepo *self,
else if (!glnx_dfd_name_get_all_xattrs (self->objects_dir_fd, loose_path_buf,
&ret_xattrs,
cancellable, error))
- goto out;
+ return FALSE;
}
}
}
@@ -2908,22 +2795,20 @@ ostree_repo_load_file (OstreeRepo *self,
out_file_info ? &ret_file_info : NULL,
out_xattrs ? &ret_xattrs : NULL,
cancellable, error))
- goto out;
+ return FALSE;
}
else
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"Couldn't find file object '%s'", checksum);
- goto out;
+ return FALSE;
}
}
- ret = TRUE;
ot_transfer_out_value (out_input, &ret_input);
ot_transfer_out_value (out_file_info, &ret_file_info);
ot_transfer_out_value (out_xattrs, &ret_xattrs);
- out:
- return ret;
+ return TRUE;
}
/**
@@ -2948,7 +2833,6 @@ ostree_repo_load_object_stream (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
guint64 size;
g_autoptr(GInputStream) ret_input = NULL;
@@ -2957,7 +2841,7 @@ ostree_repo_load_object_stream (OstreeRepo *self,
if (!load_metadata_internal (self, objtype, checksum, TRUE, NULL,
&ret_input, &size,
cancellable, error))
- goto out;
+ return FALSE;
}
else
{
@@ -2967,19 +2851,17 @@ ostree_repo_load_object_stream (OstreeRepo *self,
if (!ostree_repo_load_file (self, checksum, &input, &finfo, &xattrs,
cancellable, error))
- goto out;
+ return FALSE;
if (!ostree_raw_file_to_content_stream (input, finfo, xattrs,
&ret_input, &size,
cancellable, error))
- goto out;
+ return FALSE;
}
- ret = TRUE;
ot_transfer_out_value (out_input, &ret_input);
*out_size = size;
- out:
- return ret;
+ return TRUE;
}
/*
@@ -2997,41 +2879,34 @@ _ostree_repo_has_loose_object (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- struct stat stbuf;
- int res = -1;
char loose_path_buf[_OSTREE_LOOSE_PATH_MAX];
-
_ostree_loose_path (loose_path_buf, checksum, objtype, self->mode);
- if (self->commit_stagedir_fd != -1)
+ gboolean found = FALSE;
+ /* It's easier to share code if we make this an array */
+ const int dfd_searches[] = { self->commit_stagedir_fd, self->objects_dir_fd };
+ for (guint i = 0; i < G_N_ELEMENTS (dfd_searches); i++)
{
- do
- res = fstatat (self->commit_stagedir_fd, loose_path_buf, &stbuf, AT_SYMLINK_NOFOLLOW);
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (res == -1 && errno != ENOENT)
+ int dfd = dfd_searches[i];
+ if (dfd == -1)
+ continue;
+ struct stat stbuf;
+ if (TEMP_FAILURE_RETRY (fstatat (dfd, loose_path_buf, &stbuf, AT_SYMLINK_NOFOLLOW)) < 0)
{
- glnx_set_error_from_errno (error);
- goto out;
+ if (errno == ENOENT)
+ ; /* Next dfd */
+ else
+ return glnx_throw_errno (error);
+ }
+ else
+ {
+ found = TRUE;
+ break;
}
}
- if (res < 0)
- {
- do
- res = fstatat (self->objects_dir_fd, loose_path_buf, &stbuf, AT_SYMLINK_NOFOLLOW);
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (res == -1 && errno != ENOENT)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
- }
-
- ret = TRUE;
- *out_is_stored = (res != -1);
-out:
- return ret;
+ *out_is_stored = found;
+ return TRUE;
}
/**
@@ -3056,12 +2931,11 @@ ostree_repo_has_object (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
gboolean ret_have_object;
if (!_ostree_repo_has_loose_object (self, checksum, objtype, &ret_have_object,
cancellable, error))
- goto out;
+ return FALSE;
/* In the future, here is where we would also look up in metadata pack files */
@@ -3069,14 +2943,12 @@ ostree_repo_has_object (OstreeRepo *self,
{
if (!ostree_repo_has_object (self->parent_repo, objtype, checksum,
&ret_have_object, cancellable, error))
- goto out;
+ return FALSE;
}
- ret = TRUE;
if (out_have_object)
*out_have_object = ret_have_object;
- out:
- return ret;
+ return TRUE;
}
/**
@@ -3098,10 +2970,7 @@ ostree_repo_delete_object (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- int res;
char loose_path[_OSTREE_LOOSE_PATH_MAX];
-
_ostree_loose_path (loose_path, sha256, objtype, self->mode);
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
@@ -3110,27 +2979,15 @@ ostree_repo_delete_object (OstreeRepo *self,
_ostree_loose_path (meta_loose, sha256, OSTREE_OBJECT_TYPE_COMMIT_META, self->mode);
- do
- res = unlinkat (self->objects_dir_fd, meta_loose, 0);
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (res == -1)
+ if (TEMP_FAILURE_RETRY (unlinkat (self->objects_dir_fd, meta_loose, 0)) < 0)
{
if (G_UNLIKELY (errno != ENOENT))
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "unlinkat(%s)", meta_loose);
}
}
- do
- res = unlinkat (self->objects_dir_fd, loose_path, 0);
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (G_UNLIKELY (res == -1))
- {
- glnx_set_prefix_error_from_errno (error, "Deleting object %s.%s", sha256, ostree_object_type_to_string (objtype));
- goto out;
- }
+ if (TEMP_FAILURE_RETRY (unlinkat (self->objects_dir_fd, loose_path, 0)) < 0)
+ return glnx_throw_errno_prefix (error, "Deleting object %s.%s", sha256, ostree_object_type_to_string (objtype));
/* If the repository is configured to use tombstone commits, create one when deleting a commit. */
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
@@ -3139,7 +2996,7 @@ ostree_repo_delete_object (OstreeRepo *self,
GKeyFile *readonly_config = ostree_repo_get_config (self);
if (!ot_keyfile_get_boolean_with_default (readonly_config, "core", "tombstone-commits", FALSE,
&tombstone_commits, error))
- goto out;
+ return FALSE;
if (tombstone_commits)
{
@@ -3155,13 +3012,11 @@ ostree_repo_delete_object (OstreeRepo *self,
variant,
cancellable,
error))
- goto out;
+ return FALSE;
}
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
static gboolean
@@ -3171,25 +3026,21 @@ copy_detached_metadata (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
g_autoptr(GVariant) detached_meta = NULL;
-
if (!ostree_repo_read_commit_detached_metadata (source,
checksum, &detached_meta,
cancellable, error))
- goto out;
+ return FALSE;
if (detached_meta)
{
if (!ostree_repo_write_commit_detached_metadata (self,
checksum, detached_meta,
cancellable, error))
- goto out;
+ return FALSE;
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
static gboolean
@@ -3201,14 +3052,13 @@ import_one_object_copy (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
guint64 length;
g_autoptr(GInputStream) object_stream = NULL;
if (!ostree_repo_load_object_stream (source, objtype, checksum,
&object_stream, &length,
cancellable, error))
- goto out;
+ return FALSE;
if (objtype == OSTREE_OBJECT_TYPE_FILE)
{
@@ -3217,7 +3067,7 @@ import_one_object_copy (OstreeRepo *self,
if (!ostree_repo_write_content_trusted (self, checksum,
object_stream, length,
cancellable, error))
- goto out;
+ return FALSE;
}
else
{
@@ -3226,7 +3076,7 @@ import_one_object_copy (OstreeRepo *self,
object_stream, length,
&real_csum,
cancellable, error))
- goto out;
+ return FALSE;
}
}
else
@@ -3234,7 +3084,7 @@ import_one_object_copy (OstreeRepo *self,
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
{
if (!copy_detached_metadata (self, source, checksum, cancellable, error))
- goto out;
+ return FALSE;
}
if (trusted)
@@ -3242,7 +3092,7 @@ import_one_object_copy (OstreeRepo *self,
if (!ostree_repo_write_metadata_stream_trusted (self, objtype,
checksum, object_stream, length,
cancellable, error))
- goto out;
+ return FALSE;
}
else
{
@@ -3251,19 +3101,17 @@ import_one_object_copy (OstreeRepo *self,
if (!ostree_repo_load_variant (source, objtype, checksum,
&variant, error))
- goto out;
+ return FALSE;
if (!ostree_repo_write_metadata (self, objtype,
checksum, variant,
&real_csum,
cancellable, error))
- goto out;
+ return FALSE;
}
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
static gboolean
@@ -3275,44 +3123,36 @@ import_one_object_link (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
char loose_path_buf[_OSTREE_LOOSE_PATH_MAX];
-
_ostree_loose_path (loose_path_buf, checksum, objtype, self->mode);
if (!_ostree_repo_ensure_loose_objdir_at (self->objects_dir_fd, loose_path_buf, cancellable, error))
- goto out;
+ return FALSE;
*out_was_supported = TRUE;
if (linkat (source->objects_dir_fd, loose_path_buf, self->objects_dir_fd, loose_path_buf, 0) != 0)
{
if (errno == EEXIST)
- {
- ret = TRUE;
- }
+ return TRUE;
else if (errno == EMLINK || errno == EXDEV || errno == EPERM)
{
/* EMLINK, EXDEV and EPERM shouldn't be fatal; we just can't do the
* optimization of hardlinking instead of copying.
*/
*out_was_supported = FALSE;
- ret = TRUE;
+ return TRUE;
}
else
- glnx_set_error_from_errno (error);
-
- goto out;
+ return glnx_throw_errno (error);
}
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
{
if (!copy_detached_metadata (self, source, checksum, cancellable, error))
- goto out;
+ return FALSE;
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/**
@@ -3335,7 +3175,7 @@ gboolean
ostree_repo_import_object_from (OstreeRepo *self,
OstreeRepo *source,
OstreeObjectType objtype,
- const char *checksum,
+ const char *checksum,
GCancellable *cancellable,
GError **error)
{
@@ -3370,7 +3210,6 @@ ostree_repo_import_object_from_with_trust (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
gboolean hardlink_was_supported = FALSE;
if (trusted && /* Don't hardlink into untrusted remotes */
@@ -3379,7 +3218,7 @@ ostree_repo_import_object_from_with_trust (OstreeRepo *self,
if (!import_one_object_link (self, source, checksum, objtype,
&hardlink_was_supported,
cancellable, error))
- goto out;
+ return FALSE;
}
if (!hardlink_was_supported)
@@ -3388,19 +3227,17 @@ ostree_repo_import_object_from_with_trust (OstreeRepo *self,
if (!ostree_repo_has_object (self, objtype, checksum, &has_object,
cancellable, error))
- goto out;
+ return FALSE;
if (!has_object)
{
if (!import_one_object_copy (self, source, checksum, objtype, trusted,
cancellable, error))
- goto out;
+ return FALSE;
}
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
@@ -3425,15 +3262,10 @@ ostree_repo_query_object_storage_size (OstreeRepo *self,
GError **error)
{
char loose_path[_OSTREE_LOOSE_PATH_MAX];
- int res;
- struct stat stbuf;
-
_ostree_loose_path (loose_path, sha256, objtype, self->mode);
- do
- res = fstatat (self->objects_dir_fd, loose_path, &stbuf, AT_SYMLINK_NOFOLLOW);
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (G_UNLIKELY (res == -1))
+ struct stat stbuf;
+ if (TEMP_FAILURE_RETRY (fstatat (self->objects_dir_fd, loose_path, &stbuf, AT_SYMLINK_NOFOLLOW)) < 0)
return glnx_throw_errno_prefix (error, "Querying object %s.%s", sha256, ostree_object_type_to_string (objtype));
*out_size = stbuf.st_size;
@@ -3607,31 +3439,26 @@ ostree_repo_list_commit_objects_starting_with (OstreeRepo *self
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- g_autoptr(GHashTable) ret_commits = NULL;
-
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
g_return_val_if_fail (self->inited, FALSE);
- ret_commits = g_hash_table_new_full (ostree_hash_object_name, g_variant_equal,
- (GDestroyNotify) g_variant_unref,
- (GDestroyNotify) g_variant_unref);
+ g_autoptr(GHashTable) ret_commits =
+ g_hash_table_new_full (ostree_hash_object_name, g_variant_equal,
+ (GDestroyNotify) g_variant_unref,
+ (GDestroyNotify) g_variant_unref);
if (!list_loose_objects (self, ret_commits, start, cancellable, error))
- goto out;
-
+ return FALSE;
if (self->parent_repo)
{
if (!list_loose_objects (self->parent_repo, ret_commits, start,
cancellable, error))
- goto out;
+ return FALSE;
}
- ret = TRUE;
ot_transfer_out_value (out_commits, &ret_commits);
- out:
- return ret;
+ return TRUE;
}
/**
@@ -3803,7 +3630,6 @@ void
ostree_repo_pull_default_console_progress_changed (OstreeAsyncProgress *progress,
gpointer user_data)
{
- GString *buf;
g_autofree char *status = NULL;
gboolean scanning;
guint outstanding_fetches;
@@ -3815,37 +3641,46 @@ ostree_repo_pull_default_console_progress_changed (OstreeAsyncProgress *progress
guint fetched_delta_part_fallbacks;
guint total_delta_part_fallbacks;
- buf = g_string_new ("");
+ g_autoptr(GString) buf = g_string_new ("");
- status = ostree_async_progress_get_status (progress);
- outstanding_fetches = ostree_async_progress_get_uint (progress, "outstanding-fetches");
- outstanding_metadata_fetches = ostree_async_progress_get_uint (progress, "outstanding-metadata-fetches");
- outstanding_writes = ostree_async_progress_get_uint (progress, "outstanding-writes");
- scanning = ostree_async_progress_get_uint (progress, "scanning") == 1;
- n_scanned_metadata = ostree_async_progress_get_uint (progress, "scanned-metadata");
- fetched_delta_parts = ostree_async_progress_get_uint (progress, "fetched-delta-parts");
- total_delta_parts = ostree_async_progress_get_uint (progress, "total-delta-parts");
- fetched_delta_part_fallbacks = ostree_async_progress_get_uint (progress, "fetched-delta-fallbacks");
- total_delta_part_fallbacks = ostree_async_progress_get_uint (progress, "total-delta-fallbacks");
+ ostree_async_progress_get (progress,
+ "outstanding-fetches", "u", &outstanding_fetches,
+ "outstanding-metadata-fetches", "u", &outstanding_metadata_fetches,
+ "outstanding-writes", "u", &outstanding_writes,
+ "scanning", "u", &scanning,
+ "scanned-metadata", "u", &n_scanned_metadata,
+ "fetched-delta-parts", "u", &fetched_delta_parts,
+ "total-delta-parts", "u", &total_delta_parts,
+ "fetched-delta-fallbacks", "u", &fetched_delta_part_fallbacks,
+ "total-delta-fallbacks", "u", &total_delta_part_fallbacks,
+ "status", "s", &status,
+ NULL);
- if (status)
+ if (*status != '\0')
{
g_string_append (buf, status);
}
else if (outstanding_fetches)
{
- guint64 bytes_transferred = ostree_async_progress_get_uint64 (progress, "bytes-transferred");
- guint fetched = ostree_async_progress_get_uint (progress, "fetched");
- guint metadata_fetched = ostree_async_progress_get_uint (progress, "metadata-fetched");
- guint requested = ostree_async_progress_get_uint (progress, "requested");
- guint64 start_time = ostree_async_progress_get_uint64 (progress, "start-time");
- guint64 total_delta_part_size = ostree_async_progress_get_uint64 (progress, "total-delta-part-size");
+ guint64 bytes_transferred, start_time, total_delta_part_size;
+ guint fetched, metadata_fetched, requested;
guint64 current_time = g_get_monotonic_time ();
- g_autofree char *formatted_bytes_transferred =
- g_format_size_full (bytes_transferred, 0);
+ g_autofree char *formatted_bytes_transferred = NULL;
g_autofree char *formatted_bytes_sec = NULL;
guint64 bytes_sec;
+ /* Note: This is not atomic wrt the above getter call. */
+ ostree_async_progress_get (progress,
+ "bytes-transferred", "t", &bytes_transferred,
+ "fetched", "u", &fetched,
+ "metadata-fetched", "u", &metadata_fetched,
+ "requested", "u", &requested,
+ "start-time", "t", &start_time,
+ "total-delta-part-size", "t", &total_delta_part_size,
+ NULL);
+
+ formatted_bytes_transferred = g_format_size_full (bytes_transferred, 0);
+
/* Ignore the first second, or when we haven't transferred any
* data, since those could cause divide by zero below.
*/
@@ -3915,8 +3750,6 @@ ostree_repo_pull_default_console_progress_changed (OstreeAsyncProgress *progress
}
glnx_console_text (buf->str);
-
- g_string_free (buf, TRUE);
}
/**
@@ -3936,29 +3769,25 @@ ostree_repo_append_gpg_signature (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
g_autoptr(GVariant) metadata = NULL;
- g_autoptr(GVariant) new_metadata = NULL;
-
if (!ostree_repo_read_commit_detached_metadata (self,
commit_checksum,
&metadata,
cancellable,
error))
- goto out;
+ return FALSE;
- new_metadata = _ostree_detached_metadata_append_gpg_sig (metadata, signature_bytes);
+ g_autoptr(GVariant) new_metadata =
+ _ostree_detached_metadata_append_gpg_sig (metadata, signature_bytes);
if (!ostree_repo_write_commit_detached_metadata (self,
commit_checksum,
new_metadata,
cancellable,
error))
- goto out;
+ return FALSE;
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
static gboolean
@@ -4078,77 +3907,64 @@ ostree_repo_sign_commit (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
g_autoptr(GBytes) commit_data = NULL;
g_autoptr(GBytes) signature = NULL;
- g_autoptr(GVariant) commit_variant = NULL;
- g_autoptr(GVariant) old_metadata = NULL;
- g_autoptr(GVariant) new_metadata = NULL;
- glnx_unref_object OstreeGpgVerifyResult *result = NULL;
- GError *local_error = NULL;
+ g_autoptr(GVariant) commit_variant = NULL;
if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_COMMIT,
commit_checksum, &commit_variant, error))
- {
- g_prefix_error (error, "Failed to read commit: ");
- goto out;
- }
+ return glnx_prefix_error (error, "Failed to read commit");
+ g_autoptr(GVariant) old_metadata = NULL;
if (!ostree_repo_read_commit_detached_metadata (self,
commit_checksum,
&old_metadata,
cancellable,
error))
- {
- g_prefix_error (error, "Failed to read detached metadata: ");
- goto out;
- }
+ return glnx_prefix_error (error, "Failed to read detached metadata");
commit_data = g_variant_get_data_as_bytes (commit_variant);
/* The verify operation is merely to parse any existing signatures to
* check if the commit has already been signed with the given key ID.
* We want to avoid storing duplicate signatures in the metadata. */
- result = _ostree_repo_gpg_verify_with_metadata (self,
- commit_data,
- old_metadata,
- NULL, NULL, NULL,
- cancellable,
- &local_error);
-
- /* "Not found" just means the commit is not yet signed. That's okay. */
- if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ g_autoptr(GError) local_error = NULL;
+ glnx_unref_object OstreeGpgVerifyResult *result
+ =_ostree_repo_gpg_verify_with_metadata (self, commit_data, old_metadata,
+ NULL, NULL, NULL,
+ cancellable, &local_error);
+ if (!result)
{
- g_clear_error (&local_error);
- }
- else if (local_error != NULL)
- {
- g_propagate_error (error, local_error);
- goto out;
+ /* "Not found" just means the commit is not yet signed. That's okay. */
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ {
+ g_clear_error (&local_error);
+ }
+ else
+ return g_propagate_error (error, g_steal_pointer (&local_error)), FALSE;
}
else if (ostree_gpg_verify_result_lookup (result, key_id, NULL))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS,
"Commit is already signed with GPG key %s", key_id);
- goto out;
+ return FALSE;
}
if (!sign_data (self, commit_data, key_id, homedir,
&signature, cancellable, error))
- goto out;
+ return FALSE;
- new_metadata = _ostree_detached_metadata_append_gpg_sig (old_metadata, signature);
+ g_autoptr(GVariant) new_metadata =
+ _ostree_detached_metadata_append_gpg_sig (old_metadata, signature);
if (!ostree_repo_write_commit_detached_metadata (self,
commit_checksum,
new_metadata,
cancellable,
error))
- goto out;
+ return FALSE;
- ret = TRUE;
-out:
- return ret;
+ return TRUE;
}
/**
@@ -4172,8 +3988,9 @@ ostree_repo_sign_delta (OstreeRepo *self,
const gchar *homedir,
GCancellable *cancellable,
GError **error)
-{ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- "ostree_repo_sign_delta is deprecated");
+{
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "ostree_repo_sign_delta is deprecated");
return FALSE;
}
@@ -4194,34 +4011,29 @@ ostree_repo_add_gpg_signature_summary (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- g_autoptr(GBytes) summary_data = NULL;
- g_autoptr(GVariant) existing_signatures = NULL;
- g_autoptr(GVariant) new_metadata = NULL;
- g_autoptr(GVariant) normalized = NULL;
- guint i;
-
- summary_data = ot_file_mapat_bytes (self->repo_dir_fd, "summary", error);
+ g_autoptr(GBytes) summary_data = ot_file_mapat_bytes (self->repo_dir_fd, "summary", error);
if (!summary_data)
- goto out;
+ return FALSE;
+ g_autoptr(GVariant) existing_signatures = NULL;
if (!ot_util_variant_map_at (self->repo_dir_fd, "summary.sig",
G_VARIANT_TYPE (OSTREE_SUMMARY_SIG_GVARIANT_STRING),
OT_VARIANT_MAP_ALLOW_NOENT, &existing_signatures, error))
- goto out;
+ return FALSE;
- for (i = 0; key_id[i]; i++)
+ g_autoptr(GVariant) new_metadata = NULL;
+ for (guint i = 0; key_id[i]; i++)
{
g_autoptr(GBytes) signature_data = NULL;
if (!sign_data (self, summary_data, key_id[i], homedir,
&signature_data,
cancellable, error))
- goto out;
+ return FALSE;
new_metadata = _ostree_detached_metadata_append_gpg_sig (existing_signatures, signature_data);
}
- normalized = g_variant_get_normal_form (new_metadata);
+ g_autoptr(GVariant) normalized = g_variant_get_normal_form (new_metadata);
if (!_ostree_repo_file_replace_contents (self,
self->repo_dir_fd,
@@ -4229,11 +4041,9 @@ ostree_repo_add_gpg_signature_summary (OstreeRepo *self,
g_variant_get_data (normalized),
g_variant_get_size (normalized),
cancellable, error))
- goto out;
+ return FALSE;
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/* Special remote for _ostree_repo_gpg_verify_with_metadata() */
@@ -4297,7 +4107,7 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self,
OstreeRemote *remote;
g_autoptr(GFile) file = NULL;
- remote = ost_repo_get_remote_inherited (self, remote_name, error);
+ remote = _ostree_repo_get_remote_inherited (self, remote_name, error);
if (remote == NULL)
return NULL;
@@ -4316,7 +4126,7 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self,
if (gpgkeypath)
_ostree_gpg_verifier_add_key_ascii_file (verifier, gpgkeypath);
- ost_remote_unref (remote);
+ ostree_remote_unref (remote);
}
if (add_global_keyring_dir)
@@ -4647,6 +4457,10 @@ ostree_repo_verify_summary (OstreeRepo *self,
* An OSTree repository can contain a high level "summary" file that
* describes the available branches and other metadata.
*
+ * If the timetable for making commits and updating the summary file is fairly
+ * regular, setting the `ostree.summary.expires` key in @additional_metadata
+ * will aid clients in working out when to check for updates.
+ *
* It is regenerated automatically after a commit if
* `core/commit-update-summary` is set.
*/
@@ -4656,32 +4470,26 @@ ostree_repo_regenerate_summary (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
g_autoptr(GHashTable) refs = NULL;
- g_autoptr(GVariantBuilder) refs_builder = NULL;
- g_autoptr(GVariant) summary = NULL;
- GList *ordered_keys = NULL;
- GList *iter = NULL;
- g_auto(GVariantDict) additional_metadata_builder = OT_VARIANT_BUILDER_INITIALIZER;
-
if (!ostree_repo_list_refs (self, NULL, &refs, cancellable, error))
- goto out;
+ return FALSE;
+ g_auto(GVariantDict) additional_metadata_builder = OT_VARIANT_BUILDER_INITIALIZER;
g_variant_dict_init (&additional_metadata_builder, additional_metadata);
- refs_builder = g_variant_builder_new (G_VARIANT_TYPE ("a(s(taya{sv}))"));
+ g_autoptr(GVariantBuilder) refs_builder = g_variant_builder_new (G_VARIANT_TYPE ("a(s(taya{sv}))"));
- ordered_keys = g_hash_table_get_keys (refs);
+ g_autoptr(GList) ordered_keys = g_hash_table_get_keys (refs);
ordered_keys = g_list_sort (ordered_keys, (GCompareFunc)strcmp);
- for (iter = ordered_keys; iter; iter = iter->next)
+ for (GList *iter = ordered_keys; iter; iter = iter->next)
{
const char *ref = iter->data;
const char *commit = g_hash_table_lookup (refs, ref);
- g_autofree char *remotename = NULL;
- g_autoptr(GVariant) commit_obj = NULL;
+ g_auto(GVariantDict) commit_metadata_builder = OT_VARIANT_BUILDER_INITIALIZER;
g_assert (commit);
+ g_autofree char *remotename = NULL;
if (!ostree_parse_refspec (ref, &remotename, NULL, NULL))
g_assert_not_reached ();
@@ -4689,55 +4497,59 @@ ostree_repo_regenerate_summary (OstreeRepo *self,
if (remotename != NULL)
continue;
+ g_autoptr(GVariant) commit_obj = NULL;
if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_COMMIT, commit, &commit_obj, error))
- goto out;
+ return FALSE;
- g_variant_builder_add_value (refs_builder,
+ g_variant_dict_init (&commit_metadata_builder, NULL);
+
+ /* Forward the commit’s timestamp if it’s valid. */
+ guint64 commit_timestamp = ostree_commit_get_timestamp (commit_obj);
+ g_autoptr(GDateTime) dt = g_date_time_new_from_unix_utc (commit_timestamp);
+
+ if (dt != NULL)
+ g_variant_dict_insert_value (&commit_metadata_builder, OSTREE_COMMIT_TIMESTAMP,
+ g_variant_new_uint64 (GUINT64_TO_BE (commit_timestamp)));
+
+ g_variant_builder_add_value (refs_builder,
g_variant_new ("(s(t@ay@a{sv}))", ref,
(guint64) g_variant_get_size (commit_obj),
ostree_checksum_to_bytes_v (commit),
- ot_gvariant_new_empty_string_dict ()));
+ g_variant_dict_end (&commit_metadata_builder)));
}
{
- guint i;
g_autoptr(GPtrArray) delta_names = NULL;
g_auto(GVariantDict) deltas_builder = OT_VARIANT_BUILDER_INITIALIZER;
if (!ostree_repo_list_static_delta_names (self, &delta_names, cancellable, error))
- goto out;
+ return FALSE;
g_variant_dict_init (&deltas_builder, NULL);
- for (i = 0; i < delta_names->len; i++)
+ for (guint i = 0; i < delta_names->len; i++)
{
g_autofree char *from = NULL;
g_autofree char *to = NULL;
- g_autofree guchar *csum = NULL;
- g_autofree char *superblock = NULL;
- glnx_fd_close int superblock_file_fd = -1;
- g_autoptr(GInputStream) in_stream = NULL;
-
if (!_ostree_parse_delta_name (delta_names->pdata[i], &from, &to, error))
- goto out;
+ return FALSE;
- superblock = _ostree_get_relative_static_delta_superblock_path ((from && from[0]) ? from : NULL, to);
- superblock_file_fd = openat (self->repo_dir_fd, superblock, O_RDONLY | O_CLOEXEC);
+ g_autofree char *superblock = _ostree_get_relative_static_delta_superblock_path ((from && from[0]) ? from : NULL, to);
+ glnx_fd_close int superblock_file_fd = openat (self->repo_dir_fd, superblock, O_RDONLY | O_CLOEXEC);
if (superblock_file_fd == -1)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno (error);
- in_stream = g_unix_input_stream_new (superblock_file_fd, TRUE);
+ g_autoptr(GInputStream) in_stream = g_unix_input_stream_new (superblock_file_fd, FALSE);
if (!in_stream)
- goto out;
+ return FALSE;
+ superblock_file_fd = -1; /* Transfer ownership */
+ g_autofree guchar *csum = NULL;
if (!ot_gio_checksum_stream (in_stream,
&csum,
cancellable,
error))
- goto out;
+ return FALSE;
g_variant_dict_insert_value (&deltas_builder, delta_names->pdata[i], ot_gvariant_new_bytearray (csum, 32));
}
@@ -4745,6 +4557,12 @@ ostree_repo_regenerate_summary (OstreeRepo *self,
g_variant_dict_insert_value (&additional_metadata_builder, OSTREE_SUMMARY_STATIC_DELTAS, g_variant_dict_end (&deltas_builder));
}
+ {
+ g_variant_dict_insert_value (&additional_metadata_builder, OSTREE_SUMMARY_LAST_MODIFIED,
+ g_variant_new_uint64 (GUINT64_TO_BE (g_get_real_time () / G_USEC_PER_SEC)));
+ }
+
+ g_autoptr(GVariant) summary = NULL;
{
g_autoptr(GVariantBuilder) summary_builder =
g_variant_builder_new (OSTREE_SUMMARY_GVARIANT_FORMAT);
@@ -4762,22 +4580,15 @@ ostree_repo_regenerate_summary (OstreeRepo *self,
g_variant_get_size (summary),
cancellable,
error))
- goto out;
+ return FALSE;
if (unlinkat (self->repo_dir_fd, "summary.sig", 0) < 0)
{
if (errno != ENOENT)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "unlinkat");
}
- ret = TRUE;
- out:
- if (ordered_keys)
- g_list_free (ordered_keys);
- return ret;
+ return TRUE;
}
gboolean
@@ -4939,3 +4750,32 @@ _ostree_repo_allocate_tmpdir (int tmpdir_dfd,
out:
return ret;
}
+
+/* See ostree-repo-private.h for more information about this */
+void
+_ostree_repo_memory_cache_ref_init (OstreeRepoMemoryCacheRef *state,
+ OstreeRepo *repo)
+{
+ state->repo = g_object_ref (repo);
+ GMutex *lock = &repo->cache_lock;
+ g_mutex_lock (lock);
+ repo->dirmeta_cache_refcount++;
+ if (repo->dirmeta_cache == NULL)
+ repo->dirmeta_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref);
+ g_mutex_unlock (lock);
+
+}
+
+/* See ostree-repo-private.h for more information about this */
+void
+_ostree_repo_memory_cache_ref_destroy (OstreeRepoMemoryCacheRef *state)
+{
+ OstreeRepo *repo = state->repo;
+ GMutex *lock = &repo->cache_lock;
+ g_mutex_lock (lock);
+ repo->dirmeta_cache_refcount--;
+ if (repo->dirmeta_cache_refcount == 0)
+ g_clear_pointer (&repo->dirmeta_cache, (GDestroyNotify) g_hash_table_unref);
+ g_mutex_unlock (lock);
+ g_object_unref (repo);
+}
diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h
index 1664d65d..86bed09c 100644
--- a/src/libostree/ostree-repo.h
+++ b/src/libostree/ostree-repo.h
@@ -767,14 +767,17 @@ typedef struct {
gboolean enable_fsync; /* Deprecated */
gboolean process_whiteouts;
gboolean no_copy_fallback;
- gboolean unused_bools[7];
+ gboolean force_copy; /* Since: 2017.6 */
+ gboolean unused_bools[6];
const char *subpath;
OstreeRepoDevInoCache *devino_to_csum_cache;
int unused_ints[6];
- gpointer unused_ptrs[7];
+ gpointer unused_ptrs[5];
+ OstreeSePolicy *sepolicy; /* Since: 2017.6 */
+ const char *sepolicy_prefix;
} OstreeRepoCheckoutAtOptions;
_OSTREE_PUBLIC
diff --git a/src/libostree/ostree-sepolicy-private.h b/src/libostree/ostree-sepolicy-private.h
index 55d49eaf..def8ab74 100644
--- a/src/libostree/ostree-sepolicy-private.h
+++ b/src/libostree/ostree-sepolicy-private.h
@@ -37,5 +37,6 @@ gboolean _ostree_sepolicy_preparefscreatecon (OstreeSepolicyFsCreatecon *con,
guint32 mode,
GError **error);
+GVariant *_ostree_filter_selinux_xattr (GVariant *xattrs);
G_END_DECLS
diff --git a/src/libostree/ostree-sepolicy.c b/src/libostree/ostree-sepolicy.c
index 6063022c..7387ea0f 100644
--- a/src/libostree/ostree-sepolicy.c
+++ b/src/libostree/ostree-sepolicy.c
@@ -47,8 +47,6 @@ struct OstreeSePolicy {
int rootfs_dfd_owned;
GFile *path;
- gboolean runtime_enabled;
-
#ifdef HAVE_SELINUX
GFile *selinux_policy_root;
struct selabel_handle *selinux_hnd;
@@ -198,24 +196,21 @@ get_policy_checksum (char **out_csum,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
-
const char *binary_policy_path = selinux_binary_policy_path ();
const char *binfile_prefix = glnx_basename (binary_policy_path);
g_autofree char *bindir_path = g_path_get_dirname (binary_policy_path);
- glnx_fd_close int bindir_dfd = -1;
g_autofree char *best_policy = NULL;
int best_version = 0;
- g_auto(GLnxDirFdIterator) dfd_iter = { 0,};
-
+ glnx_fd_close int bindir_dfd = -1;
if (!glnx_opendirat (AT_FDCWD, bindir_path, TRUE, &bindir_dfd, error))
- goto out;
+ return FALSE;
+ g_auto(GLnxDirFdIterator) dfd_iter = { 0,};
if (!glnx_dirfd_iterator_init_at (bindir_dfd, ".", FALSE, &dfd_iter, error))
- goto out;
+ return FALSE;
while (TRUE)
{
@@ -223,8 +218,7 @@ get_policy_checksum (char **out_csum,
if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent,
cancellable, error))
- goto out;
-
+ return FALSE;
if (dent == NULL)
break;
@@ -259,44 +253,54 @@ get_policy_checksum (char **out_csum,
}
if (!best_policy)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Could not find binary policy file");
- goto out;
- }
+ return glnx_throw (error, "Could not find binary policy file");
*out_csum = ot_checksum_file_at (bindir_dfd, best_policy, G_CHECKSUM_SHA256,
cancellable, error);
if (*out_csum == NULL)
- goto out;
+ return FALSE;
- ret = TRUE;
-out:
- return ret;
+ return TRUE;
}
#endif
+
+/* Workaround for http://marc.info/?l=selinux&m=149323809332417&w=2 */
+#ifdef HAVE_SELINUX
+static gboolean
+cached_is_selinux_enabled (void)
+{
+ static gsize initialized;
+ static gboolean cached_enabled;
+ if (g_once_init_enter (&initialized))
+ {
+ cached_enabled = is_selinux_enabled () == 1;
+ g_once_init_leave (&initialized, 1);
+ }
+ return cached_enabled;
+}
+#endif
+
static gboolean
initable_init (GInitable *initable,
GCancellable *cancellable,
GError **error)
{
#ifdef HAVE_SELINUX
- gboolean ret = FALSE;
OstreeSePolicy *self = OSTREE_SEPOLICY (initable);
- g_autoptr(GFile) path = NULL;
- g_autoptr(GFile) etc_selinux_dir = NULL;
- g_autoptr(GFile) policy_config_path = NULL;
- g_autoptr(GFile) policy_root = NULL;
- g_autoptr(GFileInputStream) filein = NULL;
- g_autoptr(GDataInputStream) datain = NULL;
gboolean enabled = FALSE;
g_autofree char *policytype = NULL;
const char *selinux_prefix = "SELINUX=";
const char *selinuxtype_prefix = "SELINUXTYPE=";
+ /* First thing here, call is_selinux_enabled() to prime the cache. See the
+ * link above for more information why.
+ */
+ (void) cached_is_selinux_enabled ();
+
/* TODO - use this below */
+ g_autoptr(GFile) path = NULL;
if (self->rootfs_dfd != -1)
path = ot_fdrel_to_gfile (self->rootfs_dfd, ".");
else if (self->path)
@@ -306,45 +310,44 @@ initable_init (GInitable *initable,
/* TODO - use this below */
if (!glnx_opendirat (AT_FDCWD, gs_file_get_path_cached (self->path), TRUE,
&self->rootfs_dfd_owned, error))
- goto out;
+ return FALSE;
self->rootfs_dfd = self->rootfs_dfd_owned;
#endif
}
else
g_assert_not_reached ();
- etc_selinux_dir = g_file_resolve_relative_path (path, "etc/selinux");
+ g_autoptr(GFile) etc_selinux_dir = g_file_resolve_relative_path (path, "etc/selinux");
if (!g_file_query_exists (etc_selinux_dir, NULL))
{
g_object_unref (etc_selinux_dir);
etc_selinux_dir = g_file_resolve_relative_path (path, "usr/etc/selinux");
}
- policy_config_path = g_file_get_child (etc_selinux_dir, "config");
+ g_autoptr(GFile) policy_config_path = g_file_get_child (etc_selinux_dir, "config");
+ g_autoptr(GFile) policy_root = NULL;
if (g_file_query_exists (policy_config_path, NULL))
{
- filein = g_file_read (policy_config_path, cancellable, error);
- if (!filein)
- goto out;
+ g_autoptr(GFileInputStream) filein = filein = g_file_read (policy_config_path, cancellable, error);
- datain = g_data_input_stream_new ((GInputStream*)filein);
+ if (!filein)
+ return FALSE;
+
+ g_autoptr(GDataInputStream) datain = g_data_input_stream_new ((GInputStream*)filein);
while (TRUE)
{
gsize len;
- GError *temp_error = NULL;
+ g_autoptr(GError) temp_error = NULL;
g_autofree char *line = g_data_input_stream_read_line_utf8 (datain, &len,
cancellable, &temp_error);
-
+
if (temp_error)
- {
- g_propagate_error (error, temp_error);
- goto out;
- }
+ return g_propagate_error (error, g_steal_pointer (&temp_error)), FALSE;
if (!line)
break;
-
+
if (g_str_has_prefix (line, selinuxtype_prefix))
{
policytype = g_strstrip (g_strdup (line + strlen (selinuxtype_prefix)));
@@ -362,57 +365,32 @@ initable_init (GInitable *initable,
if (enabled)
{
- self->runtime_enabled = is_selinux_enabled () == 1;
+ const char *policy_rootpath = gs_file_get_path_cached (policy_root);
g_setenv ("LIBSELINUX_DISABLE_PCRE_PRECOMPILED", "1", FALSE);
- if (selinux_set_policy_root (gs_file_get_path_cached (policy_root)) != 0)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "selinux_set_policy_root(%s): %s",
- gs_file_get_path_cached (etc_selinux_dir),
- strerror (errno));
- goto out;
- }
+ if (selinux_set_policy_root (policy_rootpath) != 0)
+ return glnx_throw_errno_prefix (error, "selinux_set_policy_root(%s)", policy_rootpath);
self->selinux_hnd = selabel_open (SELABEL_CTX_FILE, NULL, 0);
if (!self->selinux_hnd)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "With policy root '%s': selabel_open(SELABEL_CTX_FILE): %s",
- gs_file_get_path_cached (etc_selinux_dir),
- strerror (errno));
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "With policy root '%s': selabel_open(SELABEL_CTX_FILE)",
+ policy_rootpath);
- {
- char *con = NULL;
- if (selabel_lookup_raw (self->selinux_hnd, &con, "/", 0755) != 0)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "With policy root '%s': Failed to look up context of /: %s",
- gs_file_get_path_cached (etc_selinux_dir),
- strerror (errno));
- goto out;
- }
- freecon (con);
- }
+ char *con = NULL;
+ if (selabel_lookup_raw (self->selinux_hnd, &con, "/", 0755) != 0)
+ return glnx_throw_errno_prefix (error, "With policy root '%s': Failed to look up context of /",
+ policy_rootpath);
+ freecon (con);
if (!get_policy_checksum (&self->selinux_policy_csum, cancellable, error))
- {
- g_prefix_error (error, "While calculating SELinux checksum: ");
- goto out;
- }
+ return glnx_prefix_error (error, "While calculating SELinux checksum");
self->selinux_policy_name = g_steal_pointer (&policytype);
self->selinux_policy_root = g_object_ref (etc_selinux_dir);
}
- ret = TRUE;
- out:
- return ret;
-#else
- return TRUE;
#endif
+ return TRUE;
}
static void
@@ -580,11 +558,7 @@ ostree_sepolicy_restorecon (OstreeSePolicy *self,
GError **error)
{
#ifdef HAVE_SELINUX
- gboolean ret = FALSE;
g_autoptr(GFileInfo) src_info = NULL;
- g_autofree char *label = NULL;
- gboolean do_relabel = TRUE;
-
if (info != NULL)
src_info = g_object_ref (info);
else
@@ -593,9 +567,10 @@ ostree_sepolicy_restorecon (OstreeSePolicy *self,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
cancellable, error);
if (!src_info)
- goto out;
+ return FALSE;
}
+ gboolean do_relabel = TRUE;
if (flags & OSTREE_SEPOLICY_RESTORECON_FLAGS_KEEP_EXISTING)
{
char *existing_con = NULL;
@@ -607,42 +582,31 @@ ostree_sepolicy_restorecon (OstreeSePolicy *self,
}
}
+ g_autofree char *label = NULL;
if (do_relabel)
{
- if (!ostree_sepolicy_get_label (self, path,
+ if (!ostree_sepolicy_get_label (self, path,
g_file_info_get_attribute_uint32 (src_info, "unix::mode"),
&label,
cancellable, error))
- goto out;
+ return FALSE;
if (!label)
{
if (!(flags & OSTREE_SEPOLICY_RESTORECON_FLAGS_ALLOW_NOLABEL))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "No label found for '%s'", path);
- goto out;
- }
+ return glnx_throw (error, "No label found for '%s'", path);
}
else
{
- int res = lsetfilecon (gs_file_get_path_cached (target), label);
- if (res != 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ if (lsetfilecon (gs_file_get_path_cached (target), label) < 0)
+ return glnx_throw_errno_prefix (error, "lsetfilecon");
}
}
- ret = TRUE;
if (out_new_label)
*out_new_label = g_steal_pointer (&label);
- out:
- return ret;
-#else
- return TRUE;
#endif
+ return TRUE;
}
/**
@@ -660,7 +624,6 @@ ostree_sepolicy_setfscreatecon (OstreeSePolicy *self,
GError **error)
{
#ifdef HAVE_SELINUX
- gboolean ret = FALSE;
g_autofree char *label = NULL;
/* setfscreatecon() will bomb out if the host has SELinux disabled,
@@ -669,24 +632,17 @@ ostree_sepolicy_setfscreatecon (OstreeSePolicy *self,
* request. To correctly handle the case of disabled host but
* enabled target will require nontrivial work.
*/
- if (!self->runtime_enabled)
+ if (!cached_is_selinux_enabled ())
return TRUE;
if (!ostree_sepolicy_get_label (self, path, mode, &label, NULL, error))
- goto out;
+ return FALSE;
if (setfscreatecon_raw (label) != 0)
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
+ return glnx_throw_errno_prefix (error, "setfscreatecon");
- ret = TRUE;
- out:
- return ret;
-#else
- return TRUE;
#endif
+ return TRUE;
}
/**
@@ -730,3 +686,44 @@ _ostree_sepolicy_fscreatecon_clear (OstreeSepolicyFsCreatecon *con)
return;
ostree_sepolicy_fscreatecon_cleanup (NULL);
}
+
+/*
+ * Given @xattrs, filter out `security.selinux`, and return
+ * a new GVariant without it. Supports @xattrs as %NULL to
+ * mean "no xattrs", and also returns %NULL if no xattrs
+ * would result (rather than a zero-length array).
+ */
+GVariant *
+_ostree_filter_selinux_xattr (GVariant *xattrs)
+{
+ if (!xattrs)
+ return NULL;
+
+ gboolean have_xattrs = FALSE;
+ GVariantBuilder builder;
+ guint n = g_variant_n_children (xattrs);
+ for (guint i = 0; i < n; i++)
+ {
+ const char *name = NULL;
+ g_autoptr(GVariant) value = NULL;
+
+ g_variant_get_child (xattrs, i, "(^&ay@ay)",
+ &name, &value);
+
+ if (strcmp (name, "security.selinux") == 0)
+ continue;
+ /* Initialize builder lazily */
+ if (!have_xattrs)
+ {
+ have_xattrs = TRUE;
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)"));
+ }
+ g_variant_builder_add (&builder, "(@ay@ay)",
+ g_variant_new_bytestring (name),
+ value);
+ }
+ /* Canonicalize zero length to NULL for efficiency */
+ if (!have_xattrs)
+ return NULL;
+ return g_variant_ref_sink (g_variant_builder_end (&builder));
+}
diff --git a/src/libostree/ostree-sysroot-cleanup.c b/src/libostree/ostree-sysroot-cleanup.c
index 022654c3..499f20eb 100644
--- a/src/libostree/ostree-sysroot-cleanup.c
+++ b/src/libostree/ostree-sysroot-cleanup.c
@@ -25,127 +25,87 @@
#include "ostree-sysroot-private.h"
+/* @deploydir_dfd: Directory FD for ostree/deploy
+ * @osname: Target osname
+ * @inout_deployments: All deployments in this subdir will be appended to this array
+ */
gboolean
-_ostree_sysroot_list_deployment_dirs_for_os (GFile *osdir,
+_ostree_sysroot_list_deployment_dirs_for_os (int deploydir_dfd,
+ const char *osname,
GPtrArray *inout_deployments,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- const char *osname = glnx_basename (gs_file_get_path_cached (osdir));
- g_autoptr(GFileEnumerator) dir_enum = NULL;
- g_autoptr(GFile) osdeploy_dir = NULL;
- GError *temp_error = NULL;
-
- osdeploy_dir = g_file_get_child (osdir, "deploy");
-
- dir_enum = g_file_enumerate_children (osdeploy_dir, OSTREE_GIO_FAST_QUERYINFO,
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
- NULL, &temp_error);
- if (!dir_enum)
- {
- if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
- {
- g_clear_error (&temp_error);
- goto done;
- }
- else
- {
- g_propagate_error (error, temp_error);
- goto out;
- }
- }
+ g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
+ gboolean exists;
+ const char *osdeploy_path = glnx_strjoina (osname, "/deploy");
+ if (!ot_dfd_iter_init_allow_noent (deploydir_dfd, osdeploy_path, &dfd_iter, &exists, error))
+ return FALSE;
+ if (!exists)
+ return TRUE;
while (TRUE)
{
- const char *name;
- GFileInfo *file_info = NULL;
- GFile *child = NULL;
- glnx_unref_object OstreeDeployment *deployment = NULL;
- g_autofree char *csum = NULL;
- gint deployserial;
+ struct dirent *dent;
- if (!g_file_enumerator_iterate (dir_enum, &file_info, &child,
- cancellable, error))
- goto out;
- if (file_info == NULL)
+ if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
+ return FALSE;
+ if (dent == NULL)
break;
- name = g_file_info_get_name (file_info);
-
- if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY)
+ if (dent->d_type != DT_DIR)
continue;
- if (!_ostree_sysroot_parse_deploy_path_name (name, &csum, &deployserial, error))
- goto out;
-
- deployment = ostree_deployment_new (-1, osname, csum, deployserial, NULL, -1);
- g_ptr_array_add (inout_deployments, g_object_ref (deployment));
+ g_autofree char *csum = NULL;
+ gint deployserial;
+ if (!_ostree_sysroot_parse_deploy_path_name (dent->d_name, &csum, &deployserial, error))
+ return FALSE;
+
+ g_ptr_array_add (inout_deployments, ostree_deployment_new (-1, osname, csum, deployserial, NULL, -1));
}
- done:
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
+/* Return in @out_deployments a new array of OstreeDeployment loaded from the
+ * filesystem state.
+ */
static gboolean
list_all_deployment_directories (OstreeSysroot *self,
GPtrArray **out_deployments,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- g_autoptr(GFileEnumerator) dir_enum = NULL;
- g_autoptr(GFile) deploydir = NULL;
- g_autoptr(GPtrArray) ret_deployments = NULL;
- GError *temp_error = NULL;
+ g_autoptr(GPtrArray) ret_deployments =
+ g_ptr_array_new_with_free_func (g_object_unref);
- deploydir = g_file_resolve_relative_path (self->path, "ostree/deploy");
-
- ret_deployments = g_ptr_array_new_with_free_func (g_object_unref);
-
- dir_enum = g_file_enumerate_children (deploydir, OSTREE_GIO_FAST_QUERYINFO,
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
- cancellable, &temp_error);
- if (!dir_enum)
- {
- if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
- {
- g_clear_error (&temp_error);
- goto done;
- }
- else
- {
- g_propagate_error (error, temp_error);
- goto out;
- }
- }
+ g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
+ gboolean exists;
+ if (!ot_dfd_iter_init_allow_noent (self->sysroot_fd, "ostree/deploy", &dfd_iter, &exists, error))
+ return FALSE;
+ if (!exists)
+ return TRUE;
while (TRUE)
{
- GFileInfo *file_info = NULL;
- GFile *child = NULL;
+ struct dirent *dent;
- if (!g_file_enumerator_iterate (dir_enum, &file_info, &child,
- NULL, error))
- goto out;
- if (file_info == NULL)
+ if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
+ return FALSE;
+ if (dent == NULL)
break;
- if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY)
+ if (dent->d_type != DT_DIR)
continue;
-
- if (!_ostree_sysroot_list_deployment_dirs_for_os (child, ret_deployments,
+
+ if (!_ostree_sysroot_list_deployment_dirs_for_os (dfd_iter.fd, dent->d_name,
+ ret_deployments,
cancellable, error))
- goto out;
+ return FALSE;
}
-
- done:
- ret = TRUE;
+
ot_transfer_out_value (out_deployments, &ret_deployments);
- out:
- return ret;
+ return TRUE;
}
static gboolean
@@ -154,7 +114,7 @@ parse_bootdir_name (const char *name,
char **out_csum)
{
const char *lastdash;
-
+
if (out_osname)
*out_osname = NULL;
if (out_csum)
@@ -164,7 +124,7 @@ parse_bootdir_name (const char *name,
if (!lastdash)
return FALSE;
-
+
if (!ostree_validate_checksum_string (lastdash + 1, NULL))
return FALSE;
@@ -183,7 +143,6 @@ list_all_boot_directories (OstreeSysroot *self,
GError **error)
{
gboolean ret = FALSE;
- g_autoptr(GFileEnumerator) dir_enum = NULL;
g_autoptr(GFile) boot_ostree = NULL;
g_autoptr(GPtrArray) ret_bootdirs = NULL;
GError *temp_error = NULL;
@@ -192,9 +151,10 @@ list_all_boot_directories (OstreeSysroot *self,
ret_bootdirs = g_ptr_array_new_with_free_func (g_object_unref);
- dir_enum = g_file_enumerate_children (boot_ostree, OSTREE_GIO_FAST_QUERYINFO,
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
- cancellable, &temp_error);
+ g_autoptr(GFileEnumerator) dir_enum =
+ g_file_enumerate_children (boot_ostree, OSTREE_GIO_FAST_QUERYINFO,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ cancellable, &temp_error);
if (!dir_enum)
{
if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c
index ed8c8bca..257a058b 100644
--- a/src/libostree/ostree-sysroot-deploy.c
+++ b/src/libostree/ostree-sysroot-deploy.c
@@ -255,7 +255,7 @@ ensure_directory_from_template (int orig_etc_fd,
g_assert (path != NULL);
g_assert (*path != '/' && *path != '\0');
- if (!ot_gopendirat (modified_etc_fd, path, TRUE, &src_dfd, error))
+ if (!glnx_opendirat (modified_etc_fd, path, TRUE, &src_dfd, error))
goto out;
/* Create with mode 0700, we'll fchmod/fchown later */
@@ -293,7 +293,7 @@ ensure_directory_from_template (int orig_etc_fd,
}
}
- if (!ot_gopendirat (new_etc_fd, path, TRUE, &target_dfd, error))
+ if (!glnx_opendirat (new_etc_fd, path, TRUE, &target_dfd, error))
goto out;
if (!dirfd_copy_attributes_and_xattrs (modified_etc_fd, path, src_dfd, target_dfd,
@@ -767,6 +767,7 @@ selinux_relabel_var_if_needed (OstreeSysroot *sysroot,
static gboolean
merge_configuration (OstreeSysroot *sysroot,
+ OstreeRepo *repo,
OstreeDeployment *previous_deployment,
OstreeDeployment *deployment,
int deployment_dfd,
@@ -829,19 +830,15 @@ merge_configuration (OstreeSysroot *sysroot,
usretc_exists = TRUE;
etc_exists = FALSE;
}
-
+
if (usretc_exists)
{
- glnx_fd_close int deployment_usr_dfd = -1;
-
- if (!glnx_opendirat (deployment_dfd, "usr", TRUE, &deployment_usr_dfd, error))
- goto out;
-
- /* TODO - set out labels as we copy files */
- g_assert (!etc_exists);
- if (!copy_dir_recurse (deployment_usr_dfd, deployment_dfd, "etc",
- sysroot->debug_flags, cancellable, error))
- goto out;
+ /* We need copies of /etc from /usr/etc (so admins can use vi), and if
+ * SELinux is enabled, we need to relabel.
+ */
+ OstreeRepoCheckoutAtOptions etc_co_opts = { .force_copy = TRUE,
+ .subpath = "/usr/etc",
+ .sepolicy_prefix = "/etc"};
/* Here, we initialize SELinux policy from the /usr/etc inside
* the root - this is before we've finalized the configuration
@@ -849,13 +846,15 @@ merge_configuration (OstreeSysroot *sysroot,
sepolicy = ostree_sepolicy_new (deployment_path, cancellable, error);
if (!sepolicy)
goto out;
-
if (ostree_sepolicy_get_name (sepolicy) != NULL)
- {
- if (!selinux_relabel_dir (sysroot, sepolicy, deployment_etc_path, "etc",
+ etc_co_opts.sepolicy = sepolicy;
+
+ /* Copy usr/etc → etc */
+ if (!ostree_repo_checkout_at (repo, &etc_co_opts,
+ deployment_dfd, "etc",
+ ostree_deployment_get_csum (deployment),
cancellable, error))
- goto out;
- }
+ goto out;
}
if (source_etc_path)
@@ -1307,7 +1306,7 @@ install_deployment_kernel (OstreeSysroot *sysroot,
contents = glnx_file_get_contents_utf8_at (deployment_dfd, "etc/os-release", NULL,
cancellable, error);
if (!contents)
- return g_prefix_error (error, "Reading /etc/os-release: "), FALSE;
+ return glnx_prefix_error (error, "Reading /etc/os-release");
}
}
else
@@ -1315,7 +1314,7 @@ install_deployment_kernel (OstreeSysroot *sysroot,
contents = glnx_file_get_contents_utf8_at (deployment_dfd, "usr/lib/os-release", NULL,
cancellable, error);
if (!contents)
- return g_prefix_error (error, "Reading /usr/lib/os-release: "), FALSE;
+ return glnx_prefix_error (error, "Reading /usr/lib/os-release");
}
g_autoptr(GHashTable) osrelease_values = parse_os_release (contents, "\n");
@@ -1380,6 +1379,7 @@ install_deployment_kernel (OstreeSysroot *sysroot,
val = ostree_bootconfig_parser_get (bootconfig, "options");
+ /* Note this is parsed in ostree-impl-system-generator.c */
g_autofree char *ostree_kernel_arg = g_strdup_printf ("ostree=/ostree/boot.%d/%s/%s/%d",
new_bootversion, osname, bootcsum,
ostree_deployment_get_bootserial (deployment));
@@ -1899,19 +1899,20 @@ allocate_deployserial (OstreeSysroot *self,
GCancellable *cancellable,
GError **error)
{
- guint i;
int new_deployserial = 0;
g_autoptr(GPtrArray) tmp_current_deployments =
g_ptr_array_new_with_free_func (g_object_unref);
- const char *osdir_name = glnx_strjoina ("ostree/deploy/", osname);
- g_autoptr(GFile) osdir = g_file_resolve_relative_path (self->path, osdir_name);
+ glnx_fd_close int deploy_dfd = -1;
+ if (!glnx_opendirat (self->sysroot_fd, "ostree/deploy", TRUE, &deploy_dfd, error))
+ return FALSE;
- if (!_ostree_sysroot_list_deployment_dirs_for_os (osdir, tmp_current_deployments,
+ if (!_ostree_sysroot_list_deployment_dirs_for_os (deploy_dfd, osname,
+ tmp_current_deployments,
cancellable, error))
return FALSE;
- for (i = 0; i < tmp_current_deployments->len; i++)
+ for (guint i = 0; i < tmp_current_deployments->len; i++)
{
OstreeDeployment *deployment = tmp_current_deployments->pdata[i];
@@ -2017,7 +2018,7 @@ ostree_sysroot_deploy_tree (OstreeSysroot *self,
ostree_deployment_set_bootconfig (new_deployment, bootconfig);
glnx_unref_object OstreeSePolicy *sepolicy = NULL;
- if (!merge_configuration (self, merge_deployment, new_deployment,
+ if (!merge_configuration (self, repo, merge_deployment, new_deployment,
deployment_dfd,
&sepolicy,
cancellable, error))
diff --git a/src/libostree/ostree-sysroot-private.h b/src/libostree/ostree-sysroot-private.h
index 4bc7802b..26cfd363 100644
--- a/src/libostree/ostree-sysroot-private.h
+++ b/src/libostree/ostree-sysroot-private.h
@@ -87,7 +87,8 @@ _ostree_sysroot_parse_deploy_path_name (const char *name,
GError **error);
gboolean
-_ostree_sysroot_list_deployment_dirs_for_os (GFile *osdir,
+_ostree_sysroot_list_deployment_dirs_for_os (int deploydir_dfd,
+ const char *osname,
GPtrArray *inout_deployments,
GCancellable *cancellable,
GError **error);
diff --git a/src/libostree/ostree-sysroot-upgrader.c b/src/libostree/ostree-sysroot-upgrader.c
index 4e7c8bf3..9816b3d6 100644
--- a/src/libostree/ostree-sysroot-upgrader.c
+++ b/src/libostree/ostree-sysroot-upgrader.c
@@ -22,6 +22,7 @@
#include "otutil.h"
+#include "ostree.h"
#include "ostree-sysroot-upgrader.h"
/**
@@ -50,7 +51,7 @@ struct OstreeSysrootUpgrader {
char *override_csum;
char *new_revision;
-};
+};
enum {
PROP_0,
@@ -70,7 +71,6 @@ parse_refspec (OstreeSysrootUpgrader *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
g_autofree char *origin_refspec = NULL;
g_autofree char *unconfigured_state = NULL;
g_autofree char *csum = NULL;
@@ -82,37 +82,28 @@ parse_refspec (OstreeSysrootUpgrader *self,
*/
unconfigured_state = g_key_file_get_string (self->origin, "origin", "unconfigured-state", NULL);
if (unconfigured_state)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "origin unconfigured-state: %s", unconfigured_state);
- goto out;
- }
+ return glnx_throw (error, "origin unconfigured-state: %s", unconfigured_state);
}
origin_refspec = g_key_file_get_string (self->origin, "origin", "refspec", NULL);
if (!origin_refspec)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "No origin/refspec in current deployment origin; cannot upgrade via ostree");
- goto out;
- }
+ return glnx_throw (error, "No origin/refspec in current deployment origin; cannot upgrade via ostree");
+
g_clear_pointer (&self->origin_remote, g_free);
g_clear_pointer (&self->origin_ref, g_free);
if (!ostree_parse_refspec (origin_refspec,
- &self->origin_remote,
+ &self->origin_remote,
&self->origin_ref,
error))
- goto out;
+ return FALSE;
csum = g_key_file_get_string (self->origin, "origin", "override-commit", NULL);
if (csum != NULL && !ostree_validate_checksum_string (csum, error))
- goto out;
+ return FALSE;
g_clear_pointer (&self->override_csum, g_free);
self->override_csum = g_steal_pointer (&csum);
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
static gboolean
@@ -120,17 +111,12 @@ ostree_sysroot_upgrader_initable_init (GInitable *initable,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
OstreeSysrootUpgrader *self = (OstreeSysrootUpgrader*)initable;
OstreeDeployment *booted_deployment =
ostree_sysroot_get_booted_deployment (self->sysroot);
if (booted_deployment == NULL && self->osname == NULL)
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Not currently booted into an OSTree system and no OS specified");
- goto out;
- }
+ return glnx_throw (error, "Not currently booted into an OSTree system and no OS specified");
if (self->osname == NULL)
{
@@ -138,37 +124,23 @@ ostree_sysroot_upgrader_initable_init (GInitable *initable,
self->osname = g_strdup (ostree_deployment_get_osname (booted_deployment));
}
else if (self->osname[0] == '\0')
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Invalid empty osname");
- goto out;
- }
+ return glnx_throw (error, "Invalid empty osname");
- self->merge_deployment = ostree_sysroot_get_merge_deployment (self->sysroot, self->osname);
+ self->merge_deployment = ostree_sysroot_get_merge_deployment (self->sysroot, self->osname);
if (self->merge_deployment == NULL)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "No previous deployment for OS '%s'", self->osname);
- goto out;
- }
+ return glnx_throw (error, "No previous deployment for OS '%s'", self->osname);
self->origin = ostree_deployment_get_origin (self->merge_deployment);
if (!self->origin)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "No origin known for deployment %s.%d",
- ostree_deployment_get_csum (self->merge_deployment),
- ostree_deployment_get_deployserial (self->merge_deployment));
- goto out;
- }
+ return glnx_throw (error, "No origin known for deployment %s.%d",
+ ostree_deployment_get_csum (self->merge_deployment),
+ ostree_deployment_get_deployserial (self->merge_deployment));
g_key_file_ref (self->origin);
if (!parse_refspec (self, cancellable, error))
- goto out;
+ return FALSE;
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
static void
@@ -401,19 +373,15 @@ ostree_sysroot_upgrader_set_origin (OstreeSysrootUpgrader *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
-
g_clear_pointer (&self->origin, g_key_file_unref);
if (origin)
{
self->origin = g_key_file_ref (origin);
if (!parse_refspec (self, cancellable, error))
- goto out;
+ return FALSE;
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/**
@@ -447,21 +415,19 @@ ostree_sysroot_upgrader_check_timestamps (OstreeRepo *repo,
const char *to_rev,
GError **error)
{
- gboolean ret = FALSE;
g_autoptr(GVariant) old_commit = NULL;
- g_autoptr(GVariant) new_commit = NULL;
-
if (!ostree_repo_load_variant (repo,
OSTREE_OBJECT_TYPE_COMMIT,
from_rev,
&old_commit,
error))
- goto out;
-
+ return FALSE;
+
+ g_autoptr(GVariant) new_commit = NULL;
if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT,
to_rev, &new_commit,
error))
- goto out;
+ return FALSE;
if (ostree_commit_get_timestamp (old_commit) > ostree_commit_get_timestamp (new_commit))
{
@@ -470,25 +436,23 @@ ostree_sysroot_upgrader_check_timestamps (OstreeRepo *repo,
g_autofree char *old_ts_str = NULL;
g_autofree char *new_ts_str = NULL;
- g_assert (old_ts);
- g_assert (new_ts);
+ if (old_ts == NULL || new_ts == NULL)
+ return glnx_throw (error, "Upgrade target revision '%s' timestamp (%" G_GINT64_FORMAT ") or current revision '%s' timestamp (%" G_GINT64_FORMAT ") is invalid",
+ to_rev, ostree_commit_get_timestamp (new_commit),
+ from_rev, ostree_commit_get_timestamp (old_commit));
+
old_ts_str = g_date_time_format (old_ts, "%c");
new_ts_str = g_date_time_format (new_ts, "%c");
g_date_time_unref (old_ts);
g_date_time_unref (new_ts);
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Upgrade target revision '%s' with timestamp '%s' is chronologically older than current revision '%s' with timestamp '%s'; use --allow-downgrade to permit",
- to_rev, new_ts_str, from_rev, old_ts_str);
- goto out;
+ return glnx_throw (error, "Upgrade target revision '%s' with timestamp '%s' is chronologically older than current revision '%s' with timestamp '%s'; use --allow-downgrade to permit",
+ to_rev, new_ts_str, from_rev, old_ts_str);
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
-
/**
* ostree_sysroot_upgrader_pull:
* @self: Upgrader
@@ -544,8 +508,7 @@ ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- glnx_unref_object OstreeRepo *repo = NULL;
+ g_autoptr(OstreeRepo) repo = NULL;
char *refs_to_fetch[] = { NULL, NULL };
const char *from_revision = NULL;
g_autofree char *origin_refspec = NULL;
@@ -556,7 +519,7 @@ ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self,
refs_to_fetch[0] = self->origin_ref;
if (!ostree_sysroot_get_repo (self->sysroot, &repo, cancellable, error))
- goto out;
+ return FALSE;
if (self->origin_remote)
origin_refspec = g_strconcat (self->origin_remote, ":", self->origin_ref, NULL);
@@ -572,7 +535,7 @@ ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self,
if (!ostree_repo_pull_one_dir (repo, self->origin_remote, dir_to_pull, refs_to_fetch,
flags, progress,
cancellable, error))
- goto out;
+ return FALSE;
if (progress)
ostree_async_progress_finish (progress);
@@ -586,7 +549,7 @@ ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self,
self->override_csum,
cancellable,
error))
- goto out;
+ return FALSE;
self->new_revision = g_strdup (self->override_csum);
}
@@ -594,7 +557,7 @@ ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self,
{
if (!ostree_repo_resolve_rev (repo, origin_refspec, FALSE,
&self->new_revision, error))
- goto out;
+ return FALSE;
}
@@ -613,13 +576,11 @@ ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self,
if (!ostree_sysroot_upgrader_check_timestamps (repo, from_revision,
self->new_revision,
error))
- goto out;
+ return FALSE;
}
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/**
@@ -636,9 +597,7 @@ ostree_sysroot_upgrader_deploy (OstreeSysrootUpgrader *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- glnx_unref_object OstreeDeployment *new_deployment = NULL;
-
+ g_autoptr(OstreeDeployment) new_deployment = NULL;
if (!ostree_sysroot_deploy_tree (self->sysroot, self->osname,
self->new_revision,
self->origin,
@@ -646,18 +605,16 @@ ostree_sysroot_upgrader_deploy (OstreeSysrootUpgrader *self,
NULL,
&new_deployment,
cancellable, error))
- goto out;
+ return FALSE;
if (!ostree_sysroot_simple_write_deployment (self->sysroot, self->osname,
new_deployment,
self->merge_deployment,
0,
cancellable, error))
- goto out;
+ return FALSE;
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
GType
diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c
index bdf7376b..e47214c5 100644
--- a/src/libostree/ostree-sysroot.c
+++ b/src/libostree/ostree-sysroot.c
@@ -284,47 +284,33 @@ ostree_sysroot_ensure_initialized (OstreeSysroot *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- struct stat stbuf;
-
if (!ensure_sysroot_fd (self, error))
- goto out;
+ return FALSE;
if (!glnx_shutil_mkdir_p_at (self->sysroot_fd, "ostree/repo", 0755,
cancellable, error))
- goto out;
+ return FALSE;
if (!glnx_shutil_mkdir_p_at (self->sysroot_fd, "ostree/deploy", 0755,
cancellable, error))
- goto out;
+ return FALSE;
+ struct stat stbuf;
if (fstatat (self->sysroot_fd, "ostree/repo/objects", &stbuf, 0) != 0)
{
if (errno != ENOENT)
- {
- glnx_set_prefix_error_from_errno (error, "stat %s", "ostree/repo/objects");
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "stat(ostree/repo/objects)");
else
{
g_autoptr(GFile) repo_dir = g_file_resolve_relative_path (self->path, "ostree/repo");
glnx_unref_object OstreeRepo *repo = ostree_repo_new (repo_dir);
if (!ostree_repo_create (repo, OSTREE_REPO_MODE_BARE,
cancellable, error))
- goto out;
+ return FALSE;
}
}
- ret = TRUE;
- out:
- return ret;
-}
-
-static void
-match_info_cleanup (void *loc)
-{
- GMatchInfo **match = (GMatchInfo**)loc;
- if (*match) g_match_info_unref (*match);
+ return TRUE;
}
gboolean
@@ -333,13 +319,9 @@ _ostree_sysroot_parse_deploy_path_name (const char *name,
int *out_serial,
GError **error)
{
- gboolean ret = FALSE;
- __attribute__((cleanup(match_info_cleanup))) GMatchInfo *match = NULL;
- g_autofree char *serial_str = NULL;
static gsize regex_initialized;
static GRegex *regex;
-
if (g_once_init_enter (®ex_initialized))
{
regex = g_regex_new ("^([0-9a-f]+)\\.([0-9]+)$", 0, 0, NULL);
@@ -347,20 +329,14 @@ _ostree_sysroot_parse_deploy_path_name (const char *name,
g_once_init_leave (®ex_initialized, 1);
}
+ g_autoptr(GMatchInfo) match = NULL;
if (!g_regex_match (regex, name, 0, &match))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Invalid deploy name '%s', expected CHECKSUM.TREESERIAL", name);
- goto out;
- }
+ return glnx_throw (error, "Invalid deploy name '%s', expected CHECKSUM.TREESERIAL", name);
+ g_autofree char *serial_str = g_match_info_fetch (match, 2);
*out_csum = g_match_info_fetch (match, 1);
- serial_str = g_match_info_fetch (match, 2);
*out_serial = (int)g_ascii_strtoll (serial_str, NULL, 10);
-
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
gboolean
@@ -370,49 +346,36 @@ _ostree_sysroot_read_current_subbootversion (OstreeSysroot *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- struct stat stbuf;
- g_autofree char *ostree_bootdir_name = g_strdup_printf ("ostree/boot.%d", bootversion);
-
if (!ensure_sysroot_fd (self, error))
- goto out;
+ return FALSE;
+ g_autofree char *ostree_bootdir_name = g_strdup_printf ("ostree/boot.%d", bootversion);
+ struct stat stbuf;
if (fstatat (self->sysroot_fd, ostree_bootdir_name, &stbuf, AT_SYMLINK_NOFOLLOW) != 0)
{
if (errno == ENOENT)
*out_subbootversion = 0;
else
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno (error);
}
else
{
- g_autofree char *current_subbootdir_name = NULL;
-
- current_subbootdir_name = glnx_readlinkat_malloc (self->sysroot_fd, ostree_bootdir_name,
- cancellable, error);
+ g_autofree char *current_subbootdir_name =
+ glnx_readlinkat_malloc (self->sysroot_fd, ostree_bootdir_name,
+ cancellable, error);
if (!current_subbootdir_name)
- goto out;
-
+ return FALSE;
+
if (g_str_has_suffix (current_subbootdir_name, ".0"))
*out_subbootversion = 0;
else if (g_str_has_suffix (current_subbootdir_name, ".1"))
*out_subbootversion = 1;
else
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Invalid target '%s' in %s",
- current_subbootdir_name,
- ostree_bootdir_name);
- goto out;
- }
+ return glnx_throw (error, "Invalid target '%s' in %s",
+ current_subbootdir_name, ostree_bootdir_name);
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
static gint
@@ -451,60 +414,46 @@ _ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- int fd; /* Temporary owned by iterator */
- g_autofree char *entries_path = g_strdup_printf ("boot/loader.%d/entries", bootversion);
- g_autoptr(GPtrArray) ret_loader_configs = NULL;
- g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
-
if (!ensure_sysroot_fd (self, error))
- goto out;
+ return FALSE;
- ret_loader_configs = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
+ g_autoptr(GPtrArray) ret_loader_configs =
+ g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
- fd = glnx_opendirat_with_errno (self->sysroot_fd, entries_path, TRUE);
- if (fd == -1)
+ g_autofree char *entries_path = g_strdup_printf ("boot/loader.%d/entries", bootversion);
+ gboolean entries_exists;
+ g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
+ if (!ot_dfd_iter_init_allow_noent (self->sysroot_fd, entries_path,
+ &dfd_iter, &entries_exists, error))
+ return FALSE;
+ if (!entries_exists)
{
- if (errno == ENOENT)
- goto done;
- else
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ /* Note early return */
+ *out_loader_configs = g_steal_pointer (&ret_loader_configs);
+ return TRUE;
}
- if (!glnx_dirfd_iterator_init_take_fd (fd, &dfd_iter, error))
- goto out;
-
while (TRUE)
{
struct dirent *dent;
struct stat stbuf;
if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error))
- goto out;
-
+ return FALSE;
if (dent == NULL)
break;
if (fstatat (dfd_iter.fd, dent->d_name, &stbuf, 0) != 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno (error);
if (g_str_has_prefix (dent->d_name, "ostree-") &&
g_str_has_suffix (dent->d_name, ".conf") &&
S_ISREG (stbuf.st_mode))
{
glnx_unref_object OstreeBootconfigParser *config = ostree_bootconfig_parser_new ();
-
+
if (!ostree_bootconfig_parser_parse_at (config, dfd_iter.fd, dent->d_name, cancellable, error))
- {
- g_prefix_error (error, "Parsing %s: ", dent->d_name);
- goto out;
- }
+ return glnx_prefix_error (error, "Parsing %s", dent->d_name);
g_ptr_array_add (ret_loader_configs, g_object_ref (config));
}
@@ -512,13 +461,8 @@ _ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self,
/* Callers expect us to give them a sorted array */
g_ptr_array_sort (ret_loader_configs, compare_loader_configs_for_sorting);
-
- done:
- if (out_loader_configs)
- *out_loader_configs = g_steal_pointer (&ret_loader_configs);
- ret = TRUE;
- out:
- return ret;
+ ot_transfer_out_value(out_loader_configs, &ret_loader_configs);
+ return TRUE;
}
static gboolean
@@ -527,49 +471,34 @@ read_current_bootversion (OstreeSysroot *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
int ret_bootversion;
struct stat stbuf;
if (fstatat (self->sysroot_fd, "boot/loader", &stbuf, AT_SYMLINK_NOFOLLOW) != 0)
{
if (errno != ENOENT)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno (error);
ret_bootversion = 0;
}
else
{
- g_autofree char *target = NULL;
-
if (!S_ISLNK (stbuf.st_mode))
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Not a symbolic link: boot/loader");
- goto out;
- }
+ return glnx_throw (error, "Not a symbolic link: boot/loader");
- target = glnx_readlinkat_malloc (self->sysroot_fd, "boot/loader", cancellable, error);
+ g_autofree char *target =
+ glnx_readlinkat_malloc (self->sysroot_fd, "boot/loader", cancellable, error);
if (!target)
- goto out;
+ return FALSE;
if (g_strcmp0 (target, "loader.0") == 0)
ret_bootversion = 0;
else if (g_strcmp0 (target, "loader.1") == 0)
ret_bootversion = 1;
else
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Invalid target '%s' in boot/loader", target);
- goto out;
- }
+ return glnx_throw (error, "Invalid target '%s' in boot/loader", target);
}
- ret = TRUE;
*out_bootversion = ret_bootversion;
- out:
- return ret;
+ return TRUE;
}
static gboolean
@@ -580,42 +509,29 @@ parse_origin (OstreeSysroot *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- g_autoptr(GKeyFile) ret_origin = NULL;
g_autofree char *origin_path = g_strconcat ("../", deployment_name, ".origin", NULL);
- struct stat stbuf;
- g_autofree char *origin_contents = NULL;
+ g_autoptr(GKeyFile) ret_origin = g_key_file_new ();
- ret_origin = g_key_file_new ();
-
+ struct stat stbuf;
if (fstatat (deployment_dfd, origin_path, &stbuf, 0) != 0)
{
- if (errno == ENOENT)
- ;
- else
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ if (errno != ENOENT)
+ return glnx_throw_errno (error);
}
else
{
- origin_contents = glnx_file_get_contents_utf8_at (deployment_dfd, origin_path,
- NULL, cancellable, error);
+ g_autofree char *origin_contents =
+ glnx_file_get_contents_utf8_at (deployment_dfd, origin_path,
+ NULL, cancellable, error);
if (!origin_contents)
- goto out;
+ return FALSE;
if (!g_key_file_load_from_data (ret_origin, origin_contents, -1, 0, error))
- goto out;
+ return glnx_prefix_error (error, "Parsing %s", origin_path);
}
- ret = TRUE;
- if (out_origin)
- *out_origin = g_steal_pointer (&ret_origin);
- out:
- if (error)
- g_prefix_error (error, "Parsing %s: ", origin_path);
- return ret;
+ ot_transfer_out_value(out_origin, &ret_origin);
+ return TRUE;
}
static gboolean
@@ -626,14 +542,8 @@ parse_bootlink (const char *bootlink,
int *out_treebootserial,
GError **error)
{
- gboolean ret = FALSE;
- __attribute__((cleanup(match_info_cleanup))) GMatchInfo *match = NULL;
- g_autofree char *bootversion_str = NULL;
- g_autofree char *treebootserial_str = NULL;
-
static gsize regex_initialized;
static GRegex *regex;
-
if (g_once_init_enter (®ex_initialized))
{
regex = g_regex_new ("^/ostree/boot.([01])/([^/]+)/([^/]+)/([0-9]+)$", 0, 0, NULL);
@@ -641,23 +551,17 @@ parse_bootlink (const char *bootlink,
g_once_init_leave (®ex_initialized, 1);
}
+ g_autoptr(GMatchInfo) match = NULL;
if (!g_regex_match (regex, bootlink, 0, &match))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Invalid ostree= argument '%s', expected ostree=/ostree/boot.BOOTVERSION/OSNAME/BOOTCSUM/TREESERIAL", bootlink);
- goto out;
- }
-
- bootversion_str = g_match_info_fetch (match, 1);
+ return glnx_throw (error, "Invalid ostree= argument '%s', expected ostree=/ostree/boot.BOOTVERSION/OSNAME/BOOTCSUM/TREESERIAL", bootlink);
+
+ g_autofree char *bootversion_str = g_match_info_fetch (match, 1);
+ g_autofree char *treebootserial_str = g_match_info_fetch (match, 4);
*out_entry_bootversion = (int)g_ascii_strtoll (bootversion_str, NULL, 10);
*out_osname = g_match_info_fetch (match, 2);
*out_bootcsum = g_match_info_fetch (match, 3);
- treebootserial_str = g_match_info_fetch (match, 4);
*out_treebootserial = (int)g_ascii_strtoll (treebootserial_str, NULL, 10);
-
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
static char *
@@ -677,60 +581,54 @@ parse_deployment (OstreeSysroot *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- const char *relative_boot_link;
- glnx_unref_object OstreeDeployment *ret_deployment = NULL;
+ if (!ensure_sysroot_fd (self, error))
+ return FALSE;
+
int entry_boot_version;
- int treebootserial = -1;
- int deployserial = -1;
g_autofree char *osname = NULL;
g_autofree char *bootcsum = NULL;
- g_autofree char *treecsum = NULL;
- glnx_fd_close int deployment_dfd = -1;
- const char *deploy_basename;
- g_autofree char *treebootserial_target = NULL;
- g_autoptr(GKeyFile) origin = NULL;
- g_autofree char *unlocked_development_path = NULL;
- struct stat stbuf;
-
- if (!ensure_sysroot_fd (self, error))
- goto out;
-
+ int treebootserial = -1;
if (!parse_bootlink (boot_link, &entry_boot_version,
&osname, &bootcsum, &treebootserial,
error))
- goto out;
+ return FALSE;
- relative_boot_link = boot_link;
+ const char *relative_boot_link = boot_link;
if (*relative_boot_link == '/')
relative_boot_link++;
- treebootserial_target = glnx_readlinkat_malloc (self->sysroot_fd, relative_boot_link,
- cancellable, error);
+ g_autofree char *treebootserial_target =
+ glnx_readlinkat_malloc (self->sysroot_fd, relative_boot_link,
+ cancellable, error);
if (!treebootserial_target)
- goto out;
-
- deploy_basename = glnx_basename (treebootserial_target);
+ return FALSE;
+ const char *deploy_basename = glnx_basename (treebootserial_target);
+ g_autofree char *treecsum = NULL;
+ int deployserial = -1;
if (!_ostree_sysroot_parse_deploy_path_name (deploy_basename,
&treecsum, &deployserial, error))
- goto out;
+ return FALSE;
+ glnx_fd_close int deployment_dfd = -1;
if (!glnx_opendirat (self->sysroot_fd, relative_boot_link, TRUE,
&deployment_dfd, error))
- goto out;
+ return FALSE;
+ g_autoptr(GKeyFile) origin = NULL;
if (!parse_origin (self, deployment_dfd, deploy_basename, &origin,
cancellable, error))
- goto out;
+ return FALSE;
- ret_deployment = ostree_deployment_new (-1, osname, treecsum, deployserial,
- bootcsum, treebootserial);
+ glnx_unref_object OstreeDeployment *ret_deployment
+ = ostree_deployment_new (-1, osname, treecsum, deployserial,
+ bootcsum, treebootserial);
if (origin)
ostree_deployment_set_origin (ret_deployment, origin);
ret_deployment->unlocked = OSTREE_DEPLOYMENT_UNLOCKED_NONE;
- unlocked_development_path = get_unlocked_development_path (ret_deployment);
+ g_autofree char *unlocked_development_path = get_unlocked_development_path (ret_deployment);
+ struct stat stbuf;
if (lstat (unlocked_development_path, &stbuf) == 0)
ret_deployment->unlocked = OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT;
else
@@ -747,11 +645,9 @@ parse_deployment (OstreeSysroot *self,
g_debug ("Deployment %s.%d unlocked=%d", treecsum, deployserial, ret_deployment->unlocked);
- ret = TRUE;
if (out_deployment)
*out_deployment = g_steal_pointer (&ret_deployment);
- out:
- return ret;
+ return TRUE;
}
static char *
@@ -787,29 +683,19 @@ list_deployments_process_one_boot_entry (OstreeSysroot *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- g_autofree char *ostree_arg = NULL;
- glnx_unref_object OstreeDeployment *deployment = NULL;
-
- ostree_arg = get_ostree_kernel_arg_from_config (config);
+ g_autofree char *ostree_arg = get_ostree_kernel_arg_from_config (config);
if (ostree_arg == NULL)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "No ostree= kernel argument found");
- goto out;
- }
-
+ return glnx_throw (error, "No ostree= kernel argument found");
+
+ glnx_unref_object OstreeDeployment *deployment = NULL;
if (!parse_deployment (self, ostree_arg, &deployment,
cancellable, error))
- goto out;
-
+ return FALSE;
+
ostree_deployment_set_bootconfig (deployment, config);
g_ptr_array_add (inout_deployments, g_object_ref (deployment));
-
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
static gint
@@ -847,29 +733,21 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- guint i;
- int bootversion = 0;
- int subbootversion = 0;
- struct stat stbuf;
- g_autoptr(GPtrArray) boot_loader_configs = NULL;
- g_autoptr(GPtrArray) deployments = NULL;
-
if (!ensure_sysroot_fd (self, error))
- goto out;
+ return FALSE;
+ int bootversion = 0;
if (!read_current_bootversion (self, &bootversion, cancellable, error))
- goto out;
+ return FALSE;
+ int subbootversion = 0;
if (!_ostree_sysroot_read_current_subbootversion (self, bootversion, &subbootversion,
cancellable, error))
- goto out;
+ return FALSE;
+ struct stat stbuf;
if (fstatat (self->sysroot_fd, "ostree/deploy", &stbuf, 0) < 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "fstatat");
if (out_changed)
{
@@ -877,8 +755,8 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self,
self->loaded_ts.tv_nsec == stbuf.st_mtim.tv_nsec)
{
*out_changed = FALSE;
- ret = TRUE;
- goto out;
+ /* Note early return */
+ return TRUE;
}
}
@@ -887,23 +765,24 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self,
self->bootversion = -1;
self->subbootversion = -1;
+ g_autoptr(GPtrArray) boot_loader_configs = NULL;
if (!_ostree_sysroot_read_boot_loader_configs (self, bootversion, &boot_loader_configs,
cancellable, error))
- goto out;
+ return FALSE;
- deployments = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
+ g_autoptr(GPtrArray) deployments = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
- for (i = 0; i < boot_loader_configs->len; i++)
+ for (guint i = 0; i < boot_loader_configs->len; i++)
{
OstreeBootconfigParser *config = boot_loader_configs->pdata[i];
if (!list_deployments_process_one_boot_entry (self, config, deployments,
cancellable, error))
- goto out;
+ return FALSE;
}
g_ptr_array_sort (deployments, compare_deployments_by_boot_loader_version_reversed);
- for (i = 0; i < deployments->len; i++)
+ for (guint i = 0; i < deployments->len; i++)
{
OstreeDeployment *deployment = deployments->pdata[i];
ostree_deployment_set_index (deployment, i);
@@ -911,7 +790,7 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self,
if (!find_booted_deployment (self, deployments, &self->booted_deployment,
cancellable, error))
- goto out;
+ return FALSE;
self->bootversion = bootversion;
self->subbootversion = subbootversion;
@@ -920,11 +799,9 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self,
self->loaded = TRUE;
self->loaded_ts = stbuf.st_mtim;
- ret = TRUE;
if (out_changed)
*out_changed = TRUE;
- out:
- return ret;
+ return TRUE;
}
int
@@ -1039,18 +916,13 @@ ostree_sysroot_get_repo (OstreeSysroot *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
-
/* ostree_repo_open() is idempotent. */
if (!ostree_repo_open (self->repo, cancellable, error))
- goto out;
+ return FALSE;
if (out_repo != NULL)
*out_repo = g_object_ref (self->repo);
-
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/**
@@ -1066,37 +938,33 @@ _ostree_sysroot_query_bootloader (OstreeSysroot *sysroot,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
gboolean is_active;
- glnx_unref_object OstreeBootloader *ret_loader = NULL;
-
- ret_loader = (OstreeBootloader*)_ostree_bootloader_syslinux_new (sysroot);
+ glnx_unref_object OstreeBootloader *ret_loader =
+ (OstreeBootloader*)_ostree_bootloader_syslinux_new (sysroot);
if (!_ostree_bootloader_query (ret_loader, &is_active,
cancellable, error))
- goto out;
+ return FALSE;
+
if (!is_active)
{
g_object_unref (ret_loader);
ret_loader = (OstreeBootloader*)_ostree_bootloader_grub2_new (sysroot);
if (!_ostree_bootloader_query (ret_loader, &is_active,
cancellable, error))
- goto out;
+ return FALSE;
}
if (!is_active)
{
g_object_unref (ret_loader);
ret_loader = (OstreeBootloader*)_ostree_bootloader_uboot_new (sysroot);
if (!_ostree_bootloader_query (ret_loader, &is_active, cancellable, error))
- goto out;
+ return FALSE;
}
if (!is_active)
g_clear_object (&ret_loader);
- ret = TRUE;
- if (out_bootloader)
- *out_bootloader = g_steal_pointer (&ret_loader);
- out:
- return ret;
+ ot_transfer_out_value(out_bootloader, &ret_loader);
+ return TRUE;
}
char *
@@ -1128,21 +996,17 @@ parse_kernel_commandline (OstreeKernelArgs **out_args,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
g_autoptr(GFile) proc_cmdline = g_file_new_for_path ("/proc/cmdline");
g_autofree char *contents = NULL;
gsize len;
if (!g_file_load_contents (proc_cmdline, cancellable, &contents, &len, NULL,
error))
- goto out;
+ return FALSE;
g_strchomp (contents);
-
- ret = TRUE;
*out_args = _ostree_kernel_args_from_string (contents);
- out:
- return ret;
+ return TRUE;
}
static gboolean
@@ -1152,50 +1016,37 @@ find_booted_deployment (OstreeSysroot *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
struct stat root_stbuf;
struct stat self_stbuf;
glnx_unref_object OstreeDeployment *ret_deployment = NULL;
if (stat ("/", &root_stbuf) != 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "stat /");
if (!ensure_sysroot_fd (self, error))
- goto out;
+ return FALSE;
if (fstat (self->sysroot_fd, &self_stbuf) != 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "fstat");
if (root_stbuf.st_dev == self_stbuf.st_dev &&
root_stbuf.st_ino == self_stbuf.st_ino)
- {
- guint i;
- const char *bootlink_arg;
+ {
__attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kernel_args = NULL;
-
if (!parse_kernel_commandline (&kernel_args, cancellable, error))
- goto out;
-
- bootlink_arg = _ostree_kernel_args_get_last_value (kernel_args, "ostree");
+ return FALSE;
+
+ const char *bootlink_arg = _ostree_kernel_args_get_last_value (kernel_args, "ostree");
if (bootlink_arg)
{
- for (i = 0; i < deployments->len; i++)
+ for (guint i = 0; i < deployments->len; i++)
{
OstreeDeployment *deployment = deployments->pdata[i];
g_autofree char *deployment_path = ostree_sysroot_get_deployment_dirpath (self, deployment);
struct stat stbuf;
if (fstatat (self->sysroot_fd, deployment_path, &stbuf, 0) != 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "fstatat");
if (stbuf.st_dev == root_stbuf.st_dev &&
stbuf.st_ino == root_stbuf.st_ino)
@@ -1206,11 +1057,7 @@ find_booted_deployment (OstreeSysroot *self,
}
if (ret_deployment == NULL)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Unexpected state: ostree= kernel argument found, but / is not a deployment root");
- goto out;
- }
+ return glnx_throw (error, "Unexpected state: ostree= kernel argument found, but / is not a deployment root");
}
else
{
@@ -1218,10 +1065,8 @@ find_booted_deployment (OstreeSysroot *self,
}
}
- ret = TRUE;
ot_transfer_out_value (out_deployment, &ret_deployment);
- out:
- return ret;
+ return TRUE;
}
/**
@@ -1261,7 +1106,7 @@ ostree_sysroot_get_merge_deployment (OstreeSysroot *self,
if (strcmp (ostree_deployment_get_osname (deployment), osname) != 0)
continue;
-
+
return g_object_ref (deployment);
}
}
@@ -1325,11 +1170,10 @@ ostree_sysroot_try_lock (OstreeSysroot *self,
gboolean *out_acquired,
GError **error)
{
- gboolean ret = FALSE;
g_autoptr(GError) local_error = NULL;
if (!ensure_sysroot_fd (self, error))
- goto out;
+ return FALSE;
/* Note use of LOCK_NB */
if (!glnx_make_lock_file (self->sysroot_fd, OSTREE_SYSROOT_LOCKFILE,
@@ -1342,7 +1186,7 @@ ostree_sysroot_try_lock (OstreeSysroot *self,
else
{
g_propagate_error (error, g_steal_pointer (&local_error));
- goto out;
+ return FALSE;
}
}
else
@@ -1350,9 +1194,7 @@ ostree_sysroot_try_lock (OstreeSysroot *self,
*out_acquired = TRUE;
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/**
@@ -1383,7 +1225,7 @@ lock_in_thread (GTask *task,
if (g_cancellable_set_error_if_cancelled (cancellable, &local_error))
ostree_sysroot_unlock (self);
-
+
out:
if (local_error)
g_task_return_error (task, local_error);
@@ -1444,77 +1286,49 @@ ostree_sysroot_init_osname (OstreeSysroot *self,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- const char *deploydir = glnx_strjoina ("ostree/deploy/", osname);
- glnx_fd_close int dfd = -1;
-
if (!ensure_sysroot_fd (self, error))
- goto out;
+ return FALSE;
+ const char *deploydir = glnx_strjoina ("ostree/deploy/", osname);
if (mkdirat (self->sysroot_fd, deploydir, 0777) < 0)
- {
- glnx_set_prefix_error_from_errno (error, "Creating %s", deploydir);
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "Creating %s", deploydir);
+ glnx_fd_close int dfd = -1;
if (!glnx_opendirat (self->sysroot_fd, deploydir, TRUE, &dfd, error))
- goto out;
+ return FALSE;
if (mkdirat (dfd, "var", 0777) < 0)
- {
- glnx_set_prefix_error_from_errno (error, "Creating %s", "var");
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "Creating %s", "var");
/* This is a bit of a legacy hack...but we have to keep it around
* now. We're ensuring core subdirectories of /var exist.
*/
if (mkdirat (dfd, "var/tmp", 0777) < 0)
- {
- glnx_set_prefix_error_from_errno (error, "Creating %s", "var/tmp");
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "Creating %s", "var/tmp");
if (fchmodat (dfd, "var/tmp", 01777, 0) < 0)
- {
- glnx_set_prefix_error_from_errno (error, "Fchmod %s", "var/tmp");
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "fchmod %s", "var/tmp");
if (mkdirat (dfd, "var/lib", 0777) < 0)
- {
- glnx_set_prefix_error_from_errno (error, "Creating %s", "var/tmp");
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "Creating %s", "var/tmp");
/* This needs to be available and properly labeled early during the boot
* process (before tmpfiles.d kicks in), so that journald can flush logs from
* the first boot there. https://bugzilla.redhat.com/show_bug.cgi?id=1265295
* */
if (mkdirat (dfd, "var/log", 0755) < 0)
- {
- glnx_set_prefix_error_from_errno (error, "Creating %s", "var/log");
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "Creating %s", "var/log");
if (symlinkat ("../run", dfd, "var/run") < 0)
- {
- glnx_set_prefix_error_from_errno (error, "Symlinking %s", "var/run");
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "Symlinking %s", "var/run");
if (symlinkat ("../run/lock", dfd, "var/lock") < 0)
- {
- glnx_set_prefix_error_from_errno (error, "Symlinking %s", "var/lock");
- goto out;
- }
+ return glnx_throw_errno_prefix (error, "Symlinking %s", "var/lock");
if (!_ostree_sysroot_bump_mtime (self, error))
- goto out;
+ return FALSE;
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
/**
diff --git a/src/libostree/ostree-types.h b/src/libostree/ostree-types.h
index f6aea0f0..61ac4283 100644
--- a/src/libostree/ostree-types.h
+++ b/src/libostree/ostree-types.h
@@ -38,4 +38,8 @@ typedef struct OstreeSysrootUpgrader OstreeSysrootUpgrader;
typedef struct OstreeMutableTree OstreeMutableTree;
typedef struct OstreeRepoFile OstreeRepoFile;
+#ifdef OSTREE_ENABLE_EXPERIMENTAL_API
+typedef struct OstreeRemote OstreeRemote;
+#endif
+
G_END_DECLS
diff --git a/src/libostree/ostree-version.h b/src/libostree/ostree-version.h
index d5546832..f9549150 100644
--- a/src/libostree/ostree-version.h
+++ b/src/libostree/ostree-version.h
@@ -40,14 +40,14 @@
*
* ostree release version component (e.g. 2 if %OSTREE_VERSION is 2017.2)
*/
-#define OSTREE_RELEASE_VERSION (5)
+#define OSTREE_RELEASE_VERSION (6)
/**
* OSTREE_VERSION
*
* ostree version.
*/
-#define OSTREE_VERSION (2017.5)
+#define OSTREE_VERSION (2017.6)
/**
* OSTREE_VERSION_S:
@@ -55,7 +55,7 @@
* ostree version, encoded as a string, useful for printing and
* concatenation.
*/
-#define OSTREE_VERSION_S "2017.5"
+#define OSTREE_VERSION_S "2017.6"
#define OSTREE_ENCODE_VERSION(year,release) \
((year) << 16 | (release))
diff --git a/src/libostree/ostree.h b/src/libostree/ostree.h
index eb4ed8d3..5d1ac1e1 100644
--- a/src/libostree/ostree.h
+++ b/src/libostree/ostree.h
@@ -24,6 +24,9 @@
#include
#include
#include
+#ifdef OSTREE_ENABLE_EXPERIMENTAL_API
+#include
+#endif
#include
#include
#include
diff --git a/src/libotutil/ot-checksum-utils.c b/src/libotutil/ot-checksum-utils.c
index 39417044..eb0185bd 100644
--- a/src/libotutil/ot-checksum-utils.c
+++ b/src/libotutil/ot-checksum-utils.c
@@ -47,7 +47,7 @@ ot_csum_from_gchecksum (GChecksum *checksum)
{
guchar *ret = g_malloc (32);
gsize len = 32;
-
+
g_checksum_get_digest (checksum, ret, &len);
g_assert (len == 32);
return ret;
@@ -62,13 +62,11 @@ ot_gio_write_update_checksum (GOutputStream *out,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
-
if (out)
{
if (!g_output_stream_write_all (out, data, len, out_bytes_written,
cancellable, error))
- goto out;
+ return FALSE;
}
else if (out_bytes_written)
{
@@ -77,10 +75,7 @@ ot_gio_write_update_checksum (GOutputStream *out,
if (checksum)
g_checksum_update (checksum, data, len);
-
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
gboolean
@@ -90,8 +85,6 @@ ot_gio_splice_update_checksum (GOutputStream *out,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
-
g_return_val_if_fail (out != NULL || checksum != NULL, FALSE);
if (checksum != NULL)
@@ -101,24 +94,25 @@ ot_gio_splice_update_checksum (GOutputStream *out,
do
{
if (!g_input_stream_read_all (in, buf, sizeof(buf), &bytes_read, cancellable, error))
- goto out;
+ return FALSE;
if (!ot_gio_write_update_checksum (out, buf, bytes_read, &bytes_written, checksum,
cancellable, error))
- goto out;
+ return FALSE;
}
while (bytes_read > 0);
}
else if (out != NULL)
{
if (g_output_stream_splice (out, in, 0, cancellable, error) < 0)
- goto out;
+ return FALSE;
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
+/* Copy @in to @out, return in @out_csum the binary checksum for
+ * all data read.
+ */
gboolean
ot_gio_splice_get_checksum (GOutputStream *out,
GInputStream *in,
@@ -126,22 +120,14 @@ ot_gio_splice_get_checksum (GOutputStream *out,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
- GChecksum *checksum = NULL;
- g_autofree guchar *ret_csum = NULL;
-
- checksum = g_checksum_new (G_CHECKSUM_SHA256);
+ g_autoptr(GChecksum) checksum = g_checksum_new (G_CHECKSUM_SHA256);
if (!ot_gio_splice_update_checksum (out, in, checksum, cancellable, error))
- goto out;
+ return FALSE;
- ret_csum = ot_csum_from_gchecksum (checksum);
-
- ret = TRUE;
+ g_autofree guchar *ret_csum = ot_csum_from_gchecksum (checksum);
ot_transfer_out_value (out_csum, &ret_csum);
- out:
- g_clear_pointer (&checksum, (GDestroyNotify) g_checksum_free);
- return ret;
+ return TRUE;
}
gboolean
@@ -162,21 +148,13 @@ ot_checksum_file_at (int dfd,
GCancellable *cancellable,
GError **error)
{
- GChecksum *checksum = NULL;
- char *ret = NULL;
g_autoptr(GInputStream) in = NULL;
-
if (!ot_openat_read_stream (dfd, path, TRUE, &in, cancellable, error))
- goto out;
-
- checksum = g_checksum_new (checksum_type);
+ return FALSE;
+ g_autoptr(GChecksum) checksum = g_checksum_new (checksum_type);
if (!ot_gio_splice_update_checksum (NULL, in, checksum, cancellable, error))
- goto out;
-
- ret = g_strdup (g_checksum_get_string (checksum));
- out:
- g_clear_pointer (&checksum, (GDestroyNotify) g_checksum_free);
- return ret;
+ return FALSE;
+ return g_strdup (g_checksum_get_string (checksum));
}
diff --git a/src/libotutil/ot-fs-utils.c b/src/libotutil/ot-fs-utils.c
index a0a72ca5..529077fb 100644
--- a/src/libotutil/ot-fs-utils.c
+++ b/src/libotutil/ot-fs-utils.c
@@ -35,98 +35,6 @@ ot_fdrel_to_gfile (int dfd, const char *path)
return g_file_new_for_path (abspath);
}
-int
-ot_opendirat (int dfd, const char *path, gboolean follow)
-{
- int flags = O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY;
- if (!follow)
- flags |= O_NOFOLLOW;
- return openat (dfd, path, flags);
-}
-
-gboolean
-ot_gopendirat (int dfd,
- const char *path,
- gboolean follow,
- int *out_fd,
- GError **error)
-{
- int ret = ot_opendirat (dfd, path, follow);
- if (ret == -1)
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
- *out_fd = ret;
- return TRUE;
-}
-
-GBytes *
-ot_lgetxattrat (int dfd,
- const char *path,
- const char *attribute,
- GError **error)
-{
- /* A workaround for the lack of lgetxattrat(), thanks to Florian Weimer:
- * https://mail.gnome.org/archives/ostree-list/2014-February/msg00017.html
- */
- g_autofree char *full_path = g_strdup_printf ("/proc/self/fd/%d/%s", dfd, path);
- GBytes *bytes = NULL;
- ssize_t bytes_read, real_size;
- char *buf;
-
- do
- bytes_read = lgetxattr (full_path, attribute, NULL, 0);
- while (G_UNLIKELY (bytes_read < 0 && errno == EINTR));
- if (G_UNLIKELY (bytes_read < 0))
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
-
- buf = g_malloc (bytes_read);
- do
- real_size = lgetxattr (full_path, attribute, buf, bytes_read);
- while (G_UNLIKELY (real_size < 0 && errno == EINTR));
- if (G_UNLIKELY (real_size < 0))
- {
- glnx_set_error_from_errno (error);
- g_free (buf);
- goto out;
- }
-
- bytes = g_bytes_new_take (buf, real_size);
- out:
- return bytes;
-}
-
-gboolean
-ot_lsetxattrat (int dfd,
- const char *path,
- const char *attribute,
- const void *value,
- gsize value_size,
- int flags,
- GError **error)
-{
- /* A workaround for the lack of lsetxattrat(), thanks to Florian Weimer:
- * https://mail.gnome.org/archives/ostree-list/2014-February/msg00017.html
- */
- g_autofree char *full_path = g_strdup_printf ("/proc/self/fd/%d/%s", dfd, path);
- int res;
-
- do
- res = lsetxattr (full_path, "user.ostreemeta", value, value_size, flags);
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (G_UNLIKELY (res == -1))
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
-
- return TRUE;
-}
-
gboolean
ot_readlinkat_gfile_info (int dfd,
const char *path,
@@ -264,6 +172,31 @@ ot_openat_ignore_enoent (int dfd,
return ret;
}
+/* Like glnx_dirfd_iterator_init_at(), but if %ENOENT, then set
+ * @out_exists to %FALSE, and return successfully.
+ */
+gboolean
+ot_dfd_iter_init_allow_noent (int dfd,
+ const char *path,
+ GLnxDirFdIterator *dfd_iter,
+ gboolean *out_exists,
+ GError **error)
+{
+ glnx_fd_close int fd = glnx_opendirat_with_errno (dfd, path, TRUE);
+ if (fd < 0)
+ {
+ if (errno != ENOENT)
+ return glnx_throw_errno_prefix (error, "opendirat");
+ *out_exists = FALSE;
+ return TRUE;
+ }
+ if (!glnx_dirfd_iterator_init_take_fd (fd, dfd_iter, error))
+ return FALSE;
+ fd = -1;
+ *out_exists = TRUE;
+ return TRUE;
+}
+
GBytes *
ot_file_mapat_bytes (int dfd,
const char *path,
diff --git a/src/libotutil/ot-fs-utils.h b/src/libotutil/ot-fs-utils.h
index 13909c8e..14df8acb 100644
--- a/src/libotutil/ot-fs-utils.h
+++ b/src/libotutil/ot-fs-utils.h
@@ -21,31 +21,12 @@
#pragma once
#include "ot-unix-utils.h"
+#include "libglnx.h"
G_BEGIN_DECLS
GFile * ot_fdrel_to_gfile (int dfd, const char *path);
-int ot_opendirat (int dfd, const char *path, gboolean follow);
-gboolean ot_gopendirat (int dfd,
- const char *path,
- gboolean follow,
- int *out_fd,
- GError **error);
-
-GBytes * ot_lgetxattrat (int dfd,
- const char *path,
- const char *attribute,
- GError **error);
-
-gboolean ot_lsetxattrat (int dfd,
- const char *path,
- const char *attribute,
- const void *value,
- gsize value_size,
- int flags,
- GError **error);
-
gboolean ot_readlinkat_gfile_info (int dfd,
const char *path,
GFileInfo *target_info,
@@ -73,6 +54,12 @@ gboolean ot_openat_ignore_enoent (int dfd,
int *out_fd,
GError **error);
+gboolean ot_dfd_iter_init_allow_noent (int dfd,
+ const char *path,
+ GLnxDirFdIterator *dfd_iter,
+ gboolean *out_exists,
+ GError **error);
+
GBytes *ot_file_mapat_bytes (int dfd,
const char *path,
GError **error);
diff --git a/src/libotutil/ot-gpg-utils.c b/src/libotutil/ot-gpg-utils.c
index b71f4845..001daa0a 100644
--- a/src/libotutil/ot-gpg-utils.c
+++ b/src/libotutil/ot-gpg-utils.c
@@ -67,7 +67,6 @@ ot_gpgme_error_to_gio_error (gpgme_error_t gpg_error,
gboolean
ot_gpgme_ctx_tmp_home_dir (gpgme_ctx_t gpgme_ctx,
- const char *tmp_dir,
char **out_tmp_home_dir,
GOutputStream **out_pubring_stream,
GCancellable *cancellable,
@@ -85,10 +84,7 @@ ot_gpgme_ctx_tmp_home_dir (gpgme_ctx_t gpgme_ctx,
* and hand the caller an open output stream to concatenate necessary
* keyring files. */
- if (tmp_dir == NULL)
- tmp_dir = g_get_tmp_dir ();
-
- tmp_home_dir = g_build_filename (tmp_dir, "ostree-gpg-XXXXXX", NULL);
+ tmp_home_dir = g_build_filename (g_get_tmp_dir (), "ostree-gpg-XXXXXX", NULL);
if (mkdtemp (tmp_home_dir) == NULL)
{
diff --git a/src/libotutil/ot-gpg-utils.h b/src/libotutil/ot-gpg-utils.h
index c2337f7b..184a8d64 100644
--- a/src/libotutil/ot-gpg-utils.h
+++ b/src/libotutil/ot-gpg-utils.h
@@ -34,7 +34,6 @@ GLNX_DEFINE_CLEANUP_FUNCTION0(gpgme_ctx_t, ot_cleanup_gpgme_ctx, gpgme_release)
void ot_gpgme_error_to_gio_error (gpgme_error_t gpg_error, GError **error);
gboolean ot_gpgme_ctx_tmp_home_dir (gpgme_ctx_t gpgme_ctx,
- const char *tmp_dir,
char **out_tmp_home_dir,
GOutputStream **out_pubring_stream,
GCancellable *cancellable,
diff --git a/src/ostree/ostree-trivial-httpd.c b/src/ostree/ostree-trivial-httpd.c
index d6f0c4d4..176f5ec7 100644
--- a/src/ostree/ostree-trivial-httpd.c
+++ b/src/ostree/ostree-trivial-httpd.c
@@ -457,10 +457,10 @@ httpd_callback (SoupServer *server, SoupMessage *msg,
static void
on_dir_changed (GFileMonitor *mon,
- GFile *file,
- GFile *other,
- GFileMonitorEvent event,
- gpointer user_data)
+ GFile *file,
+ GFile *other,
+ GFileMonitorEvent event,
+ gpointer user_data)
{
OtTrivialHttpd *self = user_data;
diff --git a/src/ostree/ot-admin-builtin-instutil.c b/src/ostree/ot-admin-builtin-instutil.c
index f27316a3..0694ba77 100644
--- a/src/ostree/ot-admin-builtin-instutil.c
+++ b/src/ostree/ot-admin-builtin-instutil.c
@@ -47,12 +47,9 @@ static GOptionContext *
ostree_admin_instutil_option_context_new_with_commands (void)
{
OstreeAdminInstUtilCommand *command = admin_instutil_subcommands;
- GOptionContext *context;
- GString *summary;
+ GOptionContext *context = g_option_context_new ("COMMAND");
- context = g_option_context_new ("COMMAND");
-
- summary = g_string_new ("Builtin \"admin instutil\" Commands:");
+ g_autoptr(GString) summary = g_string_new ("Builtin \"admin instutil\" Commands:");
while (command->name != NULL)
{
@@ -62,8 +59,6 @@ ostree_admin_instutil_option_context_new_with_commands (void)
g_option_context_set_summary (context, summary->str);
- g_string_free (summary, TRUE);
-
return context;
}
diff --git a/src/ostree/ot-admin-builtin-status.c b/src/ostree/ot-admin-builtin-status.c
index 940e5df0..79621a1d 100644
--- a/src/ostree/ot-admin-builtin-status.c
+++ b/src/ostree/ot-admin-builtin-status.c
@@ -124,7 +124,6 @@ ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GErro
OstreeDeploymentUnlockedState unlocked = ostree_deployment_get_unlocked (deployment);
g_autofree char *version = version_of_commit (repo, ref);
glnx_unref_object OstreeGpgVerifyResult *result = NULL;
- GString *output_buffer;
guint jj, n_signatures;
GError *local_error = NULL;
@@ -159,6 +158,7 @@ ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GErro
if (deployment_get_gpg_verify (deployment, repo))
{
+ g_autoptr(GString) output_buffer = g_string_sized_new (256);
/* Print any digital signatures on this commit. */
result = ostree_repo_verify_commit_ext (repo, ref, NULL, NULL,
@@ -176,7 +176,6 @@ ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GErro
goto out;
}
- output_buffer = g_string_sized_new (256);
n_signatures = ostree_gpg_verify_result_count_all (result);
for (jj = 0; jj < n_signatures; jj++)
@@ -186,7 +185,6 @@ ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GErro
}
g_print ("%s", output_buffer->str);
- g_string_free (output_buffer, TRUE);
}
}
}
diff --git a/src/ostree/ot-admin-builtin-undeploy.c b/src/ostree/ot-admin-builtin-undeploy.c
index cc86ee43..00252c80 100644
--- a/src/ostree/ot-admin-builtin-undeploy.c
+++ b/src/ostree/ot-admin-builtin-undeploy.c
@@ -35,7 +35,6 @@ static GOptionEntry options[] = {
gboolean
ot_admin_builtin_undeploy (int argc, char **argv, GCancellable *cancellable, GError **error)
{
- gboolean ret = FALSE;
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
const char *deploy_index_str;
@@ -48,16 +47,16 @@ ot_admin_builtin_undeploy (int argc, char **argv, GCancellable *cancellable, GEr
if (!ostree_admin_option_context_parse (context, options, &argc, &argv,
OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER,
&sysroot, cancellable, error))
- goto out;
+ return FALSE;
if (argc < 2)
{
ot_util_usage_error (context, "INDEX must be specified", error);
- goto out;
+ return FALSE;
}
if (!ostree_sysroot_load (sysroot, cancellable, error))
- goto out;
+ return FALSE;
current_deployments = ostree_sysroot_get_deployments (sysroot);
deploy_index_str = argv[1];
@@ -65,31 +64,26 @@ ot_admin_builtin_undeploy (int argc, char **argv, GCancellable *cancellable, GEr
target_deployment = ot_admin_get_indexed_deployment (sysroot, deploy_index, error);
if (!target_deployment)
- goto out;
+ return FALSE;
if (target_deployment == ostree_sysroot_get_booted_deployment (sysroot))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"Cannot undeploy currently booted deployment %i", deploy_index);
- goto out;
+ return FALSE;
}
-
+
g_ptr_array_remove_index (current_deployments, deploy_index);
if (!ostree_sysroot_write_deployments (sysroot, current_deployments,
cancellable, error))
- goto out;
+ return FALSE;
g_print ("Deleted deployment %s.%d\n", ostree_deployment_get_csum (target_deployment),
ostree_deployment_get_deployserial (target_deployment));
-
- if (!ostree_sysroot_cleanup (sysroot, cancellable, error))
- {
- g_prefix_error (error, "Performing final cleanup: ");
- goto out;
- }
- ret = TRUE;
- out:
- return ret;
+ if (!ostree_sysroot_cleanup (sysroot, cancellable, error))
+ return glnx_prefix_error (error, "Performing final cleanup");
+
+ return TRUE;
}
diff --git a/src/ostree/ot-admin-functions.c b/src/ostree/ot-admin-functions.c
index 7ba2207e..672d384a 100644
--- a/src/ostree/ot-admin-functions.c
+++ b/src/ostree/ot-admin-functions.c
@@ -33,20 +33,11 @@ ot_admin_require_booted_deployment_or_osname (OstreeSysroot *sysroot,
GCancellable *cancellable,
GError **error)
{
- gboolean ret = FALSE;
OstreeDeployment *booted_deployment =
ostree_sysroot_get_booted_deployment (sysroot);
-
if (booted_deployment == NULL && osname == NULL)
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Not currently booted into an OSTree system and no --os= argument given");
- goto out;
- }
-
- ret = TRUE;
- out:
- return ret;
+ return glnx_throw (error, "Not currently booted into an OSTree system and no --os= argument given");
+ return TRUE;
}
/**
@@ -141,7 +132,7 @@ ot_admin_sysroot_lock (OstreeSysroot *sysroot,
g_source_set_callback (timeout_src, (GSourceFunc)on_sysroot_lock_timeout, &state, NULL);
g_source_attach (timeout_src, state.mainctx);
g_source_unref (timeout_src);
-
+
on_sysroot_lock_timeout (&state);
ostree_sysroot_lock_async (sysroot, NULL, (GAsyncReadyCallback)on_sysroot_lock_acquired, &state);
@@ -161,14 +152,11 @@ gboolean
ot_admin_execve_reboot (OstreeSysroot *sysroot, GError **error)
{
g_autoptr(GFile) real_sysroot = g_file_new_for_path ("/");
-
+
if (g_file_equal (ostree_sysroot_get_path (sysroot), real_sysroot))
{
if (execlp ("systemctl", "systemctl", "reboot", NULL) < 0)
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
+ return glnx_throw_errno (error);
}
return TRUE;
diff --git a/src/ostree/ot-builtin-admin.c b/src/ostree/ot-builtin-admin.c
index 0d8290a8..16aaec03 100644
--- a/src/ostree/ot-builtin-admin.c
+++ b/src/ostree/ot-builtin-admin.c
@@ -56,12 +56,9 @@ static GOptionContext *
ostree_admin_option_context_new_with_commands (void)
{
OstreeAdminCommand *command = admin_subcommands;
- GOptionContext *context;
- GString *summary;
+ GOptionContext *context = g_option_context_new ("--print-current-dir|COMMAND");
- context = g_option_context_new ("--print-current-dir|COMMAND");
-
- summary = g_string_new ("Builtin \"admin\" Commands:");
+ g_autoptr(GString) summary = g_string_new ("Builtin \"admin\" Commands:");
while (command->name != NULL)
{
@@ -71,8 +68,6 @@ ostree_admin_option_context_new_with_commands (void)
g_option_context_set_summary (context, summary->str);
- g_string_free (summary, TRUE);
-
return context;
}
diff --git a/src/ostree/ot-builtin-checkout.c b/src/ostree/ot-builtin-checkout.c
index 74e27cfb..8ffe5bb7 100644
--- a/src/ostree/ot-builtin-checkout.c
+++ b/src/ostree/ot-builtin-checkout.c
@@ -42,6 +42,7 @@ static gboolean opt_from_stdin;
static char *opt_from_file;
static gboolean opt_disable_fsync;
static gboolean opt_require_hardlinks;
+static gboolean opt_force_copy;
static gboolean
parse_fsync_cb (const char *option_name,
@@ -62,7 +63,7 @@ parse_fsync_cb (const char *option_name,
static GOptionEntry options[] = {
{ "user-mode", 'U', 0, G_OPTION_ARG_NONE, &opt_user_mode, "Do not change file ownership or initialize extended attributes", NULL },
{ "disable-cache", 0, 0, G_OPTION_ARG_NONE, &opt_disable_cache, "Do not update or use the internal repository uncompressed object cache", NULL },
- { "subpath", 0, 0, G_OPTION_ARG_STRING, &opt_subpath, "Checkout sub-directory PATH", "PATH" },
+ { "subpath", 0, 0, G_OPTION_ARG_FILENAME, &opt_subpath, "Checkout sub-directory PATH", "PATH" },
{ "union", 0, 0, G_OPTION_ARG_NONE, &opt_union, "Keep existing directories, overwrite existing files", NULL },
{ "union-add", 0, 0, G_OPTION_ARG_NONE, &opt_union_add, "Keep existing files/directories, only add new", NULL },
{ "whiteouts", 0, 0, G_OPTION_ARG_NONE, &opt_whiteouts, "Process 'whiteout' (Docker style) entries", NULL },
@@ -71,6 +72,7 @@ static GOptionEntry options[] = {
{ "from-file", 0, 0, G_OPTION_ARG_STRING, &opt_from_file, "Process many checkouts from input file", "FILE" },
{ "fsync", 0, 0, G_OPTION_ARG_CALLBACK, parse_fsync_cb, "Specify how to invoke fsync()", "POLICY" },
{ "require-hardlinks", 'H', 0, G_OPTION_ARG_NONE, &opt_require_hardlinks, "Do not fall back to full copies if hardlinking fails", NULL },
+ { "force-copy", 'C', 0, G_OPTION_ARG_NONE, &opt_force_copy, "Never hardlink (but may reflink if available)", NULL },
{ NULL }
};
@@ -89,7 +91,7 @@ process_one_checkout (OstreeRepo *repo,
* `ostree_repo_checkout_at` until such time as we have a more
* convenient infrastructure for testing C APIs with data.
*/
- if (opt_disable_cache || opt_whiteouts || opt_require_hardlinks || opt_union_add)
+ if (opt_disable_cache || opt_whiteouts || opt_require_hardlinks || opt_union_add || opt_force_copy)
{
OstreeRepoCheckoutAtOptions options = { 0, };
@@ -102,6 +104,11 @@ process_one_checkout (OstreeRepo *repo,
"Cannot specify both --union and --union-add");
goto out;
}
+ if (opt_require_hardlinks && opt_force_copy)
+ {
+ glnx_throw (error, "Cannot specify both --require-hardlinks and --force-copy");
+ goto out;
+ }
else if (opt_union)
options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES;
else if (opt_union_add)
@@ -111,6 +118,7 @@ process_one_checkout (OstreeRepo *repo,
if (subpath)
options.subpath = subpath;
options.no_copy_fallback = opt_require_hardlinks;
+ options.force_copy = opt_force_copy;
if (!ostree_repo_checkout_at (repo, &options,
AT_FDCWD, destination,
diff --git a/src/ostree/ot-builtin-commit.c b/src/ostree/ot-builtin-commit.c
index e6738c89..4b0d8821 100644
--- a/src/ostree/ot-builtin-commit.c
+++ b/src/ostree/ot-builtin-commit.c
@@ -76,7 +76,7 @@ static GOptionEntry options[] = {
{ "parent", 0, 0, G_OPTION_ARG_STRING, &opt_parent, "Parent ref, or \"none\"", "REF" },
{ "subject", 's', 0, G_OPTION_ARG_STRING, &opt_subject, "One line subject", "SUBJECT" },
{ "body", 'm', 0, G_OPTION_ARG_STRING, &opt_body, "Full description", "BODY" },
- { "body-file", 'F', 0, G_OPTION_ARG_STRING, &opt_body_file, "Commit message from FILE path", "FILE" },
+ { "body-file", 'F', 0, G_OPTION_ARG_FILENAME, &opt_body_file, "Commit message from FILE path", "FILE" },
{ "editor", 'e', 0, G_OPTION_ARG_NONE, &opt_editor, "Use an editor to write the commit message", NULL },
{ "branch", 'b', 0, G_OPTION_ARG_STRING, &opt_branch, "Branch", "BRANCH" },
{ "orphan", 0, 0, G_OPTION_ARG_NONE, &opt_orphan, "Create a commit without writing a ref", NULL },
@@ -94,7 +94,7 @@ static GOptionEntry options[] = {
{ "skip-list", 0, 0, G_OPTION_ARG_FILENAME, &opt_skiplist_file, "File containing list of files to skip", "PATH" },
{ "table-output", 0, 0, G_OPTION_ARG_NONE, &opt_table_output, "Output more information in a KEY: VALUE format", NULL },
{ "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_key_ids, "GPG Key ID to sign the commit with", "KEY-ID"},
- { "gpg-homedir", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR"},
+ { "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR"},
{ "generate-sizes", 0, 0, G_OPTION_ARG_NONE, &opt_generate_sizes, "Generate size information along with commit metadata", NULL },
{ "disable-fsync", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL },
{ "fsync", 0, 0, G_OPTION_ARG_CALLBACK, parse_fsync_cb, "Specify how to invoke fsync()", "POLICY" },
@@ -218,7 +218,7 @@ commit_editor (OstreeRepo *repo,
g_autofree char *input = NULL;
g_autofree char *output = NULL;
gboolean ret = FALSE;
- GString *bodybuf = NULL;
+ g_autoptr(GString) bodybuf = NULL;
char **lines = NULL;
int i;
@@ -288,8 +288,6 @@ commit_editor (OstreeRepo *repo,
out:
g_strfreev (lines);
- if (bodybuf)
- g_string_free (bodybuf, TRUE);
return ret;
}
diff --git a/src/ostree/ot-builtin-export.c b/src/ostree/ot-builtin-export.c
index f3cdfbe0..2d40112a 100644
--- a/src/ostree/ot-builtin-export.c
+++ b/src/ostree/ot-builtin-export.c
@@ -39,9 +39,9 @@ static gboolean opt_no_xattrs;
static GOptionEntry options[] = {
{ "no-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_no_xattrs, "Skip output of extended attributes", NULL },
- { "subpath", 0, 0, G_OPTION_ARG_STRING, &opt_subpath, "Checkout sub-directory PATH", "PATH" },
- { "prefix", 0, 0, G_OPTION_ARG_STRING, &opt_prefix, "Add PATH as prefix to archive pathnames", "PATH" },
- { "output", 'o', 0, G_OPTION_ARG_STRING, &opt_output_path, "Output to PATH ", "PATH" },
+ { "subpath", 0, 0, G_OPTION_ARG_FILENAME, &opt_subpath, "Checkout sub-directory PATH", "PATH" },
+ { "prefix", 0, 0, G_OPTION_ARG_FILENAME, &opt_prefix, "Add PATH as prefix to archive pathnames", "PATH" },
+ { "output", 'o', 0, G_OPTION_ARG_FILENAME, &opt_output_path, "Output to PATH ", "PATH" },
{ NULL }
};
diff --git a/src/ostree/ot-builtin-fsck.c b/src/ostree/ot-builtin-fsck.c
index 2f154cff..7519d6db 100644
--- a/src/ostree/ot-builtin-fsck.c
+++ b/src/ostree/ot-builtin-fsck.c
@@ -246,6 +246,7 @@ ostree_builtin_fsck (int argc, char **argv, GCancellable *cancellable, GError **
gpointer key, value;
gboolean found_corruption = FALSE;
guint n_partial = 0;
+ g_autoptr(GHashTable) all_refs = NULL;
g_autoptr(GHashTable) objects = NULL;
g_autoptr(GHashTable) commits = NULL;
g_autoptr(GPtrArray) tombstones = NULL;
@@ -254,6 +255,27 @@ ostree_builtin_fsck (int argc, char **argv, GCancellable *cancellable, GError **
if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
goto out;
+ if (!opt_quiet)
+ g_print ("Validating refs...\n");
+
+ /* Validate that the commit for each ref is available */
+ if (!ostree_repo_list_refs (repo, NULL, &all_refs,
+ cancellable, error))
+ return FALSE;
+ g_hash_table_iter_init (&hash_iter, all_refs);
+ while (g_hash_table_iter_next (&hash_iter, &key, &value))
+ {
+ const char *refname = key;
+ const char *checksum = value;
+ g_autoptr(GVariant) commit = NULL;
+ if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT,
+ checksum, &commit, error))
+ {
+ g_prefix_error (error, "Loading commit for ref %s: ", refname);
+ goto out;
+ }
+ }
+
if (!opt_quiet)
g_print ("Enumerating objects...\n");
diff --git a/src/ostree/ot-builtin-gpg-sign.c b/src/ostree/ot-builtin-gpg-sign.c
index c19ec682..e14eba68 100644
--- a/src/ostree/ot-builtin-gpg-sign.c
+++ b/src/ostree/ot-builtin-gpg-sign.c
@@ -26,13 +26,14 @@
#include "ot-builtins.h"
#include "ostree.h"
#include "otutil.h"
+#include "ostree-core-private.h"
static gboolean opt_delete;
static char *opt_gpg_homedir;
static GOptionEntry options[] = {
{ "delete", 'd', 0, G_OPTION_ARG_NONE, &opt_delete, "Delete signatures having any of the GPG KEY-IDs" },
- { "gpg-homedir", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR" },
+ { "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR" },
{ NULL }
};
@@ -85,7 +86,7 @@ delete_signatures (OstreeRepo *repo,
g_variant_dict_init (&metadata_dict, old_metadata);
signature_data = g_variant_dict_lookup_value (&metadata_dict,
- "ostree.gpgsigs",
+ _OSTREE_METADATA_GPGSIGS_NAME,
G_VARIANT_TYPE ("aay"));
/* Taking the approach of deleting whatever matches we find for the
@@ -154,7 +155,7 @@ delete_signatures (OstreeRepo *repo,
/* Update the metadata dictionary. */
if (g_queue_is_empty (&signatures))
{
- g_variant_dict_remove (&metadata_dict, "ostree.gpgsigs");
+ g_variant_dict_remove (&metadata_dict, _OSTREE_METADATA_GPGSIGS_NAME);
}
else
{
@@ -170,7 +171,7 @@ delete_signatures (OstreeRepo *repo,
}
g_variant_dict_insert_value (&metadata_dict,
- "ostree.gpgsigs",
+ _OSTREE_METADATA_GPGSIGS_NAME,
g_variant_builder_end (&signature_builder));
}
diff --git a/src/ostree/ot-builtin-ls.c b/src/ostree/ot-builtin-ls.c
index 3abeb5c4..3e0336f6 100644
--- a/src/ostree/ot-builtin-ls.c
+++ b/src/ostree/ot-builtin-ls.c
@@ -47,15 +47,13 @@ static void
print_one_file_text (GFile *f,
GFileInfo *file_info)
{
- GString *buf = NULL;
+ g_autoptr(GString) buf = g_string_new ("");
char type_c;
guint32 mode;
guint32 type;
if (!ostree_repo_file_ensure_resolved ((OstreeRepoFile*)f, NULL))
g_assert_not_reached ();
-
- buf = g_string_new ("");
type_c = '?';
mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
@@ -119,8 +117,6 @@ print_one_file_text (GFile *f,
g_string_append_printf (buf, " -> %s", g_file_info_get_attribute_byte_string (file_info, "standard::symlink-target"));
g_print ("%s\n", buf->str);
-
- g_string_free (buf, TRUE);
}
static void
diff --git a/src/ostree/ot-builtin-pull.c b/src/ostree/ot-builtin-pull.c
index 4287afcd..d88c5ee8 100644
--- a/src/ostree/ot-builtin-pull.c
+++ b/src/ostree/ot-builtin-pull.c
@@ -43,12 +43,12 @@ static char* opt_url;
static GOptionEntry options[] = {
{ "commit-metadata-only", 0, 0, G_OPTION_ARG_NONE, &opt_commit_only, "Fetch only the commit metadata", NULL },
- { "cache-dir", 0, 0, G_OPTION_ARG_STRING, &opt_cache_dir, "Use custom cache dir", NULL },
+ { "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL },
{ "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL },
{ "disable-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_disable_static_deltas, "Do not use static deltas", NULL },
{ "require-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_require_static_deltas, "Require static deltas", NULL },
{ "mirror", 0, 0, G_OPTION_ARG_NONE, &opt_mirror, "Write refs suitable for a mirror", NULL },
- { "subpath", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_subpaths, "Only pull the provided subpath(s)", NULL },
+ { "subpath", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_subpaths, "Only pull the provided subpath(s)", NULL },
{ "untrusted", 0, 0, G_OPTION_ARG_NONE, &opt_untrusted, "Do not trust (local) sources", NULL },
{ "dry-run", 0, 0, G_OPTION_ARG_NONE, &opt_dry_run, "Only print information on what will be downloaded (requires static deltas)", NULL },
{ "depth", 0, 0, G_OPTION_ARG_INT, &opt_depth, "Traverse DEPTH parents (-1=infinite) (default: 0)", "DEPTH" },
@@ -84,27 +84,29 @@ dry_run_console_progress_changed (OstreeAsyncProgress *progress,
guint fetched_delta_parts, total_delta_parts;
guint fetched_delta_part_fallbacks, total_delta_part_fallbacks;
guint64 fetched_delta_part_size, total_delta_part_size, total_delta_part_usize;
- GString *buf;
g_assert (!printed_console_progress);
printed_console_progress = TRUE;
- /* Number of parts */
- fetched_delta_parts = ostree_async_progress_get_uint (progress, "fetched-delta-parts");
- total_delta_parts = ostree_async_progress_get_uint (progress, "total-delta-parts");
- fetched_delta_part_fallbacks = ostree_async_progress_get_uint (progress, "fetched-delta-fallbacks");
- total_delta_part_fallbacks = ostree_async_progress_get_uint (progress, "total-delta-fallbacks");
+ ostree_async_progress_get (progress,
+ /* Number of parts */
+ "fetched-delta-parts", "u", &fetched_delta_parts,
+ "total-delta-parts", "u", &total_delta_parts,
+ "fetched-delta-fallbacks", "u", &fetched_delta_part_fallbacks,
+ "total-delta-fallbacks", "u", &total_delta_part_fallbacks,
+ /* Size variables */
+ "fetched-delta-part-size", "t", &fetched_delta_part_size,
+ "total-delta-part-size", "t", &total_delta_part_size,
+ "total-delta-part-usize", "t", &total_delta_part_usize,
+ NULL);
+
/* Fold the count of deltaparts + fallbacks for simplicity; if changing this,
* please change ostree_repo_pull_default_console_progress_changed() first.
*/
fetched_delta_parts += fetched_delta_part_fallbacks;
total_delta_parts += total_delta_part_fallbacks;
- /* Size variables */
- fetched_delta_part_size = ostree_async_progress_get_uint64 (progress, "fetched-delta-part-size");
- total_delta_part_size = ostree_async_progress_get_uint64 (progress, "total-delta-part-size");
- total_delta_part_usize = ostree_async_progress_get_uint64 (progress, "total-delta-part-usize");
- buf = g_string_new ("");
+ g_autoptr(GString) buf = g_string_new ("");
{ g_autofree char *formatted_fetched =
g_format_size (fetched_delta_part_size);
@@ -119,7 +121,6 @@ dry_run_console_progress_changed (OstreeAsyncProgress *progress,
formatted_usize);
}
g_print ("%s\n", buf->str);
- g_string_free (buf, TRUE);
}
gboolean
diff --git a/src/ostree/ot-builtin-remote.c b/src/ostree/ot-builtin-remote.c
index f0667a42..dd999c01 100644
--- a/src/ostree/ot-builtin-remote.c
+++ b/src/ostree/ot-builtin-remote.c
@@ -51,12 +51,9 @@ static GOptionContext *
remote_option_context_new_with_commands (void)
{
OstreeRemoteCommand *subcommand = remote_subcommands;
- GOptionContext *context;
- GString *summary;
+ GOptionContext *context = g_option_context_new ("COMMAND");
- context = g_option_context_new ("COMMAND");
-
- summary = g_string_new ("Builtin \"remote\" Commands:");
+ g_autoptr(GString) summary = g_string_new ("Builtin \"remote\" Commands:");
while (subcommand->name != NULL)
{
@@ -66,8 +63,6 @@ remote_option_context_new_with_commands (void)
g_option_context_set_summary (context, summary->str);
- g_string_free (summary, TRUE);
-
return context;
}
diff --git a/src/ostree/ot-builtin-show.c b/src/ostree/ot-builtin-show.c
index 3aaa2303..dcd9090c 100644
--- a/src/ostree/ot-builtin-show.c
+++ b/src/ostree/ot-builtin-show.c
@@ -42,7 +42,7 @@ static GOptionEntry options[] = {
{ "print-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_metadata_key, "Print string value of metadata key", "KEY" },
{ "print-detached-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_detached_metadata_key, "Print string value of detached metadata key", "KEY" },
{ "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "Show raw variant data" },
- { "gpg-homedir", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR"},
+ { "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR"},
{ "gpg-verify-remote", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_verify_remote, "Use REMOTE name for GPG configuration", "REMOTE"},
{ NULL }
};
diff --git a/src/ostree/ot-builtin-static-delta.c b/src/ostree/ot-builtin-static-delta.c
index 1019f06f..c98436af 100644
--- a/src/ostree/ot-builtin-static-delta.c
+++ b/src/ostree/ot-builtin-static-delta.c
@@ -72,7 +72,7 @@ static GOptionEntry generate_options[] = {
{ "min-fallback-size", 0, 0, G_OPTION_ARG_STRING, &opt_min_fallback_size, "Minimum uncompressed size in megabytes for individual HTTP request", NULL},
{ "max-bsdiff-size", 0, 0, G_OPTION_ARG_STRING, &opt_max_bsdiff_size, "Maximum size in megabytes to consider bsdiff compression for input files", NULL},
{ "max-chunk-size", 0, 0, G_OPTION_ARG_STRING, &opt_max_chunk_size, "Maximum size of delta chunks in megabytes", NULL},
- { "filename", 0, 0, G_OPTION_ARG_STRING, &opt_filename, "Write the delta content to PATH (a directory). If not specified, the OSTree repository is used", "PATH"},
+ { "filename", 0, 0, G_OPTION_ARG_FILENAME, &opt_filename, "Write the delta content to PATH (a directory). If not specified, the OSTree repository is used", "PATH"},
{ NULL }
};
diff --git a/src/ostree/ot-builtin-summary.c b/src/ostree/ot-builtin-summary.c
index 04ba84e8..9055d972 100644
--- a/src/ostree/ot-builtin-summary.c
+++ b/src/ostree/ot-builtin-summary.c
@@ -20,19 +20,23 @@
#include "config.h"
+#include "ostree-repo-private.h"
+#include "ot-dump.h"
#include "ot-main.h"
#include "ot-builtins.h"
#include "ostree.h"
#include "otutil.h"
-static gboolean opt_update;
+static gboolean opt_update, opt_view, opt_raw;
static char **opt_key_ids;
static char *opt_gpg_homedir;
static GOptionEntry options[] = {
{ "update", 'u', 0, G_OPTION_ARG_NONE, &opt_update, "Update the summary", NULL },
+ { "view", 'v', 0, G_OPTION_ARG_NONE, &opt_view, "View the local summary file", NULL },
+ { "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "View the raw bytes of the summary file", NULL },
{ "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_key_ids, "GPG Key ID to sign the summary with", "KEY-ID"},
- { "gpg-homedir", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR"},
+ { "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR"},
{ NULL }
};
@@ -42,6 +46,7 @@ ostree_builtin_summary (int argc, char **argv, GCancellable *cancellable, GError
gboolean ret = FALSE;
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL;
+ OstreeDumpFlags flags = OSTREE_DUMP_NONE;
context = g_option_context_new ("Manage summary metadata");
@@ -66,6 +71,19 @@ ostree_builtin_summary (int argc, char **argv, GCancellable *cancellable, GError
goto out;
}
}
+ else if (opt_view)
+ {
+ g_autoptr(GBytes) summary_data = NULL;
+
+ if (opt_raw)
+ flags |= OSTREE_DUMP_RAW;
+
+ summary_data = ot_file_mapat_bytes (repo->repo_dir_fd, "summary", error);
+ if (!summary_data)
+ goto out;
+
+ ot_dump_summary_bytes (summary_data, flags);
+ }
else
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
diff --git a/src/ostree/ot-dump.c b/src/ostree/ot-dump.c
index 4fc84cbd..b24003c7 100644
--- a/src/ostree/ot-dump.c
+++ b/src/ostree/ot-dump.c
@@ -26,6 +26,8 @@
#include
+#include "ostree-repo-private.h"
+#include "ostree-repo-static-delta-private.h"
#include "ot-dump.h"
#include "otutil.h"
#include "ot-admin-functions.h"
@@ -199,6 +201,18 @@ dump_summary_ref (const char *ref_name,
}
}
+static gchar *
+uint64_secs_to_iso8601 (guint64 secs)
+{
+ g_autoptr(GDateTime) dt = g_date_time_new_from_unix_utc (secs);
+ g_autoptr(GDateTime) local = (dt != NULL) ? g_date_time_to_local (dt) : NULL;
+
+ if (local != NULL)
+ return g_date_time_format (local, "%FT%T%:::z");
+ else
+ return g_strdup ("invalid");
+}
+
void
ot_dump_summary_bytes (GBytes *summary_bytes,
OstreeDumpFlags flags)
@@ -251,11 +265,35 @@ ot_dump_summary_bytes (GBytes *summary_bytes,
g_variant_iter_init (&iter, exts);
- /* XXX Should we print something more human-friendly for
- * known extension names like 'ostree.static-deltas'? */
while (g_variant_iter_loop (&iter, "{sv}", &key, &value))
{
- g_autofree char *string = g_variant_print (value, FALSE);
- g_print ("%s: %s\n", key, string);
+ g_autofree gchar *value_str = NULL;
+ const gchar *pretty_key = NULL;
+
+ if (g_strcmp0 (key, OSTREE_SUMMARY_STATIC_DELTAS) == 0)
+ {
+ pretty_key = "Static Deltas";
+ value_str = g_variant_print (value, FALSE);
+ }
+ else if (g_strcmp0 (key, OSTREE_SUMMARY_LAST_MODIFIED) == 0)
+ {
+ pretty_key = "Last-Modified";
+ value_str = uint64_secs_to_iso8601 (GUINT64_FROM_BE (g_variant_get_uint64 (value)));
+ }
+ else if (g_strcmp0 (key, OSTREE_SUMMARY_EXPIRES) == 0)
+ {
+ pretty_key = "Expires";
+ value_str = uint64_secs_to_iso8601 (GUINT64_FROM_BE (g_variant_get_uint64 (value)));
+ }
+ else
+ {
+ value_str = g_variant_print (value, FALSE);
+ }
+
+ /* Print out. */
+ if (pretty_key != NULL)
+ g_print ("%s (%s): %s\n", pretty_key, key, value_str);
+ else
+ g_print ("%s: %s\n", key, value_str);
}
}
diff --git a/src/ostree/ot-main.c b/src/ostree/ot-main.c
index 7eb65602..9aca8287 100644
--- a/src/ostree/ot-main.c
+++ b/src/ostree/ot-main.c
@@ -45,26 +45,23 @@ static GOptionEntry global_entries[] = {
};
static GOptionEntry repo_entry[] = {
- { "repo", 0, 0, G_OPTION_ARG_STRING, &opt_repo, "Path to OSTree repository (defaults to /sysroot/ostree/repo)", "PATH" },
+ { "repo", 0, 0, G_OPTION_ARG_FILENAME, &opt_repo, "Path to OSTree repository (defaults to /sysroot/ostree/repo)", "PATH" },
{ NULL }
};
static GOptionEntry global_admin_entries[] = {
/* No description since it's hidden from --help output. */
{ "print-current-dir", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_print_current_dir, NULL, NULL },
- { "sysroot", 0, 0, G_OPTION_ARG_STRING, &opt_sysroot, "Create a new OSTree sysroot at PATH", "PATH" },
+ { "sysroot", 0, 0, G_OPTION_ARG_FILENAME, &opt_sysroot, "Create a new OSTree sysroot at PATH", "PATH" },
{ NULL }
};
static GOptionContext *
ostree_option_context_new_with_commands (OstreeCommand *commands)
{
- GOptionContext *context;
- GString *summary;
+ GOptionContext *context = g_option_context_new ("COMMAND");
- context = g_option_context_new ("COMMAND");
-
- summary = g_string_new ("Builtin Commands:");
+ g_autoptr(GString) summary = g_string_new ("Builtin Commands:");
while (commands->name != NULL)
{
@@ -74,8 +71,6 @@ ostree_option_context_new_with_commands (OstreeCommand *commands)
g_option_context_set_summary (context, summary->str);
- g_string_free (summary, TRUE);
-
return context;
}
@@ -223,7 +218,6 @@ ostree_option_context_parse (GOptionContext *context,
GError **error)
{
glnx_unref_object OstreeRepo *repo = NULL;
- gboolean success = FALSE;
/* Entries are listed in --help output in the order added. We add the
* main entries ourselves so that we can add the --repo entry first. */
@@ -278,7 +272,7 @@ ostree_option_context_parse (GOptionContext *context,
{
g_propagate_error (error, g_steal_pointer (&local_error));
}
- goto out;
+ return FALSE;
}
}
else if (opt_repo != NULL)
@@ -289,17 +283,14 @@ ostree_option_context_parse (GOptionContext *context,
if (!(flags & OSTREE_BUILTIN_FLAG_NO_CHECK))
{
if (!ostree_repo_open (repo, cancellable, error))
- goto out;
+ return FALSE;
}
}
if (out_repo)
*out_repo = g_steal_pointer (&repo);
- success = TRUE;
-
-out:
- return success;
+ return TRUE;
}
gboolean
@@ -312,22 +303,19 @@ ostree_admin_option_context_parse (GOptionContext *context,
GCancellable *cancellable,
GError **error)
{
- g_autoptr(GFile) sysroot_path = NULL;
- glnx_unref_object OstreeSysroot *sysroot = NULL;
- gboolean success = FALSE;
-
/* Entries are listed in --help output in the order added. We add the
* main entries ourselves so that we can add the --sysroot entry first. */
g_option_context_add_main_entries (context, global_admin_entries, NULL);
if (!ostree_option_context_parse (context, main_entries, argc, argv, OSTREE_BUILTIN_FLAG_NO_REPO, NULL, cancellable, error))
- goto out;
+ return FALSE;
+ g_autoptr(GFile) sysroot_path = NULL;
if (opt_sysroot != NULL)
sysroot_path = g_file_new_for_path (opt_sysroot);
- sysroot = ostree_sysroot_new (sysroot_path);
+ glnx_unref_object OstreeSysroot *sysroot = ostree_sysroot_new (sysroot_path);
if (flags & OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER)
{
@@ -338,7 +326,7 @@ ostree_admin_option_context_parse (GOptionContext *context,
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
"You must be root to perform this command");
- goto out;
+ return FALSE;
}
}
@@ -350,15 +338,11 @@ ostree_admin_option_context_parse (GOptionContext *context,
g_autofree char *deployment_path = NULL;
if (!ostree_sysroot_load (sysroot, cancellable, error))
- goto out;
+ return FALSE;
deployments = ostree_sysroot_get_deployments (sysroot);
if (deployments->len == 0)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Unable to find a deployment in sysroot");
- goto out;
- }
+ return glnx_throw (error, "Unable to find a deployment in sysroot");
first_deployment = deployments->pdata[0];
deployment_file = ostree_sysroot_get_deployment_directory (sysroot, first_deployment);
deployment_path = g_file_get_path (deployment_file);
@@ -379,46 +363,36 @@ ostree_admin_option_context_parse (GOptionContext *context,
{
/* Released when sysroot is finalized, or on process exit */
if (!ot_admin_sysroot_lock (sysroot, error))
- goto out;
+ return FALSE;
}
if (out_sysroot)
*out_sysroot = g_steal_pointer (&sysroot);
- success = TRUE;
-
-out:
- return success;
+ return TRUE;
}
gboolean
ostree_ensure_repo_writable (OstreeRepo *repo,
GError **error)
{
- gboolean ret;
-
- ret = ostree_repo_is_writable (repo, error);
-
- g_prefix_error (error, "Cannot write to repository: ");
-
- return ret;
+ if (!ostree_repo_is_writable (repo, error))
+ return glnx_prefix_error (error, "Cannot write to repository");
+ return TRUE;
}
void
ostree_print_gpg_verify_result (OstreeGpgVerifyResult *result)
{
- GString *buffer;
- guint n_sigs, ii;
-
- n_sigs = ostree_gpg_verify_result_count_all (result);
+ guint n_sigs = ostree_gpg_verify_result_count_all (result);
/* XXX If we ever add internationalization, use ngettext() here. */
g_print ("GPG: Verification enabled, found %u signature%s:\n",
n_sigs, n_sigs == 1 ? "" : "s");
- buffer = g_string_sized_new (256);
+ g_autoptr(GString) buffer = g_string_sized_new (256);
- for (ii = 0; ii < n_sigs; ii++)
+ for (guint ii = 0; ii < n_sigs; ii++)
{
g_string_append_c (buffer, '\n');
ostree_gpg_verify_result_describe (result, ii, buffer, " ",
@@ -426,13 +400,11 @@ ostree_print_gpg_verify_result (OstreeGpgVerifyResult *result)
}
g_print ("%s", buffer->str);
- g_string_free (buffer, TRUE);
}
gboolean
ot_enable_tombstone_commits (OstreeRepo *repo, GError **error)
{
- gboolean ret = FALSE;
gboolean tombstone_commits = FALSE;
GKeyFile *config = ostree_repo_get_config (repo);
@@ -442,10 +414,8 @@ ot_enable_tombstone_commits (OstreeRepo *repo, GError **error)
{
g_key_file_set_boolean (config, "core", "tombstone-commits", TRUE);
if (!ostree_repo_write_config (repo, config, error))
- goto out;
+ return FALSE;
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
diff --git a/src/ostree/ot-remote-builtin-refs.c b/src/ostree/ot-remote-builtin-refs.c
index f5b3afe3..9e6ee144 100644
--- a/src/ostree/ot-remote-builtin-refs.c
+++ b/src/ostree/ot-remote-builtin-refs.c
@@ -28,7 +28,7 @@
static char* opt_cache_dir;
static GOptionEntry option_entries[] = {
- { "cache-dir", 0, 0, G_OPTION_ARG_STRING, &opt_cache_dir, "Use custom cache dir", NULL },
+ { "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL },
{ NULL }
};
diff --git a/src/ostree/ot-remote-builtin-summary.c b/src/ostree/ot-remote-builtin-summary.c
index b4d99254..5ddcf69b 100644
--- a/src/ostree/ot-remote-builtin-summary.c
+++ b/src/ostree/ot-remote-builtin-summary.c
@@ -31,7 +31,7 @@ static gboolean opt_raw;
static char* opt_cache_dir;
static GOptionEntry option_entries[] = {
- { "cache-dir", 0, 0, G_OPTION_ARG_STRING, &opt_cache_dir, "Use custom cache dir", NULL },
+ { "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL },
{ "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "Show raw variant data", NULL },
{ NULL }
};
diff --git a/src/ostree/ot-remote-cookie-util.c b/src/ostree/ot-remote-cookie-util.c
index a96038aa..e3ca9eac 100644
--- a/src/ostree/ot-remote-cookie-util.c
+++ b/src/ostree/ot-remote-cookie-util.c
@@ -298,14 +298,18 @@ ot_list_cookies_at (int dfd, const char *jar_path, GError **error)
while (ot_parse_cookies_next (parser))
{
g_autoptr(GDateTime) expires = g_date_time_new_from_unix_utc (parser->expiration);
- g_autofree char *expires_str = g_date_time_format (expires, "%Y-%m-%d %H:%M:%S +0000");
+ g_autofree char *expires_str = NULL;
+
+ if (expires != NULL)
+ expires_str = g_date_time_format (expires, "%Y-%m-%d %H:%M:%S +0000");
g_print ("--\n");
g_print ("Domain: %s\n", parser->domain);
g_print ("Path: %s\n", parser->path);
g_print ("Name: %s\n", parser->name);
g_print ("Secure: %s\n", parser->secure);
- g_print ("Expires: %s\n", expires_str);
+ if (expires_str != NULL)
+ g_print ("Expires: %s\n", expires_str);
g_print ("Value: %s\n", parser->value);
}
#else
diff --git a/src/rofiles-fuse/main.c b/src/rofiles-fuse/main.c
index 3f0832f5..12a9d886 100644
--- a/src/rofiles-fuse/main.c
+++ b/src/rofiles-fuse/main.c
@@ -56,12 +56,12 @@ callback_getattr (const char *path, struct stat *st_data)
if (!*path)
{
if (fstat (basefd, st_data) == -1)
- return -errno;
+ return -errno;
}
else
{
if (fstatat (basefd, path, st_data, AT_SYMLINK_NOFOLLOW) == -1)
- return -errno;
+ return -errno;
}
return 0;
}
@@ -85,7 +85,7 @@ callback_readlink (const char *path, char *buf, size_t size)
static int
callback_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
- off_t offset, struct fuse_file_info *fi)
+ off_t offset, struct fuse_file_info *fi)
{
DIR *dp;
struct dirent *de;
@@ -102,7 +102,7 @@ callback_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
{
dfd = openat (basefd, path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY);
if (dfd == -1)
- return -errno;
+ return -errno;
}
/* Transfers ownership of fd */
@@ -117,7 +117,7 @@ callback_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
st.st_ino = de->d_ino;
st.st_mode = de->d_type << 12;
if (filler (buf, de->d_name, &st, 0))
- break;
+ break;
}
(void) closedir (dp);
@@ -170,7 +170,7 @@ callback_symlink (const char *from, const char *to)
if (fstatat (basefd, to, &stbuf, AT_SYMLINK_NOFOLLOW) == -1)
{
fprintf (stderr, "Failed to find newly created symlink '%s': %s\n",
- to, g_strerror (errno));
+ to, g_strerror (errno));
exit (EXIT_FAILURE);
}
return 0;
@@ -209,19 +209,19 @@ can_write (const char *path)
if (fstatat (basefd, path, &stbuf, 0) == -1)
{
if (errno == ENOENT)
- return 0;
+ return 0;
else
- return -errno;
+ return -errno;
}
if (stbuf_is_regfile_hardlinked (&stbuf))
return -EROFS;
return 0;
}
-#define VERIFY_WRITE(path) do { \
- int r = can_write (path); \
- if (r != 0) \
- return r; \
+#define VERIFY_WRITE(path) do { \
+ int r = can_write (path); \
+ if (r != 0) \
+ return r; \
} while (0)
static int
@@ -366,7 +366,7 @@ callback_read_buf (const char *path, struct fuse_bufvec **bufp,
static int
callback_read (const char *path, char *buf, size_t size, off_t offset,
- struct fuse_file_info *finfo)
+ struct fuse_file_info *finfo)
{
int r;
r = pread (finfo->fh, buf, size, offset);
@@ -390,7 +390,7 @@ callback_write_buf (const char *path, struct fuse_bufvec *buf, off_t offset,
static int
callback_write (const char *path, const char *buf, size_t size, off_t offset,
- struct fuse_file_info *finfo)
+ struct fuse_file_info *finfo)
{
int r;
r = pwrite (finfo->fh, buf, size, offset);
@@ -426,7 +426,7 @@ static int
callback_access (const char *path, int mode)
{
path = ENSURE_RELPATH (path);
-
+
/* Apparently at least GNU coreutils rm calls `faccessat(W_OK)`
* before trying to do an unlink. So...we'll just lie about
* writable access here.
@@ -438,14 +438,14 @@ callback_access (const char *path, int mode)
static int
callback_setxattr (const char *path, const char *name, const char *value,
- size_t size, int flags)
+ size_t size, int flags)
{
return -ENOTSUP;
}
static int
callback_getxattr (const char *path, const char *name, char *value,
- size_t size)
+ size_t size)
{
return -ENOTSUP;
}
@@ -503,8 +503,7 @@ struct fuse_operations callback_oper = {
.removexattr = callback_removexattr
};
-enum
-{
+enum {
KEY_HELP,
KEY_VERSION,
};
@@ -513,19 +512,19 @@ static void
usage (const char *progname)
{
fprintf (stdout,
- "usage: %s basepath mountpoint [options]\n"
- "\n"
- " Makes basepath visible at mountpoint such that files are read-only, directories are writable\n"
- "\n"
- "general options:\n"
- " -o opt,[opt...] mount options\n"
- " -h --help print help\n"
- "\n", progname);
+ "usage: %s basepath mountpoint [options]\n"
+ "\n"
+ " Makes basepath visible at mountpoint such that files are read-only, directories are writable\n"
+ "\n"
+ "general options:\n"
+ " -o opt,[opt...] mount options\n"
+ " -h --help print help\n"
+ "\n", progname);
}
static int
rofs_parse_opt (void *data, const char *arg, int key,
- struct fuse_args *outargs)
+ struct fuse_args *outargs)
{
(void) data;
@@ -533,19 +532,19 @@ rofs_parse_opt (void *data, const char *arg, int key,
{
case FUSE_OPT_KEY_NONOPT:
if (basefd == -1)
- {
- basefd = openat (AT_FDCWD, arg, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY);
- if (basefd == -1)
- {
- perror ("openat");
- exit (EXIT_FAILURE);
- }
- return 0;
- }
+ {
+ basefd = openat (AT_FDCWD, arg, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY);
+ if (basefd == -1)
+ {
+ perror ("openat");
+ exit (EXIT_FAILURE);
+ }
+ return 0;
+ }
else
- {
- return 1;
- }
+ {
+ return 1;
+ }
case FUSE_OPT_KEY_OPT:
return 1;
case KEY_HELP:
diff --git a/src/switchroot/ostree-mount-util.h b/src/switchroot/ostree-mount-util.h
index b24aa44d..1e7253d2 100644
--- a/src/switchroot/ostree-mount-util.h
+++ b/src/switchroot/ostree-mount-util.h
@@ -25,6 +25,10 @@
#include
#include
#include
+#include
+#include
+#include
+#include
static inline int
path_is_on_readonly_fs (char *path)
@@ -37,4 +41,66 @@ path_is_on_readonly_fs (char *path)
return (stvfsbuf.f_flag & ST_RDONLY) != 0;
}
+static inline char *
+read_proc_cmdline (void)
+{
+ FILE *f = fopen("/proc/cmdline", "r");
+ char *cmdline = NULL;
+ size_t len;
+
+ if (!f)
+ goto out;
+
+ /* Note that /proc/cmdline will not end in a newline, so getline
+ * will fail unelss we provide a length.
+ */
+ if (getline (&cmdline, &len, f) < 0)
+ goto out;
+ /* ... but the length will be the size of the malloc buffer, not
+ * strlen(). Fix that.
+ */
+ len = strlen (cmdline);
+
+ if (cmdline[len-1] == '\n')
+ cmdline[len-1] = '\0';
+out:
+ if (f)
+ fclose (f);
+ return cmdline;
+}
+
+static inline char *
+read_proc_cmdline_ostree (void)
+{
+ char *cmdline = NULL;
+ const char *iter;
+ char *ret = NULL;
+
+ cmdline = read_proc_cmdline ();
+ if (!cmdline)
+ err (EXIT_FAILURE, "failed to read /proc/cmdline");
+
+ iter = cmdline;
+ while (iter != NULL)
+ {
+ const char *next = strchr (iter, ' ');
+ const char *next_nonspc = next;
+ while (next_nonspc && *next_nonspc == ' ')
+ next_nonspc += 1;
+ if (strncmp (iter, "ostree=", strlen ("ostree=")) == 0)
+ {
+ const char *start = iter + strlen ("ostree=");
+ if (next)
+ ret = strndup (start, next - start);
+ else
+ ret = strdup (start);
+ break;
+ }
+ iter = next_nonspc;
+ }
+
+ free (cmdline);
+ return ret;
+}
+
#endif /* __OSTREE_MOUNT_UTIL_H_ */
diff --git a/src/switchroot/ostree-prepare-root.c b/src/switchroot/ostree-prepare-root.c
index ce48a91e..9b8c3381 100644
--- a/src/switchroot/ostree-prepare-root.c
+++ b/src/switchroot/ostree-prepare-root.c
@@ -1,13 +1,13 @@
/* -*- c-file-style: "gnu" -*-
* Switch to new root directory and start init.
- *
+ *
* Copyright 2011,2012,2013 Colin Walters
*
- * Based on code from util-linux/sys-utils/switch_root.c,
+ * Based on code from util-linux/sys-utils/switch_root.c,
* Copyright 2002-2009 Red Hat, Inc. All rights reserved.
* Authors:
- * Peter Jones
- * Jeremy Katz
+ * Peter Jones
+ * Jeremy Katz
*
* Relicensed with permission to LGPLv2+.
*
@@ -46,68 +46,6 @@
#include "ostree-mount-util.h"
-static char *
-read_proc_cmdline (void)
-{
- FILE *f = fopen("/proc/cmdline", "r");
- char *cmdline = NULL;
- size_t len;
-
- if (!f)
- goto out;
-
- /* Note that /proc/cmdline will not end in a newline, so getline
- * will fail unelss we provide a length.
- */
- if (getline (&cmdline, &len, f) < 0)
- goto out;
- /* ... but the length will be the size of the malloc buffer, not
- * strlen(). Fix that.
- */
- len = strlen (cmdline);
-
- if (cmdline[len-1] == '\n')
- cmdline[len-1] = '\0';
-out:
- if (f)
- fclose (f);
- return cmdline;
-}
-
-static char *
-parse_ostree_cmdline (void)
-{
- char *cmdline = NULL;
- const char *iter;
- char *ret = NULL;
-
- cmdline = read_proc_cmdline ();
- if (!cmdline)
- err (EXIT_FAILURE, "failed to read /proc/cmdline");
-
- iter = cmdline;
- while (iter != NULL)
- {
- const char *next = strchr (iter, ' ');
- const char *next_nonspc = next;
- while (next_nonspc && *next_nonspc == ' ')
- next_nonspc += 1;
- if (strncmp (iter, "ostree=", strlen ("ostree=")) == 0)
- {
- const char *start = iter + strlen ("ostree=");
- if (next)
- ret = strndup (start, next - start);
- else
- ret = strdup (start);
- break;
- }
- iter = next_nonspc;
- }
-
- free (cmdline);
- return ret;
-}
-
/* This is an API for other projects to determine whether or not the
* currently running system is ostree-controlled.
*/
@@ -115,8 +53,8 @@ static void
touch_run_ostree (void)
{
int fd;
-
- fd = open ("/run/ostree-booted", O_CREAT | O_WRONLY | O_NOCTTY, 0640);
+
+ fd = open ("/run/ostree-booted", O_CREAT | O_WRONLY | O_NOCTTY | O_CLOEXEC, 0640);
/* We ignore failures here in case /run isn't mounted...not much we
* can do about that, but we don't want to fail.
*/
@@ -132,7 +70,7 @@ resolve_deploy_path (const char * root_mountpoint)
struct stat stbuf;
char *ostree_target, *deploy_path;
- ostree_target = parse_ostree_cmdline ();
+ ostree_target = read_proc_cmdline_ostree ();
if (!ostree_target)
errx (EXIT_FAILURE, "No OSTree target; expected ostree=/ostree/boot.N/...");
@@ -211,9 +149,12 @@ main(int argc, char *argv[])
if (chdir (deploy_path) < 0)
err (EXIT_FAILURE, "failed to chdir to deploy_path");
+ /* In the systemd case, this is handled by ostree-system-generator */
+#ifndef HAVE_SYSTEMD_AND_LIBMOUNT
/* Link to the deployment's /var */
if (mount ("../../var", "var", NULL, MS_MGC_VAL|MS_BIND, NULL) < 0)
err (EXIT_FAILURE, "failed to bind mount ../../var to var");
+#endif
/* If /boot is on the same partition, use a bind mount to make it visible
* at /boot inside the deployment. */
@@ -239,11 +180,11 @@ main(int argc, char *argv[])
* later boot and `systemd-remount-fs.service`.
*/
if (path_is_on_readonly_fs ("."))
- {
- if (mount (".", ".", NULL, MS_REMOUNT | MS_SILENT, NULL) < 0)
- err (EXIT_FAILURE, "failed to remount rootfs writable (for overlayfs)");
- }
-
+ {
+ if (mount (".", ".", NULL, MS_REMOUNT | MS_SILENT, NULL) < 0)
+ err (EXIT_FAILURE, "failed to remount rootfs writable (for overlayfs)");
+ }
+
if (mount ("overlay", "usr", "overlay", 0, usr_ovl_options) < 0)
err (EXIT_FAILURE, "failed to mount /usr overlayfs");
}
diff --git a/src/switchroot/ostree-remount.c b/src/switchroot/ostree-remount.c
index 589a3867..a6d14d08 100644
--- a/src/switchroot/ostree-remount.c
+++ b/src/switchroot/ostree-remount.c
@@ -38,28 +38,10 @@
#include "ostree-mount-util.h"
-/* Having a writeable /var is necessary for full system functioning.
- * If /var isn't writeable, we mount tmpfs over it. While this is
- * somewhat outside of ostree's scope, having all /var twiddling
- * in one place will make future maintenance easier.
- */
-static void
-maybe_mount_tmpfs_on_var (void)
-{
- if (!path_is_on_readonly_fs ("/var"))
- return;
-
- if (umount ("/var") < 0 && errno != EINVAL)
- warn ("failed to unmount /var prior to mounting tmpfs, mounting over");
-
- if (mount ("tmpfs", "/var", "tmpfs", 0, NULL) < 0)
- err (EXIT_FAILURE, "failed to mount tmpfs on /var");
-}
-
int
main(int argc, char *argv[])
{
- const char *remounts[] = { "/sysroot", "/etc", "/home", "/root", "/tmp", "/var", NULL };
+ const char *remounts[] = { "/sysroot", "/var", NULL };
struct stat stbuf;
int i;
@@ -69,8 +51,6 @@ main(int argc, char *argv[])
* to clear the readonly flag in that case.
*/
- maybe_mount_tmpfs_on_var ();
-
exit (EXIT_SUCCESS);
}
@@ -84,17 +64,25 @@ main(int argc, char *argv[])
*/
if (S_ISLNK (stbuf.st_mode))
continue;
+ /* If not a mountpoint, skip it */
+ struct statvfs stvfsbuf;
+ if (statvfs (target, &stvfsbuf) == -1)
+ continue;
+ /* If no read-only flag, skip it */
+ if ((stvfsbuf.f_flag & ST_RDONLY) == 0)
+ continue;
+ /* It's a mounted, read-only fs; remount it */
if (mount (target, target, NULL, MS_REMOUNT | MS_SILENT, NULL) < 0)
- {
+ {
/* Also ignore ENINVAL - if the target isn't a mountpoint
* already, then assume things are OK.
*/
if (errno != EINVAL)
err (EXIT_FAILURE, "failed to remount %s", target);
- }
+ }
+ else
+ printf ("Remounted: %s\n", target);
}
- maybe_mount_tmpfs_on_var ();
-
exit (EXIT_SUCCESS);
}
diff --git a/src/switchroot/ostree-system-generator.c b/src/switchroot/ostree-system-generator.c
new file mode 100644
index 00000000..e7205b5a
--- /dev/null
+++ b/src/switchroot/ostree-system-generator.c
@@ -0,0 +1,67 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2017 Colin Walters
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#include "ostree-cmdprivate.h"
+#include "ostree-mount-util.h"
+
+static const char *arg_dest = "/tmp";
+static const char *arg_dest_late = "/tmp";
+
+/* This program is a simple stub that calls the implementation that
+ * lives inside libostree.
+ */
+int
+main(int argc, char *argv[])
+{
+ /* Important: if this isn't an ostree-booted system, do nothing; people could
+ * have the package installed as a dependency for flatpak or whatever.
+ */
+ { struct stat stbuf;
+ if (fstatat (AT_FDCWD, "/run/ostree-booted", &stbuf, 0) < 0)
+ exit (EXIT_SUCCESS);
+ }
+
+ if (argc > 1 && argc != 4)
+ errx (EXIT_FAILURE, "This program takes three or no arguments");
+
+ if (argc > 1)
+ arg_dest = argv[1];
+ if (argc > 3)
+ arg_dest_late = argv[3];
+
+ char *ostree_cmdline = read_proc_cmdline_ostree ();
+ if (!ostree_cmdline)
+ errx (EXIT_FAILURE, "Failed to find ostree= kernel argument");
+
+ { g_autoptr(GError) local_error = NULL;
+ if (!ostree_cmd__private__()->ostree_system_generator (ostree_cmdline, arg_dest, NULL, arg_dest_late, &local_error))
+ errx (EXIT_FAILURE, "%s", local_error->message);
+ }
+
+ exit (EXIT_SUCCESS);
+}
diff --git a/tests/basic-test.sh b/tests/basic-test.sh
index f4b2b118..b209b839 100644
--- a/tests/basic-test.sh
+++ b/tests/basic-test.sh
@@ -19,7 +19,7 @@
set -euo pipefail
-echo "1..65"
+echo "1..66"
$CMD_PREFIX ostree --version > version.yaml
python -c 'import yaml; yaml.safe_load(open("version.yaml"))'
@@ -28,7 +28,7 @@ echo "ok yaml version"
CHECKOUT_U_ARG=""
COMMIT_ARGS=""
DIFF_ARGS=""
-if grep bare-user-only repo/config; then
+if grep -q bare-user-only repo/config; then
# In bare-user-only repos we can only represent files with uid/gid 0, no
# xattrs and canonical permissions, so we need to commit them as such, or
# we end up with repos that don't pass fsck
@@ -50,11 +50,14 @@ validate_checkout_basic() {
$OSTREE checkout test2 checkout-test2
validate_checkout_basic checkout-test2
+if grep -q 'mode=bare$' repo/config; then
+ assert_not_streq $(stat -c '%h' checkout-test2/firstfile) 1
+fi
echo "ok checkout"
# Note this tests bare-user *and* bare-user-only
rm checkout-test2 -rf
-if grep bare-user repo/config; then
+if grep -q bare-user repo/config; then
$OSTREE checkout -U -H test2 checkout-test2
else
$OSTREE checkout -H test2 checkout-test2
@@ -78,6 +81,14 @@ fi
fi
echo "ok checkout -H"
+rm checkout-test2 -rf
+$OSTREE checkout -C test2 checkout-test2
+for file in firstfile baz/cow baz/alink; do
+ assert_streq $(stat -c '%h' checkout-test2/$file) 1
+done
+
+echo "ok checkout -C"
+
$OSTREE rev-parse test2
$OSTREE rev-parse 'test2^'
$OSTREE rev-parse 'test2^^' 2>/dev/null && fatal "rev-parse test2^^ unexpectedly succeeded!"
@@ -330,6 +341,18 @@ cd ${test_tmpdir}
$OSTREE checkout --subpath /yet/another test2 checkout-test2-subpath
cd checkout-test2-subpath
assert_file_has_content tree/green "leaf"
+cd ${test_tmpdir}
+rm checkout-test2-subpath -rf
+$OSTREE ls -R test2
+# Test checking out a file
+$OSTREE checkout --subpath /baz/saucer test2 checkout-test2-subpath
+assert_file_has_content checkout-test2-subpath/saucer alien
+# Test checking out a file without making a subdir
+mkdir t
+cd t
+$OSTREE checkout --subpath /baz/saucer test2 .
+assert_file_has_content saucer alien
+rm t -rf
echo "ok checkout subpath"
cd ${test_tmpdir}
diff --git a/tests/libostreetest.c b/tests/libostreetest.c
index cda1649d..2fb83f51 100644
--- a/tests/libostreetest.c
+++ b/tests/libostreetest.c
@@ -99,7 +99,7 @@ ot_test_setup_sysroot (GCancellable *cancellable,
{ g_autoptr(GString) buf = g_string_new ("mutable-deployments");
if (statfs ("/", &stbuf) < 0)
- return glnx_throw_errno (error), NULL;
+ return glnx_null_throw_errno (error);
/* Keep this in sync with the overlayfs bits in libtest.sh */
#ifndef OVERLAYFS_SUPER_MAGIC
#define OVERLAYFS_SUPER_MAGIC 0x794c7630
diff --git a/tests/libtest-core.sh b/tests/libtest-core.sh
new file mode 100644
index 00000000..d1d3bbdf
--- /dev/null
+++ b/tests/libtest-core.sh
@@ -0,0 +1,118 @@
+# Core source library for shell script tests
+#
+# Copyright (C) 2017 Colin Walters
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+fatal() {
+ echo $@ 1>&2; exit 1
+}
+# fatal() is shorter to type, but retain this alias
+assert_not_reached () {
+ fatal "$@"
+}
+
+# Some tests look for specific English strings. Use a UTF-8 version
+# of the C (POSIX) locale if we have one, or fall back to POSIX
+# (https://sourceware.org/glibc/wiki/Proposals/C.UTF-8)
+if locale -a | grep C.UTF-8 >/dev/null; then
+ export LC_ALL=C.UTF-8
+else
+ export LC_ALL=C
+fi
+
+# This should really be the default IMO
+export G_DEBUG=fatal-warnings
+assert_streq () {
+ test "$1" = "$2" || fatal "$1 != $2"
+}
+
+assert_str_match () {
+ if ! echo "$1" | grep -E -q "$2"; then
+ fatal "$1 does not match regexp $2"
+ fi
+}
+
+assert_not_streq () {
+ (! test "$1" = "$2") || fatal "$1 == $2"
+}
+
+assert_has_file () {
+ test -f "$1" || fatal "Couldn't find '$1'"
+}
+
+assert_has_dir () {
+ test -d "$1" || fatal "Couldn't find '$1'"
+}
+
+assert_not_has_file () {
+ if test -f "$1"; then
+ sed -e 's/^/# /' < "$1" >&2
+ fatal "File '$1' exists"
+ fi
+}
+
+assert_not_file_has_content () {
+ if grep -q -e "$2" "$1"; then
+ sed -e 's/^/# /' < "$1" >&2
+ fatal "File '$1' incorrectly matches regexp '$2'"
+ fi
+}
+
+assert_not_has_dir () {
+ if test -d "$1"; then
+ fatal "Directory '$1' exists"
+ fi
+}
+
+assert_file_has_content () {
+ if ! grep -q -e "$2" "$1"; then
+ sed -e 's/^/# /' < "$1" >&2
+ fatal "File '$1' doesn't match regexp '$2'"
+ fi
+}
+
+assert_file_has_content_literal () {
+ if ! grep -q -F -e "$2" "$1"; then
+ sed -e 's/^/# /' < "$1" >&2
+ fatal "File '$1' doesn't match fixed string list '$2'"
+ fi
+}
+
+assert_symlink_has_content () {
+ if ! test -L "$1"; then
+ echo 1>&2 "File '$1' is not a symbolic link"
+ exit 1
+ fi
+ if ! readlink "$1" | grep -q -e "$2"; then
+ sed -e 's/^/# /' < "$1" >&2
+ echo 1>&2 "Symbolic link '$1' doesn't match regexp '$2'"
+ exit 1
+ fi
+}
+
+assert_file_empty() {
+ if test -s "$1"; then
+ sed -e 's/^/# /' < "$1" >&2
+ fatal "File '$1' is not empty"
+ fi
+}
+
+# Use to skip all of these tests
+skip() {
+ echo "1..0 # SKIP" "$@"
+ exit 0
+}
diff --git a/tests/libtest.sh b/tests/libtest.sh
index 58351f81..3ce718f9 100755
--- a/tests/libtest.sh
+++ b/tests/libtest.sh
@@ -17,6 +17,8 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
+dn=$(dirname $0)
+
if [ -n "${G_TEST_SRCDIR:-}" ]; then
test_srcdir="${G_TEST_SRCDIR}/tests"
else
@@ -28,26 +30,10 @@ if [ -n "${G_TEST_BUILDDIR:-}" ]; then
else
test_builddir=$(dirname $0)
fi
-
-fatal() {
- echo $@ 1>&2; exit 1
-}
-# fatal() is shorter to type, but retain this alias
-assert_not_reached () {
- fatal "$@"
-}
+. ${test_srcdir}/libtest-core.sh
test_tmpdir=$(pwd)
-# Some tests look for specific English strings. Use a UTF-8 version
-# of the C (POSIX) locale if we have one, or fall back to POSIX
-# (https://sourceware.org/glibc/wiki/Proposals/C.UTF-8)
-if locale -a | grep C.UTF-8 >/dev/null; then
- export LC_ALL=C.UTF-8
-else
- export LC_ALL=C
-fi
-
# Sanity check that we're in a tmpdir that has
# just .testtmp (created by tap-driver for `make check`,
# or nothing at all (as ginstest-runner does)
@@ -62,8 +48,6 @@ if ! test -f .testtmp; then
touch .testtmp
fi
-export G_DEBUG=fatal-warnings
-
# Also, unbreak `tar` inside `make check`...Automake will inject
# TAR_OPTIONS: --owner=0 --group=0 --numeric-owner presumably so that
# tarballs are predictable, except we don't want this in our tests.
@@ -121,77 +105,17 @@ fi
if test -n "${OSTREE_UNINSTALLED:-}"; then
OSTREE_HTTPD=${OSTREE_UNINSTALLED}/ostree-trivial-httpd
else
- OSTREE_HTTPD="${CMD_PREFIX} ostree trivial-httpd"
+ # trivial-httpd is now in $libexecdir by default, which we don't
+ # know at this point. Fortunately, libtest.sh is also in
+ # $libexecdir, so make an educated guess. If it's not found, assume
+ # it's still runnable as "ostree trivial-httpd".
+ if [ -x "${test_srcdir}/../../libostree/ostree-trivial-httpd" ]; then
+ OSTREE_HTTPD="${CMD_PREFIX} ${test_srcdir}/../../libostree/ostree-trivial-httpd"
+ else
+ OSTREE_HTTPD="${CMD_PREFIX} ostree trivial-httpd"
+ fi
fi
-assert_streq () {
- test "$1" = "$2" || fatal "$1 != $2"
-}
-
-assert_str_match () {
- if ! echo "$1" | grep -E -q "$2"; then
- fatal "$1 does not match regexp $2"
- fi
-}
-
-assert_not_streq () {
- (! test "$1" = "$2") || fatal "$1 == $2"
-}
-
-assert_has_file () {
- test -f "$1" || fatal "Couldn't find '$1'"
-}
-
-assert_has_dir () {
- test -d "$1" || fatal "Couldn't find '$1'"
-}
-
-assert_not_has_file () {
- if test -f "$1"; then
- sed -e 's/^/# /' < "$1" >&2
- fatal "File '$1' exists"
- fi
-}
-
-assert_not_file_has_content () {
- if grep -q -e "$2" "$1"; then
- sed -e 's/^/# /' < "$1" >&2
- fatal "File '$1' incorrectly matches regexp '$2'"
- fi
-}
-
-assert_not_has_dir () {
- if test -d "$1"; then
- fatal "Directory '$1' exists"
- fi
-}
-
-assert_file_has_content () {
- if ! grep -q -e "$2" "$1"; then
- sed -e 's/^/# /' < "$1" >&2
- fatal "File '$1' doesn't match regexp '$2'"
- fi
-}
-
-assert_symlink_has_content () {
- if ! test -L "$1"; then
- echo 1>&2 "File '$1' is not a symbolic link"
- exit 1
- fi
- if ! readlink "$1" | grep -q -e "$2"; then
- sed -e 's/^/# /' < "$1" >&2
- echo 1>&2 "Symbolic link '$1' doesn't match regexp '$2'"
- exit 1
- fi
-}
-
-assert_file_empty() {
- if test -s "$1"; then
- sed -e 's/^/# /' < "$1" >&2
- fatal "File '$1' is not empty"
- fi
-}
-
assert_files_hardlinked() {
f1=$(stat -c %i $1)
f2=$(stat -c %i $2)
@@ -491,6 +415,9 @@ EOF
mkdir sysroot
export OSTREE_SYSROOT=sysroot
${CMD_PREFIX} ostree admin init-fs sysroot
+ if test -n "${OSTREE_NO_XATTRS:-}"; then
+ echo -e 'disable-xattrs=true\n' >> sysroot/ostree/repo/config
+ fi
${CMD_PREFIX} ostree admin os-init testos
case $bootmode in
@@ -541,11 +468,6 @@ os_repository_new_commit ()
cd ${test_tmpdir}
}
-skip() {
- echo "1..0 # SKIP" "$@"
- exit 0
-}
-
skip_without_user_xattrs () {
touch test-xattrs
setfattr -n user.testvalue -v somevalue test-xattrs || \
diff --git a/tests/pull-test.sh b/tests/pull-test.sh
index f2486c31..f81d8023 100644
--- a/tests/pull-test.sh
+++ b/tests/pull-test.sh
@@ -35,7 +35,7 @@ function verify_initial_contents() {
assert_file_has_content baz/cow '^moo$'
}
-echo "1..15"
+echo "1..16"
# Try both syntaxes
repo_init
@@ -150,23 +150,33 @@ prev_rev=$(ostree --repo=ostree-srv/gnomerepo rev-parse main^)
new_rev=$(ostree --repo=ostree-srv/gnomerepo rev-parse main)
${CMD_PREFIX} ostree --repo=ostree-srv/gnomerepo summary -u
+# Explicitly test delta fetches via ref name as well as commit hash
+for delta_target in main ${new_rev}; do
cd ${test_tmpdir}
repo_init
${CMD_PREFIX} ostree --repo=repo pull origin main@${prev_rev}
-${CMD_PREFIX} ostree --repo=repo pull --dry-run --require-static-deltas origin main >dry-run-pull.txt
+${CMD_PREFIX} ostree --repo=repo pull --dry-run --require-static-deltas origin ${delta_target} >dry-run-pull.txt
# Compression can vary, so we support 400-699
assert_file_has_content dry-run-pull.txt 'Delta update: 0/1 parts, 0 bytes/[456][0-9][0-9] bytes, 455 bytes total uncompressed'
rev=$(${CMD_PREFIX} ostree --repo=repo rev-parse origin:main)
assert_streq "${prev_rev}" "${rev}"
${CMD_PREFIX} ostree --repo=repo fsck
+done
+# Explicitly test delta fetches via ref name as well as commit hash
+for delta_target in main ${new_rev}; do
cd ${test_tmpdir}
repo_init
${CMD_PREFIX} ostree --repo=repo pull origin main@${prev_rev}
-${CMD_PREFIX} ostree --repo=repo pull --require-static-deltas origin main
-rev=$(${CMD_PREFIX} ostree --repo=repo rev-parse origin:main)
-assert_streq "${new_rev}" "${rev}"
+${CMD_PREFIX} ostree --repo=repo pull --require-static-deltas origin ${delta_target}
+if test ${delta_target} = main; then
+ rev=$(${CMD_PREFIX} ostree --repo=repo rev-parse origin:main)
+ assert_streq "${new_rev}" "${rev}"
+else
+ ${CMD_PREFIX} ostree --repo=repo rev-parse ${delta_target}
+fi
${CMD_PREFIX} ostree --repo=repo fsck
+done
cd ${test_tmpdir}
repo_init
@@ -208,8 +218,23 @@ fi
assert_file_has_content err.txt "deltas required, but none found"
${CMD_PREFIX} ostree --repo=repo fsck
+# Now test with a partial commit
+repo_init
+${CMD_PREFIX} ostree --repo=repo pull --commit-metadata-only origin main@${prev_rev}
+if ${CMD_PREFIX} ostree --repo=repo pull --require-static-deltas origin main 2>err.txt; then
+ assert_not_reached "--require-static-deltas unexpectedly succeeded"
+fi
+assert_file_has_content err.txt "deltas required, but none found"
echo "ok delta required but don't exist"
+repo_init
+${CMD_PREFIX} ostree --repo=repo pull origin main@${prev_rev}
+if ${CMD_PREFIX} ostree --repo=repo pull --require-static-deltas origin ${new_rev} 2>err.txt; then
+ assert_not_reached "--require-static-deltas unexpectedly succeeded"
+fi
+assert_file_has_content err.txt "deltas required, but none found"
+echo "ok delta required for revision"
+
cd ${test_tmpdir}
rm main-files -rf
${CMD_PREFIX} ostree --repo=ostree-srv/gnomerepo checkout main main-files
diff --git a/tests/readdir-rand.c b/tests/readdir-rand.c
index afef387c..10bf8677 100644
--- a/tests/readdir-rand.c
+++ b/tests/readdir-rand.c
@@ -83,7 +83,7 @@ readdir (DIR *dirp)
struct dirent *(*real_readdir)(DIR *dirp) = dlsym (RTLD_NEXT, READDIR);
struct dirent *ret;
gboolean cache_another = TRUE;
-
+
ensure_initialized ();
/* The core idea here is that each time through the loop, we read a
@@ -101,40 +101,40 @@ readdir (DIR *dirp)
errno = 0;
ret = real_readdir (dirp);
if (ret == NULL && errno != 0)
- goto out;
+ goto out;
g_mutex_lock (&direntcache_lock);
de = g_hash_table_lookup (direntcache, dirp);
if (ret)
- {
- if (g_random_boolean ())
- {
- struct dirent *copy;
- if (!de)
- {
- de = dir_entries_new ();
- g_hash_table_insert (direntcache, dirp, de);
- }
- copy = g_memdup (ret, sizeof (struct dirent));
- g_ptr_array_add (de->entries, copy);
- }
- else
- {
- cache_another = FALSE;
- }
- }
+ {
+ if (g_random_boolean ())
+ {
+ struct dirent *copy;
+ if (!de)
+ {
+ de = dir_entries_new ();
+ g_hash_table_insert (direntcache, dirp, de);
+ }
+ copy = g_memdup (ret, sizeof (struct dirent));
+ g_ptr_array_add (de->entries, copy);
+ }
+ else
+ {
+ cache_another = FALSE;
+ }
+ }
else
- {
- if (de && de->offset < de->entries->len)
- {
- ret = de->entries->pdata[de->offset];
- de->offset++;
- }
- cache_another = FALSE;
- }
+ {
+ if (de && de->offset < de->entries->len)
+ {
+ ret = de->entries->pdata[de->offset];
+ de->offset++;
+ }
+ cache_another = FALSE;
+ }
g_mutex_unlock (&direntcache_lock);
}
-
+
out:
return ret;
}
@@ -145,7 +145,7 @@ closedir (DIR *dirp)
int (*real_closedir)(DIR *dirp) = dlsym (RTLD_NEXT, "closedir");
ensure_initialized ();
-
+
g_mutex_lock (&direntcache_lock);
g_hash_table_remove (direntcache, dirp);
g_mutex_unlock (&direntcache_lock);
@@ -170,7 +170,7 @@ seekdir (DIR *dirp, long loc)
ensure_initialized ();
- /* For now, crash if seekdir is called when we have cached entries.
+ /* For now, crash if seekdir is called when we have cached entries.
* If some app wants to use this and seekdir() we can implement it.
*/
assert_no_cached_entries (dirp);
diff --git a/tests/test-basic-root.sh b/tests/test-basic-root.sh
new file mode 100755
index 00000000..a2fa8809
--- /dev/null
+++ b/tests/test-basic-root.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+#
+# Copyright (C) 2011 Colin Walters
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+set -euo pipefail
+
+. $(dirname $0)/libtest.sh
+
+id=$(id -u)
+
+if test ${id} != 0; then
+ skip "continued basic tests must be run as root (possibly in a container)"
+fi
+
+setup_test_repository "bare"
+
+echo "1..1"
+
+nextid=$(($id + 1))
+
+rm checkout-test2 -rf
+$OSTREE checkout test2 checkout-test2
+$OSTREE commit ${COMMIT_ARGS} -b test2 --tree=ref=test2 --owner-uid=$nextid
+$OSTREE ls test2 baz/cow > ls.txt
+assert_file_has_content ls.txt '-00644 '${nextid}' '${id}
+# As bare and running as root (e.g. Docker container), do some ownership tests
+# https://github.com/ostreedev/ostree/pull/801
+# Both hardlinks and copies should respect ownership, but we don't have -C yet;
+# add it when we do.
+for opt in -H; do
+ rm test2-co -rf
+ $OSTREE checkout ${opt} test2 test2-co
+ assert_streq "$(stat -c '%u' test2-co/baz/cow)" ${nextid}
+ assert_streq "$(stat -c '%u' test2-co/baz/alink)" ${nextid}
+done
+rm test2-co -rf
+# But user mode doesn't
+$OSTREE checkout -U test2 test2-co
+assert_streq "$(stat -c '%u' test2-co/baz/cow)" ${id}
+assert_streq "$(stat -c '%u' test2-co/baz/alink)" ${id}
+echo "ok ownership"
diff --git a/tests/test-core.js b/tests/test-core.js
index e9ace6e9..64d1b62d 100644
--- a/tests/test-core.js
+++ b/tests/test-core.js
@@ -52,4 +52,18 @@ let child = root.get_child('some-file');
let info = child.query_info("standard::name,standard::type,standard::size", 0, null);
assertEquals(info.get_size(), 12);
+// Write a ref and read it back
+repo.prepare_transaction(null);
+repo.transaction_set_refspec('someref', commit);
+repo.commit_transaction(null, null);
+let [,readCommit] = repo.resolve_rev('someref', false);
+assertEquals(readCommit, commit);
+
+// Delete a ref
+repo.prepare_transaction(null);
+repo.transaction_set_refspec('someref', null);
+repo.commit_transaction(null, null);
+[,readCommit] = repo.resolve_rev('someref', true);
+assertEquals(readCommit, null);
+
print("test-core complete");
diff --git a/tests/test-corruption.sh b/tests/test-corruption.sh
index ef0e94ef..8e2aba56 100755
--- a/tests/test-corruption.sh
+++ b/tests/test-corruption.sh
@@ -19,10 +19,12 @@
set -euo pipefail
-echo "1..2"
+echo "1..3"
. $(dirname $0)/libtest.sh
+cd ${test_tmpdir}
+rm repo files -rf
setup_test_repository "bare"
$OSTREE checkout test2 checkout-test2
cd checkout-test2
@@ -34,6 +36,8 @@ $OSTREE fsck -q
echo "ok chmod"
cd ${test_tmpdir}
+rm repo files -rf
+setup_test_repository "bare"
rm checkout-test2 -rf
$OSTREE checkout test2 checkout-test2
cd checkout-test2
@@ -41,3 +45,14 @@ chmod o+x firstfile
$OSTREE fsck -q --delete && (echo 1>&2 "fsck unexpectedly succeeded"; exit 1)
echo "ok chmod"
+
+cd ${test_tmpdir}
+rm repo files -rf
+setup_test_repository "bare"
+find repo/ -name '*.commit' -delete
+if $OSTREE fsck -q 2>err.txt; then
+ assert_not_reached "fsck unexpectedly succeeded"
+fi
+assert_file_has_content_literal err.txt "Loading commit for ref test2: No such metadata object"
+
+echo "ok missing commit"
diff --git a/tests/test-delta.sh b/tests/test-delta.sh
index 84320b80..8baee723 100755
--- a/tests/test-delta.sh
+++ b/tests/test-delta.sh
@@ -169,9 +169,9 @@ echo 'ok heuristic endian detection'
${CMD_PREFIX} ostree --repo=repo summary -u
mkdir repo2 && ostree_repo_init repo2 --mode=bare-user
-${CMD_PREFIX} ostree --repo=repo2 pull-local --require-static-deltas repo ${newrev}
+${CMD_PREFIX} ostree --repo=repo2 pull-local --require-static-deltas repo ${origrev}
${CMD_PREFIX} ostree --repo=repo2 fsck
-${CMD_PREFIX} ostree --repo=repo2 ls ${newrev} >/dev/null
+${CMD_PREFIX} ostree --repo=repo2 ls ${origrev} >/dev/null
echo 'ok pull delta'
diff --git a/tests/test-gpg-verify-result.c b/tests/test-gpg-verify-result.c
index d2c1ff66..62b05e33 100644
--- a/tests/test-gpg-verify-result.c
+++ b/tests/test-gpg-verify-result.c
@@ -28,11 +28,10 @@
#define assert_no_gpg_error(err, filename) \
G_STMT_START { \
if (err != GPG_ERR_NO_ERROR) { \
- GString *string = g_string_new ("assertion failed "); \
+ g_autoptr(GString) string = g_string_new ("assertion failed "); \
g_string_append_printf (string, "%s: %s ", gpgme_strsource (err), gpgme_strerror (err)); \
g_string_append (string, filename ? filename : ""); \
g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, string->str); \
- g_string_free (string, TRUE); \
} \
} G_STMT_END
diff --git a/tests/test-pull-many.sh b/tests/test-pull-many.sh
deleted file mode 100755
index 73245a6b..00000000
--- a/tests/test-pull-many.sh
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2017 Colin Walters
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-set -euo pipefail
-
-. $(dirname $0)/libtest.sh
-
-setup_exampleos_repo
-
-echo '1..3'
-
-cd ${test_tmpdir}
-set -x
-
-echo "$(date): Pulling content..."
-rev=$(${CMD_PREFIX} ostree --repo=ostree-srv/exampleos/repo rev-parse ${REF})
-${CMD_PREFIX} ostree --repo=repo pull --disable-static-deltas origin ${REF}
-${CMD_PREFIX} ostree --repo=repo fsck
-assert_streq ${rev} $(${CMD_PREFIX} ostree --repo=repo rev-parse ${REF})
-
-echo "ok without deltas"
-
-previous=$(${CMD_PREFIX} ostree --repo=repo rev-parse ${rev}^)
-rm repo/refs/{heads,remotes}/* -rf
-${CMD_PREFIX} ostree --repo=repo prune --refs-only
-${CMD_PREFIX} ostree --repo=repo pull origin ${REF}@${previous}
-${CMD_PREFIX} ostree --repo=repo pull --dry-run --require-static-deltas origin ${REF} > output.txt
-assert_file_has_content output.txt 'Delta update: 0/1 parts, 0 bytes/1.[012] MB, 1.[345] MB total uncompressed'
-
-echo "ok delta dry-run"
-
-${CMD_PREFIX} ostree --repo=repo pull --require-static-deltas origin ${REF}
-assert_streq $(${CMD_PREFIX} ostree --repo=repo rev-parse ${REF}) ${rev}
-${CMD_PREFIX} ostree --repo=repo fsck
-
-echo "ok"
diff --git a/tests/test-repo-checkout-subpath.sh b/tests/test-repo-checkout-subpath.sh
deleted file mode 100755
index 2da5adc2..00000000
--- a/tests/test-repo-checkout-subpath.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2011,2013 Colin Walters
-# Copyright (C) 2014 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-set -euo pipefail
-
-. $(dirname $0)/libtest.sh
-
-setup_test_repository "bare"
-
-echo '1..1'
-
-repopath=${test_tmpdir}/ostree-srv/gnomerepo
-
-${CMD_PREFIX} ostree --repo=repo checkout -U --subpath=/ test2 checkedout
-
-${CMD_PREFIX} ostree --repo=repo checkout -U --subpath=/firstfile test2 checkedout2
-
-echo "ok"
diff --git a/tests/test-rollsum.c b/tests/test-rollsum.c
index 37c8bab8..a6c1bebd 100644
--- a/tests/test-rollsum.c
+++ b/tests/test-rollsum.c
@@ -152,7 +152,7 @@ test_bupsplit_sum(void)
sum1a = bupsplit_sum(buf, 0, BUP_SELFTEST_SIZE);
sum1b = bupsplit_sum(buf, 1, BUP_SELFTEST_SIZE);
sum2a = bupsplit_sum(buf, BUP_SELFTEST_SIZE - BUP_WINDOWSIZE*5/2,
- BUP_SELFTEST_SIZE - BUP_WINDOWSIZE);
+ BUP_SELFTEST_SIZE - BUP_WINDOWSIZE);
sum2b = bupsplit_sum(buf, 0, BUP_SELFTEST_SIZE - BUP_WINDOWSIZE);
sum3a = bupsplit_sum(buf, 0, BUP_WINDOWSIZE+3);
sum3b = bupsplit_sum(buf, 3, BUP_WINDOWSIZE+3);
diff --git a/tests/test-summary-view.sh b/tests/test-summary-view.sh
new file mode 100755
index 00000000..6dcfd088
--- /dev/null
+++ b/tests/test-summary-view.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+#
+# Copyright © 2017 Endless Mobile, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+# Authors:
+# - Philip Withnall
+
+set -euo pipefail
+
+. $(dirname $0)/libtest.sh
+
+echo "1..2"
+
+COMMIT_SIGN="--gpg-homedir=${TEST_GPG_KEYHOME} --gpg-sign=${TEST_GPG_KEYID_1}"
+setup_fake_remote_repo1 "archive-z2" "${COMMIT_SIGN}"
+
+# Set up a second branch.
+mkdir ${test_tmpdir}/ostree-srv/other-files
+cd ${test_tmpdir}/ostree-srv/other-files
+echo 'hello world some object' > hello-world
+${CMD_PREFIX} ostree --repo=${test_tmpdir}/ostree-srv/gnomerepo commit ${COMMIT_SIGN} -b other -s "A commit" -m "Example commit body"
+
+# Generate the summary file.
+${CMD_PREFIX} ostree --repo=${test_tmpdir}/ostree-srv/gnomerepo summary -u
+
+# Check out the repository.
+prev_dir=`pwd`
+cd ${test_tmpdir}
+ostree_repo_init repo --mode=archive-z2
+${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin $(cat httpd-address)/ostree/gnomerepo
+${CMD_PREFIX} ostree --repo=repo pull --mirror origin
+
+# Check the summary file exists in the checkout, and can be viewed.
+assert_has_file repo/summary
+${OSTREE} summary --view > summary.txt
+assert_file_has_content_literal summary.txt "* main"
+assert_file_has_content_literal summary.txt "* other"
+assert_file_has_content_literal summary.txt "ostree.summary.last-modified"
+assert_file_has_content_literal summary.txt "Static Deltas (ostree.static-deltas): {}"
+echo "ok view summary"
+
+# Check the summary can be viewed raw too.
+${OSTREE} summary --view --raw > raw-summary.txt
+assert_file_has_content_literal raw-summary.txt "('main', ("
+assert_file_has_content_literal raw-summary.txt "('other', ("
+assert_file_has_content_literal raw-summary.txt "{'ostree.summary.last-modified': expected-symbols.txt
-eu-readelf -a ${G_TEST_BUILDDIR}/.libs/libostree-1.so | grep 'FUNC.*GLOBAL.*DEFAULT.*@@LIBOSTREE_' | sed -e 's,^.* \(ostree_[A-Za-z0-9_]*\)@@LIBOSTREE_[0-9_.]*,\1,' |sort -u > found-symbols.txt
+grep --no-filename ' ostree_[A-Za-z0-9_]*;' ${G_TEST_SRCDIR}/src/libostree/libostree.sym $experimental_sym | sed -e 's,^ *\([A-Za-z0-9_]*\);,\1,' | sort -u > expected-symbols.txt
+eu-readelf -a ${G_TEST_BUILDDIR}/.libs/libostree-1.so | grep 'FUNC.*GLOBAL.*DEFAULT.*@@LIBOSTREE_' | sed -e 's,^.* \(ostree_[A-Za-z0-9_]*\)@@LIBOSTREE_[0-9A-Z_.]*,\1,' |sort -u > found-symbols.txt
diff -u expected-symbols.txt found-symbols.txt
echo "ok exports"
@@ -31,7 +39,7 @@ echo "ok exports"
grep -E -v '(ostree_cmd__private__)|(ostree_fetcher_config_flags_get_type)' found-symbols.txt > expected-documented.txt
echo "Verifying all public symbols are documented:"
-grep '^ostree_' ${G_TEST_SRCDIR}/apidoc/ostree-sections.txt |sort -u > found-documented.txt
+grep '^ostree_' ${G_TEST_SRCDIR}/apidoc/ostree-sections.txt $experimental_sections |sort -u > found-documented.txt
diff -u expected-documented.txt found-documented.txt
echo 'ok documented symbols'