Imported Upstream version 2016.4
This commit is contained in:
commit
36b5deae48
|
|
@ -137,8 +137,9 @@ libostree_1_la_SOURCES += \
|
|||
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)
|
||||
libostree_1_la_LDFLAGS = -version-number 1:0:0 -Bsymbolic-functions -export-symbols-regex '^ostree_'
|
||||
$(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) $(OT_DEP_LZMA_CFLAGS) $(OT_DEP_ZLIB_CFLAGS) \
|
||||
-fvisibility=hidden '-D_OSTREE_PUBLIC=__attribute__((visibility("default"))) extern'
|
||||
libostree_1_la_LDFLAGS = -version-number 1:0:0 -Bsymbolic-functions -Wl,--version-script=$(top_srcdir)/src/libostree/libostree.sym
|
||||
libostree_1_la_LIBADD = libotutil.la libbupsplit.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)
|
||||
|
||||
if USE_LIBARCHIVE
|
||||
|
|
@ -158,6 +159,11 @@ libostree_1_la_CFLAGS += $(OT_INTERNAL_SOUP_CFLAGS)
|
|||
libostree_1_la_LIBADD += $(OT_INTERNAL_SOUP_LIBS)
|
||||
endif
|
||||
|
||||
if USE_LIBMOUNT
|
||||
libostree_1_la_CFLAGS += $(OT_DEP_LIBMOUNT_CFLAGS)
|
||||
libostree_1_la_LIBADD += $(OT_DEP_LIBMOUNT_LIBS)
|
||||
endif
|
||||
|
||||
if USE_SELINUX
|
||||
libostree_1_la_CFLAGS += $(OT_DEP_SELINUX_CFLAGS)
|
||||
libostree_1_la_LIBADD += $(OT_DEP_SELINUX_LIBS)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,17 @@
|
|||
|
||||
if ENABLE_MAN
|
||||
|
||||
man1_files = ostree.1 ostree-admin-cleanup.1 ostree-admin-config-diff.1 ostree-admin-deploy.1 ostree-admin-init-fs.1 ostree-admin-instutil.1 ostree-admin-os-init.1 ostree-admin-status.1 ostree-admin-set-origin.1 ostree-admin-switch.1 ostree-admin-undeploy.1 ostree-admin-upgrade.1 ostree-admin.1 ostree-cat.1 ostree-checkout.1 ostree-checksum.1 ostree-commit.1 ostree-export.1 ostree-gpg-sign.1 ostree-config.1 ostree-diff.1 ostree-fsck.1 ostree-init.1 ostree-log.1 ostree-ls.1 ostree-prune.1 ostree-pull-local.1 ostree-pull.1 ostree-refs.1 ostree-remote.1 ostree-reset.1 ostree-rev-parse.1 ostree-show.1 ostree-summary.1 ostree-static-delta.1 ostree-trivial-httpd.1
|
||||
man1_files = ostree.1 ostree-admin-cleanup.1 \
|
||||
ostree-admin-config-diff.1 ostree-admin-deploy.1 \
|
||||
ostree-admin-init-fs.1 ostree-admin-instutil.1 ostree-admin-os-init.1 \
|
||||
ostree-admin-status.1 ostree-admin-set-origin.1 ostree-admin-switch.1 \
|
||||
ostree-admin-undeploy.1 ostree-admin-upgrade.1 ostree-admin-unlock.1 \
|
||||
ostree-admin.1 ostree-cat.1 ostree-checkout.1 ostree-checksum.1 \
|
||||
ostree-commit.1 ostree-export.1 ostree-gpg-sign.1 ostree-config.1 \
|
||||
ostree-diff.1 ostree-fsck.1 ostree-init.1 ostree-log.1 ostree-ls.1 \
|
||||
ostree-prune.1 ostree-pull-local.1 ostree-pull.1 ostree-refs.1 \
|
||||
ostree-remote.1 ostree-reset.1 ostree-rev-parse.1 ostree-show.1 \
|
||||
ostree-summary.1 ostree-static-delta.1 ostree-trivial-httpd.1
|
||||
|
||||
if BUILDOPT_FUSE
|
||||
man1_files += rofiles-fuse.1
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ ostree_SOURCES += \
|
|||
src/ostree/ot-admin-builtin-status.c \
|
||||
src/ostree/ot-admin-builtin-switch.c \
|
||||
src/ostree/ot-admin-builtin-upgrade.c \
|
||||
src/ostree/ot-admin-builtin-unlock.c \
|
||||
src/ostree/ot-admin-builtins.h \
|
||||
src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c \
|
||||
src/ostree/ot-admin-instutil-builtin-set-kargs.c \
|
||||
|
|
|
|||
|
|
@ -17,67 +17,69 @@
|
|||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
include $(top_srcdir)/buildutil/glib-tap.mk
|
||||
|
||||
if BUILDOPT_INSTALL_TESTS
|
||||
# We should probably consider flipping the default for DEBUG. Also,
|
||||
# include the builddir in $PATH so we find our just-built ostree
|
||||
# binary.
|
||||
TESTS_ENVIRONMENT += OT_TESTS_DEBUG=1 \
|
||||
PATH=$$(cd $(top_builddir) && pwd):$${PATH}
|
||||
|
||||
insttestdir=$(pkglibexecdir)/installed-tests
|
||||
testfiles = test-basic \
|
||||
test-pull-subpath \
|
||||
test-archivez \
|
||||
test-remote-add \
|
||||
test-remote-gpg-import \
|
||||
test-commit-sign \
|
||||
test-export \
|
||||
test-help \
|
||||
test-libarchive \
|
||||
test-pull-archive-z \
|
||||
test-pull-commit-only \
|
||||
test-pull-corruption \
|
||||
test-pull-depth \
|
||||
test-pull-mirror-summary \
|
||||
test-pull-large-metadata \
|
||||
test-pull-metalink \
|
||||
test-pull-summary-sigs \
|
||||
test-pull-resume \
|
||||
test-local-pull-depth \
|
||||
test-gpg-signed-commit \
|
||||
test-admin-upgrade-unconfigured \
|
||||
test-admin-deploy-syslinux \
|
||||
test-admin-deploy-2 \
|
||||
test-admin-deploy-karg \
|
||||
test-admin-deploy-switch \
|
||||
test-admin-deploy-etcmerge-cornercases \
|
||||
test-admin-deploy-uboot \
|
||||
test-admin-instutil-set-kargs \
|
||||
test-admin-upgrade-not-backwards \
|
||||
test-admin-pull-deploy-commit \
|
||||
test-admin-locking \
|
||||
test-admin-deploy-clean \
|
||||
test-repo-checkout-subpath \
|
||||
test-reset-nonlinear \
|
||||
test-oldstyle-partial \
|
||||
test-setuid \
|
||||
test-delta \
|
||||
test-xattrs \
|
||||
test-auto-summary \
|
||||
test-prune \
|
||||
test_scripts = \
|
||||
tests/test-basic.sh \
|
||||
tests/test-pull-subpath.sh \
|
||||
tests/test-archivez.sh \
|
||||
tests/test-remote-add.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-pull-archive-z.sh \
|
||||
tests/test-pull-commit-only.sh \
|
||||
tests/test-pull-corruption.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-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 \
|
||||
tests/test-admin-deploy-switch.sh \
|
||||
tests/test-admin-deploy-etcmerge-cornercases.sh \
|
||||
tests/test-admin-deploy-uboot.sh \
|
||||
tests/test-admin-instutil-set-kargs.sh \
|
||||
tests/test-admin-upgrade-not-backwards.sh \
|
||||
tests/test-admin-pull-deploy-commit.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-setuid.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 \
|
||||
$(NULL)
|
||||
|
||||
if BUILDOPT_FUSE
|
||||
testfiles += test-rofiles-fuse
|
||||
test_scripts += tests/test-rofiles-fuse.sh
|
||||
endif
|
||||
|
||||
insttest_SCRIPTS = $(addprefix tests/,$(testfiles:=.sh))
|
||||
|
||||
# This one uses corrupt-repo-ref.js
|
||||
if BUILDOPT_GJS
|
||||
testfiles += test-corruption
|
||||
test_scripts += tests/test-corruption.sh
|
||||
endif
|
||||
|
||||
testmetadir = $(datadir)/installed-tests/$(PACKAGE)
|
||||
testmeta_DATA = $(testfiles:=.test)
|
||||
|
||||
insttest_DATA = tests/archive-test.sh \
|
||||
installed_test_data = tests/archive-test.sh \
|
||||
tests/pull-test.sh \
|
||||
tests/libtest.sh \
|
||||
tests/admin-test.sh \
|
||||
|
|
@ -89,69 +91,61 @@ insttest_DATA = tests/archive-test.sh \
|
|||
tests/pre-endian-deltas-repo-little.tar.xz \
|
||||
$(NULL)
|
||||
|
||||
insttest_SCRIPTS += \
|
||||
tests/syslinux-entries-crosscheck.py \
|
||||
$(NULL)
|
||||
test_extra_scripts = tests/syslinux-entries-crosscheck.py
|
||||
|
||||
gpginsttestdir = $(pkglibexecdir)/installed-tests/gpghome
|
||||
# We can't use nobase_ as we need to strip off the tests/, can't
|
||||
# use plain installed_ as we do need the gpghome/ prefix.
|
||||
if ENABLE_INSTALLED_TESTS
|
||||
gpginsttestdir = $(installed_testdir)/gpghome
|
||||
gpginsttest_DATA = tests/gpghome/secring.gpg \
|
||||
tests/gpghome/pubring.gpg \
|
||||
tests/gpghome/trustdb.gpg \
|
||||
tests/gpghome/key1.asc \
|
||||
tests/gpghome/key2.asc \
|
||||
tests/gpghome/key3.asc
|
||||
gpginsttest_trusteddir = $(pkglibexecdir)/installed-tests/gpghome/trusted
|
||||
gpginsttest_trusteddir = $(installed_testdir)/gpghome/trusted
|
||||
gpginsttest_trusted_DATA = tests/gpghome/trusted/pubring.gpg
|
||||
|
||||
install-gpg-data-hook:
|
||||
ln -sf trusted/pubring.gpg $(DESTDIR)$(gpginsttestdir)/pubring.gpg
|
||||
INSTALL_DATA_HOOKS += install-gpg-data-hook
|
||||
|
||||
%.test: tests/%.sh Makefile
|
||||
$(AM_V_GEN) (echo '[Test]' > $@.tmp; \
|
||||
echo 'Exec=$(pkglibexecdir)/installed-tests/$(notdir $<)' >> $@.tmp; \
|
||||
echo 'Type=session' >> $@.tmp; \
|
||||
echo 'Output=TAP' >> $@.tmp; \
|
||||
mv $@.tmp $@)
|
||||
|
||||
%.test: tests/%.js Makefile
|
||||
$(AM_V_GEN) (echo '[Test]' > $@.tmp; \
|
||||
echo 'Exec=env TESTDATADIR=$(pkglibexecdir)/installed-tests $(pkglibexecdir)/installed-tests/$(notdir $<)' >> $@.tmp; \
|
||||
echo 'Type=session' >> $@.tmp; \
|
||||
mv $@.tmp $@)
|
||||
gpgvinsttestdir = $(installed_testdir)/gpg-verify-data
|
||||
gpgvinsttest_DATA = $(addprefix tests/gpg-verify-data/, \
|
||||
gpg.conf lgpl2 lgpl2.sig pubring.gpg secring.gpg trustdb.gpg)
|
||||
endif
|
||||
|
||||
if BUILDOPT_GJS
|
||||
insttest_SCRIPTS += tests/test-core.js \
|
||||
installed_test_scripts = tests/test-core.js \
|
||||
tests/test-sizes.js \
|
||||
tests/test-sysroot.js \
|
||||
$(NULL)
|
||||
testmeta_DATA += test-core.test test-sizes.test test-sysroot.test
|
||||
endif
|
||||
|
||||
insttest_LTLIBRARIES = libreaddir-rand.la
|
||||
test_ltlibraries = libreaddir-rand.la
|
||||
libreaddir_rand_la_SOURCES = tests/readdir-rand.c
|
||||
libreaddir_rand_la_CFLAGS = $(OT_INTERNAL_GIO_UNIX_CFLAGS)
|
||||
libreaddir_rand_la_LIBADD = $(OT_INTERNAL_GIO_UNIX_LIBS)
|
||||
libreaddir_rand_la_LDFLAGS = -avoid-version
|
||||
|
||||
endif
|
||||
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
|
||||
|
||||
# "make check" do not depend from --enable-installed-tests
|
||||
# An interactive tool
|
||||
noinst_PROGRAMS += tests/test-rollsum-cli
|
||||
|
||||
TESTS = 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
|
||||
|
||||
if USE_LIBARCHIVE
|
||||
TESTS += tests/test-libarchive-import
|
||||
test_programs += tests/test-libarchive-import
|
||||
endif
|
||||
|
||||
check_PROGRAMS = $(TESTS)
|
||||
TESTS_ENVIRONMENT = \
|
||||
G_TEST_SRCDIR=$(abs_srcdir)/tests \
|
||||
G_TEST_BUILDDIR=$(abs_builddir)/tests
|
||||
TESTS_CFLAGS = $(ostree_bin_shared_cflags) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -I$(srcdir)/libglnx
|
||||
TESTS_LDADD = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_GIO_UNIX_LIBS)
|
||||
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)
|
||||
|
||||
noinst_LTLIBRARIES += libostreetest.la
|
||||
libostreetest_la_SOURCES = tests/libostreetest.c
|
||||
libostreetest_la_CFLAGS = $(common_tests_cflags) -I $(srcdir)/tests
|
||||
libostreetest_la_LIBADD = $(common_tests_ldadd)
|
||||
|
||||
TESTS_CFLAGS = $(common_tests_cflags)
|
||||
TESTS_LDADD = $(common_tests_ldadd) libostreetest.la
|
||||
|
||||
tests_test_rollsum_cli_SOURCES = src/libostree/ostree-rollsum.c tests/test-rollsum-cli.c
|
||||
tests_test_rollsum_cli_CFLAGS = $(TESTS_CFLAGS) $(OT_DEP_ZLIB_CFLAGS)
|
||||
|
|
@ -164,6 +158,12 @@ tests_test_rollsum_LDADD = libbupsplit.la $(TESTS_LDADD) $(OT_DEP_ZLIB_LIBS)
|
|||
tests_test_mutable_tree_CFLAGS = $(TESTS_CFLAGS)
|
||||
tests_test_mutable_tree_LDADD = $(TESTS_LDADD)
|
||||
|
||||
tests_test_basic_c_CFLAGS = $(TESTS_CFLAGS)
|
||||
tests_test_basic_c_LDADD = $(TESTS_LDADD)
|
||||
|
||||
tests_test_sysroot_c_CFLAGS = $(TESTS_CFLAGS)
|
||||
tests_test_sysroot_c_LDADD = $(TESTS_LDADD)
|
||||
|
||||
tests_test_ot_unix_utils_CFLAGS = $(TESTS_CFLAGS)
|
||||
tests_test_ot_unix_utils_LDADD = $(TESTS_LDADD)
|
||||
|
||||
|
|
@ -179,8 +179,8 @@ tests_test_checksum_CFLAGS = $(TESTS_CFLAGS) $(libglnx_cflags)
|
|||
tests_test_checksum_LDADD = $(TESTS_LDADD)
|
||||
|
||||
tests_test_libarchive_import_SOURCES = tests/test-libarchive-import.c
|
||||
tests_test_libarchive_import_CFLAGS = $(TESTS_CFLAGS) $(libglnx_cflags)
|
||||
tests_test_libarchive_import_LDADD = $(TESTS_LDADD)
|
||||
tests_test_libarchive_import_CFLAGS = $(TESTS_CFLAGS) $(libglnx_cflags) $(OT_DEP_LIBARCHIVE_CFLAGS)
|
||||
tests_test_libarchive_import_LDADD = $(TESTS_LDADD) $(OT_DEP_LIBARCHIVE_LIBS)
|
||||
|
||||
tests_test_keyfile_utils_CFLAGS = $(TESTS_CFLAGS)
|
||||
tests_test_keyfile_utils_LDADD = $(TESTS_LDADD)
|
||||
|
|
@ -210,3 +210,15 @@ EXTRA_DIST += \
|
|||
tests/gpg-verify-data/secring.gpg \
|
||||
tests/gpg-verify-data/trustdb.gpg \
|
||||
tests/gpg-verify-data/gpg.conf
|
||||
|
||||
# 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.
|
||||
if ENABLE_INSTALLED_TESTS
|
||||
install-test-data-file-path-hack:
|
||||
if test -L $(DESTDIR)$(installed_testdir)/tests; then \
|
||||
rm $(DESTDIR)$(installed_testdir)/tests; \
|
||||
fi
|
||||
ln -s . $(DESTDIR)$(installed_testdir)/tests
|
||||
INSTALL_DATA_HOOKS += install-test-data-file-path-hack
|
||||
endif
|
||||
|
|
|
|||
11
Makefile.am
11
Makefile.am
|
|
@ -19,7 +19,7 @@ include Makefile-decls.am
|
|||
|
||||
shortened_sysconfdir = $$(echo "$(sysconfdir)" | sed -e 's|^$(prefix)||' -e 's|^/||')
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||
ACLOCAL_AMFLAGS = -I buildutil ${ACLOCAL_FLAGS}
|
||||
AM_CPPFLAGS += -DDATADIR='"$(datadir)"' -DLIBEXECDIR='"$(libexecdir)"' \
|
||||
-DLOCALEDIR=\"$(datadir)/locale\" -DSYSCONFDIR=\"$(sysconfdir)\" \
|
||||
-DSHORTENED_SYSCONFDIR=\"$(shortened_sysconfdir)\" \
|
||||
|
|
@ -100,12 +100,3 @@ release-tarball-embedded:
|
|||
$(embed_dependency) embedded-dependencies/libsoup; \
|
||||
mv ostree-embeddeps-$${GITVERSION}.tar{.tmp,}; \
|
||||
gzip -f ostree-embeddeps-$${GITVERSION}.tar
|
||||
|
||||
check-local:
|
||||
@echo " *** NOTE ***"
|
||||
@echo " *** NOTE ***"
|
||||
@echo " \"make check\" only runs a subset of OSTree's tests."
|
||||
@echo " The other tests use: use https://live.gnome.org/GnomeGoals/InstalledTests"
|
||||
@echo " To run them, ostree must be configured with --enable-installed-tests and installed"
|
||||
@echo " *** NOTE ***"
|
||||
@echo " *** NOTE ***"
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ provide a minimal host for Docker formatted Linux containers.
|
|||
Replicating a base immutable OS, then using Docker for applications
|
||||
meshes together two different tools with different tradeoffs.
|
||||
|
||||
[xdg-app](https://github.com/alexlarsson/xdg-app) uses OSTree
|
||||
[xdg-app](https://github.com/alexlarsson/xdg-app) uses OSTree
|
||||
for desktop application containers.
|
||||
|
||||
[GNOME Continuous](https://wiki.gnome.org/Projects/GnomeContinuous) is
|
||||
|
|
@ -83,7 +83,7 @@ More documentation
|
|||
New! See the docs online at [Read The Docs (OSTree)](https://ostree.readthedocs.org/en/latest/ )
|
||||
|
||||
Some more information is available on the old wiki page:
|
||||
https://wiki.gnome.org/Projects/OSTree
|
||||
<https://wiki.gnome.org/Projects/OSTree>
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
|
|
|||
|
|
@ -260,6 +260,7 @@ ostree_repo_write_content_async
|
|||
ostree_repo_write_content_finish
|
||||
ostree_repo_resolve_rev
|
||||
ostree_repo_list_refs
|
||||
ostree_repo_list_refs_ext
|
||||
ostree_repo_remote_list_refs
|
||||
ostree_repo_load_variant
|
||||
ostree_repo_load_commit
|
||||
|
|
@ -380,6 +381,7 @@ ostree_sysroot_new
|
|||
ostree_sysroot_new_default
|
||||
ostree_sysroot_get_path
|
||||
ostree_sysroot_load
|
||||
ostree_sysroot_load_if_changed
|
||||
ostree_sysroot_lock
|
||||
ostree_sysroot_try_lock
|
||||
ostree_sysroot_lock_async
|
||||
|
|
@ -396,6 +398,7 @@ ostree_sysroot_get_deployment_origin_path
|
|||
ostree_sysroot_cleanup
|
||||
ostree_sysroot_prepare_cleanup
|
||||
ostree_sysroot_get_repo
|
||||
ostree_sysroot_init_osname
|
||||
ostree_sysroot_deployment_set_kargs
|
||||
ostree_sysroot_write_deployments
|
||||
ostree_sysroot_deploy_tree
|
||||
|
|
|
|||
|
|
@ -0,0 +1,125 @@
|
|||
# GLIB - Library of useful C routines
|
||||
|
||||
TESTS_ENVIRONMENT= \
|
||||
G_TEST_SRCDIR="$(abs_srcdir)" \
|
||||
G_TEST_BUILDDIR="$(abs_builddir)" \
|
||||
UNINSTALLEDTESTS=1 \
|
||||
G_DEBUG=gc-friendly \
|
||||
MALLOC_CHECK_=2 \
|
||||
MALLOC_PERTURB_=$$(($${RANDOM:-256} % 256))
|
||||
LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/buildutil/tap-driver.sh
|
||||
LOG_COMPILER = $(top_srcdir)/buildutil/tap-test
|
||||
|
||||
TESTS =
|
||||
|
||||
installed_test_LTLIBRARIES =
|
||||
installed_test_PROGRAMS =
|
||||
installed_test_SCRIPTS =
|
||||
installed_test_DATA =
|
||||
nobase_installed_test_DATA =
|
||||
|
||||
noinst_SCRIPTS =
|
||||
noinst_DATA =
|
||||
|
||||
check_LTLIBRARIES =
|
||||
check_PROGRAMS =
|
||||
check_SCRIPTS =
|
||||
check_DATA =
|
||||
|
||||
# We support a fairly large range of possible variables. It is expected that all types of files in a test suite
|
||||
# will belong in exactly one of the following variables.
|
||||
#
|
||||
# First, we support the usual automake suffixes, but in lowercase, with the customary meaning:
|
||||
#
|
||||
# test_programs, test_scripts, test_data, test_ltlibraries
|
||||
#
|
||||
# The above are used to list files that are involved in both uninstalled and installed testing. The
|
||||
# test_programs and test_scripts are taken to be actual testcases and will be run as part of the test suite.
|
||||
# Note that _data is always used with the nobase_ automake variable name to ensure that installed test data is
|
||||
# installed in the same way as it appears in the package layout.
|
||||
#
|
||||
# In order to mark a particular file as being only for one type of testing, use 'installed' or 'uninstalled',
|
||||
# like so:
|
||||
#
|
||||
# installed_test_programs, uninstalled_test_programs
|
||||
# installed_test_scripts, uninstalled_test_scripts
|
||||
# installed_test_data, uninstalled_test_data
|
||||
# installed_test_ltlibraries, uninstalled_test_ltlibraries
|
||||
#
|
||||
# Additionally, we support 'extra' infixes for programs and scripts. This is used for support programs/scripts
|
||||
# that should not themselves be run as testcases (but exist to be used from other testcases):
|
||||
#
|
||||
# test_extra_programs, installed_test_extra_programs, uninstalled_test_extra_programs
|
||||
# test_extra_scripts, installed_test_extra_scripts, uninstalled_test_extra_scripts
|
||||
#
|
||||
# Additionally, for _scripts and _data, we support the customary dist_ prefix so that the named script or data
|
||||
# file automatically end up in the tarball.
|
||||
#
|
||||
# dist_test_scripts, dist_test_data, dist_test_extra_scripts
|
||||
# dist_installed_test_scripts, dist_installed_test_data, dist_installed_test_extra_scripts
|
||||
# dist_uninstalled_test_scripts, dist_uninstalled_test_data, dist_uninstalled_test_extra_scripts
|
||||
#
|
||||
# Note that no file is automatically disted unless it appears in one of the dist_ variables. This follows the
|
||||
# standard automake convention of not disting programs scripts or data by default.
|
||||
#
|
||||
# test_programs, test_scripts, uninstalled_test_programs and uninstalled_test_scripts (as well as their disted
|
||||
# variants) will be run as part of the in-tree 'make check'. These are all assumed to be runnable under
|
||||
# gtester. That's a bit strange for scripts, but it's possible.
|
||||
|
||||
TESTS += $(test_programs) $(test_scripts) $(uninstalled_test_programs) $(uninstalled_test_scripts) \
|
||||
$(dist_test_scripts) $(dist_uninstalled_test_scripts)
|
||||
|
||||
# Note: build even the installed-only targets during 'make check' to ensure that they still work.
|
||||
# We need to do a bit of trickery here and manage disting via EXTRA_DIST instead of using dist_ prefixes to
|
||||
# prevent automake from mistreating gmake functions like $(wildcard ...) and $(addprefix ...) as if they were
|
||||
# filenames, including removing duplicate instances of the opening part before the space, eg. '$(addprefix'.
|
||||
all_test_programs = $(test_programs) $(uninstalled_test_programs) $(installed_test_programs) \
|
||||
$(test_extra_programs) $(uninstalled_test_extra_programs) $(installed_test_extra_programs)
|
||||
all_test_scripts = $(test_scripts) $(uninstalled_test_scripts) $(installed_test_scripts) \
|
||||
$(test_extra_scripts) $(uninstalled_test_extra_scripts) $(installed_test_extra_scripts)
|
||||
all_dist_test_scripts = $(dist_test_scripts) $(dist_uninstalled_test_scripts) $(dist_installed_test_scripts) \
|
||||
$(dist_test_extra_scripts) $(dist_uninstalled_test_extra_scripts) $(dist_installed_test_extra_scripts)
|
||||
all_test_scripts += $(all_dist_test_scripts)
|
||||
EXTRA_DIST += $(all_dist_test_scripts)
|
||||
all_test_data = $(test_data) $(uninstalled_test_data) $(installed_test_data)
|
||||
all_dist_test_data = $(dist_test_data) $(dist_uninstalled_test_data) $(dist_installed_test_data)
|
||||
all_test_data += $(all_dist_test_data)
|
||||
EXTRA_DIST += $(all_dist_test_data)
|
||||
all_test_ltlibs = $(test_ltlibraries) $(uninstalled_test_ltlibraries) $(installed_test_ltlibraries)
|
||||
|
||||
if ENABLE_ALWAYS_BUILD_TESTS
|
||||
noinst_LTLIBRARIES += $(all_test_ltlibs)
|
||||
noinst_PROGRAMS += $(all_test_programs)
|
||||
noinst_SCRIPTS += $(all_test_scripts)
|
||||
noinst_DATA += $(all_test_data)
|
||||
else
|
||||
check_LTLIBRARIES += $(all_test_ltlibs)
|
||||
check_PROGRAMS += $(all_test_programs)
|
||||
check_SCRIPTS += $(all_test_scripts)
|
||||
check_DATA += $(all_test_data)
|
||||
endif
|
||||
|
||||
if ENABLE_INSTALLED_TESTS
|
||||
installed_test_PROGRAMS += $(test_programs) $(installed_test_programs) \
|
||||
$(test_extra_programs) $(installed_test_extra_programs)
|
||||
installed_test_SCRIPTS += $(test_scripts) $(installed_test_scripts) \
|
||||
$(test_extra_scripts) $(test_installed_extra_scripts)
|
||||
installed_test_SCRIPTS += $(dist_test_scripts) $(dist_test_extra_scripts) \
|
||||
$(dist_installed_test_scripts) $(dist_installed_test_extra_scripts)
|
||||
installed_test_DATA += $(test_data) $(installed_test_data)
|
||||
installed_test_DATA += $(dist_test_data) $(dist_installed_test_data)
|
||||
installed_test_LTLIBRARIES += $(test_ltlibraries) $(installed_test_ltlibraries)
|
||||
installed_testcases = $(test_programs) $(installed_test_programs) \
|
||||
$(test_scripts) $(installed_test_scripts) \
|
||||
$(dist_test_scripts) $(dist_installed_test_scripts)
|
||||
|
||||
installed_test_meta_DATA = $(installed_testcases:=.test)
|
||||
|
||||
%.test: %$(EXEEXT) Makefile
|
||||
$(AM_V_GEN) (echo '[Test]' > $@.tmp; \
|
||||
echo 'Type=session' >> $@.tmp; \
|
||||
echo 'Exec=env G_TEST_SRCDIR=$(installed_testdir) G_TEST_BUILDDIR=$(installed_testdir) $(installed_testdir)/$(notdir $<)' >> $@.tmp; \
|
||||
mv $@.tmp $@)
|
||||
|
||||
CLEANFILES += $(installed_test_meta_DATA)
|
||||
endif
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
dnl GLIB_TESTS
|
||||
dnl
|
||||
|
||||
AC_DEFUN([GLIB_TESTS],
|
||||
[
|
||||
AC_ARG_ENABLE(installed-tests,
|
||||
AS_HELP_STRING([--enable-installed-tests],
|
||||
[Enable installation of some test cases]),
|
||||
[case ${enableval} in
|
||||
yes) ENABLE_INSTALLED_TESTS="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")
|
||||
AC_ARG_ENABLE(always-build-tests,
|
||||
AS_HELP_STRING([--enable-always-build-tests],
|
||||
[Enable always building tests during 'make all']),
|
||||
[case ${enableval} in
|
||||
yes) ENABLE_ALWAYS_BUILD_TESTS="1" ;;
|
||||
no) ENABLE_ALWAYS_BUILD_TESTS="" ;;
|
||||
*) AC_MSG_ERROR([bad value ${enableval} for --enable-always-build-tests]) ;;
|
||||
esac])
|
||||
AM_CONDITIONAL([ENABLE_ALWAYS_BUILD_TESTS], test "$ENABLE_ALWAYS_BUILD_TESTS" = "1")
|
||||
if test "$ENABLE_INSTALLED_TESTS" == "1"; then
|
||||
AC_SUBST(installed_test_metadir, [${datadir}/installed-tests/]AC_PACKAGE_NAME)
|
||||
AC_SUBST(installed_testdir, [${libexecdir}/installed-tests/]AC_PACKAGE_NAME)
|
||||
fi
|
||||
])
|
||||
|
|
@ -0,0 +1,652 @@
|
|||
#! /bin/sh
|
||||
# Copyright (C) 2011-2013 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
scriptversion=2011-12-27.17; # UTC
|
||||
|
||||
# Make unconditional expansion of undefined variables an error. This
|
||||
# helps a lot in preventing typo-related bugs.
|
||||
set -u
|
||||
|
||||
me=tap-driver.sh
|
||||
|
||||
fatal ()
|
||||
{
|
||||
echo "$me: fatal: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
usage_error ()
|
||||
{
|
||||
echo "$me: $*" >&2
|
||||
print_usage >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
print_usage ()
|
||||
{
|
||||
cat <<END
|
||||
Usage:
|
||||
tap-driver.sh --test-name=NAME --log-file=PATH --trs-file=PATH
|
||||
[--expect-failure={yes|no}] [--color-tests={yes|no}]
|
||||
[--enable-hard-errors={yes|no}] [--ignore-exit]
|
||||
[--diagnostic-string=STRING] [--merge|--no-merge]
|
||||
[--comments|--no-comments] [--] TEST-COMMAND
|
||||
The \`--test-name', \`--log-file' and \`--trs-file' options are mandatory.
|
||||
END
|
||||
}
|
||||
|
||||
# TODO: better error handling in option parsing (in particular, ensure
|
||||
# TODO: $log_file, $trs_file and $test_name are defined).
|
||||
test_name= # Used for reporting.
|
||||
log_file= # Where to save the result and output of the test script.
|
||||
trs_file= # Where to save the metadata of the test run.
|
||||
expect_failure=0
|
||||
color_tests=0
|
||||
merge=0
|
||||
ignore_exit=0
|
||||
comments=0
|
||||
diag_string='#'
|
||||
while test $# -gt 0; do
|
||||
case $1 in
|
||||
--help) print_usage; exit $?;;
|
||||
--version) echo "$me $scriptversion"; exit $?;;
|
||||
--test-name) test_name=$2; shift;;
|
||||
--log-file) log_file=$2; shift;;
|
||||
--trs-file) trs_file=$2; shift;;
|
||||
--color-tests) color_tests=$2; shift;;
|
||||
--expect-failure) expect_failure=$2; shift;;
|
||||
--enable-hard-errors) shift;; # No-op.
|
||||
--merge) merge=1;;
|
||||
--no-merge) merge=0;;
|
||||
--ignore-exit) ignore_exit=1;;
|
||||
--comments) comments=1;;
|
||||
--no-comments) comments=0;;
|
||||
--diagnostic-string) diag_string=$2; shift;;
|
||||
--) shift; break;;
|
||||
-*) usage_error "invalid option: '$1'";;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
test $# -gt 0 || usage_error "missing test command"
|
||||
|
||||
case $expect_failure in
|
||||
yes) expect_failure=1;;
|
||||
*) expect_failure=0;;
|
||||
esac
|
||||
|
||||
if test $color_tests = yes; then
|
||||
init_colors='
|
||||
color_map["red"]="[0;31m" # Red.
|
||||
color_map["grn"]="[0;32m" # Green.
|
||||
color_map["lgn"]="[1;32m" # Light green.
|
||||
color_map["blu"]="[1;34m" # Blue.
|
||||
color_map["mgn"]="[0;35m" # Magenta.
|
||||
color_map["std"]="[m" # No color.
|
||||
color_for_result["ERROR"] = "mgn"
|
||||
color_for_result["PASS"] = "grn"
|
||||
color_for_result["XPASS"] = "red"
|
||||
color_for_result["FAIL"] = "red"
|
||||
color_for_result["XFAIL"] = "lgn"
|
||||
color_for_result["SKIP"] = "blu"'
|
||||
else
|
||||
init_colors=''
|
||||
fi
|
||||
|
||||
# :; is there to work around a bug in bash 3.2 (and earlier) which
|
||||
# does not always set '$?' properly on redirection failure.
|
||||
# See the Autoconf manual for more details.
|
||||
:;{
|
||||
(
|
||||
# Ignore common signals (in this subshell only!), to avoid potential
|
||||
# problems with Korn shells. Some Korn shells are known to propagate
|
||||
# to themselves signals that have killed a child process they were
|
||||
# waiting for; this is done at least for SIGINT (and usually only for
|
||||
# it, in truth). Without the `trap' below, such a behaviour could
|
||||
# cause a premature exit in the current subshell, e.g., in case the
|
||||
# test command it runs gets terminated by a SIGINT. Thus, the awk
|
||||
# script we are piping into would never seen the exit status it
|
||||
# expects on its last input line (which is displayed below by the
|
||||
# last `echo $?' statement), and would thus die reporting an internal
|
||||
# error.
|
||||
# For more information, see the Autoconf manual and the threads:
|
||||
# <http://lists.gnu.org/archive/html/bug-autoconf/2011-09/msg00004.html>
|
||||
# <http://mail.opensolaris.org/pipermail/ksh93-integration-discuss/2009-February/004121.html>
|
||||
trap : 1 3 2 13 15
|
||||
if test $merge -gt 0; then
|
||||
exec 2>&1
|
||||
else
|
||||
exec 2>&3
|
||||
fi
|
||||
"$@"
|
||||
echo $?
|
||||
) | LC_ALL=C ${AM_TAP_AWK-awk} \
|
||||
-v me="$me" \
|
||||
-v test_script_name="$test_name" \
|
||||
-v log_file="$log_file" \
|
||||
-v trs_file="$trs_file" \
|
||||
-v expect_failure="$expect_failure" \
|
||||
-v merge="$merge" \
|
||||
-v ignore_exit="$ignore_exit" \
|
||||
-v comments="$comments" \
|
||||
-v diag_string="$diag_string" \
|
||||
'
|
||||
# FIXME: the usages of "cat >&3" below could be optimized when using
|
||||
# FIXME: GNU awk, and/on on systems that supports /dev/fd/.
|
||||
|
||||
# Implementation note: in what follows, `result_obj` will be an
|
||||
# associative array that (partly) simulates a TAP result object
|
||||
# from the `TAP::Parser` perl module.
|
||||
|
||||
## ----------- ##
|
||||
## FUNCTIONS ##
|
||||
## ----------- ##
|
||||
|
||||
function fatal(msg)
|
||||
{
|
||||
print me ": " msg | "cat >&2"
|
||||
exit 1
|
||||
}
|
||||
|
||||
function abort(where)
|
||||
{
|
||||
fatal("internal error " where)
|
||||
}
|
||||
|
||||
# Convert a boolean to a "yes"/"no" string.
|
||||
function yn(bool)
|
||||
{
|
||||
return bool ? "yes" : "no";
|
||||
}
|
||||
|
||||
function add_test_result(result)
|
||||
{
|
||||
if (!test_results_index)
|
||||
test_results_index = 0
|
||||
test_results_list[test_results_index] = result
|
||||
test_results_index += 1
|
||||
test_results_seen[result] = 1;
|
||||
}
|
||||
|
||||
# Whether the test script should be re-run by "make recheck".
|
||||
function must_recheck()
|
||||
{
|
||||
for (k in test_results_seen)
|
||||
if (k != "XFAIL" && k != "PASS" && k != "SKIP")
|
||||
return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
# Whether the content of the log file associated to this test should
|
||||
# be copied into the "global" test-suite.log.
|
||||
function copy_in_global_log()
|
||||
{
|
||||
for (k in test_results_seen)
|
||||
if (k != "PASS")
|
||||
return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
# FIXME: this can certainly be improved ...
|
||||
function get_global_test_result()
|
||||
{
|
||||
if ("ERROR" in test_results_seen)
|
||||
return "ERROR"
|
||||
if ("FAIL" in test_results_seen || "XPASS" in test_results_seen)
|
||||
return "FAIL"
|
||||
all_skipped = 1
|
||||
for (k in test_results_seen)
|
||||
if (k != "SKIP")
|
||||
all_skipped = 0
|
||||
if (all_skipped)
|
||||
return "SKIP"
|
||||
return "PASS";
|
||||
}
|
||||
|
||||
function stringify_result_obj(result_obj)
|
||||
{
|
||||
if (result_obj["is_unplanned"] || result_obj["number"] != testno)
|
||||
return "ERROR"
|
||||
|
||||
if (plan_seen == LATE_PLAN)
|
||||
return "ERROR"
|
||||
|
||||
if (result_obj["directive"] == "TODO")
|
||||
return result_obj["is_ok"] ? "XPASS" : "XFAIL"
|
||||
|
||||
if (result_obj["directive"] == "SKIP")
|
||||
return result_obj["is_ok"] ? "SKIP" : COOKED_FAIL;
|
||||
|
||||
if (length(result_obj["directive"]))
|
||||
abort("in function stringify_result_obj()")
|
||||
|
||||
return result_obj["is_ok"] ? COOKED_PASS : COOKED_FAIL
|
||||
}
|
||||
|
||||
function decorate_result(result)
|
||||
{
|
||||
color_name = color_for_result[result]
|
||||
if (color_name)
|
||||
return color_map[color_name] "" result "" color_map["std"]
|
||||
# If we are not using colorized output, or if we do not know how
|
||||
# to colorize the given result, we should return it unchanged.
|
||||
return result
|
||||
}
|
||||
|
||||
function report(result, details)
|
||||
{
|
||||
if (result ~ /^(X?(PASS|FAIL)|SKIP|ERROR)/)
|
||||
{
|
||||
msg = ": " test_script_name
|
||||
add_test_result(result)
|
||||
}
|
||||
else if (result == "#")
|
||||
{
|
||||
msg = " " test_script_name ":"
|
||||
}
|
||||
else
|
||||
{
|
||||
abort("in function report()")
|
||||
}
|
||||
if (length(details))
|
||||
msg = msg " " details
|
||||
# Output on console might be colorized.
|
||||
print decorate_result(result) msg
|
||||
# Log the result in the log file too, to help debugging (this is
|
||||
# especially true when said result is a TAP error or "Bail out!").
|
||||
print result msg | "cat >&3";
|
||||
}
|
||||
|
||||
function testsuite_error(error_message)
|
||||
{
|
||||
report("ERROR", "- " error_message)
|
||||
}
|
||||
|
||||
function handle_tap_result()
|
||||
{
|
||||
details = result_obj["number"];
|
||||
if (length(result_obj["description"]))
|
||||
details = details " " result_obj["description"]
|
||||
|
||||
if (plan_seen == LATE_PLAN)
|
||||
{
|
||||
details = details " # AFTER LATE PLAN";
|
||||
}
|
||||
else if (result_obj["is_unplanned"])
|
||||
{
|
||||
details = details " # UNPLANNED";
|
||||
}
|
||||
else if (result_obj["number"] != testno)
|
||||
{
|
||||
details = sprintf("%s # OUT-OF-ORDER (expecting %d)",
|
||||
details, testno);
|
||||
}
|
||||
else if (result_obj["directive"])
|
||||
{
|
||||
details = details " # " result_obj["directive"];
|
||||
if (length(result_obj["explanation"]))
|
||||
details = details " " result_obj["explanation"]
|
||||
}
|
||||
|
||||
report(stringify_result_obj(result_obj), details)
|
||||
}
|
||||
|
||||
# `skip_reason` should be empty whenever planned > 0.
|
||||
function handle_tap_plan(planned, skip_reason)
|
||||
{
|
||||
planned += 0 # Avoid getting confused if, say, `planned` is "00"
|
||||
if (length(skip_reason) && planned > 0)
|
||||
abort("in function handle_tap_plan()")
|
||||
if (plan_seen)
|
||||
{
|
||||
# Error, only one plan per stream is acceptable.
|
||||
testsuite_error("multiple test plans")
|
||||
return;
|
||||
}
|
||||
planned_tests = planned
|
||||
# The TAP plan can come before or after *all* the TAP results; we speak
|
||||
# respectively of an "early" or a "late" plan. If we see the plan line
|
||||
# after at least one TAP result has been seen, assume we have a late
|
||||
# plan; in this case, any further test result seen after the plan will
|
||||
# be flagged as an error.
|
||||
plan_seen = (testno >= 1 ? LATE_PLAN : EARLY_PLAN)
|
||||
# If testno > 0, we have an error ("too many tests run") that will be
|
||||
# automatically dealt with later, so do not worry about it here. If
|
||||
# $plan_seen is true, we have an error due to a repeated plan, and that
|
||||
# has already been dealt with above. Otherwise, we have a valid "plan
|
||||
# with SKIP" specification, and should report it as a particular kind
|
||||
# of SKIP result.
|
||||
if (planned == 0 && testno == 0)
|
||||
{
|
||||
if (length(skip_reason))
|
||||
skip_reason = "- " skip_reason;
|
||||
report("SKIP", skip_reason);
|
||||
}
|
||||
}
|
||||
|
||||
function extract_tap_comment(line)
|
||||
{
|
||||
if (index(line, diag_string) == 1)
|
||||
{
|
||||
# Strip leading `diag_string` from `line`.
|
||||
line = substr(line, length(diag_string) + 1)
|
||||
# And strip any leading and trailing whitespace left.
|
||||
sub("^[ \t]*", "", line)
|
||||
sub("[ \t]*$", "", line)
|
||||
# Return what is left (if any).
|
||||
return line;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
# When this function is called, we know that line is a TAP result line,
|
||||
# so that it matches the (perl) RE "^(not )?ok\b".
|
||||
function setup_result_obj(line)
|
||||
{
|
||||
# Get the result, and remove it from the line.
|
||||
result_obj["is_ok"] = (substr(line, 1, 2) == "ok" ? 1 : 0)
|
||||
sub("^(not )?ok[ \t]*", "", line)
|
||||
|
||||
# If the result has an explicit number, get it and strip it; otherwise,
|
||||
# automatically assing the next progresive number to it.
|
||||
if (line ~ /^[0-9]+$/ || line ~ /^[0-9]+[^a-zA-Z0-9_]/)
|
||||
{
|
||||
match(line, "^[0-9]+")
|
||||
# The final `+ 0` is to normalize numbers with leading zeros.
|
||||
result_obj["number"] = substr(line, 1, RLENGTH) + 0
|
||||
line = substr(line, RLENGTH + 1)
|
||||
}
|
||||
else
|
||||
{
|
||||
result_obj["number"] = testno
|
||||
}
|
||||
|
||||
if (plan_seen == LATE_PLAN)
|
||||
# No further test results are acceptable after a "late" TAP plan
|
||||
# has been seen.
|
||||
result_obj["is_unplanned"] = 1
|
||||
else if (plan_seen && testno > planned_tests)
|
||||
result_obj["is_unplanned"] = 1
|
||||
else
|
||||
result_obj["is_unplanned"] = 0
|
||||
|
||||
# Strip trailing and leading whitespace.
|
||||
sub("^[ \t]*", "", line)
|
||||
sub("[ \t]*$", "", line)
|
||||
|
||||
# This will have to be corrected if we have a "TODO"/"SKIP" directive.
|
||||
result_obj["description"] = line
|
||||
result_obj["directive"] = ""
|
||||
result_obj["explanation"] = ""
|
||||
|
||||
if (index(line, "#") == 0)
|
||||
return # No possible directive, nothing more to do.
|
||||
|
||||
# Directives are case-insensitive.
|
||||
rx = "[ \t]*#[ \t]*([tT][oO][dD][oO]|[sS][kK][iI][pP])[ \t]*"
|
||||
|
||||
# See whether we have the directive, and if yes, where.
|
||||
pos = match(line, rx "$")
|
||||
if (!pos)
|
||||
pos = match(line, rx "[^a-zA-Z0-9_]")
|
||||
|
||||
# If there was no TAP directive, we have nothing more to do.
|
||||
if (!pos)
|
||||
return
|
||||
|
||||
# Let`s now see if the TAP directive has been escaped. For example:
|
||||
# escaped: ok \# SKIP
|
||||
# not escaped: ok \\# SKIP
|
||||
# escaped: ok \\\\\# SKIP
|
||||
# not escaped: ok \ # SKIP
|
||||
if (substr(line, pos, 1) == "#")
|
||||
{
|
||||
bslash_count = 0
|
||||
for (i = pos; i > 1 && substr(line, i - 1, 1) == "\\"; i--)
|
||||
bslash_count += 1
|
||||
if (bslash_count % 2)
|
||||
return # Directive was escaped.
|
||||
}
|
||||
|
||||
# Strip the directive and its explanation (if any) from the test
|
||||
# description.
|
||||
result_obj["description"] = substr(line, 1, pos - 1)
|
||||
# Now remove the test description from the line, that has been dealt
|
||||
# with already.
|
||||
line = substr(line, pos)
|
||||
# Strip the directive, and save its value (normalized to upper case).
|
||||
sub("^[ \t]*#[ \t]*", "", line)
|
||||
result_obj["directive"] = toupper(substr(line, 1, 4))
|
||||
line = substr(line, 5)
|
||||
# Now get the explanation for the directive (if any), with leading
|
||||
# and trailing whitespace removed.
|
||||
sub("^[ \t]*", "", line)
|
||||
sub("[ \t]*$", "", line)
|
||||
result_obj["explanation"] = line
|
||||
}
|
||||
|
||||
function get_test_exit_message(status)
|
||||
{
|
||||
if (status == 0)
|
||||
return ""
|
||||
if (status !~ /^[1-9][0-9]*$/)
|
||||
abort("getting exit status")
|
||||
if (status < 127)
|
||||
exit_details = ""
|
||||
else if (status == 127)
|
||||
exit_details = " (command not found?)"
|
||||
else if (status >= 128 && status <= 255)
|
||||
exit_details = sprintf(" (terminated by signal %d?)", status - 128)
|
||||
else if (status > 256 && status <= 384)
|
||||
# We used to report an "abnormal termination" here, but some Korn
|
||||
# shells, when a child process die due to signal number n, can leave
|
||||
# in $? an exit status of 256+n instead of the more standard 128+n.
|
||||
# Apparently, both behaviours are allowed by POSIX (2008), so be
|
||||
# prepared to handle them both. See also Austing Group report ID
|
||||
# 0000051 <http://www.austingroupbugs.net/view.php?id=51>
|
||||
exit_details = sprintf(" (terminated by signal %d?)", status - 256)
|
||||
else
|
||||
# Never seen in practice.
|
||||
exit_details = " (abnormal termination)"
|
||||
return sprintf("exited with status %d%s", status, exit_details)
|
||||
}
|
||||
|
||||
function write_test_results()
|
||||
{
|
||||
print ":global-test-result: " get_global_test_result() > trs_file
|
||||
print ":recheck: " yn(must_recheck()) > trs_file
|
||||
print ":copy-in-global-log: " yn(copy_in_global_log()) > trs_file
|
||||
for (i = 0; i < test_results_index; i += 1)
|
||||
print ":test-result: " test_results_list[i] > trs_file
|
||||
close(trs_file);
|
||||
}
|
||||
|
||||
BEGIN {
|
||||
|
||||
## ------- ##
|
||||
## SETUP ##
|
||||
## ------- ##
|
||||
|
||||
'"$init_colors"'
|
||||
|
||||
# Properly initialized once the TAP plan is seen.
|
||||
planned_tests = 0
|
||||
|
||||
COOKED_PASS = expect_failure ? "XPASS": "PASS";
|
||||
COOKED_FAIL = expect_failure ? "XFAIL": "FAIL";
|
||||
|
||||
# Enumeration-like constants to remember which kind of plan (if any)
|
||||
# has been seen. It is important that NO_PLAN evaluates "false" as
|
||||
# a boolean.
|
||||
NO_PLAN = 0
|
||||
EARLY_PLAN = 1
|
||||
LATE_PLAN = 2
|
||||
|
||||
testno = 0 # Number of test results seen so far.
|
||||
bailed_out = 0 # Whether a "Bail out!" directive has been seen.
|
||||
|
||||
# Whether the TAP plan has been seen or not, and if yes, which kind
|
||||
# it is ("early" is seen before any test result, "late" otherwise).
|
||||
plan_seen = NO_PLAN
|
||||
|
||||
## --------- ##
|
||||
## PARSING ##
|
||||
## --------- ##
|
||||
|
||||
is_first_read = 1
|
||||
|
||||
while (1)
|
||||
{
|
||||
# Involutions required so that we are able to read the exit status
|
||||
# from the last input line.
|
||||
st = getline
|
||||
if (st < 0) # I/O error.
|
||||
fatal("I/O error while reading from input stream")
|
||||
else if (st == 0) # End-of-input
|
||||
{
|
||||
if (is_first_read)
|
||||
abort("in input loop: only one input line")
|
||||
break
|
||||
}
|
||||
if (is_first_read)
|
||||
{
|
||||
is_first_read = 0
|
||||
nextline = $0
|
||||
continue
|
||||
}
|
||||
else
|
||||
{
|
||||
curline = nextline
|
||||
nextline = $0
|
||||
$0 = curline
|
||||
}
|
||||
# Copy any input line verbatim into the log file.
|
||||
print | "cat >&3"
|
||||
# Parsing of TAP input should stop after a "Bail out!" directive.
|
||||
if (bailed_out)
|
||||
continue
|
||||
|
||||
# TAP test result.
|
||||
if ($0 ~ /^(not )?ok$/ || $0 ~ /^(not )?ok[^a-zA-Z0-9_]/)
|
||||
{
|
||||
testno += 1
|
||||
setup_result_obj($0)
|
||||
handle_tap_result()
|
||||
}
|
||||
# TAP plan (normal or "SKIP" without explanation).
|
||||
else if ($0 ~ /^1\.\.[0-9]+[ \t]*$/)
|
||||
{
|
||||
# The next two lines will put the number of planned tests in $0.
|
||||
sub("^1\\.\\.", "")
|
||||
sub("[^0-9]*$", "")
|
||||
handle_tap_plan($0, "")
|
||||
continue
|
||||
}
|
||||
# TAP "SKIP" plan, with an explanation.
|
||||
else if ($0 ~ /^1\.\.0+[ \t]*#/)
|
||||
{
|
||||
# The next lines will put the skip explanation in $0, stripping
|
||||
# any leading and trailing whitespace. This is a little more
|
||||
# tricky in truth, since we want to also strip a potential leading
|
||||
# "SKIP" string from the message.
|
||||
sub("^[^#]*#[ \t]*(SKIP[: \t][ \t]*)?", "")
|
||||
sub("[ \t]*$", "");
|
||||
handle_tap_plan(0, $0)
|
||||
}
|
||||
# "Bail out!" magic.
|
||||
# Older versions of prove and TAP::Harness (e.g., 3.17) did not
|
||||
# recognize a "Bail out!" directive when preceded by leading
|
||||
# whitespace, but more modern versions (e.g., 3.23) do. So we
|
||||
# emulate the latter, "more modern" behaviour.
|
||||
else if ($0 ~ /^[ \t]*Bail out!/)
|
||||
{
|
||||
bailed_out = 1
|
||||
# Get the bailout message (if any), with leading and trailing
|
||||
# whitespace stripped. The message remains stored in `$0`.
|
||||
sub("^[ \t]*Bail out![ \t]*", "");
|
||||
sub("[ \t]*$", "");
|
||||
# Format the error message for the
|
||||
bailout_message = "Bail out!"
|
||||
if (length($0))
|
||||
bailout_message = bailout_message " " $0
|
||||
testsuite_error(bailout_message)
|
||||
}
|
||||
# Maybe we have too look for dianogtic comments too.
|
||||
else if (comments != 0)
|
||||
{
|
||||
comment = extract_tap_comment($0);
|
||||
if (length(comment))
|
||||
report("#", comment);
|
||||
}
|
||||
}
|
||||
|
||||
## -------- ##
|
||||
## FINISH ##
|
||||
## -------- ##
|
||||
|
||||
# A "Bail out!" directive should cause us to ignore any following TAP
|
||||
# error, as well as a non-zero exit status from the TAP producer.
|
||||
if (!bailed_out)
|
||||
{
|
||||
if (!plan_seen)
|
||||
{
|
||||
testsuite_error("missing test plan")
|
||||
}
|
||||
else if (planned_tests != testno)
|
||||
{
|
||||
bad_amount = testno > planned_tests ? "many" : "few"
|
||||
testsuite_error(sprintf("too %s tests run (expected %d, got %d)",
|
||||
bad_amount, planned_tests, testno))
|
||||
}
|
||||
if (!ignore_exit)
|
||||
{
|
||||
# Fetch exit status from the last line.
|
||||
exit_message = get_test_exit_message(nextline)
|
||||
if (exit_message)
|
||||
testsuite_error(exit_message)
|
||||
}
|
||||
}
|
||||
|
||||
write_test_results()
|
||||
|
||||
exit 0
|
||||
|
||||
} # End of "BEGIN" block.
|
||||
'
|
||||
|
||||
# TODO: document that we consume the file descriptor 3 :-(
|
||||
} 3>"$log_file"
|
||||
|
||||
test $? -eq 0 || fatal "I/O or internal error"
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#! /bin/bash
|
||||
#
|
||||
# Run a test in tap mode, ensuring we have a temporary directory. We
|
||||
# always use /var/tmp becuase we might want to use user xattrs, which
|
||||
# aren't available on tmpfs.
|
||||
#
|
||||
# The test binary is passed as $1
|
||||
|
||||
srcd=$(cd $(dirname $1) && pwd)
|
||||
bn=$(basename $1)
|
||||
tempdir=$(mktemp -d /var/tmp/tap-test.XXXXXX)
|
||||
touch ${tempdir}/.testtmp
|
||||
function cleanup () {
|
||||
if test -n "${TEST_SKIP_CLEANUP:-}"; then
|
||||
echo "Skipping cleanup of ${tempdir}"
|
||||
else if test -f ${tempdir}/.test; then
|
||||
rm "${tempdir}" -rf
|
||||
fi
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
cd ${tempdir}
|
||||
${srcd}/${bn} -k --tap
|
||||
4
cfg.mk
4
cfg.mk
|
|
@ -1,4 +1,4 @@
|
|||
export VC_LIST_EXCEPT_DEFAULT=^(lib/.*|m4/.*|md5/.*|build-aux/.*|src/gettext\.h|.*ChangeLog)$$
|
||||
export VC_LIST_EXCEPT_DEFAULT=^(lib/.*|m4/.*|md5/.*|build-aux/.*|src/gettext\.h|.*ChangeLog|buildutil/.*)$$
|
||||
|
||||
local-checks-to-skip = \
|
||||
sc_const_long_option \
|
||||
|
|
@ -27,4 +27,4 @@ local-checks-to-skip = \
|
|||
show-vc-list-except:
|
||||
@$(VC_LIST_EXCEPT)
|
||||
|
||||
VC_LIST_ALWAYS_EXCLUDE_REGEX = ^ABOUT-NLS|maint.mk|*.gpg|*.sig$$
|
||||
VC_LIST_ALWAYS_EXCLUDE_REGEX = ^ABOUT-NLS|maint.mk|*.gpg|*.sig|.xz$$
|
||||
|
|
|
|||
38
configure.ac
38
configure.ac
|
|
@ -1,11 +1,11 @@
|
|||
AC_PREREQ([2.63])
|
||||
AC_INIT([ostree], [2016.3], [walters@verbum.org])
|
||||
AC_INIT([ostree], [2016.4], [walters@verbum.org])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_MACRO_DIR([buildutil])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
|
||||
AM_INIT_AUTOMAKE([1.13 -Wno-portability foreign no-define tar-ustar no-dist-gzip dist-xz
|
||||
color-tests parallel-tests subdir-objects])
|
||||
color-tests subdir-objects])
|
||||
AM_MAINTAINER_MODE([enable])
|
||||
AM_SILENT_RULES([yes])
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
|
@ -34,11 +34,7 @@ LT_INIT([disable-static])
|
|||
OSTREE_FEATURES=""
|
||||
AC_SUBST([OSTREE_FEATURES])
|
||||
|
||||
AC_ARG_ENABLE(installed_tests,
|
||||
AS_HELP_STRING([--enable-installed-tests],
|
||||
[Install test programs (default: no)]),,
|
||||
[enable_installed_tests=no])
|
||||
AM_CONDITIONAL(BUILDOPT_INSTALL_TESTS, test x$enable_installed_tests = xyes)
|
||||
GLIB_TESTS
|
||||
|
||||
AC_CHECK_HEADER([sys/xattr.h],,[AC_MSG_ERROR([You must have sys/xattr.h from glibc])])
|
||||
|
||||
|
|
@ -196,6 +192,31 @@ AS_IF([ test x$with_selinux != xno ], [
|
|||
if test x$with_selinux != xno; then OSTREE_FEATURES="$OSTREE_FEATURES +selinux"; fi
|
||||
AM_CONDITIONAL(USE_SELINUX, test $with_selinux != no)
|
||||
|
||||
dnl This is what is in RHEL7.2 right now, picking it arbitrarily
|
||||
LIBMOUNT_DEPENDENCY="mount >= 2.23.0"
|
||||
|
||||
AC_ARG_WITH(libmount,
|
||||
AS_HELP_STRING([--without-libmount], [Do not use libmount]),
|
||||
:, with_libmount=maybe)
|
||||
|
||||
AS_IF([ test x$with_libmount != xno ], [
|
||||
AC_MSG_CHECKING([for $LIBMOUNT_DEPENDENCY])
|
||||
PKG_CHECK_EXISTS($LIBMOUNT_DEPENDENCY, have_libmount=yes, have_libmount=no)
|
||||
AC_MSG_RESULT([$have_libmount])
|
||||
AS_IF([ test x$have_libmount = xno && test x$with_libmount != xmaybe ], [
|
||||
AC_MSG_ERROR([libmount is enabled but could not be found])
|
||||
])
|
||||
AS_IF([ test x$have_libmount = xyes], [
|
||||
AC_DEFINE([HAVE_LIBMOUNT], 1, [Define if we have libmount.pc])
|
||||
PKG_CHECK_MODULES(OT_DEP_LIBMOUNT, $LIBMOUNT_DEPENDENCY)
|
||||
with_libmount=yes
|
||||
], [
|
||||
with_libmount=no
|
||||
])
|
||||
], [ with_libmount=no ])
|
||||
if test x$with_libmount != xno; then OSTREE_FEATURES="$OSTREE_FEATURES +libmount"; fi
|
||||
AM_CONDITIONAL(USE_LIBMOUNT, test $with_libmount != no)
|
||||
|
||||
# Enabled by default because I think people should use it.
|
||||
AC_ARG_ENABLE(rofiles-fuse,
|
||||
[AS_HELP_STRING([--enable-rofiles-fuse],
|
||||
|
|
@ -264,6 +285,7 @@ echo "
|
|||
libsoup (retrieve remote HTTP repositories): $with_soup
|
||||
libsoup TLS client certs: $have_libsoup_client_certs
|
||||
SELinux: $with_selinux
|
||||
libmount: $with_libmount
|
||||
libarchive (parse tar files directly): $with_libarchive
|
||||
static deltas: yes (always enabled now)
|
||||
man pages (xsltproc): $enable_man
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
Portions of this code are derived from:
|
||||
|
||||
https://github.com/dradtke/gotk3
|
||||
|
||||
Copyright (c) 2013 Conformal Systems LLC.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
This file contains demonstration FFI bindings for using `-lostree-1`
|
||||
and `-larchive` from golang.
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Conformal Systems <info@conformal.com>
|
||||
*
|
||||
* This file originated from: http://opensource.conformal.com/
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package ostree
|
||||
|
||||
// #cgo pkg-config: glib-2.0 gobject-2.0
|
||||
// #include <glib.h>
|
||||
// #include <glib-object.h>
|
||||
// #include <gio/gio.h>
|
||||
// #include "glibobject.go.h"
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
"runtime"
|
||||
"fmt"
|
||||
"errors"
|
||||
)
|
||||
|
||||
func GBool(b bool) C.gboolean {
|
||||
if b {
|
||||
return C.gboolean(1)
|
||||
}
|
||||
return C.gboolean(0)
|
||||
}
|
||||
|
||||
func GoBool(b C.gboolean) bool {
|
||||
if b != 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type GError struct {
|
||||
ptr unsafe.Pointer
|
||||
}
|
||||
|
||||
func NewGError() GError {
|
||||
return GError{nil}
|
||||
}
|
||||
|
||||
func (e *GError) Native() *C.GError {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
return (*C.GError)(e.ptr)
|
||||
}
|
||||
|
||||
func ConvertGError(e *C.GError) error {
|
||||
defer C.g_error_free(e)
|
||||
return errors.New(C.GoString((*C.char)(C._g_error_get_message(e))))
|
||||
}
|
||||
|
||||
type GType uint
|
||||
|
||||
func (t GType) Name() string {
|
||||
return C.GoString((*C.char)(C.g_type_name(C.GType(t))))
|
||||
}
|
||||
|
||||
type GVariant struct {
|
||||
ptr unsafe.Pointer
|
||||
}
|
||||
|
||||
func GVariantNew(p unsafe.Pointer) *GVariant {
|
||||
o := &GVariant{p}
|
||||
runtime.SetFinalizer(o, (*GVariant).Unref)
|
||||
return o;
|
||||
}
|
||||
|
||||
func GVariantNewSink(p unsafe.Pointer) *GVariant {
|
||||
o := &GVariant{p}
|
||||
runtime.SetFinalizer(o, (*GVariant).Unref)
|
||||
o.RefSink()
|
||||
return o;
|
||||
}
|
||||
|
||||
func (v *GVariant) native() *C.GVariant {
|
||||
return (*C.GVariant)(v.ptr);
|
||||
}
|
||||
|
||||
func (v *GVariant) Ref() {
|
||||
C.g_variant_ref(v.native())
|
||||
}
|
||||
|
||||
func (v *GVariant) Unref() {
|
||||
C.g_variant_unref(v.native())
|
||||
}
|
||||
|
||||
func (v *GVariant) RefSink() {
|
||||
C.g_variant_ref_sink(v.native())
|
||||
}
|
||||
|
||||
func (v *GVariant) TypeString() string {
|
||||
cs := (*C.char)(C.g_variant_get_type_string(v.native()))
|
||||
return C.GoString(cs)
|
||||
}
|
||||
|
||||
func (v *GVariant) GetChildValue(i int) *GVariant {
|
||||
cchild := C.g_variant_get_child_value(v.native(), C.gsize(i))
|
||||
return GVariantNew(unsafe.Pointer(cchild));
|
||||
}
|
||||
|
||||
func (v *GVariant) LookupString(key string) (string, error) {
|
||||
ckey := C.CString(key)
|
||||
defer C.free(unsafe.Pointer(ckey))
|
||||
// TODO: Find a way to have constant C strings in golang
|
||||
cstr := C._g_variant_lookup_string(v.native(), ckey)
|
||||
if cstr == nil {
|
||||
return "", fmt.Errorf("No such key: %s", key)
|
||||
}
|
||||
return C.GoString(cstr), nil
|
||||
}
|
||||
|
||||
/*
|
||||
* GObject
|
||||
*/
|
||||
|
||||
// IObject is an interface type implemented by Object and all types which embed
|
||||
// an Object. It is meant to be used as a type for function arguments which
|
||||
// require GObjects or any subclasses thereof.
|
||||
type IObject interface {
|
||||
toGObject() *C.GObject
|
||||
ToObject() *GObject
|
||||
}
|
||||
|
||||
// Object is a representation of GLib's GObject.
|
||||
type GObject struct {
|
||||
ptr unsafe.Pointer
|
||||
}
|
||||
|
||||
func GObjectNew(p unsafe.Pointer) *GObject {
|
||||
o := &GObject{p}
|
||||
runtime.SetFinalizer(o, (*GObject).Unref)
|
||||
return o;
|
||||
}
|
||||
|
||||
func (v *GObject) Ptr() unsafe.Pointer {
|
||||
return v.ptr
|
||||
}
|
||||
|
||||
func (v *GObject) Native() *C.GObject {
|
||||
if v == nil || v.ptr == nil {
|
||||
return nil
|
||||
}
|
||||
return (*C.GObject)(v.ptr)
|
||||
}
|
||||
|
||||
func (v *GObject) toGObject() *C.GObject {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
return v.Native()
|
||||
}
|
||||
|
||||
func (v *GObject) Ref() {
|
||||
C.g_object_ref(C.gpointer(v.ptr))
|
||||
}
|
||||
|
||||
func (v *GObject) Unref() {
|
||||
C.g_object_unref(C.gpointer(v.ptr))
|
||||
}
|
||||
|
||||
func (v *GObject) RefSink() {
|
||||
C.g_object_ref_sink(C.gpointer(v.ptr))
|
||||
}
|
||||
|
||||
func (v *GObject) IsFloating() bool {
|
||||
c := C.g_object_is_floating(C.gpointer(v.ptr))
|
||||
return GoBool(c)
|
||||
}
|
||||
|
||||
func (v *GObject) ForceFloating() {
|
||||
C.g_object_force_floating((*C.GObject)(v.ptr))
|
||||
}
|
||||
|
||||
// GIO types
|
||||
|
||||
type GCancellable struct {
|
||||
*GObject
|
||||
}
|
||||
|
||||
func (self *GCancellable) native() *C.GCancellable {
|
||||
return (*C.GCancellable)(self.ptr)
|
||||
}
|
||||
|
||||
// At the moment, no cancellable API, just pass nil
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#include <glib.h>
|
||||
|
||||
static char *
|
||||
_g_error_get_message (GError *error)
|
||||
{
|
||||
g_assert (error != NULL);
|
||||
return error->message;
|
||||
}
|
||||
|
||||
static const char *
|
||||
_g_variant_lookup_string (GVariant *v, const char *key)
|
||||
{
|
||||
const char *r;
|
||||
if (g_variant_lookup (v, key, "&s", &r))
|
||||
return r;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
// +build linux
|
||||
|
||||
// Public API specification for libostree Go bindings
|
||||
|
||||
package ostree
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #cgo pkg-config: ostree-1
|
||||
// #include <stdlib.h>
|
||||
// #include <glib.h>
|
||||
// #include <ostree.h>
|
||||
// #include "ostree.go.h"
|
||||
import "C"
|
||||
|
||||
type Repo struct {
|
||||
*GObject
|
||||
}
|
||||
|
||||
func RepoGetType() GType {
|
||||
return GType(C.ostree_repo_get_type())
|
||||
}
|
||||
|
||||
func (r *Repo) native() *C.OstreeRepo {
|
||||
return (*C.OstreeRepo)(r.ptr)
|
||||
}
|
||||
|
||||
func repoFromNative(p *C.OstreeRepo) *Repo {
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
o := GObjectNew(unsafe.Pointer(p))
|
||||
r := &Repo{o}
|
||||
return r
|
||||
}
|
||||
|
||||
func RepoNewOpen(path string) (*Repo, error) {
|
||||
var cerr *C.GError = nil
|
||||
cpath := C.CString(path)
|
||||
pathc := C.g_file_new_for_path(cpath);
|
||||
defer C.g_object_unref(C.gpointer(pathc))
|
||||
crepo := C.ostree_repo_new(pathc)
|
||||
repo := repoFromNative(crepo);
|
||||
r := GoBool(C.ostree_repo_open(repo.native(), nil, &cerr))
|
||||
if !r {
|
||||
return nil, ConvertGError(cerr)
|
||||
}
|
||||
return repo, nil
|
||||
}
|
||||
|
||||
func (r *Repo) GetParent() *Repo {
|
||||
return repoFromNative(C.ostree_repo_get_parent(r.native()))
|
||||
}
|
||||
|
||||
type ObjectType int
|
||||
|
||||
const (
|
||||
OBJECT_TYPE_FILE ObjectType = C.OSTREE_OBJECT_TYPE_FILE
|
||||
OBJECT_TYPE_DIR_TREE = C.OSTREE_OBJECT_TYPE_DIR_TREE
|
||||
OBJECT_TYPE_DIR_META = C.OSTREE_OBJECT_TYPE_DIR_META
|
||||
OBJECT_TYPE_COMMIT = C.OSTREE_OBJECT_TYPE_COMMIT
|
||||
OBJECT_TYPE_TOMBSTONE_COMMIT = C.OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT
|
||||
)
|
||||
|
||||
func (repo *Repo) LoadVariant(t ObjectType, checksum string) (*GVariant, error) {
|
||||
var cerr *C.GError = nil
|
||||
var cvariant *C.GVariant = nil
|
||||
|
||||
r := GoBool(C.ostree_repo_load_variant(repo.native(), C.OstreeObjectType(t), C.CString(checksum), &cvariant, &cerr))
|
||||
if !r {
|
||||
return nil, ConvertGError(cerr)
|
||||
}
|
||||
variant := GVariantNew(unsafe.Pointer(cvariant))
|
||||
return variant, nil
|
||||
}
|
||||
|
||||
func (repo *Repo) ResolveRev(ref string) (string, error) {
|
||||
var cerr *C.GError = nil
|
||||
var crev *C.char = nil
|
||||
|
||||
r := GoBool(C.ostree_repo_resolve_rev(repo.native(), C.CString(ref), GBool(true), &crev, &cerr))
|
||||
if !r {
|
||||
return "", ConvertGError(cerr)
|
||||
}
|
||||
defer C.free(unsafe.Pointer(crev))
|
||||
return C.GoString(crev), nil
|
||||
}
|
||||
|
||||
func (commit *GVariant) CommitGetMetadataKeyString(key string) (string, error) {
|
||||
cmeta := GVariantNew(unsafe.Pointer(C.g_variant_get_child_value(commit.native(), 0)))
|
||||
return cmeta.LookupString(key)
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#include <ostree.h>
|
||||
#include <string.h>
|
||||
|
||||
static void
|
||||
_ostree_repo_checkout_options_init_docker_union (OstreeRepoCheckoutOptions *opts)
|
||||
{
|
||||
memset (opts, 0, sizeof (*opts));
|
||||
opts->mode = OSTREE_REPO_CHECKOUT_MODE_USER;
|
||||
opts->overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES;
|
||||
opts->disable_fsync = 1;
|
||||
opts->process_whiteouts = 1;
|
||||
}
|
||||
|
||||
static const char *
|
||||
_g_variant_lookup_string (GVariant *v, const char *key)
|
||||
{
|
||||
const char *r;
|
||||
if (g_variant_lookup (v, key, "&s", &r))
|
||||
return r;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
// +build linux
|
||||
|
||||
// Public API specification for libostree Go bindings
|
||||
|
||||
package ostree
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTypeName(t *testing.T) {
|
||||
name := RepoGetType().Name();
|
||||
if name != "OstreeRepo" {
|
||||
t.Errorf("%s != OstreeRepo");
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepoNew(t *testing.T) {
|
||||
r, err := RepoNewOpen("/ostree/repo")
|
||||
if err != nil {
|
||||
t.Errorf("%s", err);
|
||||
return
|
||||
}
|
||||
parent := r.GetParent()
|
||||
if parent != nil {
|
||||
t.Errorf("Expected no parent")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepoGetMetadataVersion(t *testing.T) {
|
||||
r, err := RepoNewOpen("/ostree/repo")
|
||||
if err != nil {
|
||||
t.Errorf("%s", err);
|
||||
return
|
||||
}
|
||||
commit,err := r.ResolveRev("rhel-atomic-host/7/x86_64/standard")
|
||||
if err != nil {
|
||||
t.Errorf("%s", err)
|
||||
return
|
||||
}
|
||||
commitv,err := r.LoadVariant(OBJECT_TYPE_COMMIT, commit)
|
||||
if err != nil {
|
||||
t.Errorf("%s", err)
|
||||
return
|
||||
}
|
||||
ver, err := commitv.CommitGetMetadataKeyString("version")
|
||||
if err != nil {
|
||||
t.Errorf("%s", err)
|
||||
return
|
||||
}
|
||||
if ver != "7.1.3" {
|
||||
t.Errorf("expected 7.1.3")
|
||||
}
|
||||
}
|
||||
|
|
@ -3,17 +3,18 @@ Submitting patches
|
|||
|
||||
You can:
|
||||
|
||||
1. Send mail to ostree-list@gnome.org, with the patch attached
|
||||
1. Submit a pull request against https://github.com/GNOME/ostree
|
||||
1. Attach them to https://bugzilla.gnome.org/
|
||||
1. Send mail to <ostree-list@gnome.org>, with the patch attached
|
||||
1. Submit a pull request against <https://github.com/GNOME/ostree>
|
||||
1. Attach them to <https://bugzilla.gnome.org/>
|
||||
|
||||
Please look at "git log" and match the commit log style.
|
||||
Please look at `git log` and match the commit log style.
|
||||
|
||||
Running the test suite
|
||||
----------------------
|
||||
|
||||
Currently, ostree uses https://wiki.gnome.org/GnomeGoals/InstalledTests
|
||||
To run just ostree's tests:
|
||||
Currently, OSTree uses <https://wiki.gnome.org/GnomeGoals/InstalledTests>
|
||||
|
||||
To run just OSTree's tests:
|
||||
|
||||
./configure ... --enable-installed-tests
|
||||
gnome-desktop-testing-runner -p 0 ostree/
|
||||
|
|
@ -47,16 +48,16 @@ This is an example of an "early exit":
|
|||
myfunc (...)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
|
||||
|
||||
/* some code */
|
||||
|
||||
|
||||
/* some more code */
|
||||
|
||||
|
||||
if (condition)
|
||||
return FALSE;
|
||||
|
||||
|
||||
/* some more code */
|
||||
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
|
|
@ -85,14 +86,14 @@ functions, particularly inside loops. For example, rather than:
|
|||
{
|
||||
/* deeply nested code */
|
||||
}
|
||||
|
||||
|
||||
/* more nested code */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Instead do this:
|
||||
|
||||
|
||||
static gboolean
|
||||
helperfunc (..., GError **error)
|
||||
{
|
||||
|
|
@ -100,22 +101,21 @@ Instead do this:
|
|||
{
|
||||
/* deeply nested code */
|
||||
}
|
||||
|
||||
|
||||
/* more nested code */
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
while (condition)
|
||||
{
|
||||
/* some code */
|
||||
if (!condition)
|
||||
continue;
|
||||
|
||||
|
||||
for (i = 0; i < somevalue; i++)
|
||||
{
|
||||
if (!helperfunc (..., i, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ Now, because we are merely installing new packages and not
|
|||
removing anything, we can make the major optimization of reusing
|
||||
our existing filesystem tree, and merely
|
||||
*layering* the composed filesystem tree of
|
||||
these new packages on top. A command like this:
|
||||
these new packages on top. A command like this:
|
||||
|
||||
```
|
||||
ostree commit -b osname/releasename/description
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ exactly one ref, which is stored in the `.origin` file for the
|
|||
deployment. The command `ostree admin upgrade`
|
||||
implements this.
|
||||
|
||||
o begin a simple upgrade, OSTree fetches the contents of the ref from
|
||||
To begin a simple upgrade, OSTree fetches the contents of the ref from
|
||||
the remote server. Suppose we're tracking a ref named
|
||||
`exampleos/buildmaster/x86_64-runtime`. OSTree fetches the URL
|
||||
`http://$example.com/repo/refs/exampleos/buildmaster/x86_64-runtime`,
|
||||
|
|
@ -56,11 +56,10 @@ checking it back out of the repo into a deployment.
|
|||
|
||||
Given a commit to deploy, OSTree first allocates a directory for
|
||||
it. This is of the form `/boot/loader/entries/ostree-$osname-$checksum.$serial.conf`.
|
||||
he $serial is normally 0, but if a
|
||||
The `$serial` is normally 0, but if a
|
||||
given commit is deployed more than once, it will be incremented.
|
||||
his is supported because the previous deployment may have
|
||||
configuration in `/etc`
|
||||
hat we do not want to use or overwrite.
|
||||
configuration in `/etc` that we do not want to use or overwrite.
|
||||
|
||||
Now that we have a deployment directory, a 3-way merge is
|
||||
performed between the (by default) currently booted deployment's
|
||||
|
|
@ -74,7 +73,7 @@ hardlink farm; the running system is untouched, and the bootloader
|
|||
configuration is untouched. We want to add this deployment o the
|
||||
"deployment list".
|
||||
|
||||
To support a more general case, OSTree supports atomic ransitioning
|
||||
To support a more general case, OSTree supports atomic transitioning
|
||||
between arbitrary sets of deployments, with the restriction that the
|
||||
currently booted deployment must always be in the new set. In the
|
||||
normal case, we have exactly one deployment, which is the booted one,
|
||||
|
|
@ -101,7 +100,10 @@ deployment lists. This happens when doing an upgrade that does not
|
|||
include the kernel; think of a simple translation update. OSTree
|
||||
optimizes for this case because on some systems `/boot` may be on a
|
||||
separate medium such as flash storage not optimized for significant
|
||||
amounts of write traffic.
|
||||
amounts of write traffic. Related to this, modern OSTree has support
|
||||
for having `/boot` be a read-only mount by default - it will
|
||||
automatically remount read-write just for the portion of time
|
||||
necessary to update the bootloader configuration.
|
||||
|
||||
To implement this, OSTree also maintains the directory
|
||||
`/ostree/boot.<replaceable>bootversion</replaceable>`, which is a set
|
||||
|
|
|
|||
|
|
@ -0,0 +1,180 @@
|
|||
# Writing a buildsystem and managing repositories
|
||||
|
||||
OSTree is not a package system. It does not directly support building
|
||||
source code. Rather, it is a tool for transporting and managing
|
||||
content, along with package-system independent aspects like bootloader
|
||||
management for updates.
|
||||
|
||||
We'll assume here that we're planning to generate commits on a build
|
||||
server, then have client systems replicate it. Doing client-side
|
||||
assembly is also possible of course, but this discussion will focus
|
||||
primarily on server-side concerns.
|
||||
|
||||
## Build vs buy
|
||||
|
||||
Therefore, you need to either pick an existing tool for writing
|
||||
content into an OSTree repository, or to write your own. An example
|
||||
tool is [rpm-ostree](https://github.com/projectatomic/rpm-ostree) - it
|
||||
takes as input RPMs, and commits them (currently oriented for a server
|
||||
side, but aiming to do client side too).
|
||||
|
||||
## Initializing
|
||||
|
||||
For this initial discussion, we're assuming you have a single
|
||||
`archive-z2` repository:
|
||||
|
||||
```
|
||||
mkdir repo
|
||||
ostree --repo=repo init --mode=archive-z2
|
||||
```
|
||||
|
||||
You can export this via a static webserver, and configure clients to
|
||||
pull from it.
|
||||
|
||||
## Writing your own OSTree buildsystem
|
||||
|
||||
There exist many, many systems that basically follow this pattern:
|
||||
|
||||
```
|
||||
$pkg --installroot=/path/to/tmpdir install foo bar baz
|
||||
$imagesystem commit --root=/path/to/tmpdir
|
||||
```
|
||||
|
||||
For various values of `$pkg` such as `yum`, `apt-get`, etc., and
|
||||
values of `$imagesystem` could be simple tarballs, Amazon Machine
|
||||
Images, ISOs, etc.
|
||||
|
||||
Now obviously in this document, we're going to talk about the
|
||||
situation where `$imagesystem` is OSTree. The general idea with
|
||||
OSTree is that wherever you might store a series of tarballs for
|
||||
applications or OS images, OSTree is likely going to be better. For
|
||||
example, it supports GPG signatures, binary deltas, writing bootloader
|
||||
configuration, etc.
|
||||
|
||||
OSTree does not include a package/component build system simply
|
||||
because there already exist plenty of good ones - rather, it is
|
||||
intended to provide an infrastructure layer.
|
||||
|
||||
The above mentioned `rpm-ostree compose tree` chooses RPM as the value
|
||||
of `$pkg` - so binaries are built as RPMs, then committed as a whole
|
||||
into an OSTree commit.
|
||||
|
||||
But let's discuss building our own. If you're just experimenting,
|
||||
it's quite easy to start with the command line. We'll assume for this
|
||||
purpose that you have a build process that outputs a directory tree -
|
||||
we'll call this tool `$pkginstallroot` (which could be `yum
|
||||
--installroot` or `dbootstrap`, etc.).
|
||||
|
||||
Your initial prototype is going to look like:
|
||||
|
||||
```
|
||||
$pkginstallroot /path/to/tmpdir
|
||||
ostree --repo=repo commit -s 'build' -b exampleos/x86_64/standard --tree=dir=/path/to/tmpdir
|
||||
```
|
||||
|
||||
Alternatively, if your build system can generate a tarball, you can
|
||||
commit that tarball into OSTree. For example,
|
||||
[OpenEmbedded](http://www.openembedded.org/) can output a tarball, and
|
||||
one can commit it via:
|
||||
|
||||
```
|
||||
ostree commit -s 'build' -b exampleos/x86_64/standard --tree=tar=myos.tar
|
||||
```
|
||||
|
||||
## Constructing trees from unions
|
||||
|
||||
The above is a very simplistic model, and you will quickly notice that
|
||||
it's slow. This is because OSTree has to re-checksum and recompress
|
||||
the content each time it's committed. (Most of the CPU time is spent
|
||||
in compression which gets thrown away if the content turns out to be
|
||||
already stored).
|
||||
|
||||
A more advanced approach is to store components in OSTree itself, then
|
||||
union them, and recommit them. At this point, we recommend taking a
|
||||
look at the OSTree API, and choose a programming language supported by
|
||||
[GObject Introspection](https://wiki.gnome.org/Projects/GObjectIntrospection)
|
||||
to write your buildsystem scripts. Python may be a good choice, or
|
||||
you could choose custom C code, etc.
|
||||
|
||||
For the purposes of this tutorial we will use shell script, but it's
|
||||
strongly recommended to choose a real programming language for your
|
||||
build system.
|
||||
|
||||
Let's say that your build system produces separate artifacts (whether
|
||||
those are RPMs, zip files, or whatever). These artifacts should be
|
||||
the result of `make install DESTDIR=` or similar. Basically
|
||||
equivalent to RPMs/debs.
|
||||
|
||||
Further, in order to make things fast, we will need a separate
|
||||
`bare-user` repository in order to perform checkouts quickly via
|
||||
hardlinks. We'll then export content into the `archive-z2` repository
|
||||
for use by client systems.
|
||||
|
||||
```
|
||||
mkdir build-repo
|
||||
ostree --repo=build-repo init --mode=bare-user
|
||||
```
|
||||
|
||||
You can begin committing those as individual branches:
|
||||
|
||||
```
|
||||
ostree --repo=build-repo commit -b exampleos/x86_64/bash --tree=tar=bash-4.2-bin.tar.gz
|
||||
ostree --repo=build-repo commit -b exampleos/x86_64/systemd --tree=tar=systemd-224-bin.tar.gz
|
||||
```
|
||||
|
||||
Set things up so that whenever a package changes, you redo the
|
||||
`commit` with the new package version - conceptually, the branch
|
||||
tracks the individual package versions over time, and defaults to
|
||||
"latest". This isn't required - one could also include the version in
|
||||
the branch name, and have metadata outside to determine "latest" (or
|
||||
the desired version).
|
||||
|
||||
Now, to construct our final tree:
|
||||
|
||||
```
|
||||
rm exampleos-build -rf
|
||||
for package in bash systemd; do
|
||||
ostree --repo=build-repo checkout -U --union exampleos/x86_64/${package} exampleos-build
|
||||
done
|
||||
# Set up a "rofiles-fuse" mount point; this ensures that any processes
|
||||
# we run for post-processing of the tree don't corrupt the hardlinks.
|
||||
mkdir -p mnt
|
||||
rofiles-fuse exampleos-build mnt
|
||||
# Now run global "triggers", generate cache files:
|
||||
ldconfig -r mnt
|
||||
(Insert other programs here)
|
||||
fusermount -u mnt
|
||||
ostree --repo=build-repo commit -b exampleos/x86_64/standard --link-checkout-speedup exampleos-build
|
||||
```
|
||||
|
||||
There are a number of interesting things going on here. The major
|
||||
architectural change is that we're using `--link-checkout-speedup`.
|
||||
This is a way to tell OSTree that our checkout is made via hardlinks,
|
||||
and to scan the repository in order to build up a reverse `(device,
|
||||
inode) -> checksum` mapping.
|
||||
|
||||
In order for this mapping to be accurate, we needed the `rofiles-fuse`
|
||||
to ensure that any changed files had new inodes (and hence a new
|
||||
checksum).
|
||||
|
||||
## Migrating content between repositories
|
||||
|
||||
Now that we have content in our `build-repo` repository (in
|
||||
`bare-user` mode), we need to move the `exampleos/x86_64/standard`
|
||||
branch content into the repository just named `repo` (in `archive-z2`
|
||||
mode) for export, which will involve zlib compression of new objects.
|
||||
We likely want to generate static deltas after that as well.
|
||||
|
||||
Let's copy the content:
|
||||
|
||||
```
|
||||
ostree --repo=repo pull-local build-repo exampleos/x86_64/standard
|
||||
```
|
||||
|
||||
Clients can now incrementally download new objects - however, this
|
||||
would also be a good time to generate a delta from the previous
|
||||
commit.
|
||||
|
||||
```
|
||||
ostree --repo=repo static-delta generate exampleos/x86_64/standard
|
||||
```
|
||||
|
|
@ -13,7 +13,7 @@ OSTree is designed to boot directly into exactly one deployment
|
|||
at a time; each deployment is intended to be a target for
|
||||
`chroot()` or equivalent.
|
||||
|
||||
### "osname": Group of deployments that share /var</title>
|
||||
### "osname": Group of deployments that share /var
|
||||
|
||||
Each deployment is grouped in exactly one "osname". From above, you
|
||||
can see that an osname is physically represented in the
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ or an unprivileged container.
|
|||
|
||||
## Static deltas
|
||||
|
||||
OSTree itself was originally focused on a continous delivery model, where
|
||||
OSTree itself was originally focused on a continuous delivery model, where
|
||||
client systems are expected to update regularly. However, many OS vendors
|
||||
would like to supply content that's updated e.g. once a month or less often.
|
||||
|
||||
|
|
@ -82,7 +82,7 @@ object. Static deltas also support `from NULL`, where the client can
|
|||
more efficiently download a commit object from scratch.
|
||||
|
||||
Effectively, we're spending server-side storage (and one-time compute
|
||||
cost), and gaining efficiency in client network bandwith.
|
||||
cost), and gaining efficiency in client network bandwidth.
|
||||
|
||||
## Static delta repository layout
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ management easier for filesystem tools
|
|||
|
||||
A delta is named `$(mbase64 $from)-$(mbase64 $to)`, for example
|
||||
`GpTyZaVut2jXFPWnO4LJiKEdRTvOw_mFUCtIKW1NIX0-L8f+VVDkEBKNc1Ncd+mDUrSVR4EyybQGCkuKtkDnTwk`,
|
||||
which in sha256 format is
|
||||
which in SHA256 format is
|
||||
`1a94f265a56eb768d714f5a73b82c988a11d453bcec3f985502b48296d4d217d-2fc7fe5550e410128d73535c77e98352b495478132c9b4060a4b8ab640e74f09`.
|
||||
|
||||
Finally, the actual content can be found in
|
||||
|
|
@ -136,7 +136,7 @@ The superblock contains:
|
|||
- delta generation timestamp
|
||||
- the new commit object
|
||||
- An array of recursive deltas to apply
|
||||
- An array of per-part metadata, including total object sizes (compressed and uncompressed),
|
||||
- An array of per-part metadata, including total object sizes (compressed and uncompressed),
|
||||
- An array of fallback objects
|
||||
|
||||
Let's define a delta part, then return to discuss details:
|
||||
|
|
@ -160,14 +160,14 @@ a per-file delta algorithm called
|
|||
[bsdiff](https://github.com/mendsley/bsdiff) that most notably works
|
||||
well on executable code.
|
||||
|
||||
The current delta compiler scans for files with maching basenamesin
|
||||
The current delta compiler scans for files with matching basenames in
|
||||
each commit that have a similar size, and attempts a bsdiff between
|
||||
them. (It would make sense later to have a build system provide a
|
||||
hint for this - for example, files within a same package).
|
||||
|
||||
A generated bsdiff is included in the payload blob, and applying it is
|
||||
an instruction.
|
||||
|
||||
|
||||
## Fallback objects
|
||||
|
||||
It's possible for there to be large-ish files which might be resistant
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# OSTree Overview
|
||||
|
||||
## Introduction
|
||||
## Introduction
|
||||
|
||||
OSTree an upgrade system for Linux-based operating systems that
|
||||
performs atomic upgrades of complete filesystem trees. It is
|
||||
|
|
@ -15,7 +15,7 @@ content-addressed object store, and layered on top of that is
|
|||
bootloader configuration, management of
|
||||
`/etc`, and other functions to perform an
|
||||
upgrade beyond just replicating files.
|
||||
|
||||
|
||||
You can use OSTree standalone in the pure replication model,
|
||||
but another approach is to add a package manager on top,
|
||||
thus creating a hybrid tree/package system.
|
||||
|
|
@ -46,7 +46,7 @@ HTTP, and where the OS includes (if desired) an entirely
|
|||
separate mechanism to install applications, stored in `/var` if they're system global, or
|
||||
`/home` for per-user
|
||||
application installation. An example application mechanism is
|
||||
http://docker.io/
|
||||
<http://docker.io/>
|
||||
|
||||
However, it is entirely possible to use OSTree underneath a
|
||||
package system, where the contents of `/usr` are computed on the client.
|
||||
|
|
@ -79,6 +79,13 @@ filesystem that supports hard links. Note: OSTree will
|
|||
transparently take advantage of some BTRFS features if deployed
|
||||
on it.
|
||||
|
||||
OSTree is orthogonal to virtualization mechanisms like AMIs and qcow2
|
||||
images, though it's most useful though if you plan to update stateful
|
||||
VMs in-place, rather than generating new images.
|
||||
|
||||
In practice, users of "bare metal" configurations will find the OSTree
|
||||
model most useful.
|
||||
|
||||
## Atomic transitions between parallel-installable read-only filesystem trees
|
||||
|
||||
Another deeply fundamental difference between both package
|
||||
|
|
|
|||
|
|
@ -0,0 +1,207 @@
|
|||
# Related Projects
|
||||
|
||||
OSTree is in many ways very evolutionary. It builds on concepts and
|
||||
ideas introduced from many different projects such as
|
||||
[Systemd Stateless](http://0pointer.net/blog/projects/stateless.html),
|
||||
[Systemd Bootloader Spec](https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/),
|
||||
[Chromium Autoupdate](http://dev.chromium.org/chromium-os/chromiumos-design-docs/filesystem-autoupdate),
|
||||
the much older
|
||||
[Fedora/Red Hat Stateless Project](https://fedoraproject.org/wiki/StatelessLinux),
|
||||
[Linux VServer](http://linux-vserver.org/index.php?title=util-vserver:Vhashify&oldid=2285)
|
||||
and many more.
|
||||
|
||||
As mentioned elsewhere, OSTree is strongly influenced by package
|
||||
manager designs as well. This page is not intended to be an
|
||||
exhaustive list of such projects, but we will try to keep it up to
|
||||
date, and relatively agnostic.
|
||||
|
||||
Broadly speaking, projects in this area fall into two camps; either
|
||||
a tool to snapshot systems on the client side (dpkg/rpm + BTRFS/LVM),
|
||||
or a tool to compose on a server and replicate (ChromiumOS, Clear
|
||||
Linux). OSTree is flexible enough to do both.
|
||||
|
||||
## Combining dpkg/rpm + (BTRFS/LVM)
|
||||
|
||||
In this approach, one uses a block/filesystem snapshot tool underneath
|
||||
the system package manager.
|
||||
|
||||
The
|
||||
[oVirt Node imgbased](https://gerrit.ovirt.org/gitweb?p=imgbased.git)
|
||||
tool is an example of this approach, as are a few others below.
|
||||
|
||||
Regarding [BTRFS](https://btrfs.wiki.kernel.org/index.php/Main_Page)
|
||||
in particular - the OSTree author believes that Linux storage is a
|
||||
wide world, and while BTRFS is quite good, it is not everywhere now,
|
||||
nor will it be in the near future. There are other recently developed
|
||||
filesystems like [f2fs](https://en.wikipedia.org/wiki/F2FS), and Red
|
||||
Hat Enterprise Linux still defaults to
|
||||
[XFS](https://en.wikipedia.org/wiki/XFS).
|
||||
|
||||
Using a snapshot tool underneath a package manager does help
|
||||
significantly. In the rest of this text, we will use "BTRFS" as a
|
||||
mostly generic tool for filesystem snapshots.
|
||||
|
||||
The obvious thing to do is layer BTRFS under dpkg/rpm, and have a
|
||||
separate subvolume for `/home` so rollbacks don't lose your data. See
|
||||
e.g. [Fedora BTRFS Rollback Feature](http://fedoraproject.org/wiki/Features/SystemRollbackWithBtrfs).
|
||||
|
||||
More generally, if you want to use BTRFS to roll back changes made by
|
||||
dpkg/rpm, you have to carefully set up the partition layout so that
|
||||
the files laid out by dpkg/rpm are installed in a subvolume to
|
||||
snapshot.
|
||||
|
||||
This problem in many ways is addressed by the changes OSTree forces,
|
||||
such as putting all local state in `/var` (e.g. `/usr/local` ->
|
||||
`/var/usrlocal`). Then one can BTRFS snapshot `/usr`. This gets pretty
|
||||
far, except handling `/etc` is messy. This is something OSTree does
|
||||
well.
|
||||
|
||||
In general, if one really tries to flesh out the BTRFS approach, a
|
||||
nontrivial middle layer of code between dpkg/rpm and BTRFS (or deep
|
||||
awareness of BTRFS in dpkg/rpm itself) will be required.
|
||||
|
||||
The OSTree author believes that having total freedom at the block
|
||||
storage layer is better for general purpose operating systems. For
|
||||
example, with OSTree, one is free to use BTRFS in any way you like -
|
||||
you can use a subvolume for `/home`, or you can not.
|
||||
|
||||
Furthermore, in its most basic incarnation, the rpm/dpkg + BTRFS
|
||||
doesn't solve the race conditions that happen when unpacking packages
|
||||
into the live system, such as deleting the files underneath Firefox
|
||||
while it's running. One could unpack packages into a separate root,
|
||||
and switch to that, which gets closer to the OSTree architecture.
|
||||
|
||||
Note though OSTree does take advantage of BTRFS if installed on top of
|
||||
it! In particular, it will use reflink for the copies of `/etc` if
|
||||
available.
|
||||
|
||||
All of the above also applies if one replaces "BTRFS" with "LVM
|
||||
snapshots" except for the reflinks.
|
||||
|
||||
Finally, see the next portion around ChromiumOS for why a hybrid but
|
||||
integrated package/image system improves on this.
|
||||
|
||||
## ChromiumOS updater
|
||||
|
||||
Many people who look at OSTree are most interested in using
|
||||
it as an updater for embedded or fixed-purpose systems, similar to use cases
|
||||
from the [ChromiumOS updater](http://dev.chromium.org/chromium-os/chromiumos-design-docs/filesystem-autoupdate).
|
||||
|
||||
The ChromiumOS approach uses two partitions that are swapped via the
|
||||
bootloader. It has a very network-efficient update protocol, using a
|
||||
custom binary delta scheme between filesystem snapshots.
|
||||
|
||||
This model even allows for switching filesystem types in an update.
|
||||
|
||||
A major downside of this approach is that the OS size is doubled on
|
||||
disk always. In contrast, OSTree uses plain Unix hardlinks, which
|
||||
means it essentially only requires disk space proportional to the
|
||||
changed files, plus some small fixed overhead.
|
||||
|
||||
This means with OSTree, one can easily have more than two trees
|
||||
(deployments). Another example is that the system OSTree repository
|
||||
could *also* be used for application containers.
|
||||
|
||||
Finally, the author of OSTree believes that what one really wants for
|
||||
many cases is image replication *with* the ability to layer on some
|
||||
additional components (e.g. packages) - a hybrid model. This is what
|
||||
[rpm-ostree](https://github.com/projectatomic/rpm-ostree/) is aiming
|
||||
to support.
|
||||
|
||||
## Ubuntu Image Based Updates
|
||||
|
||||
See <https://wiki.ubuntu.com/ImageBasedUpgrades>. Very architecturally
|
||||
similar to ChromeOS, although more interesting is discussion for
|
||||
supporting package installation on top, similar to
|
||||
[rpm-ostree package layering](https://github.com/projectatomic/rpm-ostree/pull/107).
|
||||
|
||||
## Clear Linux Software update
|
||||
|
||||
The
|
||||
[Clear Linux Software update](https://clearlinux.org/features/software-update)
|
||||
system is not very well documented.
|
||||
[This mailing list post](https://lists.clearlinux.org/pipermail/dev/2016-January/000159.html)
|
||||
has some reverse-engineered design documentation.
|
||||
|
||||
Like OSTree static deltas, it also uses bsdiff for network efficiency.
|
||||
|
||||
More information will be filled in here over time. The OSTree author
|
||||
believes that at the moment, the "CL updater" is not truly atomic in
|
||||
the sense that because it applies updates live, there is a window
|
||||
where the OS root may be inconsistent.
|
||||
|
||||
## OLPC update
|
||||
|
||||
OSTree is basically a generalization of olpc-update, except using
|
||||
plain HTTP instead of rsync. OSTree has the notion of separate trees
|
||||
that one can track independently or parallel install, while still
|
||||
sharing storage via the hardlinked repository, whereas olpc-update
|
||||
uses version numbers for a single OS.
|
||||
|
||||
OSTree has built-in plain old HTTP replication which can be served
|
||||
from a static webserver, whereas olpc-update uses `rsync` (more server
|
||||
load, but more efficient on the network side). The OSTree solution to
|
||||
improving network bandwidth consumption is via static deltas.
|
||||
|
||||
See
|
||||
[this comment](http://blog.verbum.org/2013/08/26/ostree-v2013-6-released/#comment-1169)
|
||||
for a comparison.
|
||||
|
||||
## NixOS
|
||||
|
||||
See [NixOS](http://nixos.org/). It was a very influential project for
|
||||
OSTree. NixOS and OSTree both support the idea of independent "roots"
|
||||
that are bootable.
|
||||
|
||||
In NixOS, the entire system is based on checksums of package inputs
|
||||
(build dependencies) - see [Nix store](http://nixos.org/nix/manual/#chap-package-management/). A both
|
||||
positive and negative of the Nix model is that a change in the build
|
||||
dependencies (e.g. being built with a newer gcc), requires a cascading
|
||||
rebuild of everything.
|
||||
|
||||
In OSTree, the checksums are of object *content* (including extended
|
||||
attributes). This means that any data that's identical is
|
||||
transparently, automatically shared on disk. It's possible to ask the
|
||||
Nix store to deduplicate, (via hard links and immutable bit), but this
|
||||
is significantly less efficient than the OSTree approach. The Nix use
|
||||
of the ext immutable bit is racy, since it has to be briefly removed
|
||||
to make a hard link.
|
||||
|
||||
At the lowest level, OSTree is just "git for binaries" - it isn't tied
|
||||
strongly to any particular build system. You can put whatever data you
|
||||
want inside an OSTree repository, built however you like. So for
|
||||
example, while one could make a build system that did the "purely
|
||||
functional" approach of Nix, it also works to have a build system that
|
||||
just rebuilds individual components (packages) as they change, without
|
||||
forcing a rebuild of their dependencies.
|
||||
|
||||
The author of OSTree believes that while Nix has some good ideas,
|
||||
forcing a rebuild of everything for a security update to e.g. glibc is
|
||||
not practical at scale.
|
||||
|
||||
## Solaris IPS
|
||||
|
||||
See
|
||||
[Solaris IPS](http://hub.opensolaris.org/bin/view/Project+pkg/). Broadly,
|
||||
this is a similar design as to a combination of BTRFS+RPM/deb. There
|
||||
is a bootloader management system which combines with the snapshots.
|
||||
It's relatively well thought through - however, it is a client-side
|
||||
system assembly. If one wants to image servers and replicate
|
||||
reliably, that'd be a different system.
|
||||
|
||||
|
||||
## Conary
|
||||
|
||||
See
|
||||
[Conary Updates and Rollbacks](http://wiki.rpath.com/wiki/Conary:Updates_and_Rollbacks). If
|
||||
rpm/dpkg are like CVS, Conary is closer to Subversion. It's not bad,
|
||||
but e.g. its rollback model is rather ad-hoc and not atomic. It also
|
||||
is a fully client side system and doesn't have an image-like
|
||||
replication with deltas.
|
||||
|
||||
## bmap
|
||||
|
||||
See
|
||||
[bmap](https://source.tizen.org/documentation/reference/bmaptool/introduction).
|
||||
A tool for optimized copying of disk images. Intended for offline use,
|
||||
so not directly comparable.
|
||||
|
|
@ -54,12 +54,12 @@ modes: `bare`, `bare-user`, and `archive-z2`. A bare repository is
|
|||
one where content files are just stored as regular files; it's
|
||||
designed to be the source of a "hardlink farm", where each operating
|
||||
system checkout is merely links into it. If you want to store files
|
||||
owned by e.g. root in this mode, you must run OSTree as root.
|
||||
owned by e.g. root in this mode, you must run OSTree as root.
|
||||
|
||||
The `bare-user` is a later addition that is like `bare` in that files
|
||||
are unpacked, but it can (and should generally) be created as
|
||||
non-root. In this mode, extended metadata such as owner uid, gid, and
|
||||
extended attributes are stored but not actually applied.
|
||||
extended attributes are stored but not actually applied.
|
||||
The `bare-user` mode is useful for build systems that run as non-root
|
||||
but want to generate root-owned content, as well as non-root container
|
||||
systems.
|
||||
|
|
@ -74,9 +74,13 @@ command, it will operate on the system repository.
|
|||
|
||||
## Refs
|
||||
|
||||
Like git, OSTree uses "refs" to which are text files that point to
|
||||
particular commits (i.e. filesystem trees). For example, the
|
||||
gnome-ostree operating system creates trees named like
|
||||
Like git, OSTree uses the terminology "references" (abbreviated
|
||||
"refs") which are text files that name (refer to) to particular
|
||||
commits. See the
|
||||
[Git Documentation](https://git-scm.com/book/en/v2/Git-Internals-Git-References)
|
||||
for information on how git uses them. Unlike git though, it doesn't
|
||||
usually make sense to have a "master" branch. There is a convention
|
||||
for references in OSTree that looks like this:
|
||||
`exampleos/buildmaster/x86_64-runtime` and
|
||||
`exampleos/buildmaster/x86_64-devel-debug`. These two refs point to
|
||||
two different generated filesystem trees. In this example, the
|
||||
|
|
@ -88,3 +92,30 @@ the parent of a given commit. For example,
|
|||
`exampleos/buildmaster/x86_64-runtime^` refers to the previous build,
|
||||
and `exampleos/buildmaster/x86_64-runtime^^` refers to the one before
|
||||
that.
|
||||
|
||||
## The summary file
|
||||
|
||||
A later addition to OSTree is the concept of a "summary" file, created
|
||||
via the `ostree summary -u` command. This was introduced for a few
|
||||
reasons. A primary use case is to be a target a
|
||||
(Metalink)[https://en.wikipedia.org/wiki/Metalink], which requires a
|
||||
single file with a known checksum as a target.
|
||||
|
||||
The summary file primarily contains two mappings:
|
||||
|
||||
- A mapping of the refs and their checksums, equivalent to fetching
|
||||
the ref file individually
|
||||
- A list of all static deltas, along with their metadata checksums
|
||||
|
||||
This currently means that it grows linearly with both items. On the
|
||||
other hand, using the summary file, a client can enumerate branches.
|
||||
|
||||
Further, the summary file is fetched over e.g. pinned TLS, this
|
||||
creates a strong end-to-end verification of the commit or static delta.
|
||||
|
||||
The summary file can also be GPG signed (detached), and currently this
|
||||
is the only way provide GPG signatures (transitively) on deltas.
|
||||
|
||||
If a repository administrator creates a summary file, they must
|
||||
thereafter run `ostree summary -u` to update it whenever a commit is
|
||||
made or a static delta is generated.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
<?xml version='1.0'?> <!--*-nxml-*-->
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||
|
||||
<!--
|
||||
Copyright 2016 Colin Walters <walters@verbum.org>
|
||||
|
||||
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.
|
||||
-->
|
||||
|
||||
<refentry id="ostree">
|
||||
|
||||
<refentryinfo>
|
||||
<title>ostree admin unlock</title>
|
||||
<productname>OSTree</productname>
|
||||
|
||||
<authorgroup>
|
||||
<author>
|
||||
<contrib>Developer</contrib>
|
||||
<firstname>Colin</firstname>
|
||||
<surname>Walters</surname>
|
||||
<email>walters@verbum.org</email>
|
||||
</author>
|
||||
</authorgroup>
|
||||
</refentryinfo>
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>ostree admin unlock</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>ostree-admin-unlock</refname>
|
||||
<refpurpose>Prepare the current deployment for hotfix or development</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>ostree admin unlock</command> <arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
|
||||
<para>
|
||||
Remove the read-only bind mount on <literal>/usr</literal>
|
||||
and replace it with a writable overlay filesystem. This
|
||||
default invocation of "unlock" is intended for
|
||||
development/testing purposes. All changes in the overlay
|
||||
are lost on reboot. However, this command also supports
|
||||
"hotfixes", see below.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Options</title>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>--hotfix</option></term>
|
||||
|
||||
<listitem><para>If this option is provided, the
|
||||
current deployment will be cloned as a rollback
|
||||
target. This option is intended for things like
|
||||
emergency security updates to userspace components
|
||||
such as <literal>sshd</literal>. The semantics here
|
||||
differ from the default "development" unlock mode
|
||||
in that reboots will retain any changes (which is what
|
||||
you likely want for security hotfixes).
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
|
|
@ -57,7 +57,7 @@ Boston, MA 02111-1307, USA.
|
|||
<refsect1>
|
||||
<title>Description</title>
|
||||
<para>
|
||||
Lists all refs available on the host. If pecified, PREFIX assigns the refspec prefix; default prefix is null, which lists all refs.
|
||||
Lists all refs available on the host. If specified, PREFIX assigns the refspec prefix; default prefix is null, which lists all refs.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
|
|
@ -65,6 +65,16 @@ Boston, MA 02111-1307, USA.
|
|||
<title>Options</title>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>--list</option></term>
|
||||
|
||||
<listitem><para> For historical reasons, <literal>refs</literal>
|
||||
without this option will strip the specified prefix
|
||||
from the output. Normally, one wants to see the full
|
||||
ref, so providing this option ensures the refs are
|
||||
printed in full, rather than
|
||||
truncated. </para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>--delete</option></term>
|
||||
|
||||
|
|
|
|||
|
|
@ -59,4 +59,3 @@ set -x
|
|||
validate_delta_options
|
||||
validate_delta_options --inline
|
||||
validate_delta_options --disable-bsdiff
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
site_name: My Docs
|
||||
site_name: OSTree
|
||||
pages:
|
||||
- Home: 'index.md'
|
||||
- Contributing: 'CONTRIBUTING.md'
|
||||
|
|
@ -9,3 +9,5 @@ pages:
|
|||
- Atomic Upgrades: 'manual/atomic-upgrades.md'
|
||||
- Adapting Existing Systems: 'manual/adapting-existing.md'
|
||||
- Formats: 'manual/formats.md'
|
||||
- Build Systems and Repos: 'manual/buildsystem-and-repos.md'
|
||||
- Related Projects: 'manual/related-projects.md'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,335 @@
|
|||
/***
|
||||
Copyright (C) 2016 Colin Walters <walters@verbum.org>
|
||||
|
||||
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.
|
||||
***/
|
||||
|
||||
|
||||
/*
|
||||
Retroactively make all of these symbols 2016.3, which is
|
||||
the first release where we started using versioned symbols. See
|
||||
also https://www.berrange.com/posts/2011/01/13/versioning-in-the-libvirt-library/
|
||||
*/
|
||||
LIBOSTREE_2016.3 {
|
||||
global:
|
||||
ostree_async_progress_finish;
|
||||
ostree_async_progress_get_status;
|
||||
ostree_async_progress_get_type;
|
||||
ostree_async_progress_get_uint;
|
||||
ostree_async_progress_get_uint64;
|
||||
ostree_async_progress_new;
|
||||
ostree_async_progress_new_and_connect;
|
||||
ostree_async_progress_set_status;
|
||||
ostree_async_progress_set_uint;
|
||||
ostree_async_progress_set_uint64;
|
||||
ostree_bootconfig_parser_clone;
|
||||
ostree_bootconfig_parser_get;
|
||||
ostree_bootconfig_parser_get_type;
|
||||
ostree_bootconfig_parser_new;
|
||||
ostree_bootconfig_parser_parse;
|
||||
ostree_bootconfig_parser_parse_at;
|
||||
ostree_bootconfig_parser_set;
|
||||
ostree_bootconfig_parser_write;
|
||||
ostree_bootconfig_parser_write_at;
|
||||
ostree_chain_input_stream_get_type;
|
||||
ostree_chain_input_stream_new;
|
||||
ostree_checksum_b64_inplace_from_bytes;
|
||||
ostree_checksum_b64_inplace_to_bytes;
|
||||
ostree_checksum_bytes_peek;
|
||||
ostree_checksum_bytes_peek_validate;
|
||||
ostree_checksum_file;
|
||||
ostree_checksum_file_async;
|
||||
ostree_checksum_file_async_finish;
|
||||
ostree_checksum_file_from_input;
|
||||
ostree_checksum_from_bytes;
|
||||
ostree_checksum_from_bytes_v;
|
||||
ostree_checksum_inplace_from_bytes;
|
||||
ostree_checksum_inplace_to_bytes;
|
||||
ostree_checksum_input_stream_get_type;
|
||||
ostree_checksum_input_stream_new;
|
||||
ostree_checksum_to_bytes;
|
||||
ostree_checksum_to_bytes_v;
|
||||
ostree_cmd__private__;
|
||||
ostree_cmp_checksum_bytes;
|
||||
ostree_commit_get_parent;
|
||||
ostree_commit_get_timestamp;
|
||||
ostree_content_file_parse;
|
||||
ostree_content_file_parse_at;
|
||||
ostree_content_stream_parse;
|
||||
ostree_create_directory_metadata;
|
||||
ostree_deployment_clone;
|
||||
ostree_deployment_equal;
|
||||
ostree_deployment_get_bootconfig;
|
||||
ostree_deployment_get_bootcsum;
|
||||
ostree_deployment_get_bootserial;
|
||||
ostree_deployment_get_csum;
|
||||
ostree_deployment_get_deployserial;
|
||||
ostree_deployment_get_index;
|
||||
ostree_deployment_get_origin;
|
||||
ostree_deployment_get_origin_relpath;
|
||||
ostree_deployment_get_osname;
|
||||
ostree_deployment_get_type;
|
||||
ostree_deployment_hash;
|
||||
ostree_deployment_new;
|
||||
ostree_deployment_set_bootconfig;
|
||||
ostree_deployment_set_bootserial;
|
||||
ostree_deployment_set_index;
|
||||
ostree_deployment_set_origin;
|
||||
ostree_diff_dirs;
|
||||
ostree_diff_item_get_type;
|
||||
ostree_diff_item_ref;
|
||||
ostree_diff_item_unref;
|
||||
ostree_diff_print;
|
||||
ostree_fetcher_config_flags_get_type;
|
||||
ostree_gpg_verify_result_count_all;
|
||||
ostree_gpg_verify_result_count_valid;
|
||||
ostree_gpg_verify_result_describe;
|
||||
ostree_gpg_verify_result_describe_variant;
|
||||
ostree_gpg_verify_result_get;
|
||||
ostree_gpg_verify_result_get_all;
|
||||
ostree_gpg_verify_result_get_type;
|
||||
ostree_gpg_verify_result_lookup;
|
||||
ostree_hash_object_name;
|
||||
ostree_metadata_variant_type;
|
||||
ostree_mutable_tree_ensure_dir;
|
||||
ostree_mutable_tree_ensure_parent_dirs;
|
||||
ostree_mutable_tree_get_contents_checksum;
|
||||
ostree_mutable_tree_get_files;
|
||||
ostree_mutable_tree_get_metadata_checksum;
|
||||
ostree_mutable_tree_get_subdirs;
|
||||
ostree_mutable_tree_get_type;
|
||||
ostree_mutable_tree_lookup;
|
||||
ostree_mutable_tree_new;
|
||||
ostree_mutable_tree_replace_file;
|
||||
ostree_mutable_tree_set_contents_checksum;
|
||||
ostree_mutable_tree_set_metadata_checksum;
|
||||
ostree_mutable_tree_walk;
|
||||
ostree_object_from_string;
|
||||
ostree_object_name_deserialize;
|
||||
ostree_object_name_serialize;
|
||||
ostree_object_to_string;
|
||||
ostree_object_type_from_string;
|
||||
ostree_object_type_to_string;
|
||||
ostree_parse_refspec;
|
||||
ostree_raw_file_to_content_stream;
|
||||
ostree_repo_abort_transaction;
|
||||
ostree_repo_add_gpg_signature_summary;
|
||||
ostree_repo_append_gpg_signature;
|
||||
ostree_repo_checkout_gc;
|
||||
ostree_repo_checkout_tree;
|
||||
ostree_repo_checkout_tree_at;
|
||||
ostree_repo_commit_modifier_get_type;
|
||||
ostree_repo_commit_modifier_new;
|
||||
ostree_repo_commit_modifier_ref;
|
||||
ostree_repo_commit_modifier_set_devino_cache;
|
||||
ostree_repo_commit_modifier_set_sepolicy;
|
||||
ostree_repo_commit_modifier_set_xattr_callback;
|
||||
ostree_repo_commit_modifier_unref;
|
||||
ostree_repo_commit_transaction;
|
||||
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;
|
||||
ostree_repo_commit_traverse_iter_init_commit;
|
||||
ostree_repo_commit_traverse_iter_init_dirtree;
|
||||
ostree_repo_commit_traverse_iter_next;
|
||||
ostree_repo_copy_config;
|
||||
ostree_repo_create;
|
||||
ostree_repo_delete_object;
|
||||
ostree_repo_devino_cache_get_type;
|
||||
ostree_repo_devino_cache_new;
|
||||
ostree_repo_devino_cache_ref;
|
||||
ostree_repo_devino_cache_unref;
|
||||
ostree_repo_export_tree_to_archive;
|
||||
ostree_repo_file_ensure_resolved;
|
||||
ostree_repo_file_get_checksum;
|
||||
ostree_repo_file_get_repo;
|
||||
ostree_repo_file_get_root;
|
||||
ostree_repo_file_get_type;
|
||||
ostree_repo_file_get_xattrs;
|
||||
ostree_repo_file_tree_find_child;
|
||||
ostree_repo_file_tree_get_contents;
|
||||
ostree_repo_file_tree_get_contents_checksum;
|
||||
ostree_repo_file_tree_get_metadata;
|
||||
ostree_repo_file_tree_get_metadata_checksum;
|
||||
ostree_repo_file_tree_query_child;
|
||||
ostree_repo_file_tree_set_metadata;
|
||||
ostree_repo_get_config;
|
||||
ostree_repo_get_disable_fsync;
|
||||
ostree_repo_get_mode;
|
||||
ostree_repo_get_parent;
|
||||
ostree_repo_get_path;
|
||||
ostree_repo_get_type;
|
||||
ostree_repo_has_object;
|
||||
ostree_repo_import_archive_to_mtree;
|
||||
ostree_repo_import_object_from;
|
||||
ostree_repo_is_system;
|
||||
ostree_repo_is_writable;
|
||||
ostree_repo_list_commit_objects_starting_with;
|
||||
ostree_repo_list_objects;
|
||||
ostree_repo_list_refs;
|
||||
ostree_repo_list_static_delta_names;
|
||||
ostree_repo_load_commit;
|
||||
ostree_repo_load_file;
|
||||
ostree_repo_load_object_stream;
|
||||
ostree_repo_load_variant;
|
||||
ostree_repo_load_variant_if_exists;
|
||||
ostree_repo_mode_from_string;
|
||||
ostree_repo_new;
|
||||
ostree_repo_new_default;
|
||||
ostree_repo_new_for_sysroot_path;
|
||||
ostree_repo_open;
|
||||
ostree_repo_prepare_transaction;
|
||||
ostree_repo_prune;
|
||||
ostree_repo_prune_static_deltas;
|
||||
ostree_repo_pull;
|
||||
ostree_repo_pull_default_console_progress_changed;
|
||||
ostree_repo_pull_one_dir;
|
||||
ostree_repo_pull_with_options;
|
||||
ostree_repo_query_object_storage_size;
|
||||
ostree_repo_read_commit;
|
||||
ostree_repo_read_commit_detached_metadata;
|
||||
ostree_repo_regenerate_summary;
|
||||
ostree_repo_remote_add;
|
||||
ostree_repo_remote_change;
|
||||
ostree_repo_remote_delete;
|
||||
ostree_repo_remote_fetch_summary;
|
||||
ostree_repo_remote_get_gpg_verify;
|
||||
ostree_repo_remote_get_gpg_verify_summary;
|
||||
ostree_repo_remote_get_url;
|
||||
ostree_repo_remote_gpg_import;
|
||||
ostree_repo_remote_list;
|
||||
ostree_repo_remote_list_refs;
|
||||
ostree_repo_resolve_rev;
|
||||
ostree_repo_scan_hardlinks;
|
||||
ostree_repo_set_disable_fsync;
|
||||
ostree_repo_set_ref_immediate;
|
||||
ostree_repo_sign_commit;
|
||||
ostree_repo_sign_delta;
|
||||
ostree_repo_static_delta_execute_offline;
|
||||
ostree_repo_static_delta_generate;
|
||||
ostree_repo_transaction_set_ref;
|
||||
ostree_repo_transaction_set_refspec;
|
||||
ostree_repo_transaction_stats_get_type;
|
||||
ostree_repo_traverse_commit;
|
||||
ostree_repo_traverse_commit_union;
|
||||
ostree_repo_traverse_new_reachable;
|
||||
ostree_repo_verify_commit;
|
||||
ostree_repo_verify_commit_ext;
|
||||
ostree_repo_verify_summary;
|
||||
ostree_repo_write_archive_to_mtree;
|
||||
ostree_repo_write_commit;
|
||||
ostree_repo_write_commit_detached_metadata;
|
||||
ostree_repo_write_commit_with_time;
|
||||
ostree_repo_write_config;
|
||||
ostree_repo_write_content;
|
||||
ostree_repo_write_content_async;
|
||||
ostree_repo_write_content_finish;
|
||||
ostree_repo_write_content_trusted;
|
||||
ostree_repo_write_dfd_to_mtree;
|
||||
ostree_repo_write_directory_to_mtree;
|
||||
ostree_repo_write_metadata;
|
||||
ostree_repo_write_metadata_async;
|
||||
ostree_repo_write_metadata_finish;
|
||||
ostree_repo_write_metadata_stream_trusted;
|
||||
ostree_repo_write_metadata_trusted;
|
||||
ostree_repo_write_mtree;
|
||||
ostree_sepolicy_fscreatecon_cleanup;
|
||||
ostree_sepolicy_get_label;
|
||||
ostree_sepolicy_get_name;
|
||||
ostree_sepolicy_get_path;
|
||||
ostree_sepolicy_get_type;
|
||||
ostree_sepolicy_new;
|
||||
ostree_sepolicy_restorecon;
|
||||
ostree_sepolicy_setfscreatecon;
|
||||
ostree_sysroot_cleanup;
|
||||
ostree_sysroot_deployment_set_kargs;
|
||||
ostree_sysroot_deployment_set_mutable;
|
||||
ostree_sysroot_deploy_tree;
|
||||
ostree_sysroot_ensure_initialized;
|
||||
ostree_sysroot_get_booted_deployment;
|
||||
ostree_sysroot_get_bootversion;
|
||||
ostree_sysroot_get_deployment_directory;
|
||||
ostree_sysroot_get_deployment_dirpath;
|
||||
ostree_sysroot_get_deployment_origin_path;
|
||||
ostree_sysroot_get_deployments;
|
||||
ostree_sysroot_get_fd;
|
||||
ostree_sysroot_get_merge_deployment;
|
||||
ostree_sysroot_get_path;
|
||||
ostree_sysroot_get_repo;
|
||||
ostree_sysroot_get_subbootversion;
|
||||
ostree_sysroot_get_type;
|
||||
ostree_sysroot_load;
|
||||
ostree_sysroot_lock;
|
||||
ostree_sysroot_lock_async;
|
||||
ostree_sysroot_lock_finish;
|
||||
ostree_sysroot_new;
|
||||
ostree_sysroot_new_default;
|
||||
ostree_sysroot_origin_new_from_refspec;
|
||||
ostree_sysroot_prepare_cleanup;
|
||||
ostree_sysroot_simple_write_deployment;
|
||||
ostree_sysroot_try_lock;
|
||||
ostree_sysroot_unload;
|
||||
ostree_sysroot_unlock;
|
||||
ostree_sysroot_upgrader_check_timestamps;
|
||||
ostree_sysroot_upgrader_deploy;
|
||||
ostree_sysroot_upgrader_dup_origin;
|
||||
ostree_sysroot_upgrader_flags_get_type;
|
||||
ostree_sysroot_upgrader_get_origin;
|
||||
ostree_sysroot_upgrader_get_origin_description;
|
||||
ostree_sysroot_upgrader_get_type;
|
||||
ostree_sysroot_upgrader_new;
|
||||
ostree_sysroot_upgrader_new_for_os;
|
||||
ostree_sysroot_upgrader_new_for_os_with_flags;
|
||||
ostree_sysroot_upgrader_pull;
|
||||
ostree_sysroot_upgrader_pull_one_dir;
|
||||
ostree_sysroot_upgrader_set_origin;
|
||||
ostree_sysroot_write_deployments;
|
||||
ostree_sysroot_write_origin_file;
|
||||
ostree_validate_checksum_string;
|
||||
ostree_validate_rev;
|
||||
ostree_validate_structureof_checksum_string;
|
||||
ostree_validate_structureof_commit;
|
||||
ostree_validate_structureof_csum_v;
|
||||
ostree_validate_structureof_dirmeta;
|
||||
ostree_validate_structureof_dirtree;
|
||||
ostree_validate_structureof_file_mode;
|
||||
ostree_validate_structureof_objtype;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
||||
LIBOSTREE_2016.4 {
|
||||
global:
|
||||
ostree_repo_get_dfd;
|
||||
ostree_repo_list_refs_ext;
|
||||
ostree_sysroot_init_osname;
|
||||
ostree_sysroot_load_if_changed;
|
||||
ostree_sysroot_deployment_unlock;
|
||||
ostree_deployment_get_unlocked;
|
||||
ostree_deployment_unlocked_state_to_string;
|
||||
} LIBOSTREE_2016.3;
|
||||
|
||||
/* NOTE NOTE NOTE
|
||||
* Versions above here are released. Only add symbols below this line.
|
||||
* NOTE NOTE NOTE
|
||||
*/
|
||||
|
||||
/* UNCOMMENT WITH NEW SYMBOLS HERE:
|
||||
LIBOSTREE_2016.5 {
|
||||
global:
|
||||
} LIBOSTREE_2016.4;
|
||||
*/
|
||||
|
|
@ -41,29 +41,39 @@ struct OstreeAsyncProgressClass
|
|||
void (*changed) (OstreeAsyncProgress *self, gpointer user_data);
|
||||
};
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_async_progress_get_type (void) G_GNUC_CONST;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeAsyncProgress *ostree_async_progress_new (void);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeAsyncProgress *ostree_async_progress_new_and_connect (void (*changed) (OstreeAsyncProgress *self, gpointer user_data), gpointer user_data);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
char *ostree_async_progress_get_status (OstreeAsyncProgress *self);
|
||||
|
||||
_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
|
||||
void ostree_async_progress_set_status (OstreeAsyncProgress *self,
|
||||
const char *status);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_async_progress_set_uint (OstreeAsyncProgress *self,
|
||||
const char *key,
|
||||
guint value);
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_async_progress_set_uint64 (OstreeAsyncProgress *self,
|
||||
const char *key,
|
||||
guint64 value);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_async_progress_finish (OstreeAsyncProgress *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
|
|
@ -30,38 +30,47 @@ G_BEGIN_DECLS
|
|||
|
||||
typedef struct _OstreeBootconfigParser OstreeBootconfigParser;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_bootconfig_parser_get_type (void) G_GNUC_CONST;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeBootconfigParser * ostree_bootconfig_parser_new (void);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeBootconfigParser * ostree_bootconfig_parser_clone (OstreeBootconfigParser *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_bootconfig_parser_parse (OstreeBootconfigParser *self,
|
||||
GFile *path,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self,
|
||||
int dfd,
|
||||
const char *path,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_bootconfig_parser_write (OstreeBootconfigParser *self,
|
||||
GFile *output,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_bootconfig_parser_write_at (OstreeBootconfigParser *self,
|
||||
int dfd,
|
||||
const char *path,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_bootconfig_parser_set (OstreeBootconfigParser *self,
|
||||
const char *key,
|
||||
const char *value);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
const char *ostree_bootconfig_parser_get (OstreeBootconfigParser *self,
|
||||
const char *key);
|
||||
|
||||
|
|
|
|||
|
|
@ -293,9 +293,9 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader,
|
|||
g_autoptr(GFile) efi_new_config_temp = NULL;
|
||||
g_autoptr(GFile) efi_orig_config = NULL;
|
||||
g_autoptr(GFile) new_config_path = NULL;
|
||||
glnx_unref_object GSSubprocessContext *procctx = NULL;
|
||||
glnx_unref_object GSSubprocess *proc = NULL;
|
||||
g_auto(GStrv) child_env = g_get_environ ();
|
||||
GSubprocessFlags subp_flags = 0;
|
||||
glnx_unref_object GSubprocessLauncher *launcher = NULL;
|
||||
glnx_unref_object GSubprocess *proc = NULL;
|
||||
g_autofree char *bootversion_str = g_strdup_printf ("%u", (guint)bootversion);
|
||||
g_autoptr(GFile) config_path_efi_dir = NULL;
|
||||
g_autofree char *grub2_mkconfig_chroot = NULL;
|
||||
|
|
@ -337,41 +337,35 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader,
|
|||
bootversion);
|
||||
}
|
||||
|
||||
procctx = gs_subprocess_context_newv ("grub2-mkconfig", "-o",
|
||||
gs_file_get_path_cached (new_config_path),
|
||||
NULL);
|
||||
child_env = g_environ_setenv (child_env, "_OSTREE_GRUB2_BOOTVERSION", bootversion_str, TRUE);
|
||||
if (!g_getenv ("OSTREE_DEBUG_GRUB2"))
|
||||
subp_flags |= (G_SUBPROCESS_FLAGS_STDOUT_SILENCE | G_SUBPROCESS_FLAGS_STDERR_SILENCE);
|
||||
|
||||
launcher = g_subprocess_launcher_new (subp_flags);
|
||||
g_subprocess_launcher_setenv (launcher, "_OSTREE_GRUB2_BOOTVERSION", bootversion_str, TRUE);
|
||||
/* We have to pass our state to the child */
|
||||
if (self->is_efi)
|
||||
child_env = g_environ_setenv (child_env, "_OSTREE_GRUB2_IS_EFI", "1", TRUE);
|
||||
gs_subprocess_context_set_environment (procctx, child_env);
|
||||
gs_subprocess_context_set_stdout_disposition (procctx, GS_SUBPROCESS_STREAM_DISPOSITION_NULL);
|
||||
if (g_getenv ("OSTREE_DEBUG_GRUB2"))
|
||||
gs_subprocess_context_set_stderr_disposition (procctx, GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT);
|
||||
else
|
||||
gs_subprocess_context_set_stderr_disposition (procctx, GS_SUBPROCESS_STREAM_DISPOSITION_NULL);
|
||||
|
||||
g_subprocess_launcher_setenv (launcher, "_OSTREE_GRUB2_IS_EFI", "1", TRUE);
|
||||
|
||||
/* We need to chroot() if we're not in /. This assumes our caller has
|
||||
* set up the bind mounts outside.
|
||||
*/
|
||||
if (grub2_mkconfig_chroot != NULL)
|
||||
{
|
||||
gs_subprocess_context_set_child_setup (procctx, grub2_child_setup, grub2_mkconfig_chroot);
|
||||
}
|
||||
g_subprocess_launcher_set_child_setup (launcher, grub2_child_setup, grub2_mkconfig_chroot, NULL);
|
||||
|
||||
/* In the current Fedora grub2 package, this script doesn't even try
|
||||
to be atomic; it just does:
|
||||
|
||||
cat ${grub_cfg}.new > ${grub_cfg}
|
||||
rm -f ${grub_cfg}.new
|
||||
cat ${grub_cfg}.new > ${grub_cfg}
|
||||
rm -f ${grub_cfg}.new
|
||||
|
||||
Upstream is fixed though.
|
||||
*/
|
||||
proc = gs_subprocess_new (procctx, cancellable, error);
|
||||
if (!proc)
|
||||
goto out;
|
||||
proc = g_subprocess_launcher_spawn (launcher, error,
|
||||
"grub2-mkconfig", "-o",
|
||||
gs_file_get_path_cached (new_config_path),
|
||||
NULL);
|
||||
|
||||
if (!gs_subprocess_wait_sync_check (proc, cancellable, error))
|
||||
if (!g_subprocess_wait_check (proc, cancellable, error))
|
||||
goto out;
|
||||
|
||||
/* Now let's fdatasync() for the new file */
|
||||
|
|
|
|||
|
|
@ -59,8 +59,10 @@ struct _OstreeChainInputStreamClass
|
|||
void (*_g_reserved5) (void);
|
||||
};
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_chain_input_stream_get_type (void) G_GNUC_CONST;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeChainInputStream * ostree_chain_input_stream_new (GPtrArray *streams);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
|
|
@ -57,8 +57,10 @@ struct _OstreeChecksumInputStreamClass
|
|||
void (*_g_reserved5) (void);
|
||||
};
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_checksum_input_stream_get_type (void) G_GNUC_CONST;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeChecksumInputStream * ostree_checksum_input_stream_new (GInputStream *stream,
|
||||
GChecksum *checksum);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ typedef struct {
|
|||
gboolean (* ostree_static_delta_dump) (OstreeRepo *repo, const char *delta_id, GCancellable *cancellable, GError **error);
|
||||
} OstreeCmdPrivateVTable;
|
||||
|
||||
const OstreeCmdPrivateVTable *
|
||||
/* Note this not really "public", we just export the symbol, but not the header */
|
||||
_OSTREE_PUBLIC const OstreeCmdPrivateVTable *
|
||||
ostree_cmd__private__ (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
|
|
@ -155,7 +155,8 @@ ostree_parse_refspec (const char *refspec,
|
|||
|
||||
ret = TRUE;
|
||||
|
||||
gs_transfer_out_value (out_remote, &remote);
|
||||
if (out_remote)
|
||||
*out_remote = g_steal_pointer (&remote);
|
||||
if (out_ref != NULL)
|
||||
*out_ref = g_match_info_fetch (match, 2);
|
||||
out:
|
||||
|
|
@ -766,7 +767,8 @@ ostree_checksum_file (GFile *f,
|
|||
|
||||
if (objtype == OSTREE_OBJECT_TYPE_FILE)
|
||||
{
|
||||
if (!gs_file_get_all_xattrs (f, &xattrs, cancellable, error))
|
||||
if (!glnx_dfd_name_get_all_xattrs (AT_FDCWD, gs_file_get_path_cached (f),
|
||||
&xattrs, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -950,7 +952,8 @@ _ostree_make_temporary_symlink_at (int tmp_dirfd,
|
|||
}
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_name, &tmpname);
|
||||
if (out_name)
|
||||
*out_name = g_steal_pointer (&tmpname);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <ostree-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
|
@ -164,63 +165,86 @@ typedef enum {
|
|||
OSTREE_REPO_MODE_BARE_USER
|
||||
} OstreeRepoMode;
|
||||
|
||||
const GVariantType *ostree_metadata_variant_type (OstreeObjectType objtype);
|
||||
const _OSTREE_PUBLIC
|
||||
GVariantType *ostree_metadata_variant_type (OstreeObjectType objtype);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_validate_checksum_string (const char *sha256,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
guchar *ostree_checksum_to_bytes (const char *checksum);
|
||||
_OSTREE_PUBLIC
|
||||
GVariant *ostree_checksum_to_bytes_v (const char *checksum);
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_checksum_b64_inplace_to_bytes (const char *checksum,
|
||||
guint8 *buf);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
char * ostree_checksum_from_bytes (const guchar *csum);
|
||||
_OSTREE_PUBLIC
|
||||
char * ostree_checksum_from_bytes_v (GVariant *csum_v);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_checksum_inplace_from_bytes (const guchar *csum,
|
||||
char *buf);
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_checksum_b64_inplace_from_bytes (const guchar *csum,
|
||||
char *buf);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_checksum_inplace_to_bytes (const char *checksum,
|
||||
guchar *buf);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
const guchar *ostree_checksum_bytes_peek (GVariant *bytes);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
const guchar *ostree_checksum_bytes_peek_validate (GVariant *bytes, GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
int ostree_cmp_checksum_bytes (const guchar *a, const guchar *b);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_validate_rev (const char *rev, GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_parse_refspec (const char *refspec,
|
||||
char **out_remote,
|
||||
char **out_ref,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_checksum_update_meta (GChecksum *checksum, GFileInfo *file_info, GVariant *xattrs);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
const char * ostree_object_type_to_string (OstreeObjectType objtype);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeObjectType ostree_object_type_from_string (const char *str);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
guint ostree_hash_object_name (gconstpointer a);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GVariant *ostree_object_name_serialize (const char *checksum,
|
||||
OstreeObjectType objtype);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_object_name_deserialize (GVariant *variant,
|
||||
const char **out_checksum,
|
||||
OstreeObjectType *out_objtype);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
char * ostree_object_to_string (const char *checksum,
|
||||
OstreeObjectType objtype);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_object_from_string (const char *str,
|
||||
gchar **out_checksum,
|
||||
OstreeObjectType *out_objtype);
|
||||
|
||||
gboolean
|
||||
_OSTREE_PUBLIC gboolean
|
||||
ostree_content_stream_parse (gboolean compressed,
|
||||
GInputStream *input,
|
||||
guint64 input_length,
|
||||
|
|
@ -231,6 +255,7 @@ ostree_content_stream_parse (gboolean compressed,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_content_file_parse (gboolean compressed,
|
||||
GFile *content_path,
|
||||
gboolean trusted,
|
||||
|
|
@ -240,6 +265,7 @@ gboolean ostree_content_file_parse (gboolean compressed,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_content_file_parse_at (gboolean compressed,
|
||||
int parent_dfd,
|
||||
const char *path,
|
||||
|
|
@ -250,6 +276,7 @@ gboolean ostree_content_file_parse_at (gboolean compressed,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_raw_file_to_content_stream (GInputStream *input,
|
||||
GFileInfo *file_info,
|
||||
GVariant *xattrs,
|
||||
|
|
@ -258,6 +285,7 @@ gboolean ostree_raw_file_to_content_stream (GInputStream *input,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_checksum_file_from_input (GFileInfo *file_info,
|
||||
GVariant *xattrs,
|
||||
GInputStream *in,
|
||||
|
|
@ -266,12 +294,14 @@ gboolean ostree_checksum_file_from_input (GFileInfo *file_info,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_checksum_file (GFile *f,
|
||||
OstreeObjectType objtype,
|
||||
guchar **out_csum,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_checksum_file_async (GFile *f,
|
||||
OstreeObjectType objtype,
|
||||
int io_priority,
|
||||
|
|
@ -279,38 +309,49 @@ void ostree_checksum_file_async (GFile *f,
|
|||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_checksum_file_async_finish (GFile *f,
|
||||
GAsyncResult *result,
|
||||
guchar **out_csum,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GVariant *ostree_create_directory_metadata (GFileInfo *dir_info,
|
||||
GVariant *xattrs);
|
||||
|
||||
/* VALIDATION */
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_validate_structureof_objtype (guchar objtype,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_validate_structureof_csum_v (GVariant *checksum,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_validate_structureof_checksum_string (const char *checksum,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_validate_structureof_file_mode (guint32 mode,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_validate_structureof_commit (GVariant *commit,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_validate_structureof_dirtree (GVariant *dirtree,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_validate_structureof_dirmeta (GVariant *dirmeta,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gchar * ostree_commit_get_parent (GVariant *commit_variant);
|
||||
_OSTREE_PUBLIC
|
||||
guint64 ostree_commit_get_timestamp (GVariant *commit_variant);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
|
|
@ -24,6 +24,21 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _OstreeDeployment
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
int index; /* Global offset */
|
||||
char *osname; /* osname */
|
||||
char *csum; /* OSTree checksum of tree */
|
||||
int deployserial; /* How many times this particular csum appears in deployment list */
|
||||
char *bootcsum; /* Checksum of kernel+initramfs */
|
||||
int bootserial; /* An integer assigned to this tree per its ${bootcsum} */
|
||||
OstreeBootconfigParser *bootconfig; /* Bootloader configuration */
|
||||
GKeyFile *origin; /* How to construct an upgraded version of this tree */
|
||||
OstreeDeploymentUnlockedState unlocked; /* The unlocked state */
|
||||
};
|
||||
|
||||
void _ostree_deployment_set_bootcsum (OstreeDeployment *self, const char *bootcsum);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
|
|
@ -23,20 +23,6 @@
|
|||
#include "ostree-deployment-private.h"
|
||||
#include "libglnx.h"
|
||||
|
||||
struct _OstreeDeployment
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
int index; /* Global offset */
|
||||
char *osname; /* osname */
|
||||
char *csum; /* OSTree checksum of tree */
|
||||
int deployserial; /* How many times this particular csum appears in deployment list */
|
||||
char *bootcsum; /* Checksum of kernel+initramfs */
|
||||
int bootserial; /* An integer assigned to this tree per its ${bootcsum} */
|
||||
OstreeBootconfigParser *bootconfig; /* Bootloader configuration */
|
||||
GKeyFile *origin; /* How to construct an upgraded version of this tree */
|
||||
};
|
||||
|
||||
typedef GObjectClass OstreeDeploymentClass;
|
||||
|
||||
G_DEFINE_TYPE (OstreeDeployment, ostree_deployment, G_TYPE_OBJECT)
|
||||
|
|
@ -258,6 +244,7 @@ ostree_deployment_new (int index,
|
|||
self->deployserial = deployserial;
|
||||
self->bootcsum = g_strdup (bootcsum);
|
||||
self->bootserial = bootserial;
|
||||
self->unlocked = OSTREE_DEPLOYMENT_UNLOCKED_NONE;
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
@ -279,3 +266,24 @@ ostree_deployment_get_origin_relpath (OstreeDeployment *self)
|
|||
ostree_deployment_get_csum (self),
|
||||
ostree_deployment_get_deployserial (self));
|
||||
}
|
||||
|
||||
const char *
|
||||
ostree_deployment_unlocked_state_to_string (OstreeDeploymentUnlockedState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case OSTREE_DEPLOYMENT_UNLOCKED_NONE:
|
||||
return "none";
|
||||
case OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX:
|
||||
return "hotfix";
|
||||
case OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT:
|
||||
return "development";
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
OstreeDeploymentUnlockedState
|
||||
ostree_deployment_get_unlocked (OstreeDeployment *self)
|
||||
{
|
||||
return self->unlocked;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,11 +30,15 @@ G_BEGIN_DECLS
|
|||
|
||||
typedef struct _OstreeDeployment OstreeDeployment;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_deployment_get_type (void) G_GNUC_CONST;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
guint ostree_deployment_hash (gconstpointer v);
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_deployment_equal (gconstpointer ap, gconstpointer bp);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeDeployment * ostree_deployment_new (int index,
|
||||
const char *osname,
|
||||
const char *csum,
|
||||
|
|
@ -42,22 +46,48 @@ OstreeDeployment * ostree_deployment_new (int index,
|
|||
const char *bootcsum,
|
||||
int bootserial);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
int ostree_deployment_get_index (OstreeDeployment *self);
|
||||
_OSTREE_PUBLIC
|
||||
const char *ostree_deployment_get_osname (OstreeDeployment *self);
|
||||
_OSTREE_PUBLIC
|
||||
int ostree_deployment_get_deployserial (OstreeDeployment *self);
|
||||
_OSTREE_PUBLIC
|
||||
const char *ostree_deployment_get_csum (OstreeDeployment *self);
|
||||
_OSTREE_PUBLIC
|
||||
const char *ostree_deployment_get_bootcsum (OstreeDeployment *self);
|
||||
_OSTREE_PUBLIC
|
||||
int ostree_deployment_get_bootserial (OstreeDeployment *self);
|
||||
_OSTREE_PUBLIC
|
||||
OstreeBootconfigParser *ostree_deployment_get_bootconfig (OstreeDeployment *self);
|
||||
_OSTREE_PUBLIC
|
||||
GKeyFile *ostree_deployment_get_origin (OstreeDeployment *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_deployment_set_index (OstreeDeployment *self, int index);
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_deployment_set_bootserial (OstreeDeployment *self, int index);
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_deployment_set_bootconfig (OstreeDeployment *self, OstreeBootconfigParser *bootconfig);
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_deployment_set_origin (OstreeDeployment *self, GKeyFile *origin);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeDeployment *ostree_deployment_clone (OstreeDeployment *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
char *ostree_deployment_get_origin_relpath (OstreeDeployment *self);
|
||||
|
||||
typedef enum {
|
||||
OSTREE_DEPLOYMENT_UNLOCKED_NONE,
|
||||
OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT,
|
||||
OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX
|
||||
} OstreeDeploymentUnlockedState;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
const char *ostree_deployment_unlocked_state_to_string (OstreeDeploymentUnlockedState state);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeDeploymentUnlockedState ostree_deployment_get_unlocked (OstreeDeployment *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ get_file_checksum (OstreeDiffFlags flags,
|
|||
|
||||
if (!(flags & OSTREE_DIFF_FLAGS_IGNORE_XATTRS))
|
||||
{
|
||||
if (!gs_file_get_all_xattrs (f, &xattrs, cancellable, error))
|
||||
if (!glnx_dfd_name_get_all_xattrs (AT_FDCWD, gs_file_get_path_cached (f),
|
||||
&xattrs, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,11 +47,15 @@ struct _OstreeDiffItem
|
|||
char *target_checksum;
|
||||
};
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeDiffItem *ostree_diff_item_ref (OstreeDiffItem *diffitem);
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_diff_item_unref (OstreeDiffItem *diffitem);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_diff_item_get_type (void);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_diff_dirs (OstreeDiffFlags flags,
|
||||
GFile *a,
|
||||
GFile *b,
|
||||
|
|
@ -61,6 +65,7 @@ gboolean ostree_diff_dirs (OstreeDiffFlags flags,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_diff_print (GFile *a,
|
||||
GFile *b,
|
||||
GPtrArray *modified,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ G_BEGIN_DECLS
|
|||
|
||||
/*** BEGIN enumeration-production ***/
|
||||
#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
|
||||
_OSTREE_PUBLIC
|
||||
GType @enum_name@_get_type (void) G_GNUC_CONST;
|
||||
|
||||
/*** END enumeration-production ***/
|
||||
|
|
|
|||
|
|
@ -406,7 +406,7 @@ session_thread_request_uri (ThreadClosure *thread_closure,
|
|||
exists = FALSE;
|
||||
else
|
||||
{
|
||||
gs_set_error_from_errno (&local_error, errno);
|
||||
glnx_set_error_from_errno (&local_error);
|
||||
g_task_return_error (task, local_error);
|
||||
return;
|
||||
}
|
||||
|
|
@ -706,7 +706,7 @@ finish_stream (OstreeFetcherPendingURI *pending,
|
|||
pending->out_tmpfile,
|
||||
&stbuf, AT_SYMLINK_NOFOLLOW) != 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -922,7 +922,7 @@ on_request_sent (GObject *object,
|
|||
pending->out_tmpfile, oflags, 0666);
|
||||
if (fd == -1)
|
||||
{
|
||||
gs_set_error_from_errno (&local_error, errno);
|
||||
glnx_set_error_from_errno (&local_error);
|
||||
goto out;
|
||||
}
|
||||
pending->out_stream = g_unix_output_stream_new (fd, TRUE);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <ostree-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
|
@ -82,21 +83,27 @@ typedef enum {
|
|||
OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL
|
||||
} OstreeGpgSignatureAttr;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_gpg_verify_result_get_type (void);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
guint ostree_gpg_verify_result_count_all (OstreeGpgVerifyResult *result);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
guint ostree_gpg_verify_result_count_valid (OstreeGpgVerifyResult *result);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result,
|
||||
const gchar *key_id,
|
||||
guint *out_signature_index);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GVariant * ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result,
|
||||
guint signature_index,
|
||||
OstreeGpgSignatureAttr *attrs,
|
||||
guint n_attrs);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GVariant * ostree_gpg_verify_result_get_all (OstreeGpgVerifyResult *result,
|
||||
guint signature_index);
|
||||
|
||||
|
|
@ -113,12 +120,14 @@ typedef enum {
|
|||
OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT = 0
|
||||
} OstreeGpgSignatureFormatFlags;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_gpg_verify_result_describe (OstreeGpgVerifyResult *result,
|
||||
guint signature_index,
|
||||
GString *output_buffer,
|
||||
const gchar *line_prefix,
|
||||
OstreeGpgSignatureFormatFlags flags);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_gpg_verify_result_describe_variant (GVariant *variant,
|
||||
GString *output_buffer,
|
||||
const gchar *line_prefix,
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ _ostree_kernel_args_new (void)
|
|||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_free (OstreeKernelArgs *kargs)
|
||||
_ostree_kernel_arg_autofree (OstreeKernelArgs *kargs)
|
||||
{
|
||||
if (!kargs)
|
||||
return;
|
||||
|
|
@ -77,7 +77,7 @@ _ostree_kernel_args_free (OstreeKernelArgs *kargs)
|
|||
void
|
||||
_ostree_kernel_args_cleanup (void *loc)
|
||||
{
|
||||
_ostree_kernel_args_free (*((OstreeKernelArgs**)loc));
|
||||
_ostree_kernel_arg_autofree (*((OstreeKernelArgs**)loc));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -45,50 +45,62 @@ struct OstreeMutableTreeClass
|
|||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_mutable_tree_get_type (void) G_GNUC_CONST;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeMutableTree *ostree_mutable_tree_new (void);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_mutable_tree_set_metadata_checksum (OstreeMutableTree *self,
|
||||
const char *checksum);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
const char *ostree_mutable_tree_get_metadata_checksum (OstreeMutableTree *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_mutable_tree_set_contents_checksum (OstreeMutableTree *self,
|
||||
const char *checksum);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
const char *ostree_mutable_tree_get_contents_checksum (OstreeMutableTree *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_mutable_tree_replace_file (OstreeMutableTree *self,
|
||||
const char *name,
|
||||
const char *checksum,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_mutable_tree_ensure_dir (OstreeMutableTree *self,
|
||||
const char *name,
|
||||
OstreeMutableTree **out_subdir,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_mutable_tree_lookup (OstreeMutableTree *self,
|
||||
const char *name,
|
||||
char **out_file_checksum,
|
||||
OstreeMutableTree **out_subdir,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
_OSTREE_PUBLIC gboolean
|
||||
ostree_mutable_tree_ensure_parent_dirs (OstreeMutableTree *self,
|
||||
GPtrArray *split_path,
|
||||
const char *metadata_checksum,
|
||||
OstreeMutableTree **out_parent,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_mutable_tree_walk (OstreeMutableTree *self,
|
||||
GPtrArray *split_path,
|
||||
guint start,
|
||||
OstreeMutableTree **out_subdir,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GHashTable * ostree_mutable_tree_get_subdirs (OstreeMutableTree *self);
|
||||
_OSTREE_PUBLIC
|
||||
GHashTable * ostree_mutable_tree_get_files (OstreeMutableTree *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ checkout_object_for_uncompressed_cache (OstreeRepo *self,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (G_UNLIKELY (res == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -91,7 +91,7 @@ checkout_object_for_uncompressed_cache (OstreeRepo *self,
|
|||
{
|
||||
if (errno != EEXIST)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
g_prefix_error (error, "Storing file '%s': ", temp_filename);
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -144,7 +144,7 @@ write_regular_file_content (OstreeRepo *self,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (G_UNLIKELY (res == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -153,13 +153,13 @@ write_regular_file_content (OstreeRepo *self,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (G_UNLIKELY (res == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (xattrs)
|
||||
{
|
||||
if (!gs_fd_set_all_xattrs (fd, xattrs, cancellable, error))
|
||||
if (!glnx_fd_set_all_xattrs (fd, xattrs, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -168,7 +168,7 @@ write_regular_file_content (OstreeRepo *self,
|
|||
{
|
||||
if (fsync (fd) == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -203,7 +203,7 @@ checkout_file_from_input_at (OstreeRepo *self,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (res == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -214,13 +214,13 @@ checkout_file_from_input_at (OstreeRepo *self,
|
|||
g_file_info_get_attribute_uint32 (file_info, "unix::gid"),
|
||||
AT_SYMLINK_NOFOLLOW) == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (xattrs)
|
||||
{
|
||||
if (!gs_dfd_and_name_set_all_xattrs (destination_dfd, destination_name,
|
||||
if (!glnx_dfd_name_set_all_xattrs (destination_dfd, destination_name,
|
||||
xattrs, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -242,7 +242,7 @@ checkout_file_from_input_at (OstreeRepo *self,
|
|||
while (G_UNLIKELY (fd == -1 && errno == EINTR));
|
||||
if (fd == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
temp_out = g_unix_output_stream_new (fd, TRUE);
|
||||
|
|
@ -288,7 +288,7 @@ checkout_file_unioning_from_input_at (OstreeRepo *repo,
|
|||
|
||||
if (xattrs)
|
||||
{
|
||||
if (!gs_dfd_and_name_set_all_xattrs (destination_dfd, temp_filename,
|
||||
if (!glnx_dfd_name_set_all_xattrs (destination_dfd, temp_filename,
|
||||
xattrs, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -318,7 +318,7 @@ checkout_file_unioning_from_input_at (OstreeRepo *repo,
|
|||
if (G_UNLIKELY (renameat (destination_dfd, temp_filename,
|
||||
destination_dfd, destination_name) == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -373,7 +373,7 @@ checkout_file_hardlink (OstreeRepo *self,
|
|||
else
|
||||
{
|
||||
g_prefix_error (error, "Hardlinking %s to %s: ", loose_path, destination_name);
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -650,14 +650,13 @@ checkout_tree_at (OstreeRepo *self,
|
|||
did_exist = TRUE;
|
||||
else
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gs_file_open_dir_fd_at (destination_parent_fd, destination_name,
|
||||
&destination_dfd,
|
||||
cancellable, error))
|
||||
if (!glnx_opendirat (destination_parent_fd, destination_name, TRUE,
|
||||
&destination_dfd, error))
|
||||
goto out;
|
||||
|
||||
/* Set the xattrs now, so any derived labeling works */
|
||||
|
|
@ -668,7 +667,7 @@ checkout_tree_at (OstreeRepo *self,
|
|||
|
||||
if (xattrs)
|
||||
{
|
||||
if (!gs_fd_set_all_xattrs (destination_dfd, xattrs, cancellable, error))
|
||||
if (!glnx_fd_set_all_xattrs (destination_dfd, xattrs, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -734,7 +733,7 @@ checkout_tree_at (OstreeRepo *self,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (G_UNLIKELY (res == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -748,7 +747,7 @@ checkout_tree_at (OstreeRepo *self,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (G_UNLIKELY (res == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -764,7 +763,7 @@ checkout_tree_at (OstreeRepo *self,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (G_UNLIKELY (res == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -773,7 +772,7 @@ checkout_tree_at (OstreeRepo *self,
|
|||
{
|
||||
if (fsync (destination_dfd) == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,10 +65,9 @@ _ostree_repo_ensure_loose_objdir_at (int dfd,
|
|||
loose_prefix[2] = '\0';
|
||||
if (mkdirat (dfd, loose_prefix, 0777) == -1)
|
||||
{
|
||||
int errsv = errno;
|
||||
if (G_UNLIKELY (errsv != EEXIST))
|
||||
if (G_UNLIKELY (errno != EEXIST))
|
||||
{
|
||||
gs_set_error_from_errno (error, errsv);
|
||||
glnx_set_error_from_errno (error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
|
@ -118,7 +117,7 @@ write_file_metadata_to_xattr (int fd,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (G_UNLIKELY (res == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
g_prefix_error (error, "Unable to set xattr: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -155,7 +154,7 @@ _ostree_repo_commit_loose_final (OstreeRepo *self,
|
|||
{
|
||||
if (errno != EEXIST)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
g_prefix_error (error, "Storing file '%s': ", temp_filename);
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -195,7 +194,7 @@ commit_loose_object_trusted (OstreeRepo *self,
|
|||
self->target_owner_gid,
|
||||
AT_SYMLINK_NOFOLLOW) == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -213,13 +212,13 @@ commit_loose_object_trusted (OstreeRepo *self,
|
|||
uid, gid,
|
||||
AT_SYMLINK_NOFOLLOW) == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (xattrs != NULL)
|
||||
{
|
||||
if (!gs_dfd_and_name_set_all_xattrs (self->tmp_dir_fd, temp_filename,
|
||||
if (!glnx_dfd_name_set_all_xattrs (self->tmp_dir_fd, temp_filename,
|
||||
xattrs, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -236,7 +235,7 @@ commit_loose_object_trusted (OstreeRepo *self,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (G_UNLIKELY (res == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -245,13 +244,13 @@ commit_loose_object_trusted (OstreeRepo *self,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (G_UNLIKELY (res == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (xattrs)
|
||||
{
|
||||
if (!gs_fd_set_all_xattrs (fd, xattrs, cancellable, error))
|
||||
if (!glnx_fd_set_all_xattrs (fd, xattrs, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -272,7 +271,7 @@ commit_loose_object_trusted (OstreeRepo *self,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (G_UNLIKELY (res == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -294,7 +293,7 @@ commit_loose_object_trusted (OstreeRepo *self,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (G_UNLIKELY (res == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -306,7 +305,7 @@ commit_loose_object_trusted (OstreeRepo *self,
|
|||
{
|
||||
if (fsync (fd) == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -453,7 +452,9 @@ fallocate_stream (GFileDescriptorBased *stream,
|
|||
int r = posix_fallocate (fd, 0, size);
|
||||
if (r != 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, r);
|
||||
/* posix_fallocate is a weird deviation from errno standards */
|
||||
errno = r;
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -511,7 +512,7 @@ _ostree_repo_commit_untrusted_content_bare (OstreeRepo *self,
|
|||
fd = openat (self->tmp_dir_fd, state->temp_filename, O_RDONLY);
|
||||
if (fd == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -597,7 +598,8 @@ _ostree_repo_open_trusted_content_bare (OstreeRepo *self,
|
|||
out_state->temp_filename = temp_filename;
|
||||
temp_filename = NULL;
|
||||
out_state->fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)ret_stream);
|
||||
gs_transfer_out_value (out_stream, &ret_stream);
|
||||
if (out_stream)
|
||||
*out_stream = g_steal_pointer (&ret_stream);
|
||||
}
|
||||
*out_have_object = have_obj;
|
||||
out:
|
||||
|
|
@ -843,7 +845,7 @@ write_object (OstreeRepo *self,
|
|||
|
||||
if (fstatat (self->tmp_dir_fd, temp_filename, &stbuf, AT_SYMLINK_NOFOLLOW) == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -1224,7 +1226,7 @@ rename_pending_loose_objects (OstreeRepo *self,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (res == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -1264,14 +1266,14 @@ rename_pending_loose_objects (OstreeRepo *self,
|
|||
if (G_UNLIKELY (renameat (child_dfd_iter.fd, loose_objpath + 3,
|
||||
self->objects_dir_fd, loose_objpath) < 0))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!gs_shutil_rm_rf_at (self->tmp_dir_fd, self->commit_stagedir_name,
|
||||
cancellable, error))
|
||||
if (!glnx_shutil_rm_rf_at (self->tmp_dir_fd, self->commit_stagedir_name,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
|
|
@ -1321,7 +1323,7 @@ cleanup_tmpdir (OstreeRepo *self,
|
|||
delta = curtime_secs - mtime;
|
||||
if (delta > 60*60*24)
|
||||
{
|
||||
if (!gs_shutil_rm_rf (path, cancellable, error))
|
||||
if (!glnx_shutil_rm_rf_at (AT_FDCWD, gs_file_get_path_cached (path), cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -1448,7 +1450,7 @@ ostree_repo_commit_transaction (OstreeRepo *self,
|
|||
|
||||
if (syncfs (self->tmp_dir_fd) < 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -2322,20 +2324,21 @@ get_modified_xattrs (OstreeRepo *self,
|
|||
{
|
||||
if (path)
|
||||
{
|
||||
if (!gs_file_get_all_xattrs (path, &ret_xattrs, cancellable, error))
|
||||
if (!glnx_dfd_name_get_all_xattrs (AT_FDCWD, gs_file_get_path_cached (path),
|
||||
&ret_xattrs, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else if (dfd_subpath == NULL)
|
||||
{
|
||||
g_assert (dfd != -1);
|
||||
if (!gs_fd_get_all_xattrs (dfd, &ret_xattrs,
|
||||
if (!glnx_fd_get_all_xattrs (dfd, &ret_xattrs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (dfd != -1);
|
||||
if (!gs_dfd_and_name_get_all_xattrs (dfd, dfd_subpath, &ret_xattrs,
|
||||
if (!glnx_dfd_name_get_all_xattrs (dfd, dfd_subpath, &ret_xattrs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -2371,7 +2374,8 @@ get_modified_xattrs (OstreeRepo *self,
|
|||
}
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_xattrs, &ret_xattrs);
|
||||
if (out_xattrs)
|
||||
*out_xattrs = g_steal_pointer (&ret_xattrs);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -2686,7 +2690,7 @@ write_dfd_iter_to_mtree_internal (OstreeRepo *self,
|
|||
|
||||
if (fstat (src_dfd_iter->fd, &dir_stbuf) != 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -2742,7 +2746,7 @@ write_dfd_iter_to_mtree_internal (OstreeRepo *self,
|
|||
|
||||
if (fstatat (src_dfd_iter->fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW) == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -2966,7 +2970,8 @@ ostree_repo_write_mtree (OstreeRepo *self,
|
|||
}
|
||||
|
||||
ret = TRUE;
|
||||
ot_transfer_out_value (out_file, &ret_file);
|
||||
if (out_file)
|
||||
*out_file = g_steal_pointer (&ret_file);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,38 +40,52 @@ struct _OstreeRepoFileClass
|
|||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_repo_file_get_type (void) G_GNUC_CONST;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_file_ensure_resolved (OstreeRepoFile *self,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_file_get_xattrs (OstreeRepoFile *self,
|
||||
GVariant **out_xattrs,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeRepo * ostree_repo_file_get_repo (OstreeRepoFile *self);
|
||||
_OSTREE_PUBLIC
|
||||
OstreeRepoFile * ostree_repo_file_get_root (OstreeRepoFile *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_repo_file_make_empty_tree (OstreeRepoFile *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_repo_file_tree_set_metadata (OstreeRepoFile *self,
|
||||
const char *checksum,
|
||||
GVariant *metadata);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
const char *ostree_repo_file_tree_get_contents_checksum (OstreeRepoFile *self);
|
||||
_OSTREE_PUBLIC
|
||||
const char *ostree_repo_file_tree_get_metadata_checksum (OstreeRepoFile *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GVariant *ostree_repo_file_tree_get_contents (OstreeRepoFile *self);
|
||||
_OSTREE_PUBLIC
|
||||
GVariant *ostree_repo_file_tree_get_metadata (OstreeRepoFile *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
const char * ostree_repo_file_get_checksum (OstreeRepoFile *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
int ostree_repo_file_tree_find_child (OstreeRepoFile *self,
|
||||
const char *name,
|
||||
gboolean *is_dir,
|
||||
GVariant **out_container);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_file_tree_query_child (OstreeRepoFile *self,
|
||||
int n,
|
||||
const char *attributes,
|
||||
|
|
|
|||
|
|
@ -290,7 +290,6 @@ write_libarchive_entry_to_mtree (OstreeRepo *self,
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
create_empty_dir_with_uidgid (OstreeRepo *self,
|
||||
|
|
@ -308,6 +307,7 @@ create_empty_dir_with_uidgid (OstreeRepo *self,
|
|||
|
||||
return _ostree_repo_write_directory_meta (self, tmp_dir_info, NULL, out_csum, cancellable, error);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ostree_repo_import_archive_to_mtree:
|
||||
|
|
@ -331,6 +331,7 @@ ostree_repo_import_archive_to_mtree (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
#ifdef HAVE_LIBARCHIVE
|
||||
gboolean ret = FALSE;
|
||||
struct archive *a = archive;
|
||||
struct archive_entry *entry;
|
||||
|
|
@ -393,6 +394,11 @@ ostree_repo_import_archive_to_mtree (OstreeRepo *self,
|
|||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
#else
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
"This version of ostree is not compiled with libarchive support");
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ G_BEGIN_DECLS
|
|||
|
||||
#define _OSTREE_OBJECT_SIZES_ENTRY_SIGNATURE "ay"
|
||||
|
||||
#define _OSTREE_SUMMARY_CACHE_PATH "tmp/cache/summaries"
|
||||
|
||||
/**
|
||||
* OstreeRepo:
|
||||
*
|
||||
|
|
@ -316,5 +318,23 @@ _ostree_repo_read_bare_fd (OstreeRepo *self,
|
|||
gboolean
|
||||
_ostree_repo_update_mtime (OstreeRepo *self,
|
||||
GError **error);
|
||||
|
||||
|
||||
/* Load the summary from the cache if the provided .sig file is the same as the
|
||||
cached version. */
|
||||
gboolean
|
||||
_ostree_repo_load_cache_summary_if_same_sig (OstreeRepo *self,
|
||||
const char *remote,
|
||||
GBytes *summary_sig,
|
||||
GBytes **summary,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
_ostree_repo_cache_summary (OstreeRepo *self,
|
||||
const char *remote,
|
||||
GBytes *summary,
|
||||
GBytes *summary_sig,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
|
|
@ -112,6 +112,68 @@ maybe_prune_loose_object (OtPruneData *data,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_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;
|
||||
|
||||
fd = glnx_opendirat_with_errno (self->repo_dir_fd, _OSTREE_SUMMARY_CACHE_PATH, 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;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
size_t len;
|
||||
gboolean has_sig_suffix = FALSE;
|
||||
struct dirent *dent;
|
||||
|
||||
if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (dent == NULL)
|
||||
break;
|
||||
|
||||
len = strlen (dent->d_name);
|
||||
if (len > 4 && g_strcmp0 (dent->d_name + len - 4, ".sig") == 0)
|
||||
{
|
||||
has_sig_suffix = TRUE;
|
||||
dent->d_name[len - 4] = '\0';
|
||||
}
|
||||
|
||||
if (!g_hash_table_contains (self->remotes, dent->d_name))
|
||||
{
|
||||
/* Restore the previous value to get the file name. */
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ostree_repo_prune_static_deltas:
|
||||
* @self: Repo
|
||||
|
|
@ -174,7 +236,7 @@ ostree_repo_prune_static_deltas (OstreeRepo *self, const char *commit,
|
|||
|
||||
deltadir = _ostree_get_relative_static_delta_path (from, to, NULL);
|
||||
|
||||
if (!gs_shutil_rm_rf_at (self->repo_dir_fd, deltadir,
|
||||
if (!glnx_shutil_rm_rf_at (self->repo_dir_fd, deltadir,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -241,10 +303,28 @@ ostree_repo_prune (OstreeRepo *self,
|
|||
while (g_hash_table_iter_next (&hash_iter, &key, &value))
|
||||
{
|
||||
const char *checksum = value;
|
||||
|
||||
if (!ostree_repo_traverse_commit_union (self, checksum, depth, data.reachable,
|
||||
cancellable, error))
|
||||
OstreeRepoCommitState commitstate;
|
||||
GError *local_error = NULL;
|
||||
|
||||
if (!ostree_repo_load_commit (self, checksum, NULL, &commitstate,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_repo_traverse_commit_union (self, checksum, depth, data.reachable,
|
||||
cancellable, &local_error))
|
||||
{
|
||||
/* Don't fail traversing a partial commit */
|
||||
if ((commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL) > 0 &&
|
||||
g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||||
{
|
||||
g_clear_error (&local_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_propagate_error (error, local_error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -260,15 +340,33 @@ ostree_repo_prune (OstreeRepo *self,
|
|||
GVariant *serialized_key = key;
|
||||
const char *checksum;
|
||||
OstreeObjectType objtype;
|
||||
OstreeRepoCommitState commitstate;
|
||||
GError *local_error = NULL;
|
||||
|
||||
ostree_object_name_deserialize (serialized_key, &checksum, &objtype);
|
||||
|
||||
if (objtype != OSTREE_OBJECT_TYPE_COMMIT)
|
||||
continue;
|
||||
|
||||
if (!ostree_repo_traverse_commit_union (self, checksum, depth, data.reachable,
|
||||
cancellable, error))
|
||||
|
||||
if (!ostree_repo_load_commit (self, checksum, NULL, &commitstate,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_repo_traverse_commit_union (self, checksum, depth, data.reachable,
|
||||
cancellable, &local_error))
|
||||
{
|
||||
/* Don't fail traversing a partial commit */
|
||||
if ((commitstate & OSTREE_REPO_COMMIT_STATE_PARTIAL) > 0 &&
|
||||
g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||||
{
|
||||
g_clear_error (&local_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_propagate_error (error, local_error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -295,6 +393,9 @@ ostree_repo_prune (OstreeRepo *self,
|
|||
if (!ostree_repo_prune_static_deltas (self, NULL, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!_ostree_repo_prune_tmp (self, cancellable, error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
*out_objects_total = (data.n_reachable_meta + data.n_unreachable_meta +
|
||||
data.n_reachable_content + data.n_unreachable_content);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "ostree-repo-static-delta-private.h"
|
||||
#include "ostree-metalink.h"
|
||||
#include "otutil.h"
|
||||
#include "ot-fs-utils.h"
|
||||
|
||||
#include <gio/gunixinputstream.h>
|
||||
|
||||
|
|
@ -794,7 +795,7 @@ meta_fetch_on_complete (GObject *object,
|
|||
OstreeObjectType objtype;
|
||||
GError *local_error = NULL;
|
||||
GError **error = &local_error;
|
||||
gs_fd_close int fd = -1;
|
||||
glnx_fd_close int fd = -1;
|
||||
|
||||
ostree_object_name_deserialize (fetch_data->object, &checksum, &objtype);
|
||||
g_debug ("fetch of %s%s complete", ostree_object_to_string (checksum, objtype),
|
||||
|
|
@ -840,7 +841,7 @@ meta_fetch_on_complete (GObject *object,
|
|||
fd = openat (_ostree_fetcher_get_dfd (fetcher), temp_path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -949,7 +950,7 @@ static_deltapart_fetch_on_complete (GObject *object,
|
|||
g_autoptr(GVariant) part = NULL;
|
||||
GError *local_error = NULL;
|
||||
GError **error = &local_error;
|
||||
gs_fd_close int fd = -1;
|
||||
glnx_fd_close int fd = -1;
|
||||
|
||||
g_debug ("fetch static delta part %s complete", fetch_data->expected_checksum);
|
||||
|
||||
|
|
@ -1187,7 +1188,8 @@ scan_one_metadata_object_c (OtPullData *pull_data,
|
|||
|
||||
if (pull_data->remote_repo_local)
|
||||
{
|
||||
if (!ostree_repo_import_object_from (pull_data->repo, pull_data->remote_repo_local,
|
||||
if (!is_stored &&
|
||||
!ostree_repo_import_object_from (pull_data->repo, pull_data->remote_repo_local,
|
||||
objtype, tmp_checksum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
|
@ -1398,8 +1400,8 @@ request_static_delta_superblock_sync (OtPullData *pull_data,
|
|||
if (delta_superblock_data)
|
||||
{
|
||||
{
|
||||
gs_free gchar *delta = NULL;
|
||||
gs_free guchar *ret_csum = NULL;
|
||||
g_autofree gchar *delta = NULL;
|
||||
g_autofree guchar *ret_csum = NULL;
|
||||
guchar *summary_csum;
|
||||
g_autoptr (GInputStream) summary_is = NULL;
|
||||
|
||||
|
|
@ -1436,7 +1438,8 @@ request_static_delta_superblock_sync (OtPullData *pull_data,
|
|||
}
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_delta_superblock, &ret_delta_superblock);
|
||||
if (out_delta_superblock)
|
||||
*out_delta_superblock = g_steal_pointer (&ret_delta_superblock);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1767,6 +1770,102 @@ ostree_repo_pull_one_dir (OstreeRepo *self,
|
|||
progress, cancellable, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_ostree_repo_load_cache_summary_if_same_sig (OstreeRepo *self,
|
||||
const char *remote,
|
||||
GBytes *summary_sig,
|
||||
GBytes **summary,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
const char *summary_cache_sig_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_PATH, "/", remote, ".sig");
|
||||
|
||||
glnx_fd_close int prev_fd = -1;
|
||||
g_autoptr(GBytes) old_sig_contents = NULL;
|
||||
|
||||
if (!ot_openat_ignore_enoent (self->repo_dir_fd, summary_cache_sig_file, &prev_fd, error))
|
||||
goto out;
|
||||
|
||||
if (prev_fd < 0)
|
||||
{
|
||||
ret = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
old_sig_contents = glnx_fd_readall_bytes (prev_fd, cancellable, error);
|
||||
if (!old_sig_contents)
|
||||
goto out;
|
||||
|
||||
if (g_bytes_compare (old_sig_contents, summary_sig) == 0)
|
||||
{
|
||||
const char *summary_cache_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_PATH, "/", remote);
|
||||
glnx_fd_close int summary_fd = -1;
|
||||
GBytes *summary_data;
|
||||
|
||||
|
||||
summary_fd = openat (self->repo_dir_fd, summary_cache_file, O_CLOEXEC | O_RDONLY);
|
||||
if (summary_fd < 0)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
(void) unlinkat (self->repo_dir_fd, summary_cache_sig_file, 0);
|
||||
ret = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
summary_data = glnx_fd_readall_bytes (summary_fd, cancellable, error);
|
||||
if (!summary_data)
|
||||
goto out;
|
||||
*summary = summary_data;
|
||||
}
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_ostree_repo_cache_summary (OstreeRepo *self,
|
||||
const char *remote,
|
||||
GBytes *summary,
|
||||
GBytes *summary_sig,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
const char *summary_cache_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_PATH, "/", remote);
|
||||
const char *summary_cache_sig_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_PATH, "/", remote, ".sig");
|
||||
|
||||
if (!glnx_shutil_mkdir_p_at (self->repo_dir_fd, _OSTREE_SUMMARY_CACHE_PATH, 0775, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!glnx_file_replace_contents_at (self->repo_dir_fd,
|
||||
summary_cache_file,
|
||||
g_bytes_get_data (summary, NULL),
|
||||
g_bytes_get_size (summary),
|
||||
self->disable_fsync ? GLNX_FILE_REPLACE_NODATASYNC : GLNX_FILE_REPLACE_DATASYNC_NEW,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!glnx_file_replace_contents_at (self->repo_dir_fd,
|
||||
summary_cache_sig_file,
|
||||
g_bytes_get_data (summary_sig, NULL),
|
||||
g_bytes_get_size (summary_sig),
|
||||
self->disable_fsync ? GLNX_FILE_REPLACE_NODATASYNC : GLNX_FILE_REPLACE_DATASYNC_NEW,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/* Documented in ostree-repo.c */
|
||||
gboolean
|
||||
ostree_repo_pull_with_options (OstreeRepo *self,
|
||||
|
|
@ -1995,15 +2094,36 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
|||
g_autoptr(GVariant) refs = NULL;
|
||||
g_autoptr(GVariant) deltas = NULL;
|
||||
g_autoptr(GVariant) additional_metadata = NULL;
|
||||
|
||||
if (!pull_data->summary)
|
||||
gboolean summary_from_cache = FALSE;
|
||||
|
||||
if (!pull_data->summary_data_sig)
|
||||
{
|
||||
uri = suburi_new (pull_data->base_uri, "summary.sig", NULL);
|
||||
if (!fetch_uri_contents_membuf_sync (pull_data, uri, FALSE, TRUE,
|
||||
&bytes_sig, cancellable, error))
|
||||
goto out;
|
||||
soup_uri_free (uri);
|
||||
}
|
||||
|
||||
if (bytes_sig && !_ostree_repo_load_cache_summary_if_same_sig (self,
|
||||
remote_name_or_baseurl,
|
||||
bytes_sig,
|
||||
&bytes_summary,
|
||||
cancellable,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
if (bytes_summary)
|
||||
summary_from_cache = TRUE;
|
||||
|
||||
if (!pull_data->summary && !bytes_summary)
|
||||
{
|
||||
uri = suburi_new (pull_data->base_uri, "summary", NULL);
|
||||
if (!fetch_uri_contents_membuf_sync (pull_data, uri, FALSE, TRUE,
|
||||
&bytes_summary, cancellable, error))
|
||||
goto out;
|
||||
soup_uri_free (uri);
|
||||
}
|
||||
}
|
||||
|
||||
if (!bytes_summary && pull_data->gpg_verify_summary)
|
||||
{
|
||||
|
|
@ -2019,15 +2139,6 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (bytes_summary)
|
||||
{
|
||||
uri = suburi_new (pull_data->base_uri, "summary.sig", NULL);
|
||||
if (!fetch_uri_contents_membuf_sync (pull_data, uri, FALSE, TRUE,
|
||||
&bytes_sig, cancellable, error))
|
||||
goto out;
|
||||
soup_uri_free (uri);
|
||||
}
|
||||
|
||||
if (!bytes_sig && pull_data->gpg_verify_summary)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
|
|
@ -2044,6 +2155,18 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
|||
pull_data->summary_data_sig = g_bytes_ref (bytes_sig);
|
||||
}
|
||||
|
||||
|
||||
if (!summary_from_cache && bytes_summary && bytes_sig)
|
||||
{
|
||||
if (!_ostree_repo_cache_summary (self,
|
||||
remote_name_or_baseurl,
|
||||
bytes_summary,
|
||||
bytes_sig,
|
||||
cancellable,
|
||||
error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pull_data->gpg_verify_summary && bytes_summary && bytes_sig)
|
||||
{
|
||||
g_autoptr(GVariant) sig_variant = NULL;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "ostree-repo-private.h"
|
||||
#include "otutil.h"
|
||||
#include "ot-fs-utils.h"
|
||||
|
||||
static gboolean
|
||||
add_ref_to_set (const char *remote,
|
||||
|
|
@ -114,31 +115,6 @@ write_checksum_file_at (OstreeRepo *self,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
openat_ignore_enoent (int dfd,
|
||||
const char *path,
|
||||
int *out_fd,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
int target_fd = -1;
|
||||
|
||||
target_fd = openat (dfd, path, O_CLOEXEC | O_RDONLY);
|
||||
if (target_fd < 0)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
*out_fd = target_fd;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
find_ref_in_remotes (OstreeRepo *self,
|
||||
const char *rev,
|
||||
|
|
@ -168,7 +144,7 @@ find_ref_in_remotes (OstreeRepo *self,
|
|||
if (!glnx_opendirat (dfd_iter.fd, dent->d_name, TRUE, &remote_dfd, error))
|
||||
goto out;
|
||||
|
||||
if (!openat_ignore_enoent (remote_dfd, rev, &ret_fd, error))
|
||||
if (!ot_openat_ignore_enoent (remote_dfd, rev, &ret_fd, error))
|
||||
goto out;
|
||||
|
||||
if (ret_fd != -1)
|
||||
|
|
@ -247,21 +223,21 @@ resolve_refspec (OstreeRepo *self,
|
|||
{
|
||||
const char *remote_ref = glnx_strjoina ("refs/remotes/", remote, "/", ref);
|
||||
|
||||
if (!openat_ignore_enoent (self->repo_dir_fd, remote_ref, &target_fd, error))
|
||||
if (!ot_openat_ignore_enoent (self->repo_dir_fd, remote_ref, &target_fd, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *local_ref = glnx_strjoina ("refs/heads/", ref);
|
||||
|
||||
if (!openat_ignore_enoent (self->repo_dir_fd, local_ref, &target_fd, error))
|
||||
if (!ot_openat_ignore_enoent (self->repo_dir_fd, local_ref, &target_fd, error))
|
||||
goto out;
|
||||
|
||||
if (target_fd == -1)
|
||||
{
|
||||
local_ref = glnx_strjoina ("refs/remotes/", ref);
|
||||
|
||||
if (!openat_ignore_enoent (self->repo_dir_fd, local_ref, &target_fd, error))
|
||||
if (!ot_openat_ignore_enoent (self->repo_dir_fd, local_ref, &target_fd, error))
|
||||
goto out;
|
||||
|
||||
if (target_fd == -1)
|
||||
|
|
@ -508,24 +484,13 @@ enumerate_refs_recurse (OstreeRepo *repo,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_list_refs:
|
||||
* @self: Repo
|
||||
* @refspec_prefix: (allow-none): Only list refs which match this prefix
|
||||
* @out_all_refs: (out) (element-type utf8 utf8): Mapping from ref to checksum
|
||||
* @cancellable: Cancellable
|
||||
* @error: Error
|
||||
*
|
||||
* If @refspec_prefix is %NULL, list all local and remote refspecs,
|
||||
* with their current values in @out_all_refs. Otherwise, only list
|
||||
* refspecs which have @refspec_prefix as a prefix.
|
||||
*/
|
||||
gboolean
|
||||
ostree_repo_list_refs (OstreeRepo *self,
|
||||
const char *refspec_prefix,
|
||||
GHashTable **out_all_refs,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
static gboolean
|
||||
_ostree_repo_list_refs_internal (OstreeRepo *self,
|
||||
gboolean cut_prefix,
|
||||
const char *refspec_prefix,
|
||||
GHashTable **out_all_refs,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
g_autoptr(GHashTable) ret_all_refs = NULL;
|
||||
|
|
@ -568,12 +533,14 @@ ostree_repo_list_refs (OstreeRepo *self,
|
|||
{
|
||||
glnx_fd_close int base_fd = -1;
|
||||
g_autoptr(GString) base_path = g_string_new ("");
|
||||
if (!cut_prefix)
|
||||
g_string_printf (base_path, "%s/", ref_prefix);
|
||||
|
||||
if (!glnx_opendirat (self->repo_dir_fd, path, TRUE, &base_fd, error))
|
||||
if (!glnx_opendirat (self->repo_dir_fd, cut_prefix ? path : prefix_path, TRUE, &base_fd, error))
|
||||
goto out;
|
||||
|
||||
if (!enumerate_refs_recurse (self, remote, base_fd, base_path,
|
||||
base_fd, ".",
|
||||
base_fd, cut_prefix ? "." : ref_prefix,
|
||||
ret_all_refs, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -639,6 +606,54 @@ ostree_repo_list_refs (OstreeRepo *self,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_list_refs:
|
||||
* @self: Repo
|
||||
* @refspec_prefix: (allow-none): Only list refs which match this prefix
|
||||
* @out_all_refs: (out) (element-type utf8 utf8): Mapping from ref to checksum
|
||||
* @cancellable: Cancellable
|
||||
* @error: Error
|
||||
*
|
||||
* If @refspec_prefix is %NULL, list all local and remote refspecs,
|
||||
* with their current values in @out_all_refs. Otherwise, only list
|
||||
* refspecs which have @refspec_prefix as a prefix.
|
||||
*/
|
||||
gboolean
|
||||
ostree_repo_list_refs (OstreeRepo *self,
|
||||
const char *refspec_prefix,
|
||||
GHashTable **out_all_refs,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
return _ostree_repo_list_refs_internal (self, TRUE, refspec_prefix, out_all_refs, cancellable, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_list_refs_ext:
|
||||
* @self: Repo
|
||||
* @refspec_prefix: (allow-none): Only list refs which match this prefix
|
||||
* @out_all_refs: (out) (element-type utf8 utf8): Mapping from ref to checksum
|
||||
* @flags: Options controlling listing behavior
|
||||
* @cancellable: Cancellable
|
||||
* @error: Error
|
||||
*
|
||||
* If @refspec_prefix is %NULL, list all local and remote refspecs,
|
||||
* with their current values in @out_all_refs. Otherwise, only list
|
||||
* refspecs which have @refspec_prefix as a prefix. Differently from
|
||||
* ostree_repo_list_refs(), the prefix will not be removed from the ref
|
||||
* name.
|
||||
*/
|
||||
gboolean
|
||||
ostree_repo_list_refs_ext (OstreeRepo *self,
|
||||
const char *refspec_prefix,
|
||||
GHashTable **out_all_refs,
|
||||
OstreeRepoListRefsExtFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
return _ostree_repo_list_refs_internal (self, FALSE, refspec_prefix, out_all_refs, cancellable, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_remote_list_refs:
|
||||
* @self: Repo
|
||||
|
|
|
|||
|
|
@ -181,7 +181,8 @@ build_content_sizenames_filtered (OstreeRepo *repo,
|
|||
g_ptr_array_sort (ret_sizenames, compare_sizenames);
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_sizenames, &ret_sizenames);
|
||||
if (out_sizenames)
|
||||
*out_sizenames = g_steal_pointer (&ret_sizenames);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -296,7 +297,8 @@ _ostree_delta_compute_similar_objects (OstreeRepo *repo,
|
|||
}
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_modified_regfile_content, &ret_modified_regfile_content);
|
||||
if (out_modified_regfile_content)
|
||||
*out_modified_regfile_content = g_steal_pointer (&ret_modified_regfile_content);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -456,7 +456,7 @@ get_unpacked_unlinked_content (OstreeRepo *repo,
|
|||
{
|
||||
gboolean ret = FALSE;
|
||||
g_autofree char *tmpname = g_strdup ("tmpostree-deltaobj-XXXXXX");
|
||||
gs_fd_close int fd = -1;
|
||||
glnx_fd_close int fd = -1;
|
||||
g_autoptr(GBytes) ret_content = NULL;
|
||||
g_autoptr(GInputStream) istream = NULL;
|
||||
g_autoptr(GFileInfo) ret_finfo = NULL;
|
||||
|
|
@ -465,7 +465,7 @@ get_unpacked_unlinked_content (OstreeRepo *repo,
|
|||
fd = g_mkstemp (tmpname);
|
||||
if (fd == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
/* Doesn't need a name */
|
||||
|
|
@ -488,7 +488,8 @@ get_unpacked_unlinked_content (OstreeRepo *repo,
|
|||
}
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_content, &ret_content);
|
||||
if (out_content)
|
||||
*out_content = g_steal_pointer (&ret_content);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -532,7 +533,8 @@ try_content_bsdiff (OstreeRepo *repo,
|
|||
ret_bsdiff->tmp_to = tmp_to; tmp_to = NULL;
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_bsdiff, &ret_bsdiff);
|
||||
if (out_bsdiff)
|
||||
*out_bsdiff = g_steal_pointer (&ret_bsdiff);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -597,7 +599,8 @@ try_content_rollsum (OstreeRepo *repo,
|
|||
ret_rollsum->tmp_to = tmp_to; tmp_to = NULL;
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_rollsum, &ret_rollsum);
|
||||
if (out_rollsum)
|
||||
*out_rollsum = g_steal_pointer (&ret_rollsum);
|
||||
out:
|
||||
if (matches)
|
||||
_ostree_rollsum_matches_free (matches);
|
||||
|
|
@ -1199,7 +1202,8 @@ get_fallback_headers (OstreeRepo *self,
|
|||
ret_headers = g_variant_ref_sink (g_variant_builder_end (fallback_builder));
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_headers, &ret_headers);
|
||||
if (out_headers)
|
||||
*out_headers = g_steal_pointer (&ret_headers);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -754,7 +754,7 @@ dispatch_write (OstreeRepo *repo,
|
|||
{
|
||||
if (lseek (state->read_source_fd, content_offset, SEEK_SET) == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
while (content_size > 0)
|
||||
|
|
@ -767,7 +767,7 @@ dispatch_write (OstreeRepo *repo,
|
|||
while (G_UNLIKELY (bytes_read == -1 && errno == EINTR));
|
||||
if (bytes_read == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
if (G_UNLIKELY (bytes_read == 0))
|
||||
|
|
|
|||
|
|
@ -377,9 +377,8 @@ traverse_dirtree (OstreeRepo *repo,
|
|||
ostree_cleanup_repo_commit_traverse_iter
|
||||
OstreeRepoCommitTraverseIter iter = { 0, };
|
||||
|
||||
if (!ostree_repo_load_variant_if_exists (repo, OSTREE_OBJECT_TYPE_DIR_TREE,
|
||||
checksum, &dirtree,
|
||||
error))
|
||||
if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_DIR_TREE, checksum,
|
||||
&dirtree, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_repo_commit_traverse_iter_init_dirtree (&iter, repo, dirtree,
|
||||
|
|
@ -503,7 +502,8 @@ ostree_repo_traverse_commit (OstreeRepo *repo,
|
|||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_reachable, &ret_reachable);
|
||||
if (out_reachable)
|
||||
*out_reachable = g_steal_pointer (&ret_reachable);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "ostree-repo-file-enumerator.h"
|
||||
#include "ostree-gpg-verifier.h"
|
||||
#include "ostree-repo-static-delta-private.h"
|
||||
#include "ot-fs-utils.h"
|
||||
|
||||
#ifdef HAVE_LIBSOUP
|
||||
#include "ostree-metalink.h"
|
||||
|
|
@ -1749,9 +1750,7 @@ repo_remote_fetch_summary (OstreeRepo *self,
|
|||
g_autoptr(GMainContext) mainctx = NULL;
|
||||
gboolean ret = FALSE;
|
||||
SoupURI *base_uri = NULL;
|
||||
uint i;
|
||||
const char *filenames[] = {"summary", "summary.sig"};
|
||||
GBytes **outputs[] = {out_summary, out_signatures};
|
||||
gboolean from_cache = FALSE;
|
||||
|
||||
mainctx = g_main_context_new ();
|
||||
g_main_context_push_thread_default (mainctx);
|
||||
|
|
@ -1781,19 +1780,63 @@ repo_remote_fetch_summary (OstreeRepo *self,
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (filenames); i++)
|
||||
if (!_ostree_preload_metadata_file (self,
|
||||
fetcher,
|
||||
base_uri,
|
||||
"summary.sig",
|
||||
metalink_url_string ? TRUE : FALSE,
|
||||
out_signatures,
|
||||
cancellable,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
if (*out_signatures)
|
||||
{
|
||||
if (!_ostree_repo_load_cache_summary_if_same_sig (self,
|
||||
name,
|
||||
*out_signatures,
|
||||
out_summary,
|
||||
cancellable,
|
||||
error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (*out_summary)
|
||||
from_cache = TRUE;
|
||||
else
|
||||
{
|
||||
if (!_ostree_preload_metadata_file (self,
|
||||
fetcher,
|
||||
base_uri,
|
||||
filenames[i],
|
||||
"summary",
|
||||
metalink_url_string ? TRUE : FALSE,
|
||||
outputs[i],
|
||||
out_summary,
|
||||
cancellable,
|
||||
error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!from_cache && *out_summary && *out_signatures)
|
||||
{
|
||||
g_autoptr(GError) temp_error = NULL;
|
||||
|
||||
if (!_ostree_repo_cache_summary (self,
|
||||
name,
|
||||
*out_summary,
|
||||
*out_signatures,
|
||||
cancellable,
|
||||
&temp_error))
|
||||
{
|
||||
if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED))
|
||||
g_debug ("No permissions to save summary cache");
|
||||
else
|
||||
{
|
||||
g_propagate_error (error, g_steal_pointer (&temp_error));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
|
|
@ -2072,7 +2115,8 @@ enumerate_directory_allow_noent (GFile *dirpath,
|
|||
}
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_direnum, &ret_direnum);
|
||||
if (out_direnum)
|
||||
*out_direnum = g_steal_pointer (&ret_direnum);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -2227,14 +2271,15 @@ ostree_repo_open (OstreeRepo *self,
|
|||
goto out;
|
||||
g_strdelimit (self->boot_id, "\n", '\0');
|
||||
|
||||
if (!gs_file_open_dir_fd (self->repodir, &self->repo_dir_fd, cancellable, error))
|
||||
if (!glnx_opendirat (AT_FDCWD, gs_file_get_path_cached (self->repodir), TRUE,
|
||||
&self->repo_dir_fd, error))
|
||||
{
|
||||
g_prefix_error (error, "%s: ", gs_file_get_path_cached (self->repodir));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!gs_file_open_dir_fd_at (self->repo_dir_fd, "objects",
|
||||
&self->objects_dir_fd, cancellable, error))
|
||||
if (!glnx_opendirat (self->repo_dir_fd, "objects", TRUE,
|
||||
&self->objects_dir_fd, error))
|
||||
{
|
||||
g_prefix_error (error, "Opening objects/ directory: ");
|
||||
goto out;
|
||||
|
|
@ -2244,12 +2289,12 @@ ostree_repo_open (OstreeRepo *self,
|
|||
if (!self->writable)
|
||||
{
|
||||
/* This is returned through ostree_repo_is_writable(). */
|
||||
gs_set_error_from_errno (&self->writable_error, errno);
|
||||
glnx_set_error_from_errno (&self->writable_error);
|
||||
}
|
||||
|
||||
if (fstat (self->objects_dir_fd, &stbuf) != 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -2343,16 +2388,16 @@ ostree_repo_open (OstreeRepo *self,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (!gs_file_open_dir_fd (self->tmp_dir, &self->tmp_dir_fd, cancellable, error))
|
||||
if (!glnx_opendirat (self->repo_dir_fd, "tmp", TRUE, &self->tmp_dir_fd, error))
|
||||
goto out;
|
||||
|
||||
if (self->mode == OSTREE_REPO_MODE_ARCHIVE_Z2 && self->enable_uncompressed_cache)
|
||||
{
|
||||
if (!gs_file_ensure_directory (self->uncompressed_objects_dir, TRUE, cancellable, error))
|
||||
goto out;
|
||||
if (!gs_file_open_dir_fd (self->uncompressed_objects_dir,
|
||||
&self->uncompressed_objects_dir_fd,
|
||||
cancellable, error))
|
||||
if (!glnx_opendirat (self->repo_dir_fd, "uncompressed-objects-cache", TRUE,
|
||||
&self->uncompressed_objects_dir_fd,
|
||||
error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -2423,6 +2468,24 @@ ostree_repo_get_path (OstreeRepo *self)
|
|||
return self->repodir;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_get_dfd:
|
||||
* @self: Repo
|
||||
*
|
||||
* In some cases it's useful for applications to access the repository
|
||||
* directly; for example, writing content into `repo/tmp` ensures it's
|
||||
* on the same filesystem. Another case is detecting the mtime on the
|
||||
* repository (to see whether a ref was written).
|
||||
*
|
||||
* Returns: File descriptor for repository root - owned by @self
|
||||
*/
|
||||
int
|
||||
ostree_repo_get_dfd (OstreeRepo *self)
|
||||
{
|
||||
g_return_val_if_fail (self->repo_dir_fd != -1, -1);
|
||||
return self->repo_dir_fd;
|
||||
}
|
||||
|
||||
OstreeRepoMode
|
||||
ostree_repo_get_mode (OstreeRepo *self)
|
||||
{
|
||||
|
|
@ -2463,7 +2526,7 @@ list_loose_objects_at (OstreeRepo *self,
|
|||
d = fdopendir (dfd);
|
||||
if (!d)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -2557,7 +2620,7 @@ list_loose_objects (OstreeRepo *self,
|
|||
continue;
|
||||
else
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -2573,32 +2636,6 @@ list_loose_objects (OstreeRepo *self,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
openat_allow_noent (int dfd,
|
||||
const char *path,
|
||||
int *fd,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
GError *temp_error = NULL;
|
||||
|
||||
if (!gs_file_openat_noatime (dfd, path, fd,
|
||||
cancellable, &temp_error))
|
||||
{
|
||||
if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||||
{
|
||||
*fd = -1;
|
||||
g_clear_error (&temp_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_propagate_error (error, temp_error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_metadata_internal (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
|
|
@ -2620,14 +2657,14 @@ load_metadata_internal (OstreeRepo *self,
|
|||
|
||||
_ostree_loose_path (loose_path_buf, sha256, objtype, self->mode);
|
||||
|
||||
if (!openat_allow_noent (self->objects_dir_fd, loose_path_buf, &fd,
|
||||
cancellable, error))
|
||||
if (!ot_openat_ignore_enoent (self->objects_dir_fd, loose_path_buf, &fd,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
if (fd < 0 && self->commit_stagedir_fd != -1)
|
||||
{
|
||||
if (!openat_allow_noent (self->commit_stagedir_fd, loose_path_buf, &fd,
|
||||
cancellable, error))
|
||||
if (!ot_openat_ignore_enoent (self->commit_stagedir_fd, loose_path_buf, &fd,
|
||||
error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -2714,7 +2751,7 @@ query_info_for_bare_content_object (OstreeRepo *self,
|
|||
ret = TRUE;
|
||||
goto out;
|
||||
}
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -2738,7 +2775,8 @@ query_info_for_bare_content_object (OstreeRepo *self,
|
|||
}
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_info, &ret_info);
|
||||
if (out_info)
|
||||
*out_info = g_steal_pointer (&ret_info);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -2821,8 +2859,8 @@ ostree_repo_load_file (OstreeRepo *self,
|
|||
struct stat stbuf;
|
||||
g_autoptr(GInputStream) tmp_stream = NULL;
|
||||
|
||||
if (!openat_allow_noent (self->objects_dir_fd, loose_path_buf, &fd,
|
||||
cancellable, error))
|
||||
if (!ot_openat_ignore_enoent (self->objects_dir_fd, loose_path_buf, &fd,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
if (fd != -1)
|
||||
|
|
@ -2859,7 +2897,7 @@ ostree_repo_load_file (OstreeRepo *self,
|
|||
guint32 mode;
|
||||
g_autoptr(GVariant) metadata = NULL;
|
||||
g_autoptr(GBytes) bytes = NULL;
|
||||
gs_fd_close int fd = -1;
|
||||
glnx_fd_close int fd = -1;
|
||||
|
||||
bytes = ot_lgetxattrat (self->objects_dir_fd, loose_path_buf,
|
||||
"user.ostreemeta", error);
|
||||
|
|
@ -2918,7 +2956,7 @@ ostree_repo_load_file (OstreeRepo *self,
|
|||
if (g_file_info_get_file_type (ret_file_info) == G_FILE_TYPE_REGULAR
|
||||
&& (out_input || out_xattrs))
|
||||
{
|
||||
gs_fd_close int fd = -1;
|
||||
glnx_fd_close int fd = -1;
|
||||
|
||||
if (!gs_file_openat_noatime (self->objects_dir_fd, loose_path_buf, &fd,
|
||||
cancellable, error))
|
||||
|
|
@ -2926,7 +2964,7 @@ ostree_repo_load_file (OstreeRepo *self,
|
|||
|
||||
if (out_xattrs)
|
||||
{
|
||||
if (!gs_fd_get_all_xattrs (fd, &ret_xattrs,
|
||||
if (!glnx_fd_get_all_xattrs (fd, &ret_xattrs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -2940,7 +2978,7 @@ ostree_repo_load_file (OstreeRepo *self,
|
|||
else if (g_file_info_get_file_type (ret_file_info) == G_FILE_TYPE_SYMBOLIC_LINK
|
||||
&& out_xattrs)
|
||||
{
|
||||
if (!gs_dfd_and_name_get_all_xattrs (self->objects_dir_fd, loose_path_buf,
|
||||
if (!glnx_dfd_name_get_all_xattrs (self->objects_dir_fd, loose_path_buf,
|
||||
&ret_xattrs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
|
@ -3063,7 +3101,7 @@ _ostree_repo_has_loose_object (OstreeRepo *self,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (res == -1 && errno != ENOENT)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -3077,7 +3115,7 @@ _ostree_repo_has_loose_object (OstreeRepo *self,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (res == -1 && errno != ENOENT)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -3195,7 +3233,7 @@ ostree_repo_delete_object (OstreeRepo *self,
|
|||
{
|
||||
if (G_UNLIKELY (errno != ENOENT))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -3206,7 +3244,7 @@ ostree_repo_delete_object (OstreeRepo *self,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (G_UNLIKELY (res == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -3342,7 +3380,7 @@ import_one_object_link (OstreeRepo *self,
|
|||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -3446,7 +3484,7 @@ ostree_repo_query_object_storage_size (OstreeRepo *self,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (G_UNLIKELY (res == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -4053,7 +4091,8 @@ sign_data (OstreeRepo *self,
|
|||
ret_signature = g_mapped_file_get_bytes (signature_file);
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_signature, &ret_signature);
|
||||
if (out_signature)
|
||||
*out_signature = g_steal_pointer (&ret_signature);
|
||||
out:
|
||||
if (commit_buffer)
|
||||
gpgme_data_release (commit_buffer);
|
||||
|
|
@ -4601,11 +4640,11 @@ ostree_repo_regenerate_summary (OstreeRepo *self,
|
|||
g_variant_dict_init (&deltas_builder, NULL);
|
||||
for (i = 0; i < delta_names->len; i++)
|
||||
{
|
||||
gs_free char *from = NULL;
|
||||
gs_free char *to = NULL;
|
||||
gs_free guchar *csum = NULL;
|
||||
gs_free char *superblock = NULL;
|
||||
gs_fd_close int superblock_file_fd = -1;
|
||||
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;
|
||||
|
||||
_ostree_parse_delta_name (delta_names->pdata[i], &from, &to);
|
||||
|
|
@ -4613,7 +4652,7 @@ ostree_repo_regenerate_summary (OstreeRepo *self,
|
|||
superblock_file_fd = openat (self->repo_dir_fd, superblock, O_RDONLY | O_CLOEXEC);
|
||||
if (superblock_file_fd == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -4656,7 +4695,7 @@ ostree_repo_regenerate_summary (OstreeRepo *self,
|
|||
{
|
||||
if (errno != ENOENT)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,46 +36,65 @@ G_BEGIN_DECLS
|
|||
#define OSTREE_IS_REPO(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSTREE_TYPE_REPO))
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_mode_from_string (const char *mode,
|
||||
OstreeRepoMode *out_mode,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_repo_get_type (void);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeRepo* ostree_repo_new (GFile *path);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeRepo* ostree_repo_new_for_sysroot_path (GFile *repo_path,
|
||||
GFile *sysroot_path);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeRepo* ostree_repo_new_default (void);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_open (OstreeRepo *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_repo_set_disable_fsync (OstreeRepo *self,
|
||||
gboolean disable_fsync);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_get_disable_fsync (OstreeRepo *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_is_system (OstreeRepo *repo);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_is_writable (OstreeRepo *self,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_create (OstreeRepo *self,
|
||||
OstreeRepoMode mode,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GFile * ostree_repo_get_path (OstreeRepo *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
int ostree_repo_get_dfd (OstreeRepo *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeRepoMode ostree_repo_get_mode (OstreeRepo *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GKeyFile * ostree_repo_get_config (OstreeRepo *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GKeyFile * ostree_repo_copy_config (OstreeRepo *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_remote_add (OstreeRepo *self,
|
||||
const char *name,
|
||||
const char *url,
|
||||
|
|
@ -83,6 +102,7 @@ gboolean ostree_repo_remote_add (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_remote_delete (OstreeRepo *self,
|
||||
const char *name,
|
||||
GCancellable *cancellable,
|
||||
|
|
@ -95,6 +115,7 @@ typedef enum {
|
|||
OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS
|
||||
} OstreeRepoRemoteChange;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_remote_change (OstreeRepo *self,
|
||||
GFile *sysroot,
|
||||
OstreeRepoRemoteChange changeop,
|
||||
|
|
@ -104,24 +125,29 @@ gboolean ostree_repo_remote_change (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
char ** ostree_repo_remote_list (OstreeRepo *self,
|
||||
guint *out_n_remotes);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_remote_get_url (OstreeRepo *self,
|
||||
const char *name,
|
||||
char **out_url,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_remote_get_gpg_verify (OstreeRepo *self,
|
||||
const char *name,
|
||||
gboolean *out_gpg_verify,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_remote_get_gpg_verify_summary (OstreeRepo *self,
|
||||
const char *name,
|
||||
gboolean *out_gpg_verify_summary,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_remote_gpg_import (OstreeRepo *self,
|
||||
const char *name,
|
||||
GInputStream *source_stream,
|
||||
|
|
@ -130,6 +156,7 @@ gboolean ostree_repo_remote_gpg_import (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_remote_fetch_summary (OstreeRepo *self,
|
||||
const char *name,
|
||||
GBytes **out_summary,
|
||||
|
|
@ -137,8 +164,10 @@ gboolean ostree_repo_remote_fetch_summary (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeRepo * ostree_repo_get_parent (OstreeRepo *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_write_config (OstreeRepo *self,
|
||||
GKeyFile *new_config,
|
||||
GError **error);
|
||||
|
|
@ -174,35 +203,43 @@ struct _OstreeRepoTransactionStats {
|
|||
guint64 padding4;
|
||||
};
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_repo_transaction_stats_get_type (void);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_scan_hardlinks (OstreeRepo *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_prepare_transaction (OstreeRepo *self,
|
||||
gboolean *out_transaction_resume,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_commit_transaction (OstreeRepo *self,
|
||||
OstreeRepoTransactionStats *out_stats,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_abort_transaction (OstreeRepo *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_repo_transaction_set_refspec (OstreeRepo *self,
|
||||
const char *refspec,
|
||||
const char *checksum);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_repo_transaction_set_ref (OstreeRepo *self,
|
||||
const char *remote,
|
||||
const char *ref,
|
||||
const char *checksum);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_set_ref_immediate (OstreeRepo *self,
|
||||
const char *remote,
|
||||
const char *ref,
|
||||
|
|
@ -210,6 +247,7 @@ gboolean ostree_repo_set_ref_immediate (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_has_object (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
const char *checksum,
|
||||
|
|
@ -217,6 +255,7 @@ gboolean ostree_repo_has_object (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_write_metadata (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
const char *expected_checksum,
|
||||
|
|
@ -225,6 +264,7 @@ gboolean ostree_repo_write_metadata (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_repo_write_metadata_async (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
const char *expected_checksum,
|
||||
|
|
@ -233,11 +273,13 @@ void ostree_repo_write_metadata_async (OstreeRepo *self,
|
|||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_write_metadata_finish (OstreeRepo *self,
|
||||
GAsyncResult *result,
|
||||
guchar **out_csum,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_write_content (OstreeRepo *self,
|
||||
const char *expected_checksum,
|
||||
GInputStream *object_input,
|
||||
|
|
@ -246,6 +288,7 @@ gboolean ostree_repo_write_content (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_write_metadata_trusted (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
const char *checksum,
|
||||
|
|
@ -253,6 +296,7 @@ gboolean ostree_repo_write_metadata_trusted (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_write_metadata_stream_trusted (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
const char *checksum,
|
||||
|
|
@ -261,6 +305,7 @@ gboolean ostree_repo_write_metadata_stream_trusted (OstreeRepo *self
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_write_content_trusted (OstreeRepo *self,
|
||||
const char *checksum,
|
||||
GInputStream *object_input,
|
||||
|
|
@ -268,6 +313,7 @@ gboolean ostree_repo_write_content_trusted (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_repo_write_content_async (OstreeRepo *self,
|
||||
const char *expected_checksum,
|
||||
GInputStream *object,
|
||||
|
|
@ -276,35 +322,57 @@ void ostree_repo_write_content_async (OstreeRepo *self,
|
|||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_write_content_finish (OstreeRepo *self,
|
||||
GAsyncResult *result,
|
||||
guchar **out_csum,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_resolve_rev (OstreeRepo *self,
|
||||
const char *refspec,
|
||||
gboolean allow_noent,
|
||||
char **out_rev,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_list_refs (OstreeRepo *self,
|
||||
const char *refspec_prefix,
|
||||
GHashTable **out_all_refs,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
/**
|
||||
* OstreeRepoListRefsExtFlags:
|
||||
* @OSTREE_REPO_LIST_REFS_EXT_NONE: No flags.
|
||||
*/
|
||||
typedef enum {
|
||||
OSTREE_REPO_LIST_REFS_EXT_NONE = 0,
|
||||
} OstreeRepoListRefsExtFlags;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_list_refs_ext (OstreeRepo *self,
|
||||
const char *refspec_prefix,
|
||||
GHashTable **out_all_refs,
|
||||
OstreeRepoListRefsExtFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_remote_list_refs (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
GHashTable **out_all_refs,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_load_variant (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
const char *sha256,
|
||||
GVariant **out_variant,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_load_variant_if_exists (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
const char *sha256,
|
||||
|
|
@ -315,12 +383,14 @@ typedef enum {
|
|||
OSTREE_REPO_COMMIT_STATE_PARTIAL = (1 << 0),
|
||||
} OstreeRepoCommitState;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_load_commit (OstreeRepo *self,
|
||||
const char *checksum,
|
||||
GVariant **out_commit,
|
||||
OstreeRepoCommitState *out_state,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_load_file (OstreeRepo *self,
|
||||
const char *checksum,
|
||||
GInputStream **out_input,
|
||||
|
|
@ -329,6 +399,7 @@ gboolean ostree_repo_load_file (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_load_object_stream (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
const char *checksum,
|
||||
|
|
@ -337,6 +408,7 @@ gboolean ostree_repo_load_object_stream (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_query_object_storage_size (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
const char *sha256,
|
||||
|
|
@ -344,6 +416,7 @@ gboolean ostree_repo_query_object_storage_size (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_import_object_from (OstreeRepo *self,
|
||||
OstreeRepo *source,
|
||||
OstreeObjectType objtype,
|
||||
|
|
@ -351,6 +424,7 @@ gboolean ostree_repo_import_object_from (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_delete_object (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
const char *sha256,
|
||||
|
|
@ -400,11 +474,13 @@ typedef enum {
|
|||
*/
|
||||
typedef struct OstreeRepoCommitModifier OstreeRepoCommitModifier;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeRepoCommitModifier *ostree_repo_commit_modifier_new (OstreeRepoCommitModifierFlags flags,
|
||||
OstreeRepoCommitFilter commit_filter,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy_notify);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_repo_commit_modifier_get_type (void);
|
||||
|
||||
typedef GVariant *(*OstreeRepoCommitModifierXattrCallback) (OstreeRepo *repo,
|
||||
|
|
@ -412,20 +488,26 @@ typedef GVariant *(*OstreeRepoCommitModifierXattrCallback) (OstreeRepo *repo
|
|||
GFileInfo *file_info,
|
||||
gpointer user_data);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_repo_commit_modifier_set_xattr_callback (OstreeRepoCommitModifier *modifier,
|
||||
OstreeRepoCommitModifierXattrCallback callback,
|
||||
GDestroyNotify destroy,
|
||||
gpointer user_data);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_repo_commit_modifier_set_sepolicy (OstreeRepoCommitModifier *modifier,
|
||||
OstreeSePolicy *sepolicy);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_repo_commit_modifier_set_devino_cache (OstreeRepoCommitModifier *modifier,
|
||||
OstreeRepoDevInoCache *cache);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeRepoCommitModifier *ostree_repo_commit_modifier_ref (OstreeRepoCommitModifier *modifier);
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_repo_commit_modifier_unref (OstreeRepoCommitModifier *modifier);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_write_directory_to_mtree (OstreeRepo *self,
|
||||
GFile *dir,
|
||||
OstreeMutableTree *mtree,
|
||||
|
|
@ -433,6 +515,7 @@ gboolean ostree_repo_write_directory_to_mtree (OstreeRepo *
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_write_dfd_to_mtree (OstreeRepo *self,
|
||||
int dfd,
|
||||
const char *path,
|
||||
|
|
@ -442,6 +525,7 @@ gboolean ostree_repo_write_dfd_to_mtree (OstreeRepo *self,
|
|||
GError **error);
|
||||
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_write_archive_to_mtree (OstreeRepo *self,
|
||||
GFile *archive,
|
||||
OstreeMutableTree *mtree,
|
||||
|
|
@ -466,6 +550,7 @@ typedef struct {
|
|||
gpointer unused_ptrs[8];
|
||||
} OstreeRepoImportArchiveOptions;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_import_archive_to_mtree (OstreeRepo *self,
|
||||
OstreeRepoImportArchiveOptions *opts,
|
||||
void *archive, /* Really struct archive * */
|
||||
|
|
@ -490,6 +575,7 @@ typedef struct {
|
|||
gpointer unused_ptrs[8];
|
||||
} OstreeRepoExportArchiveOptions;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_export_tree_to_archive (OstreeRepo *self,
|
||||
OstreeRepoExportArchiveOptions *opts,
|
||||
OstreeRepoFile *root,
|
||||
|
|
@ -497,12 +583,14 @@ gboolean ostree_repo_export_tree_to_archive (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_write_mtree (OstreeRepo *self,
|
||||
OstreeMutableTree *mtree,
|
||||
GFile **out_file,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_write_commit (OstreeRepo *self,
|
||||
const char *parent,
|
||||
const char *subject,
|
||||
|
|
@ -513,6 +601,7 @@ gboolean ostree_repo_write_commit (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_write_commit_with_time (OstreeRepo *self,
|
||||
const char *parent,
|
||||
const char *subject,
|
||||
|
|
@ -524,12 +613,14 @@ gboolean ostree_repo_write_commit_with_time (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_read_commit_detached_metadata (OstreeRepo *self,
|
||||
const char *checksum,
|
||||
GVariant **out_metadata,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_write_commit_detached_metadata (OstreeRepo *self,
|
||||
const char *checksum,
|
||||
GVariant *metadata,
|
||||
|
|
@ -556,7 +647,7 @@ typedef enum {
|
|||
OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES = 1
|
||||
} OstreeRepoCheckoutOverwriteMode;
|
||||
|
||||
gboolean
|
||||
_OSTREE_PUBLIC gboolean
|
||||
ostree_repo_checkout_tree (OstreeRepo *self,
|
||||
OstreeRepoCheckoutMode mode,
|
||||
OstreeRepoCheckoutOverwriteMode overwrite_mode,
|
||||
|
|
@ -592,11 +683,16 @@ typedef struct {
|
|||
gpointer unused_ptrs[7];
|
||||
} OstreeRepoCheckoutOptions;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_repo_devino_cache_get_type (void);
|
||||
_OSTREE_PUBLIC
|
||||
OstreeRepoDevInoCache *ostree_repo_devino_cache_new (void);
|
||||
_OSTREE_PUBLIC
|
||||
OstreeRepoDevInoCache * ostree_repo_devino_cache_ref (OstreeRepoDevInoCache *cache);
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_repo_devino_cache_unref (OstreeRepoDevInoCache *cache);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_checkout_tree_at (OstreeRepo *self,
|
||||
OstreeRepoCheckoutOptions *options,
|
||||
int destination_dfd,
|
||||
|
|
@ -605,10 +701,12 @@ gboolean ostree_repo_checkout_tree_at (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_checkout_gc (OstreeRepo *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_read_commit (OstreeRepo *self,
|
||||
const char *ref,
|
||||
GFile **out_root,
|
||||
|
|
@ -636,18 +734,21 @@ typedef enum {
|
|||
*/
|
||||
#define OSTREE_REPO_LIST_OBJECTS_VARIANT_TYPE (G_VARIANT_TYPE ("(bas)")
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_list_objects (OstreeRepo *self,
|
||||
OstreeRepoListObjectsFlags flags,
|
||||
GHashTable **out_objects,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_list_commit_objects_starting_with ( OstreeRepo *self,
|
||||
const char *start,
|
||||
GHashTable **out_commits,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_list_static_delta_names (OstreeRepo *self,
|
||||
GPtrArray **out_deltas,
|
||||
GCancellable *cancellable,
|
||||
|
|
@ -665,6 +766,7 @@ typedef enum {
|
|||
OSTREE_STATIC_DELTA_GENERATE_OPT_MAJOR
|
||||
} OstreeStaticDeltaGenerateOpt;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_static_delta_generate (OstreeRepo *self,
|
||||
OstreeStaticDeltaGenerateOpt opt,
|
||||
const char *from,
|
||||
|
|
@ -674,14 +776,17 @@ gboolean ostree_repo_static_delta_generate (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_static_delta_execute_offline (OstreeRepo *self,
|
||||
GFile *dir_or_file,
|
||||
gboolean skip_validation,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GHashTable *ostree_repo_traverse_new_reachable (void);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_traverse_commit (OstreeRepo *repo,
|
||||
const char *commit_checksum,
|
||||
int maxdepth,
|
||||
|
|
@ -689,6 +794,7 @@ gboolean ostree_repo_traverse_commit (OstreeRepo *repo,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_traverse_commit_union (OstreeRepo *repo,
|
||||
const char *commit_checksum,
|
||||
int maxdepth,
|
||||
|
|
@ -708,14 +814,14 @@ typedef enum {
|
|||
OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE = (1 << 0)
|
||||
} OstreeRepoCommitTraverseFlags;
|
||||
|
||||
gboolean
|
||||
_OSTREE_PUBLIC gboolean
|
||||
ostree_repo_commit_traverse_iter_init_commit (OstreeRepoCommitTraverseIter *iter,
|
||||
OstreeRepo *repo,
|
||||
GVariant *commit,
|
||||
OstreeRepoCommitTraverseFlags flags,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
_OSTREE_PUBLIC gboolean
|
||||
ostree_repo_commit_traverse_iter_init_dirtree (OstreeRepoCommitTraverseIter *iter,
|
||||
OstreeRepo *repo,
|
||||
GVariant *dirtree,
|
||||
|
|
@ -729,22 +835,26 @@ typedef enum {
|
|||
OSTREE_REPO_COMMIT_ITER_RESULT_DIR
|
||||
} OstreeRepoCommitIterResult;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeRepoCommitIterResult ostree_repo_commit_traverse_iter_next (OstreeRepoCommitTraverseIter *iter,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_repo_commit_traverse_iter_get_file (OstreeRepoCommitTraverseIter *iter,
|
||||
char **out_name,
|
||||
char **out_checksum);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_repo_commit_traverse_iter_get_dir (OstreeRepoCommitTraverseIter *iter,
|
||||
char **out_name,
|
||||
char **out_content_checksum,
|
||||
char **out_meta_checksum);
|
||||
|
||||
void
|
||||
_OSTREE_PUBLIC void
|
||||
ostree_repo_commit_traverse_iter_clear (OstreeRepoCommitTraverseIter *iter);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_repo_commit_traverse_iter_cleanup (void *p);
|
||||
|
||||
#define ostree_cleanup_repo_commit_traverse_iter __attribute__ ((cleanup(ostree_repo_commit_traverse_iter_cleanup)))
|
||||
|
|
@ -761,11 +871,12 @@ typedef enum {
|
|||
OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY
|
||||
} OstreeRepoPruneFlags;
|
||||
|
||||
gboolean
|
||||
_OSTREE_PUBLIC gboolean
|
||||
ostree_repo_prune_static_deltas (OstreeRepo *self, const char *commit,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_prune (OstreeRepo *self,
|
||||
OstreeRepoPruneFlags flags,
|
||||
gint depth,
|
||||
|
|
@ -787,6 +898,7 @@ typedef enum {
|
|||
OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY = (1 << 1)
|
||||
} OstreeRepoPullFlags;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_pull (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
char **refs_to_fetch,
|
||||
|
|
@ -795,7 +907,7 @@ gboolean ostree_repo_pull (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
_OSTREE_PUBLIC gboolean
|
||||
ostree_repo_pull_one_dir (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *dir_to_pull,
|
||||
|
|
@ -805,6 +917,7 @@ ostree_repo_pull_one_dir (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_pull_with_options (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
GVariant *options,
|
||||
|
|
@ -812,9 +925,11 @@ gboolean ostree_repo_pull_with_options (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_repo_pull_default_console_progress_changed (OstreeAsyncProgress *progress,
|
||||
gpointer user_data);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_sign_commit (OstreeRepo *self,
|
||||
const gchar *commit_checksum,
|
||||
const gchar *key_id,
|
||||
|
|
@ -822,6 +937,7 @@ gboolean ostree_repo_sign_commit (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_sign_delta (OstreeRepo *self,
|
||||
const gchar *from_commit,
|
||||
const gchar *to_commit,
|
||||
|
|
@ -830,19 +946,21 @@ gboolean ostree_repo_sign_delta (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
_OSTREE_PUBLIC gboolean
|
||||
ostree_repo_add_gpg_signature_summary (OstreeRepo *self,
|
||||
const gchar **key_id,
|
||||
const gchar *homedir,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_append_gpg_signature (OstreeRepo *self,
|
||||
const gchar *commit_checksum,
|
||||
GBytes *signature_bytes,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_verify_commit (OstreeRepo *self,
|
||||
const gchar *commit_checksum,
|
||||
GFile *keyringdir,
|
||||
|
|
@ -850,6 +968,7 @@ gboolean ostree_repo_verify_commit (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeGpgVerifyResult * ostree_repo_verify_commit_ext (OstreeRepo *self,
|
||||
const gchar *commit_checksum,
|
||||
GFile *keyringdir,
|
||||
|
|
@ -857,6 +976,7 @@ OstreeGpgVerifyResult * ostree_repo_verify_commit_ext (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeGpgVerifyResult * ostree_repo_verify_summary (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
GBytes *summary,
|
||||
|
|
@ -864,6 +984,7 @@ OstreeGpgVerifyResult * ostree_repo_verify_summary (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_regenerate_summary (OstreeRepo *self,
|
||||
GVariant *additional_metadata,
|
||||
GCancellable *cancellable,
|
||||
|
|
|
|||
|
|
@ -347,10 +347,9 @@ ostree_sepolicy_get_label (OstreeSePolicy *self,
|
|||
res = selabel_lookup_raw (self->selinux_hnd, &con, relpath, unix_mode);
|
||||
if (res != 0)
|
||||
{
|
||||
int errsv = errno;
|
||||
if (errsv != ENOENT)
|
||||
if (errno != ENOENT)
|
||||
{
|
||||
gs_set_error_from_errno (error, errsv);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -443,14 +442,15 @@ ostree_sepolicy_restorecon (OstreeSePolicy *self,
|
|||
int res = lsetfilecon (gs_file_get_path_cached (target), label);
|
||||
if (res != 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_new_label, &label);
|
||||
if (out_new_label)
|
||||
*out_new_label = g_steal_pointer (&label);
|
||||
out:
|
||||
return ret;
|
||||
#else
|
||||
|
|
@ -490,7 +490,7 @@ ostree_sepolicy_setfscreatecon (OstreeSePolicy *self,
|
|||
|
||||
if (setfscreatecon_raw (label) != 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,16 +30,21 @@ G_BEGIN_DECLS
|
|||
#define OSTREE_IS_SEPOLICY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSTREE_TYPE_SEPOLICY))
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_sepolicy_get_type (void);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeSePolicy* ostree_sepolicy_new (GFile *path,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GFile * ostree_sepolicy_get_path (OstreeSePolicy *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
const char *ostree_sepolicy_get_name (OstreeSePolicy *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sepolicy_get_label (OstreeSePolicy *self,
|
||||
const char *relpath,
|
||||
guint32 unix_mode,
|
||||
|
|
@ -53,6 +58,7 @@ typedef enum {
|
|||
OSTREE_SEPOLICY_RESTORECON_FLAGS_KEEP_EXISTING = (1 << 1)
|
||||
} OstreeSePolicyRestoreconFlags;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sepolicy_restorecon (OstreeSePolicy *self,
|
||||
const char *path,
|
||||
GFileInfo *info,
|
||||
|
|
@ -62,11 +68,13 @@ gboolean ostree_sepolicy_restorecon (OstreeSePolicy *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sepolicy_setfscreatecon (OstreeSePolicy *self,
|
||||
const char *path,
|
||||
guint32 mode,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_sepolicy_fscreatecon_cleanup (void **unused);
|
||||
|
||||
#define ostree_cleanup_sepolicy_fscreatecon __attribute__ ((cleanup(ostree_sepolicy_fscreatecon_cleanup)))
|
||||
|
|
|
|||
|
|
@ -255,28 +255,28 @@ cleanup_other_bootversions (OstreeSysroot *self,
|
|||
cleanup_subbootversion = self->subbootversion == 0 ? 1 : 0;
|
||||
|
||||
cleanup_boot_dir = ot_gfile_resolve_path_printf (self->path, "boot/loader.%d", cleanup_bootversion);
|
||||
if (!gs_shutil_rm_rf (cleanup_boot_dir, cancellable, error))
|
||||
if (!glnx_shutil_rm_rf_at (AT_FDCWD, gs_file_get_path_cached (cleanup_boot_dir), cancellable, error))
|
||||
goto out;
|
||||
g_clear_object (&cleanup_boot_dir);
|
||||
|
||||
cleanup_boot_dir = ot_gfile_resolve_path_printf (self->path, "ostree/boot.%d", cleanup_bootversion);
|
||||
if (!gs_shutil_rm_rf (cleanup_boot_dir, cancellable, error))
|
||||
if (!glnx_shutil_rm_rf_at (AT_FDCWD, gs_file_get_path_cached (cleanup_boot_dir), cancellable, error))
|
||||
goto out;
|
||||
g_clear_object (&cleanup_boot_dir);
|
||||
|
||||
cleanup_boot_dir = ot_gfile_resolve_path_printf (self->path, "ostree/boot.%d.0", cleanup_bootversion);
|
||||
if (!gs_shutil_rm_rf (cleanup_boot_dir, cancellable, error))
|
||||
if (!glnx_shutil_rm_rf_at (AT_FDCWD, gs_file_get_path_cached (cleanup_boot_dir), cancellable, error))
|
||||
goto out;
|
||||
g_clear_object (&cleanup_boot_dir);
|
||||
|
||||
cleanup_boot_dir = ot_gfile_resolve_path_printf (self->path, "ostree/boot.%d.1", cleanup_bootversion);
|
||||
if (!gs_shutil_rm_rf (cleanup_boot_dir, cancellable, error))
|
||||
if (!glnx_shutil_rm_rf_at (AT_FDCWD, gs_file_get_path_cached (cleanup_boot_dir), cancellable, error))
|
||||
goto out;
|
||||
g_clear_object (&cleanup_boot_dir);
|
||||
|
||||
cleanup_boot_dir = ot_gfile_resolve_path_printf (self->path, "ostree/boot.%d.%d", self->bootversion,
|
||||
cleanup_subbootversion);
|
||||
if (!gs_shutil_rm_rf (cleanup_boot_dir, cancellable, error))
|
||||
if (!glnx_shutil_rm_rf_at (AT_FDCWD, gs_file_get_path_cached (cleanup_boot_dir), cancellable, error))
|
||||
goto out;
|
||||
g_clear_object (&cleanup_boot_dir);
|
||||
|
||||
|
|
@ -377,7 +377,7 @@ cleanup_old_deployments (OstreeSysroot *self,
|
|||
if (g_hash_table_lookup (active_boot_checksums, bootcsum))
|
||||
continue;
|
||||
|
||||
if (!gs_shutil_rm_rf (bootdir, cancellable, error))
|
||||
if (!glnx_shutil_rm_rf_at (AT_FDCWD, gs_file_get_path_cached (bootdir), cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -401,7 +401,7 @@ cleanup_ref_prefix (OstreeRepo *repo,
|
|||
|
||||
prefix = g_strdup_printf ("ostree/%d/%d", bootversion, subbootversion);
|
||||
|
||||
if (!ostree_repo_list_refs (repo, prefix, &refs, cancellable, error))
|
||||
if (!ostree_repo_list_refs_ext (repo, prefix, &refs, OSTREE_REPO_LIST_REFS_EXT_NONE, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
|
||||
|
|
@ -410,8 +410,7 @@ cleanup_ref_prefix (OstreeRepo *repo,
|
|||
g_hash_table_iter_init (&hashiter, refs);
|
||||
while (g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue))
|
||||
{
|
||||
const char *suffix = hashkey;
|
||||
g_autofree char *ref = g_strconcat (prefix, "/", suffix, NULL);
|
||||
const char *ref = hashkey;
|
||||
ostree_repo_transaction_set_refspec (repo, ref, NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,12 @@
|
|||
|
||||
#include <gio/gunixinputstream.h>
|
||||
#include <gio/gunixoutputstream.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#ifdef HAVE_LIBMOUNT
|
||||
#include <libmount.h>
|
||||
#endif
|
||||
|
||||
#include "ostree-sysroot-private.h"
|
||||
#include "ostree-deployment-private.h"
|
||||
|
|
@ -97,26 +103,26 @@ dirfd_copy_attributes_and_xattrs (int src_parent_dfd,
|
|||
* right. This will allow other users access if they have ACLs, but
|
||||
* oh well.
|
||||
*/
|
||||
if (!gs_dfd_and_name_get_all_xattrs (src_parent_dfd, src_name,
|
||||
if (!glnx_dfd_name_get_all_xattrs (src_parent_dfd, src_name,
|
||||
&xattrs, cancellable, error))
|
||||
goto out;
|
||||
if (!gs_fd_set_all_xattrs (dest_dfd, xattrs,
|
||||
if (!glnx_fd_set_all_xattrs (dest_dfd, xattrs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (fstat (src_dfd, &src_stbuf) != 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
if (fchown (dest_dfd, src_stbuf.st_uid, src_stbuf.st_gid) != 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
if (fchmod (dest_dfd, src_stbuf.st_mode) != 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -144,7 +150,7 @@ copy_dir_recurse (int src_parent_dfd,
|
|||
/* Create with mode 0700, we'll fchmod/fchown later */
|
||||
if (mkdirat (dest_parent_dfd, name, 0700) != 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -158,7 +164,7 @@ copy_dir_recurse (int src_parent_dfd,
|
|||
srcd = fdopendir (src_dfd);
|
||||
if (!srcd)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -174,7 +180,7 @@ copy_dir_recurse (int src_parent_dfd,
|
|||
if (fstatat (src_dfd, name, &child_stbuf,
|
||||
AT_SYMLINK_NOFOLLOW) != 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -256,7 +262,7 @@ ensure_directory_from_template (int orig_etc_fd,
|
|||
}
|
||||
else
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
g_prefix_error (error, "mkdirat: ");
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -306,7 +312,7 @@ copy_modified_config_file (int orig_etc_fd,
|
|||
|
||||
if (fstatat (modified_etc_fd, path, &modified_stbuf, AT_SYMLINK_NOFOLLOW) < 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
g_prefix_error (error, "Failed to read modified config file '%s': ", path);
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -324,7 +330,7 @@ copy_modified_config_file (int orig_etc_fd,
|
|||
dest_parent_dfd = dup (new_etc_fd);
|
||||
if (dest_parent_dfd == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -337,7 +343,7 @@ copy_modified_config_file (int orig_etc_fd,
|
|||
;
|
||||
else
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -363,7 +369,7 @@ copy_modified_config_file (int orig_etc_fd,
|
|||
{
|
||||
if (unlinkat (new_etc_fd, path, 0) < 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -450,11 +456,14 @@ merge_etc_changes (GFile *orig_etc,
|
|||
removed->len,
|
||||
added->len);
|
||||
|
||||
if (!gs_file_open_dir_fd (orig_etc, &orig_etc_fd, cancellable, error))
|
||||
if (!glnx_opendirat (AT_FDCWD, gs_file_get_path_cached (orig_etc), TRUE,
|
||||
&orig_etc_fd, error))
|
||||
goto out;
|
||||
if (!gs_file_open_dir_fd (modified_etc, &modified_etc_fd, cancellable, error))
|
||||
if (!glnx_opendirat (AT_FDCWD, gs_file_get_path_cached (modified_etc), TRUE,
|
||||
&modified_etc_fd, error))
|
||||
goto out;
|
||||
if (!gs_file_open_dir_fd (new_etc, &new_etc_fd, cancellable, error))
|
||||
if (!glnx_opendirat (AT_FDCWD, gs_file_get_path_cached (new_etc), TRUE,
|
||||
&new_etc_fd, error))
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < removed->len; i++)
|
||||
|
|
@ -467,7 +476,7 @@ merge_etc_changes (GFile *orig_etc,
|
|||
g_assert (path);
|
||||
target_file = g_file_resolve_relative_path (new_etc, path);
|
||||
|
||||
if (!gs_shutil_rm_rf (target_file, cancellable, error))
|
||||
if (!glnx_shutil_rm_rf_at (AT_FDCWD, gs_file_get_path_cached (target_file), cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -873,7 +882,8 @@ merge_configuration (OstreeSysroot *sysroot,
|
|||
}
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_sepolicy, &sepolicy);
|
||||
if (out_sepolicy)
|
||||
*out_sepolicy = g_steal_pointer (&sepolicy);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -941,8 +951,8 @@ get_kernel_from_tree (int deployment_dfd,
|
|||
g_auto(GLnxDirFdIterator) dfditer = { 0, };
|
||||
g_autofree char *ret_kernel_name = NULL;
|
||||
g_autofree char *ret_initramfs_name = NULL;
|
||||
gs_free char *kernel_checksum = NULL;
|
||||
gs_free char *initramfs_checksum = NULL;
|
||||
g_autofree char *kernel_checksum = NULL;
|
||||
g_autofree char *initramfs_checksum = NULL;
|
||||
|
||||
ret_boot_dfd = glnx_opendirat_with_errno (deployment_dfd, "usr/lib/ostree-boot", TRUE);
|
||||
if (ret_boot_dfd == -1)
|
||||
|
|
@ -1360,7 +1370,7 @@ install_deployment_kernel (OstreeSysroot *sysroot,
|
|||
{
|
||||
if (errno != ENOENT)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
|
|
@ -1645,6 +1655,47 @@ cleanup_legacy_current_symlinks (OstreeSysroot *self,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_ro_mount (const char *path)
|
||||
{
|
||||
#ifdef HAVE_LIBMOUNT
|
||||
/* Dragging in all of this crud is apparently necessary just to determine
|
||||
* whether something is a mount point.
|
||||
*
|
||||
* Systemd has a totally different implementation in
|
||||
* src/basic/mount-util.c.
|
||||
*/
|
||||
struct libmnt_table *tb = mnt_new_table_from_file ("/proc/self/mountinfo");
|
||||
struct libmnt_fs *fs;
|
||||
struct libmnt_cache *cache;
|
||||
gboolean is_mount = FALSE;
|
||||
struct statvfs stvfsbuf;
|
||||
|
||||
if (!tb)
|
||||
return FALSE;
|
||||
|
||||
/* to canonicalize all necessary paths */
|
||||
cache = mnt_new_cache ();
|
||||
mnt_table_set_cache (tb, cache);
|
||||
|
||||
fs = mnt_table_find_target(tb, path, MNT_ITER_BACKWARD);
|
||||
is_mount = fs && mnt_fs_get_target (fs);
|
||||
mnt_free_cache (cache);
|
||||
mnt_free_table (tb);
|
||||
|
||||
if (!is_mount)
|
||||
return FALSE;
|
||||
|
||||
/* We *could* parse the options, but it seems more reliable to
|
||||
* introspect the actual mount at runtime.
|
||||
*/
|
||||
if (statvfs (path, &stvfsbuf) == 0)
|
||||
return (stvfsbuf.f_flag & ST_RDONLY) != 0;
|
||||
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_sysroot_write_deployments:
|
||||
* @self: Sysroot
|
||||
|
|
@ -1666,6 +1717,7 @@ ostree_sysroot_write_deployments (OstreeSysroot *self,
|
|||
gboolean requires_new_bootversion = FALSE;
|
||||
gboolean found_booted_deployment = FALSE;
|
||||
gboolean bootloader_is_atomic = FALSE;
|
||||
gboolean boot_was_ro_mount = FALSE;
|
||||
|
||||
g_assert (self->loaded);
|
||||
|
||||
|
|
@ -1753,12 +1805,26 @@ ostree_sysroot_write_deployments (OstreeSysroot *self,
|
|||
glnx_unref_object OstreeRepo *repo = NULL;
|
||||
gboolean show_osname = FALSE;
|
||||
|
||||
if (self->booted_deployment)
|
||||
boot_was_ro_mount = is_ro_mount ("/boot");
|
||||
|
||||
g_debug ("boot is ro: %s", boot_was_ro_mount ? "yes" : "no");
|
||||
|
||||
if (boot_was_ro_mount)
|
||||
{
|
||||
if (mount ("/boot", "/boot", NULL, MS_REMOUNT | MS_SILENT, NULL) < 0)
|
||||
{
|
||||
glnx_set_prefix_error_from_errno (error, "%s", "Remounting /boot read-write");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_ostree_sysroot_query_bootloader (self, &bootloader, cancellable, error))
|
||||
goto out;
|
||||
|
||||
new_loader_entries_dir = ot_gfile_resolve_path_printf (self->path, "boot/loader.%d/entries",
|
||||
new_bootversion);
|
||||
if (!gs_shutil_rm_rf (new_loader_entries_dir, cancellable, error))
|
||||
if (!glnx_shutil_rm_rf_at (AT_FDCWD, gs_file_get_path_cached (new_loader_entries_dir), cancellable, error))
|
||||
goto out;
|
||||
if (!ot_util_ensure_directory_and_fsync (new_loader_entries_dir, cancellable, error))
|
||||
goto out;
|
||||
|
|
@ -1855,6 +1921,9 @@ ostree_sysroot_write_deployments (OstreeSysroot *self,
|
|||
requires_new_bootversion ? "yes" : "no",
|
||||
new_deployments->len - self->deployments->len);
|
||||
|
||||
if (!_ostree_sysroot_bump_mtime (self, error))
|
||||
goto out;
|
||||
|
||||
/* Now reload from disk */
|
||||
if (!ostree_sysroot_load (self, cancellable, error))
|
||||
{
|
||||
|
|
@ -1875,6 +1944,18 @@ ostree_sysroot_write_deployments (OstreeSysroot *self,
|
|||
|
||||
ret = TRUE;
|
||||
out:
|
||||
if (boot_was_ro_mount)
|
||||
{
|
||||
if (mount ("/boot", "/boot", NULL, MS_REMOUNT | MS_RDONLY | MS_SILENT, NULL) < 0)
|
||||
{
|
||||
/* Only make this a warning because we don't want to
|
||||
* completely bomb out if some other process happened to
|
||||
* jump in and open a file there.
|
||||
*/
|
||||
int errsv = errno;
|
||||
g_printerr ("warning: Failed to remount /boot read-only: %s\n", strerror (errsv));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ struct OstreeSysroot {
|
|||
int bootversion;
|
||||
int subbootversion;
|
||||
OstreeDeployment *booted_deployment;
|
||||
struct timespec loaded_ts;
|
||||
|
||||
/* Only access through ostree_sysroot_get_repo() */
|
||||
OstreeRepo *repo;
|
||||
|
|
@ -57,6 +58,9 @@ struct OstreeSysroot {
|
|||
};
|
||||
|
||||
#define OSTREE_SYSROOT_LOCKFILE "ostree/lock"
|
||||
/* We keep some transient state in /run */
|
||||
#define _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_DIR "/run/ostree/deployment-state/"
|
||||
#define _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_FLAG_DEVELOPMENT "unlocked-development"
|
||||
|
||||
gboolean
|
||||
_ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self,
|
||||
|
|
@ -98,6 +102,9 @@ gboolean _ostree_sysroot_query_bootloader (OstreeSysroot *sysroot,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean _ostree_sysroot_bump_mtime (OstreeSysroot *sysroot,
|
||||
GError **error);
|
||||
|
||||
typedef enum {
|
||||
OSTREE_SYSROOT_CLEANUP_BOOTVERSIONS = 1 << 0,
|
||||
OSTREE_SYSROOT_CLEANUP_DEPLOYMENTS = 1 << 1,
|
||||
|
|
|
|||
|
|
@ -42,32 +42,42 @@ typedef enum {
|
|||
OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED = (1 << 1),
|
||||
} OstreeSysrootUpgraderFlags;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_sysroot_upgrader_get_type (void);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_sysroot_upgrader_flags_get_type (void);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeSysrootUpgrader *ostree_sysroot_upgrader_new (OstreeSysroot *sysroot,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeSysrootUpgrader *ostree_sysroot_upgrader_new_for_os (OstreeSysroot *sysroot,
|
||||
const char *osname,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeSysrootUpgrader *ostree_sysroot_upgrader_new_for_os_with_flags (OstreeSysroot *sysroot,
|
||||
const char *osname,
|
||||
OstreeSysrootUpgraderFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GKeyFile *ostree_sysroot_upgrader_get_origin (OstreeSysrootUpgrader *self);
|
||||
_OSTREE_PUBLIC
|
||||
GKeyFile *ostree_sysroot_upgrader_dup_origin (OstreeSysrootUpgrader *self);
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_upgrader_set_origin (OstreeSysrootUpgrader *self, GKeyFile *origin,
|
||||
GCancellable *cancellable, GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
char *ostree_sysroot_upgrader_get_origin_description (OstreeSysrootUpgrader *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_upgrader_check_timestamps (OstreeRepo *repo,
|
||||
const char *from_rev,
|
||||
const char *to_rev,
|
||||
|
|
@ -78,6 +88,7 @@ typedef enum {
|
|||
OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_ALLOW_OLDER = (1 << 0)
|
||||
} OstreeSysrootUpgraderPullFlags;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_upgrader_pull (OstreeSysrootUpgrader *self,
|
||||
OstreeRepoPullFlags flags,
|
||||
OstreeSysrootUpgraderPullFlags upgrader_flags,
|
||||
|
|
@ -86,6 +97,7 @@ gboolean ostree_sysroot_upgrader_pull (OstreeSysrootUpgrader *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self,
|
||||
const char *dir_to_pull,
|
||||
OstreeRepoPullFlags flags,
|
||||
|
|
@ -95,6 +107,7 @@ gboolean ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_upgrader_deploy (OstreeSysrootUpgrader *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "ostree-core-private.h"
|
||||
#include "ostree-sysroot-private.h"
|
||||
#include "ostree-deployment-private.h"
|
||||
#include "ostree-bootloader-uboot.h"
|
||||
#include "ostree-bootloader-syslinux.h"
|
||||
#include "ostree-bootloader-grub2.h"
|
||||
|
|
@ -229,6 +230,19 @@ ostree_sysroot_get_fd (OstreeSysroot *self)
|
|||
return self->sysroot_fd;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_ostree_sysroot_bump_mtime (OstreeSysroot *self,
|
||||
GError **error)
|
||||
{
|
||||
/* Allow other systems to monitor for changes */
|
||||
if (utimensat (self->sysroot_fd, "ostree/deploy", NULL, 0) < 0)
|
||||
{
|
||||
glnx_set_prefix_error_from_errno (error, "%s", "futimens");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_sysroot_unload:
|
||||
* @self: Sysroot
|
||||
|
|
@ -485,7 +499,8 @@ _ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self,
|
|||
g_ptr_array_sort (ret_loader_configs, compare_loader_configs_for_sorting);
|
||||
|
||||
done:
|
||||
gs_transfer_out_value (out_loader_configs, &ret_loader_configs);
|
||||
if (out_loader_configs)
|
||||
*out_loader_configs = g_steal_pointer (&ret_loader_configs);
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
|
|
@ -580,7 +595,8 @@ parse_origin (OstreeSysroot *self,
|
|||
}
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_origin, &ret_origin);
|
||||
if (out_origin)
|
||||
*out_origin = g_steal_pointer (&ret_origin);
|
||||
out:
|
||||
if (error)
|
||||
g_prefix_error (error, "Parsing %s: ", origin_path);
|
||||
|
|
@ -631,6 +647,16 @@ parse_bootlink (const char *bootlink,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_unlocked_development_path (OstreeDeployment *deployment)
|
||||
{
|
||||
return g_strdup_printf ("%s%s.%d/%s",
|
||||
_OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_DIR,
|
||||
ostree_deployment_get_csum (deployment),
|
||||
ostree_deployment_get_deployserial (deployment),
|
||||
_OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_FLAG_DEVELOPMENT);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_deployment (OstreeSysroot *self,
|
||||
const char *boot_link,
|
||||
|
|
@ -652,6 +678,8 @@ parse_deployment (OstreeSysroot *self,
|
|||
g_autofree char *treebootserial_target = NULL;
|
||||
g_autofree char *deploy_dir = NULL;
|
||||
GKeyFile *origin = NULL;
|
||||
g_autofree char *unlocked_development_path = NULL;
|
||||
struct stat stbuf;
|
||||
|
||||
if (!ensure_sysroot_fd (self, error))
|
||||
goto out;
|
||||
|
|
@ -689,8 +717,27 @@ parse_deployment (OstreeSysroot *self,
|
|||
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);
|
||||
if (lstat (unlocked_development_path, &stbuf) == 0)
|
||||
ret_deployment->unlocked = OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT;
|
||||
else
|
||||
{
|
||||
g_autofree char *existing_unlocked_state =
|
||||
g_key_file_get_string (origin, "origin", "unlocked", NULL);
|
||||
|
||||
if (g_strcmp0 (existing_unlocked_state, "hotfix") == 0)
|
||||
{
|
||||
ret_deployment->unlocked = OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX;
|
||||
}
|
||||
/* TODO: warn on unknown unlock types? */
|
||||
}
|
||||
|
||||
g_debug ("Deployment %s.%d unlocked=%d", treecsum, deployserial, ret_deployment->unlocked);
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_deployment, &ret_deployment);
|
||||
if (out_deployment)
|
||||
*out_deployment = g_steal_pointer (&ret_deployment);
|
||||
out:
|
||||
if (origin)
|
||||
g_key_file_unref (origin);
|
||||
|
|
@ -780,19 +827,24 @@ gboolean
|
|||
ostree_sysroot_load (OstreeSysroot *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
return ostree_sysroot_load_if_changed (self, NULL, cancellable, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_sysroot_load_if_changed (OstreeSysroot *self,
|
||||
gboolean *out_changed,
|
||||
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;
|
||||
|
||||
g_clear_pointer (&self->deployments, g_ptr_array_unref);
|
||||
g_clear_pointer (&self->booted_deployment, g_object_unref);
|
||||
self->bootversion = -1;
|
||||
self->subbootversion = -1;
|
||||
|
||||
if (!ensure_sysroot_fd (self, error))
|
||||
goto out;
|
||||
|
||||
|
|
@ -803,6 +855,28 @@ ostree_sysroot_load (OstreeSysroot *self,
|
|||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (fstatat (self->sysroot_fd, "ostree/deploy", &stbuf, 0) < 0)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (out_changed)
|
||||
{
|
||||
if (self->loaded_ts.tv_sec == stbuf.st_mtim.tv_sec &&
|
||||
self->loaded_ts.tv_nsec == stbuf.st_mtim.tv_nsec)
|
||||
{
|
||||
*out_changed = FALSE;
|
||||
ret = TRUE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
g_clear_pointer (&self->deployments, g_ptr_array_unref);
|
||||
g_clear_pointer (&self->booted_deployment, g_object_unref);
|
||||
self->bootversion = -1;
|
||||
self->subbootversion = -1;
|
||||
|
||||
if (!_ostree_sysroot_read_boot_loader_configs (self, bootversion, &boot_loader_configs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
|
@ -834,8 +908,11 @@ ostree_sysroot_load (OstreeSysroot *self,
|
|||
self->deployments = deployments;
|
||||
deployments = NULL; /* Transfer ownership */
|
||||
self->loaded = TRUE;
|
||||
self->loaded_ts = stbuf.st_mtim;
|
||||
|
||||
ret = TRUE;
|
||||
if (out_changed)
|
||||
*out_changed = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1005,7 +1082,8 @@ _ostree_sysroot_query_bootloader (OstreeSysroot *sysroot,
|
|||
g_clear_object (&ret_loader);
|
||||
|
||||
ret = TRUE;
|
||||
gs_transfer_out_value (out_bootloader, &ret_loader);
|
||||
if (out_bootloader)
|
||||
*out_bootloader = g_steal_pointer (&ret_loader);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1337,6 +1415,86 @@ ostree_sysroot_lock_finish (OstreeSysroot *self,
|
|||
return g_task_propagate_boolean ((GTask*)result, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_sysroot_init_osname:
|
||||
* @self: Sysroot
|
||||
* @osname: Name group of operating system checkouts
|
||||
* @cancellable: Cancellable
|
||||
* @error: Error
|
||||
*
|
||||
* Initialize the directory structure for an "osname", which is a
|
||||
* group of operating system deployments, with a shared `/var`. One
|
||||
* is required for generating a deployment.
|
||||
*/
|
||||
gboolean
|
||||
ostree_sysroot_init_osname (OstreeSysroot *self,
|
||||
const char *osname,
|
||||
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;
|
||||
|
||||
if (mkdirat (self->sysroot_fd, deploydir, 0777) < 0)
|
||||
{
|
||||
glnx_set_prefix_error_from_errno (error, "Creating %s", deploydir);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!glnx_opendirat (self->sysroot_fd, deploydir, TRUE, &dfd, error))
|
||||
goto out;
|
||||
|
||||
if (mkdirat (dfd, "var", 0777) < 0)
|
||||
{
|
||||
glnx_set_prefix_error_from_errno (error, "Creating %s", "var");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
if (fchmodat (dfd, "var/tmp", 01777, 0) < 0)
|
||||
{
|
||||
glnx_set_prefix_error_from_errno (error, "Fchmod %s", "var/tmp");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mkdirat (dfd, "var/lib", 0777) < 0)
|
||||
{
|
||||
glnx_set_prefix_error_from_errno (error, "Creating %s", "var/tmp");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (symlinkat ("../run", dfd, "var/run") < 0)
|
||||
{
|
||||
glnx_set_prefix_error_from_errno (error, "Symlinking %s", "var/run");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (symlinkat ("../run/lock", dfd, "var/lock") < 0)
|
||||
{
|
||||
glnx_set_prefix_error_from_errno (error, "Symlinking %s", "var/lock");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!_ostree_sysroot_bump_mtime (self, error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_sysroot_simple_write_deployment:
|
||||
* @sysroot: Sysroot
|
||||
|
|
@ -1354,6 +1512,10 @@ ostree_sysroot_lock_finish (OstreeSysroot *self,
|
|||
*
|
||||
* If %OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN is
|
||||
* specified, then all current deployments will be kept.
|
||||
*
|
||||
* If %OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT is
|
||||
* specified, then instead of prepending, the new deployment will be
|
||||
* added right after the booted or merge deployment, instead of first.
|
||||
*/
|
||||
gboolean
|
||||
ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot,
|
||||
|
|
@ -1370,6 +1532,8 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot,
|
|||
g_autoptr(GPtrArray) deployments = NULL;
|
||||
g_autoptr(GPtrArray) new_deployments = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
gboolean retain = (flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN) > 0;
|
||||
const gboolean make_default = !((flags & OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT) > 0);
|
||||
gboolean added_new = FALSE;
|
||||
|
||||
deployments = ostree_sysroot_get_deployments (sysroot);
|
||||
booted_deployment = ostree_sysroot_get_booted_deployment (sysroot);
|
||||
|
|
@ -1377,23 +1541,44 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot,
|
|||
if (osname == NULL && booted_deployment)
|
||||
osname = ostree_deployment_get_osname (booted_deployment);
|
||||
|
||||
g_ptr_array_add (new_deployments, g_object_ref (new_deployment));
|
||||
if (make_default)
|
||||
{
|
||||
g_ptr_array_add (new_deployments, g_object_ref (new_deployment));
|
||||
added_new = TRUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < deployments->len; i++)
|
||||
{
|
||||
OstreeDeployment *deployment = deployments->pdata[i];
|
||||
const gboolean is_merge_or_booted =
|
||||
ostree_deployment_equal (deployment, booted_deployment) ||
|
||||
ostree_deployment_equal (deployment, merge_deployment);
|
||||
|
||||
/* Keep deployments with different osnames, as well as the
|
||||
* booted and merge deployments
|
||||
*/
|
||||
if (retain ||
|
||||
(osname != NULL &&
|
||||
strcmp (ostree_deployment_get_osname (deployment), osname) != 0) ||
|
||||
ostree_deployment_equal (deployment, booted_deployment) ||
|
||||
ostree_deployment_equal (deployment, merge_deployment))
|
||||
(osname != NULL && strcmp (ostree_deployment_get_osname (deployment), osname) != 0) ||
|
||||
is_merge_or_booted)
|
||||
{
|
||||
g_ptr_array_add (new_deployments, g_object_ref (deployment));
|
||||
}
|
||||
|
||||
if (!added_new)
|
||||
{
|
||||
g_ptr_array_add (new_deployments, g_object_ref (new_deployment));
|
||||
added_new = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* In this non-default case , an improvement in the future would be
|
||||
* to put the new deployment right after the current default in the
|
||||
* order.
|
||||
*/
|
||||
if (!added_new)
|
||||
{
|
||||
g_ptr_array_add (new_deployments, g_object_ref (new_deployment));
|
||||
added_new = TRUE;
|
||||
}
|
||||
|
||||
if (!ostree_sysroot_write_deployments (sysroot, new_deployments, cancellable, error))
|
||||
|
|
@ -1406,3 +1591,263 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot,
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clone_deployment (OstreeSysroot *sysroot,
|
||||
OstreeDeployment *target_deployment,
|
||||
OstreeDeployment *merge_deployment,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
__attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL;
|
||||
glnx_unref_object OstreeDeployment *new_deployment = NULL;
|
||||
|
||||
/* Ensure we have a clean slate */
|
||||
if (!ostree_sysroot_prepare_cleanup (sysroot, cancellable, error))
|
||||
{
|
||||
g_prefix_error (error, "Performing initial cleanup: ");
|
||||
goto out;
|
||||
}
|
||||
|
||||
kargs = _ostree_kernel_args_new ();
|
||||
|
||||
{ OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (merge_deployment);
|
||||
g_auto(GStrv) previous_args = g_strsplit (ostree_bootconfig_parser_get (bootconfig, "options"), " ", -1);
|
||||
|
||||
_ostree_kernel_args_append_argv (kargs, previous_args);
|
||||
}
|
||||
|
||||
{
|
||||
g_auto(GStrv) kargs_strv = _ostree_kernel_args_to_strv (kargs);
|
||||
|
||||
if (!ostree_sysroot_deploy_tree (sysroot,
|
||||
ostree_deployment_get_osname (target_deployment),
|
||||
ostree_deployment_get_csum (target_deployment),
|
||||
ostree_deployment_get_origin (target_deployment),
|
||||
merge_deployment,
|
||||
kargs_strv,
|
||||
&new_deployment,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Hotfixes push the deployment as rollback target, so it shouldn't
|
||||
* be the default.
|
||||
*/
|
||||
if (!ostree_sysroot_simple_write_deployment (sysroot, ostree_deployment_get_osname (target_deployment),
|
||||
new_deployment, merge_deployment,
|
||||
OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_sysroot_deployment_unlock:
|
||||
* @self: Sysroot
|
||||
* @deployment: Deployment
|
||||
* @unlocked_state: Transition to this unlocked state
|
||||
* @cancellable: Cancellable
|
||||
* @error: Error
|
||||
*
|
||||
* Configure the target deployment @deployment such that it
|
||||
* is writable. There are multiple modes, essentially differing
|
||||
* in whether or not any changes persist across reboot.
|
||||
*
|
||||
* The `OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX` state is persistent
|
||||
* across reboots.
|
||||
*/
|
||||
gboolean
|
||||
ostree_sysroot_deployment_unlock (OstreeSysroot *self,
|
||||
OstreeDeployment *deployment,
|
||||
OstreeDeploymentUnlockedState unlocked_state,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
OstreeDeploymentUnlockedState current_unlocked =
|
||||
ostree_deployment_get_unlocked (deployment);
|
||||
glnx_unref_object OstreeDeployment *deployment_clone =
|
||||
ostree_deployment_clone (deployment);
|
||||
glnx_unref_object OstreeDeployment *merge_deployment = NULL;
|
||||
GKeyFile *origin_clone = ostree_deployment_get_origin (deployment_clone);
|
||||
const char hotfix_ovl_options[] = "lowerdir=usr,upperdir=.usr-ovl-upper,workdir=.usr-ovl-work";
|
||||
const char *ovl_options = NULL;
|
||||
g_autofree char *deployment_path = NULL;
|
||||
glnx_fd_close int deployment_dfd = -1;
|
||||
pid_t mount_child;
|
||||
|
||||
/* This function cannot re-lock */
|
||||
g_return_val_if_fail (unlocked_state != OSTREE_DEPLOYMENT_UNLOCKED_NONE, FALSE);
|
||||
|
||||
if (current_unlocked != OSTREE_DEPLOYMENT_UNLOCKED_NONE)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Deployment is already in unlocked state: %s",
|
||||
ostree_deployment_unlocked_state_to_string (current_unlocked));
|
||||
goto out;
|
||||
}
|
||||
|
||||
merge_deployment = ostree_sysroot_get_merge_deployment (self, ostree_deployment_get_osname (deployment));
|
||||
if (!merge_deployment)
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No previous deployment to duplicate");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* For hotfixes, we push a rollback target */
|
||||
if (unlocked_state == OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX)
|
||||
{
|
||||
if (!clone_deployment (self, deployment, merge_deployment, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Crack it open */
|
||||
if (!ostree_sysroot_deployment_set_mutable (self, deployment, TRUE,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
deployment_path = ostree_sysroot_get_deployment_dirpath (self, deployment);
|
||||
|
||||
if (!glnx_opendirat (self->sysroot_fd, deployment_path, TRUE, &deployment_dfd, error))
|
||||
goto out;
|
||||
|
||||
switch (unlocked_state)
|
||||
{
|
||||
case OSTREE_DEPLOYMENT_UNLOCKED_NONE:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
case OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX:
|
||||
{
|
||||
/* Create the overlayfs directories in the deployment root
|
||||
* directly for hotfixes. The ostree-prepare-root.c helper
|
||||
* is also set up to detect and mount these.
|
||||
*/
|
||||
if (!glnx_shutil_mkdir_p_at (deployment_dfd, ".usr-ovl-upper", 0755, cancellable, error))
|
||||
goto out;
|
||||
if (!glnx_shutil_mkdir_p_at (deployment_dfd, ".usr-ovl-work", 0755, cancellable, error))
|
||||
goto out;
|
||||
ovl_options = hotfix_ovl_options;
|
||||
}
|
||||
break;
|
||||
case OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT:
|
||||
{
|
||||
/* We're just doing transient development/hacking? Okay,
|
||||
* stick the overlayfs bits in /var/tmp.
|
||||
*/
|
||||
char *development_ovldir = strdupa ("/var/tmp/ostree-unlock-ovl.XXXXXX");
|
||||
const char *development_ovl_upper;
|
||||
const char *development_ovl_work;
|
||||
|
||||
if (!glnx_mkdtempat (AT_FDCWD, development_ovldir, 0700, error))
|
||||
goto out;
|
||||
|
||||
development_ovl_upper = glnx_strjoina (development_ovldir, "/upper");
|
||||
if (!glnx_shutil_mkdir_p_at (AT_FDCWD, development_ovl_upper, 0755, cancellable, error))
|
||||
goto out;
|
||||
development_ovl_work = glnx_strjoina (development_ovldir, "/work");
|
||||
if (!glnx_shutil_mkdir_p_at (AT_FDCWD, development_ovl_work, 0755, cancellable, error))
|
||||
goto out;
|
||||
ovl_options = glnx_strjoina ("lowerdir=usr,upperdir=", development_ovl_upper,
|
||||
",workdir=", development_ovl_work);
|
||||
}
|
||||
}
|
||||
|
||||
g_assert (ovl_options != NULL);
|
||||
|
||||
/* Here we run `mount()` in a fork()ed child because we need to use
|
||||
* `chdir()` in order to have the mount path options to overlayfs not
|
||||
* look ugly.
|
||||
*
|
||||
* We can't `chdir()` inside a shared library since there may be
|
||||
* threads, etc.
|
||||
*/
|
||||
{
|
||||
/* Make a copy of the fd that's *not* FD_CLOEXEC so that we pass
|
||||
* it to the child.
|
||||
*/
|
||||
glnx_fd_close int child_deployment_dfd = dup (deployment_dfd);
|
||||
|
||||
if (child_deployment_dfd < 0)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
mount_child = fork ();
|
||||
if (mount_child < 0)
|
||||
{
|
||||
glnx_set_prefix_error_from_errno (error, "%s", "fork");
|
||||
goto out;
|
||||
}
|
||||
else if (mount_child == 0)
|
||||
{
|
||||
/* Child process. Do NOT use any GLib API here. */
|
||||
if (fchdir (child_deployment_dfd) < 0)
|
||||
exit (EXIT_FAILURE);
|
||||
(void) close (child_deployment_dfd);
|
||||
if (mount ("overlay", "/usr", "overlay", 0, ovl_options) < 0)
|
||||
exit (EXIT_FAILURE);
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Parent */
|
||||
int estatus;
|
||||
|
||||
if (TEMP_FAILURE_RETRY (waitpid (mount_child, &estatus, 0)) < 0)
|
||||
{
|
||||
glnx_set_prefix_error_from_errno (error, "%s", "waitpid() on mount helper");
|
||||
goto out;
|
||||
}
|
||||
if (!g_spawn_check_exit_status (estatus, error))
|
||||
{
|
||||
g_prefix_error (error, "overlayfs mount helper: ");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now, write out the flag saying what we did */
|
||||
switch (unlocked_state)
|
||||
{
|
||||
case OSTREE_DEPLOYMENT_UNLOCKED_NONE:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
case OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX:
|
||||
g_key_file_set_string (origin_clone, "origin", "unlocked",
|
||||
ostree_deployment_unlocked_state_to_string (unlocked_state));
|
||||
if (!ostree_sysroot_write_origin_file (self, deployment, origin_clone,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
break;
|
||||
case OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT:
|
||||
{
|
||||
g_autofree char *devpath = get_unlocked_development_path (deployment);
|
||||
g_autofree char *devpath_parent = dirname (g_strdup (devpath));
|
||||
|
||||
if (!glnx_shutil_mkdir_p_at (AT_FDCWD, devpath_parent, 0755, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!g_file_set_contents (devpath, "", 0, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* For hotfixes we already pushed a rollback which will bump the
|
||||
* mtime, but we need to bump it again so that clients get the state
|
||||
* change for this deployment. For development we need to do this
|
||||
* regardless.
|
||||
*/
|
||||
if (!_ostree_sysroot_bump_mtime (self, error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,82 +31,121 @@ G_BEGIN_DECLS
|
|||
#define OSTREE_IS_SYSROOT(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSTREE_TYPE_SYSROOT))
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GType ostree_sysroot_get_type (void);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeSysroot* ostree_sysroot_new (GFile *path);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeSysroot* ostree_sysroot_new_default (void);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GFile *ostree_sysroot_get_path (OstreeSysroot *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
int ostree_sysroot_get_fd (OstreeSysroot *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_load (OstreeSysroot *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_load_if_changed (OstreeSysroot *self,
|
||||
gboolean *out_changed,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_sysroot_unload (OstreeSysroot *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_ensure_initialized (OstreeSysroot *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
int ostree_sysroot_get_bootversion (OstreeSysroot *self);
|
||||
_OSTREE_PUBLIC
|
||||
int ostree_sysroot_get_subbootversion (OstreeSysroot *self);
|
||||
_OSTREE_PUBLIC
|
||||
GPtrArray *ostree_sysroot_get_deployments (OstreeSysroot *self);
|
||||
_OSTREE_PUBLIC
|
||||
OstreeDeployment *ostree_sysroot_get_booted_deployment (OstreeSysroot *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GFile *ostree_sysroot_get_deployment_directory (OstreeSysroot *self,
|
||||
OstreeDeployment *deployment);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
char *ostree_sysroot_get_deployment_dirpath (OstreeSysroot *self,
|
||||
OstreeDeployment *deployment);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GFile * ostree_sysroot_get_deployment_origin_path (GFile *deployment_path);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_lock (OstreeSysroot *self, GError **error);
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_try_lock (OstreeSysroot *self,
|
||||
gboolean *out_acquired,
|
||||
GError **error);
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_sysroot_lock_async (OstreeSysroot *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_lock_finish (OstreeSysroot *self,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
_OSTREE_PUBLIC
|
||||
void ostree_sysroot_unlock (OstreeSysroot *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_init_osname (OstreeSysroot *self,
|
||||
const char *osname,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_cleanup (OstreeSysroot *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_prepare_cleanup (OstreeSysroot *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_write_origin_file (OstreeSysroot *sysroot,
|
||||
OstreeDeployment *deployment,
|
||||
GKeyFile *new_origin,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_get_repo (OstreeSysroot *self,
|
||||
OstreeRepo **out_repo,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_deployment_set_kargs (OstreeSysroot *self,
|
||||
OstreeDeployment *deployment,
|
||||
char **new_kargs,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_write_deployments (OstreeSysroot *self,
|
||||
GPtrArray *new_deployments,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_deploy_tree (OstreeSysroot *self,
|
||||
const char *osname,
|
||||
const char *revision,
|
||||
|
|
@ -117,24 +156,36 @@ gboolean ostree_sysroot_deploy_tree (OstreeSysroot *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_deployment_set_mutable (OstreeSysroot *self,
|
||||
OstreeDeployment *deployment,
|
||||
gboolean is_mutable,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_deployment_unlock (OstreeSysroot *self,
|
||||
OstreeDeployment *deployment,
|
||||
OstreeDeploymentUnlockedState unlocked_state,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
OstreeDeployment *ostree_sysroot_get_merge_deployment (OstreeSysroot *self,
|
||||
const char *osname);
|
||||
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
GKeyFile *ostree_sysroot_origin_new_from_refspec (OstreeSysroot *self,
|
||||
const char *refspec);
|
||||
|
||||
typedef enum {
|
||||
OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NONE = 0,
|
||||
OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN = (1 << 0)
|
||||
OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN = (1 << 0),
|
||||
OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT = (1 << 1)
|
||||
} OstreeSysrootSimpleWriteDeploymentFlags;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot,
|
||||
const char *osname,
|
||||
OstreeDeployment *new_deployment,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@
|
|||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#ifndef _OSTREE_PUBLIC
|
||||
#define _OSTREE_PUBLIC extern
|
||||
#endif
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct OstreeRepo OstreeRepo;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ ot_gopendirat (int dfd,
|
|||
int ret = ot_opendirat (dfd, path, follow);
|
||||
if (ret == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
return FALSE;
|
||||
}
|
||||
*out_fd = ret;
|
||||
|
|
@ -71,7 +71,7 @@ ot_lgetxattrat (int dfd,
|
|||
while (G_UNLIKELY (bytes_read < 0 && errno == EINTR));
|
||||
if (G_UNLIKELY (bytes_read < 0))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ ot_lgetxattrat (int dfd,
|
|||
while (G_UNLIKELY (real_size < 0 && errno == EINTR));
|
||||
if (G_UNLIKELY (real_size < 0))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
g_free (buf);
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -111,7 +111,7 @@ ot_lsetxattrat (int dfd,
|
|||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
||||
if (G_UNLIKELY (res == -1))
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -134,7 +134,7 @@ ot_readlinkat_gfile_info (int dfd,
|
|||
while (G_UNLIKELY (len == -1 && errno == EINTR));
|
||||
if (len == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
targetbuf[len] = '\0';
|
||||
|
|
@ -180,7 +180,7 @@ ot_openat_read_stream (int dfd,
|
|||
while (G_UNLIKELY (fd == -1 && errno == EINTR));
|
||||
if (fd == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -205,3 +205,28 @@ ot_ensure_unlinked_at (int dfd,
|
|||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ot_openat_ignore_enoent (int dfd,
|
||||
const char *path,
|
||||
int *out_fd,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
int target_fd = -1;
|
||||
|
||||
target_fd = openat (dfd, path, O_CLOEXEC | O_RDONLY);
|
||||
if (target_fd < 0)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
*out_fd = target_fd;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,4 +61,9 @@ gboolean ot_ensure_unlinked_at (int dfd,
|
|||
const char *path,
|
||||
GError **error);
|
||||
|
||||
gboolean ot_openat_ignore_enoent (int dfd,
|
||||
const char *path,
|
||||
int *out_fd,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
|
|
@ -309,7 +309,9 @@ ot_file_replace_contents_at (int dfd,
|
|||
int r = posix_fallocate (fd, 0, g_bytes_get_size (contents));
|
||||
if (r != 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, r);
|
||||
/* posix_fallocate is a weird deviation from errno standards */
|
||||
errno = r;
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
@ -320,7 +322,7 @@ ot_file_replace_contents_at (int dfd,
|
|||
|
||||
if (datasync && fdatasync (fd) != 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -329,7 +331,7 @@ ot_file_replace_contents_at (int dfd,
|
|||
|
||||
if (renameat (dfd, tmpname, dfd, path) == -1)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -360,8 +362,8 @@ ot_gfile_replace_contents_fsync (GFile *path,
|
|||
|
||||
parent = g_file_get_parent (path);
|
||||
|
||||
if (!gs_file_open_dir_fd (parent, &parent_dfd,
|
||||
cancellable, error))
|
||||
if (!glnx_opendirat (AT_FDCWD, gs_file_get_path_cached (parent), TRUE,
|
||||
&parent_dfd, error))
|
||||
goto out;
|
||||
|
||||
if (!ot_file_replace_contents_at (parent_dfd, target_basename,
|
||||
|
|
@ -424,12 +426,13 @@ ot_util_fsync_directory (GFile *dir,
|
|||
gboolean ret = FALSE;
|
||||
int dfd = -1;
|
||||
|
||||
if (!gs_file_open_dir_fd (dir, &dfd, cancellable, error))
|
||||
if (!glnx_opendirat (AT_FDCWD, gs_file_get_path_cached (dir), TRUE,
|
||||
&dfd, error))
|
||||
goto out;
|
||||
|
||||
if (fsync (dfd) != 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ ot_util_variant_map_fd (int fd,
|
|||
|
||||
if (fstat (fd, &stbuf) != 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -212,7 +212,7 @@ ot_util_variant_map_fd (int fd,
|
|||
map = mmap (NULL, len, PROT_READ, MAP_PRIVATE, fd, start);
|
||||
if (!map)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -113,8 +113,8 @@ ot_admin_builtin_deploy (int argc, char **argv, GCancellable *cancellable, GErro
|
|||
merge_deployment = ostree_sysroot_get_merge_deployment (sysroot, opt_osname);
|
||||
|
||||
/* Here we perform cleanup of any leftover data from previous
|
||||
* partial failures. This avoids having to call gs_shutil_rm_rf()
|
||||
* at random points throughout the process.
|
||||
* partial failures. This avoids having to call
|
||||
* glnx_shutil_rm_rf_at() at random points throughout the process.
|
||||
*
|
||||
* TODO: Add /ostree/transaction file, and only do this cleanup if
|
||||
* we find it.
|
||||
|
|
|
|||
|
|
@ -40,8 +40,6 @@ ot_admin_builtin_os_init (int argc, char **argv, GCancellable *cancellable, GErr
|
|||
glnx_unref_object OstreeSysroot *sysroot = NULL;
|
||||
gboolean ret = FALSE;
|
||||
const char *osname = NULL;
|
||||
g_autoptr(GFile) deploy_dir = NULL;
|
||||
g_autoptr(GFile) dir = NULL;
|
||||
|
||||
context = g_option_context_new ("OSNAME - Initialize empty state for given operating system");
|
||||
|
||||
|
|
@ -61,48 +59,10 @@ ot_admin_builtin_os_init (int argc, char **argv, GCancellable *cancellable, GErr
|
|||
|
||||
osname = argv[1];
|
||||
|
||||
deploy_dir = ot_gfile_get_child_build_path (ostree_sysroot_get_path (sysroot), "ostree", "deploy", osname, NULL);
|
||||
|
||||
/* Ensure core subdirectories of /var exist, since we need them for
|
||||
* dracut generation, and the host will want them too.
|
||||
*/
|
||||
g_clear_object (&dir);
|
||||
dir = ot_gfile_get_child_build_path (deploy_dir, "var", "tmp", NULL);
|
||||
if (!gs_file_ensure_directory (dir, TRUE, cancellable, error))
|
||||
goto out;
|
||||
if (chmod (gs_file_get_path_cached (dir), 01777) < 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_clear_object (&dir);
|
||||
dir = ot_gfile_get_child_build_path (deploy_dir, "var", "lib", NULL);
|
||||
if (!gs_file_ensure_directory (dir, TRUE, cancellable, error))
|
||||
if (!ostree_sysroot_init_osname (sysroot, osname, cancellable, error))
|
||||
goto out;
|
||||
|
||||
g_clear_object (&dir);
|
||||
dir = ot_gfile_get_child_build_path (deploy_dir, "var", "run", NULL);
|
||||
if (!g_file_test (gs_file_get_path_cached (dir), G_FILE_TEST_IS_SYMLINK))
|
||||
{
|
||||
if (symlink ("../run", gs_file_get_path_cached (dir)) < 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
dir = ot_gfile_get_child_build_path (deploy_dir, "var", "lock", NULL);
|
||||
if (!g_file_test (gs_file_get_path_cached (dir), G_FILE_TEST_IS_SYMLINK))
|
||||
{
|
||||
if (symlink ("../run/lock", gs_file_get_path_cached (dir)) < 0)
|
||||
{
|
||||
gs_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
g_print ("%s initialized as OSTree root\n", gs_file_get_path_cached (deploy_dir));
|
||||
g_print ("ostree/deploy/%s initialized as OSTree root\n", osname);
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
|
|
|
|||
|
|
@ -89,6 +89,9 @@ ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GErro
|
|||
glnx_unref_object OstreeRepo *repo = NULL;
|
||||
OstreeDeployment *booted_deployment = NULL;
|
||||
g_autoptr(GPtrArray) deployments = NULL;
|
||||
const int is_tty = isatty (1);
|
||||
const char *red_bold_prefix = is_tty ? "\x1b[31m\x1b[1m" : "";
|
||||
const char *red_bold_suffix = is_tty ? "\x1b[22m\x1b[0m" : "";
|
||||
guint i;
|
||||
|
||||
context = g_option_context_new ("List deployments");
|
||||
|
|
@ -118,12 +121,15 @@ ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GErro
|
|||
OstreeDeployment *deployment = deployments->pdata[i];
|
||||
GKeyFile *origin;
|
||||
const char *ref = ostree_deployment_get_csum (deployment);
|
||||
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;
|
||||
|
||||
origin = ostree_deployment_get_origin (deployment);
|
||||
|
||||
g_print ("%c %s %s.%d\n",
|
||||
deployment == booted_deployment ? '*' : ' ',
|
||||
ostree_deployment_get_osname (deployment),
|
||||
|
|
@ -131,7 +137,15 @@ ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GErro
|
|||
ostree_deployment_get_deployserial (deployment));
|
||||
if (version)
|
||||
g_print (" Version: %s\n", version);
|
||||
origin = ostree_deployment_get_origin (deployment);
|
||||
switch (unlocked)
|
||||
{
|
||||
case OSTREE_DEPLOYMENT_UNLOCKED_NONE:
|
||||
break;
|
||||
default:
|
||||
g_print (" %sUnlocked: %s%s\n", red_bold_prefix,
|
||||
ostree_deployment_unlocked_state_to_string (unlocked),
|
||||
red_bold_suffix);
|
||||
}
|
||||
if (!origin)
|
||||
g_print (" origin: none\n");
|
||||
else
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ static gboolean opt_reboot;
|
|||
static char *opt_osname;
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{ "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Reboot after switching trees", NULL },
|
||||
{ "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" },
|
||||
{ NULL }
|
||||
};
|
||||
|
|
@ -162,16 +163,11 @@ ot_admin_builtin_switch (int argc, char **argv, GCancellable *cancellable, GErro
|
|||
if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
|
||||
goto out;
|
||||
|
||||
{
|
||||
g_autoptr(GFile) real_sysroot = g_file_new_for_path ("/");
|
||||
|
||||
if (opt_reboot && g_file_equal (ostree_sysroot_get_path (sysroot), real_sysroot))
|
||||
{
|
||||
gs_subprocess_simple_run_sync (NULL, GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT,
|
||||
cancellable, error,
|
||||
"systemctl", "reboot", NULL);
|
||||
}
|
||||
}
|
||||
if (opt_reboot)
|
||||
{
|
||||
if (!ot_admin_execve_reboot (sysroot, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2016 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* 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 "ot-main.h"
|
||||
#include "ot-admin-builtins.h"
|
||||
#include "ot-admin-functions.h"
|
||||
#include "ostree.h"
|
||||
#include "otutil.h"
|
||||
|
||||
#include "../libostree/ostree-kernel-args.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <err.h>
|
||||
|
||||
static gboolean opt_hotfix;
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{ "hotfix", 0, 0, G_OPTION_ARG_NONE, &opt_hotfix, "Keep the current deployment as default", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
gboolean
|
||||
ot_admin_builtin_unlock (int argc, char **argv, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GOptionContext *context;
|
||||
glnx_unref_object OstreeSysroot *sysroot = NULL;
|
||||
glnx_unref_object OstreeRepo *repo = NULL;
|
||||
g_autoptr(GPtrArray) new_deployments = NULL;
|
||||
glnx_unref_object OstreeDeployment *merge_deployment = NULL;
|
||||
OstreeDeployment *booted_deployment = NULL;
|
||||
OstreeDeploymentUnlockedState target_state;
|
||||
|
||||
context = g_option_context_new ("Make the current deployment mutable (as a hotfix or development)");
|
||||
|
||||
if (!ostree_admin_option_context_parse (context, options, &argc, &argv,
|
||||
OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER,
|
||||
&sysroot, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
ot_util_usage_error (context, "This command takes no extra arguments", error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ostree_sysroot_load (sysroot, cancellable, error))
|
||||
goto out;
|
||||
|
||||
booted_deployment = ostree_sysroot_get_booted_deployment (sysroot);
|
||||
if (!booted_deployment)
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Not currently booted into an OSTree system");
|
||||
goto out;
|
||||
}
|
||||
|
||||
target_state = opt_hotfix ? OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX : OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT;
|
||||
|
||||
if (!ostree_sysroot_deployment_unlock (sysroot, booted_deployment,
|
||||
target_state, cancellable, error))
|
||||
goto out;
|
||||
|
||||
switch (target_state)
|
||||
{
|
||||
case OSTREE_DEPLOYMENT_UNLOCKED_NONE:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
case OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX:
|
||||
g_print ("Hotfix mode enabled. A writable overlayfs is now mounted on /usr\n"
|
||||
"for this booted deployment. A non-hotfixed clone has been created\n"
|
||||
"as the non-default rollback target.\n");
|
||||
break;
|
||||
case OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT:
|
||||
g_print ("Development mode enabled. A writable overlayfs is now mounted on /usr.\n"
|
||||
"All changes there will be discarded on reboot.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
if (context)
|
||||
g_option_context_free (context);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -97,6 +97,9 @@ ot_admin_builtin_upgrade (int argc, char **argv, GCancellable *cancellable, GErr
|
|||
"override-commit", NULL);
|
||||
}
|
||||
|
||||
/* Should we consider requiring --discard-hotfix here? */
|
||||
origin_changed |= g_key_file_remove_key (origin, "origin", "unlocked", NULL);
|
||||
|
||||
if (origin_changed)
|
||||
{
|
||||
/* XXX GCancellable parameter is not used. */
|
||||
|
|
@ -133,16 +136,13 @@ ot_admin_builtin_upgrade (int argc, char **argv, GCancellable *cancellable, GErr
|
|||
}
|
||||
else
|
||||
{
|
||||
g_autoptr(GFile) real_sysroot = g_file_new_for_path ("/");
|
||||
|
||||
if (!ostree_sysroot_upgrader_deploy (upgrader, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (opt_reboot && g_file_equal (ostree_sysroot_get_path (sysroot), real_sysroot))
|
||||
if (opt_reboot)
|
||||
{
|
||||
gs_subprocess_simple_run_sync (NULL, GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT,
|
||||
cancellable, error,
|
||||
"systemctl", "reboot", NULL);
|
||||
if (!ot_admin_execve_reboot (sysroot, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ gboolean ot_admin_builtin_init_fs (int argc, char **argv, GCancellable *cancella
|
|||
gboolean ot_admin_builtin_undeploy (int argc, char **argv, GCancellable *cancellable, GError **error);
|
||||
gboolean ot_admin_builtin_deploy (int argc, char **argv, GCancellable *cancellable, GError **error);
|
||||
gboolean ot_admin_builtin_cleanup (int argc, char **argv, GCancellable *cancellable, GError **error);
|
||||
gboolean ot_admin_builtin_unlock (int argc, char **argv, GCancellable *cancellable, GError **error);
|
||||
gboolean ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GError **error);
|
||||
gboolean ot_admin_builtin_set_origin (int argc, char **argv, GCancellable *cancellable, GError **error);
|
||||
gboolean ot_admin_builtin_diff (int argc, char **argv, GCancellable *cancellable, GError **error);
|
||||
|
|
|
|||
|
|
@ -155,3 +155,20 @@ ot_admin_sysroot_lock (OstreeSysroot *sysroot,
|
|||
g_main_context_unref (state.mainctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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 (execl ("systemctl", "systemctl", "reboot", NULL) < 0)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,5 +45,8 @@ gboolean
|
|||
ot_admin_sysroot_lock (OstreeSysroot *sysroot,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
ot_admin_execve_reboot (OstreeSysroot *sysroot,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ static OstreeAdminCommand admin_subcommands[] = {
|
|||
{ "status", ot_admin_builtin_status },
|
||||
{ "switch", ot_admin_builtin_switch },
|
||||
{ "undeploy", ot_admin_builtin_undeploy },
|
||||
{ "unlock", ot_admin_builtin_unlock },
|
||||
{ "upgrade", ot_admin_builtin_upgrade },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -27,41 +27,28 @@
|
|||
#include "ostree.h"
|
||||
|
||||
static gboolean opt_delete;
|
||||
static gboolean opt_list;
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{ "delete", 0, 0, G_OPTION_ARG_NONE, &opt_delete, "Delete refs which match PREFIX, rather than listing them", NULL },
|
||||
{ "list", 0, 0, G_OPTION_ARG_NONE, &opt_list, "Do not remove the prefix from the refs", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
gboolean
|
||||
ostree_builtin_refs (int argc, char **argv, GCancellable *cancellable, GError **error)
|
||||
static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GOptionContext *context;
|
||||
glnx_unref_object OstreeRepo *repo = NULL;
|
||||
const char *refspec_prefix = NULL;
|
||||
g_autoptr(GHashTable) refs = NULL;
|
||||
GHashTableIter hashiter;
|
||||
gpointer hashkey, hashvalue;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
context = g_option_context_new ("[PREFIX] - List refs");
|
||||
|
||||
if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (argc >= 2)
|
||||
refspec_prefix = argv[1];
|
||||
|
||||
/* Require a prefix when deleting to help avoid accidents. */
|
||||
if (opt_delete && refspec_prefix == NULL)
|
||||
if (opt_delete || opt_list)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"PREFIX is required when deleting refs");
|
||||
goto out;
|
||||
if (!ostree_repo_list_refs_ext (repo, refspec_prefix, &refs, OSTREE_REPO_LIST_REFS_EXT_NONE,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ostree_repo_list_refs (repo, refspec_prefix, &refs,
|
||||
cancellable, error))
|
||||
else if (!ostree_repo_list_refs (repo, refspec_prefix, &refs, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!opt_delete)
|
||||
|
|
@ -90,6 +77,41 @@ ostree_builtin_refs (int argc, char **argv, GCancellable *cancellable, GError **
|
|||
goto out;
|
||||
}
|
||||
}
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_builtin_refs (int argc, char **argv, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GOptionContext *context;
|
||||
glnx_unref_object OstreeRepo *repo = NULL;
|
||||
int i;
|
||||
|
||||
context = g_option_context_new ("[PREFIX] - List refs");
|
||||
|
||||
if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (argc >= 2)
|
||||
{
|
||||
for (i = 1; i < argc; i++)
|
||||
if (!do_ref (repo, argv[i], cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Require a prefix when deleting to help avoid accidents. */
|
||||
if (opt_delete)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"At least one PREFIX is required when deleting refs");
|
||||
goto out;
|
||||
}
|
||||
ret = do_ref (repo, NULL, cancellable, error);
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
|
|
|
|||
|
|
@ -427,10 +427,9 @@ ostree_builtin_trivial_httpd (int argc, char **argv, GCancellable *cancellable,
|
|||
*/
|
||||
if (prctl (PR_SET_PDEATHSIG, SIGTERM) != 0)
|
||||
{
|
||||
int errsv = errno;
|
||||
if (errsv != ENOSYS)
|
||||
if (errno != ENOSYS)
|
||||
{
|
||||
gs_set_error_from_errno (error, errsv);
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,8 +62,7 @@ ot_editor_prompt (OstreeRepo *repo,
|
|||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
glnx_unref_object GSSubprocessContext *ctx = NULL;
|
||||
glnx_unref_object GSSubprocess *proc = NULL;
|
||||
glnx_unref_object GSubprocess *proc = NULL;
|
||||
g_autoptr(GFile) file = NULL;
|
||||
g_autoptr(GFileIOStream) io = NULL;
|
||||
GOutputStream *output;
|
||||
|
|
@ -92,16 +91,11 @@ ot_editor_prompt (OstreeRepo *repo,
|
|||
g_autofree char *quoted_file = g_shell_quote (gs_file_get_path_cached (file));
|
||||
args = g_strconcat (editor, " ", quoted_file, NULL);
|
||||
}
|
||||
ctx = gs_subprocess_context_newv ("/bin/sh", "-c", args, NULL);
|
||||
gs_subprocess_context_set_stdin_disposition (ctx, GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT);
|
||||
gs_subprocess_context_set_stdout_disposition (ctx, GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT);
|
||||
gs_subprocess_context_set_stderr_disposition (ctx, GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT);
|
||||
|
||||
proc = gs_subprocess_new (ctx, cancellable, error);
|
||||
if (proc == NULL)
|
||||
goto out;
|
||||
proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_INHERIT, error,
|
||||
"/bin/sh", "-c", args, NULL);
|
||||
|
||||
if (!gs_subprocess_wait_sync_check (proc, cancellable, error))
|
||||
if (!g_subprocess_wait_check (proc, cancellable, error))
|
||||
{
|
||||
g_prefix_error (error, "There was a problem with the editor '%s'", editor);
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -294,7 +294,8 @@ ostree_option_context_parse (GOptionContext *context,
|
|||
}
|
||||
}
|
||||
|
||||
gs_transfer_out_value (out_repo, &repo);
|
||||
if (out_repo)
|
||||
*out_repo = g_steal_pointer (&repo);
|
||||
|
||||
success = TRUE;
|
||||
|
||||
|
|
@ -375,7 +376,8 @@ ostree_admin_option_context_parse (GOptionContext *context,
|
|||
goto out;
|
||||
}
|
||||
|
||||
gs_transfer_out_value (out_sysroot, &sysroot);
|
||||
if (out_sysroot)
|
||||
*out_sysroot = g_steal_pointer (&sysroot);
|
||||
|
||||
success = TRUE;
|
||||
|
||||
|
|
|
|||
|
|
@ -24,10 +24,8 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/xattr.h>
|
||||
|
|
@ -227,7 +225,7 @@ callback_symlink (const char *from, const char *to)
|
|||
{
|
||||
fprintf (stderr, "Failed to find newly created symlink '%s': %s\n",
|
||||
to, g_strerror (errno));
|
||||
exit (1);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -263,7 +261,7 @@ can_write (const char *path)
|
|||
else
|
||||
return -errno;
|
||||
}
|
||||
if (devino_set_contains (stbuf.st_dev, stbuf.st_ino))
|
||||
if (!devino_set_contains (stbuf.st_dev, stbuf.st_ino))
|
||||
return -EROFS;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -545,7 +543,7 @@ rofs_parse_opt (void *data, const char *arg, int key,
|
|||
if (basefd == -1)
|
||||
{
|
||||
perror ("openat");
|
||||
exit (1);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -557,10 +555,10 @@ rofs_parse_opt (void *data, const char *arg, int key,
|
|||
return 1;
|
||||
case KEY_HELP:
|
||||
usage (outargs->argv[0]);
|
||||
exit (0);
|
||||
exit (EXIT_SUCCESS);
|
||||
default:
|
||||
fprintf (stderr, "see `%s -h' for usage\n", outargs->argv[0]);
|
||||
exit (1);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -584,13 +582,13 @@ main (int argc, char *argv[])
|
|||
{
|
||||
fprintf (stderr, "Invalid arguments\n");
|
||||
fprintf (stderr, "see `%s -h' for usage\n", argv[0]);
|
||||
exit (1);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (basefd == -1)
|
||||
{
|
||||
fprintf (stderr, "Missing basepath\n");
|
||||
fprintf (stderr, "see `%s -h' for usage\n", argv[0]);
|
||||
exit (1);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
created_devino_hash = g_hash_table_new_full (devino_hash, devino_equal, g_free, NULL);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@
|
|||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mount.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#include "ostree-mount-util.h"
|
||||
|
||||
|
|
@ -48,3 +52,18 @@ perrorv (const char *format, ...)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
path_is_on_readonly_fs (char *path)
|
||||
{
|
||||
struct statvfs stvfsbuf;
|
||||
|
||||
if (statvfs (path, &stvfsbuf) == -1)
|
||||
{
|
||||
perrorv ("statvfs(%s): ", path);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return (stvfsbuf.f_flag & ST_RDONLY) != 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,3 +22,5 @@
|
|||
#pragma once
|
||||
|
||||
int perrorv (const char *format, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
|
||||
int path_is_on_readonly_fs (char *path);
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@ touch_run_ostree (void)
|
|||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
const char *readonly_bind_mounts[] = { "/usr", NULL };
|
||||
const char *root_mountpoint = NULL;
|
||||
char *ostree_target = NULL;
|
||||
char *deploy_path = NULL;
|
||||
|
|
@ -119,7 +118,7 @@ main(int argc, char *argv[])
|
|||
char destpath[PATH_MAX];
|
||||
char newroot[PATH_MAX];
|
||||
struct stat stbuf;
|
||||
int i;
|
||||
int orig_cwd_dfd;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
|
|
@ -211,21 +210,70 @@ main(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
/* Set up any read-only bind mounts (notably /usr) */
|
||||
for (i = 0; readonly_bind_mounts[i] != NULL; i++)
|
||||
/* Here we do a dance to chdir to the newroot so that we can have
|
||||
* the potential overlayfs mount points not look ugly. However...I
|
||||
* think we could do this a lot earlier and make all of the mounts
|
||||
* here just be relative.
|
||||
*/
|
||||
orig_cwd_dfd = openat (AT_FDCWD, ".", O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY);
|
||||
if (orig_cwd_dfd < 0)
|
||||
{
|
||||
snprintf (destpath, sizeof(destpath), "%s%s", newroot, readonly_bind_mounts[i]);
|
||||
if (mount (destpath, destpath, NULL, MS_BIND, NULL) < 0)
|
||||
perrorv ("failed to open .");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (chdir (newroot) < 0)
|
||||
{
|
||||
perrorv ("failed to chdir to newroot");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Do we have a persistent overlayfs for /usr? If so, mount it now. */
|
||||
if (lstat (".usr-ovl-work", &stbuf) == 0)
|
||||
{
|
||||
const char usr_ovl_options[] = "lowerdir=usr,upperdir=.usr-ovl-upper,workdir=.usr-ovl-work";
|
||||
|
||||
/* Except overlayfs barfs if we try to mount it on a read-only
|
||||
* filesystem. For this use case I think admins are going to be
|
||||
* okay if we remount the rootfs here, rather than waiting until
|
||||
* later boot and `systemd-remount-fs.service`.
|
||||
*/
|
||||
if (path_is_on_readonly_fs ("."))
|
||||
{
|
||||
perrorv ("failed to bind mount (class:readonly) %s", destpath);
|
||||
exit (EXIT_FAILURE);
|
||||
if (mount (".", ".", NULL, MS_REMOUNT | MS_SILENT, NULL) < 0)
|
||||
{
|
||||
perrorv ("Failed to remount rootfs writable (for overlayfs)");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
if (mount (destpath, destpath, NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0)
|
||||
|
||||
if (mount ("overlay", "usr", "overlay", 0, usr_ovl_options) < 0)
|
||||
{
|
||||
perrorv ("failed to bind mount (class:readonly) %s", destpath);
|
||||
perrorv ("failed to mount /usr overlayfs");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, a read-only bind mount for /usr */
|
||||
if (mount ("usr", "usr", NULL, MS_BIND, NULL) < 0)
|
||||
{
|
||||
perrorv ("failed to bind mount (class:readonly) /usr");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (mount ("usr", "usr", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY, NULL) < 0)
|
||||
{
|
||||
perrorv ("failed to bind mount (class:readonly) /usr");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (fchdir (orig_cwd_dfd) < 0)
|
||||
{
|
||||
perrorv ("failed to chdir to orig root");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
(void) close (orig_cwd_dfd);
|
||||
|
||||
touch_run_ostree ();
|
||||
|
||||
|
|
|
|||
|
|
@ -37,20 +37,6 @@
|
|||
|
||||
#include "ostree-mount-util.h"
|
||||
|
||||
static int
|
||||
path_is_on_readonly_fs (char *path)
|
||||
{
|
||||
struct statvfs stvfsbuf;
|
||||
|
||||
if (statvfs (path, &stvfsbuf) == -1)
|
||||
{
|
||||
perrorv ("statvfs(%s): ", path);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return (stvfsbuf.f_flag & ST_RDONLY) != 0;
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2011,2014 Colin Walters <walters@verbum.org>
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
echo "1..10"
|
||||
echo "1..16"
|
||||
|
||||
function validate_bootloader() {
|
||||
(cd ${test_tmpdir};
|
||||
|
|
@ -27,11 +27,14 @@ function validate_bootloader() {
|
|||
fi)
|
||||
}
|
||||
|
||||
orig_mtime=$(stat -c '%.Y' sysroot/ostree/deploy)
|
||||
${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmaster/x86_64-runtime
|
||||
rev=$(${CMD_PREFIX} ostree --repo=sysroot/ostree/repo rev-parse testos/buildmaster/x86_64-runtime)
|
||||
export rev
|
||||
# This initial deployment gets kicked off with some kernel arguments
|
||||
${CMD_PREFIX} ostree admin deploy --karg=root=LABEL=MOO --karg=quiet --os=testos testos:testos/buildmaster/x86_64-runtime
|
||||
new_mtime=$(stat -c '%.Y' sysroot/ostree/deploy)
|
||||
assert_not_streq "${orig_mtime}" "${new_mtime}"
|
||||
${CMD_PREFIX} ostree admin status | tee status.txt
|
||||
validate_bootloader
|
||||
|
||||
|
|
@ -56,7 +59,10 @@ ${CMD_PREFIX} ostree admin status
|
|||
|
||||
echo "ok layout"
|
||||
|
||||
orig_mtime=$(stat -c '%.Y' sysroot/ostree/deploy)
|
||||
${CMD_PREFIX} ostree admin deploy --os=testos testos:testos/buildmaster/x86_64-runtime
|
||||
new_mtime=$(stat -c '%.Y' sysroot/ostree/deploy)
|
||||
assert_not_streq "${orig_mtime}" "${new_mtime}"
|
||||
# Need a new bootversion, sine we now have two deployments
|
||||
assert_has_dir sysroot/boot/loader.0
|
||||
assert_not_has_dir sysroot/boot/loader.1
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
echo "1..48"
|
||||
echo "1..50"
|
||||
|
||||
$OSTREE checkout test2 checkout-test2
|
||||
echo "ok checkout"
|
||||
|
|
@ -41,14 +41,6 @@ echo "ok shortened checksum"
|
|||
(cd repo && ${CMD_PREFIX} ostree rev-parse test2)
|
||||
echo "ok repo-in-cwd"
|
||||
|
||||
$OSTREE refs > reflist
|
||||
assert_file_has_content reflist '^test2$'
|
||||
rm reflist
|
||||
|
||||
$OSTREE refs --delete 2>/dev/null && (echo 1>&2 "refs --delete (without prefix) unexpectedly succeeded!"; exit 1)
|
||||
|
||||
echo "ok refs"
|
||||
|
||||
cd checkout-test2
|
||||
assert_has_file firstfile
|
||||
assert_has_file baz/cow
|
||||
|
|
@ -246,15 +238,6 @@ if test -s file-objects; then
|
|||
fi
|
||||
echo "ok prune in archive-z2 deleted everything"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
$OSTREE commit -b test3 -s "Another commit" --tree=ref=test2
|
||||
${CMD_PREFIX} ostree --repo=repo refs > reflist
|
||||
assert_file_has_content reflist '^test3$'
|
||||
${CMD_PREFIX} ostree --repo=repo refs --delete test3
|
||||
${CMD_PREFIX} ostree --repo=repo refs > reflist
|
||||
assert_not_file_has_content reflist '^test3$'
|
||||
echo "ok reflist --delete"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
rm -rf test2-checkout
|
||||
$OSTREE checkout test2 test2-checkout
|
||||
|
|
@ -442,6 +425,8 @@ if test "$(id -u)" != "0"; then
|
|||
assert_has_file expected-fail
|
||||
assert_file_has_content error-message "Permission denied"
|
||||
echo "ok unwritable repo was caught"
|
||||
else
|
||||
echo "ok # SKIP not run when root"
|
||||
fi
|
||||
|
||||
cd ${test_tmpdir}
|
||||
|
|
@ -449,10 +434,12 @@ rm -rf test2-checkout
|
|||
mkdir -p test2-checkout
|
||||
cd test2-checkout
|
||||
touch blah
|
||||
stat --printf="%Z\n" ${test_tmpdir}/repo > ${test_tmpdir}/timestamp-orig.txt
|
||||
stat --printf="%.Y\n" ${test_tmpdir}/repo > ${test_tmpdir}/timestamp-orig.txt
|
||||
$OSTREE commit -b test2 -s "Should bump the mtime"
|
||||
stat --printf="%Z\n" ${test_tmpdir}/repo > ${test_tmpdir}/timestamp-new.txt
|
||||
stat --printf="%.Y\n" ${test_tmpdir}/repo > ${test_tmpdir}/timestamp-new.txt
|
||||
cd ..
|
||||
if ! cmp timestamp-{orig,new}.txt; then
|
||||
if cmp timestamp-{orig,new}.txt; then
|
||||
assert_not_reached "failed to update mtime on repo"
|
||||
fi
|
||||
|
||||
echo "ok mtime updated"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue