New upstream version 2020.2

This commit is contained in:
Simon McVittie 2020-02-22 21:42:10 +00:00
commit 08d4ffe725
71 changed files with 2382 additions and 331 deletions

View File

@ -214,7 +214,7 @@ libostree_1_la_CFLAGS += $(OT_DEP_AVAHI_CFLAGS)
libostree_1_la_LIBADD += $(OT_DEP_AVAHI_LIBS) libostree_1_la_LIBADD += $(OT_DEP_AVAHI_LIBS)
endif endif
if BUILDOPT_LIBSYSTEMD if BUILDOPT_SYSTEMD
libostree_1_la_CFLAGS += $(LIBSYSTEMD_CFLAGS) libostree_1_la_CFLAGS += $(LIBSYSTEMD_CFLAGS)
libostree_1_la_LIBADD += $(LIBSYSTEMD_LIBS) libostree_1_la_LIBADD += $(LIBSYSTEMD_LIBS)
endif endif

View File

@ -55,7 +55,8 @@ ostree_remount_SOURCES = \
src/switchroot/ostree-mount-util.h \ src/switchroot/ostree-mount-util.h \
src/switchroot/ostree-remount.c \ src/switchroot/ostree-remount.c \
$(NULL) $(NULL)
ostree_remount_CPPFLAGS = $(AM_CPPFLAGS) -Isrc/switchroot ostree_remount_CPPFLAGS = $(AM_CPPFLAGS) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -Isrc/switchroot -I$(srcdir)/libglnx
ostree_remount_LDADD = $(AM_LDFLAGS) $(OT_INTERNAL_GIO_UNIX_LIBS) libglnx.la
if BUILDOPT_SYSTEMD if BUILDOPT_SYSTEMD
ostree_prepare_root_CPPFLAGS += -DHAVE_SYSTEMD=1 ostree_prepare_root_CPPFLAGS += -DHAVE_SYSTEMD=1

View File

@ -86,6 +86,7 @@ _installed_or_uninstalled_test_scripts = \
tests/test-pull-resume.sh \ tests/test-pull-resume.sh \
tests/test-pull-basicauth.sh \ tests/test-pull-basicauth.sh \
tests/test-pull-repeated.sh \ tests/test-pull-repeated.sh \
tests/test-pull-sizes.sh \
tests/test-pull-untrusted.sh \ tests/test-pull-untrusted.sh \
tests/test-pull-override-url.sh \ tests/test-pull-override-url.sh \
tests/test-pull-localcache.sh \ tests/test-pull-localcache.sh \
@ -220,10 +221,17 @@ dist_gpginsttest_DATA = tests/gpghome/secring.gpg \
tests/gpghome/key3.asc tests/gpghome/key3.asc
gpginsttest_trusteddir = $(installed_testdir)/gpghome/trusted gpginsttest_trusteddir = $(installed_testdir)/gpghome/trusted
dist_gpginsttest_trusted_DATA = tests/gpghome/trusted/pubring.gpg dist_gpginsttest_trusted_DATA = tests/gpghome/trusted/pubring.gpg
gpginsttest_revocdir = $(installed_testdir)/gpghome/revocations
dist_gpginsttest_revoc_DATA = \
tests/gpghome/revocations/key1.rev \
tests/gpghome/revocations/key2.rev \
tests/gpghome/revocations/key3.rev \
$(NULL)
gpgvinsttestdir = $(installed_testdir)/gpg-verify-data gpgvinsttestdir = $(installed_testdir)/gpg-verify-data
dist_gpgvinsttest_DATA = $(addprefix tests/gpg-verify-data/, \ dist_gpgvinsttest_DATA = $(addprefix tests/gpg-verify-data/, \
gpg.conf lgpl2 lgpl2.sig pubring.gpg secring.gpg trustdb.gpg) gpg.conf lgpl2 lgpl2.sig lgpl2.sig0 lgpl2.sig1 lgpl2.sig2 lgpl2.sig3 \
lgpl2.sig4 pubring.gpg secring.gpg trustdb.gpg)
endif endif
endif endif
@ -347,7 +355,10 @@ tests_test_varint_LDADD = $(TESTS_LDADD)
tests_test_bsdiff_CFLAGS = $(TESTS_CFLAGS) tests_test_bsdiff_CFLAGS = $(TESTS_CFLAGS)
tests_test_bsdiff_LDADD = libbsdiff.la $(TESTS_LDADD) tests_test_bsdiff_LDADD = libbsdiff.la $(TESTS_LDADD)
tests_test_checksum_SOURCES = src/libostree/ostree-core.c tests/test-checksum.c tests_test_checksum_SOURCES = \
src/libostree/ostree-core.c \
src/libostree/ostree-varint.c \
tests/test-checksum.c
tests_test_checksum_CFLAGS = $(TESTS_CFLAGS) $(libglnx_cflags) tests_test_checksum_CFLAGS = $(TESTS_CFLAGS) $(libglnx_cflags)
tests_test_checksum_LDADD = $(TESTS_LDADD) tests_test_checksum_LDADD = $(TESTS_LDADD)

View File

@ -461,8 +461,8 @@ check_PROGRAMS = $(am__EXEEXT_12) $(am__EXEEXT_13) $(am__EXEEXT_14)
@USE_LIBARCHIVE_TRUE@am__append_29 = $(OT_DEP_LIBARCHIVE_LIBS) @USE_LIBARCHIVE_TRUE@am__append_29 = $(OT_DEP_LIBARCHIVE_LIBS)
@USE_AVAHI_TRUE@am__append_30 = $(OT_DEP_AVAHI_CFLAGS) @USE_AVAHI_TRUE@am__append_30 = $(OT_DEP_AVAHI_CFLAGS)
@USE_AVAHI_TRUE@am__append_31 = $(OT_DEP_AVAHI_LIBS) @USE_AVAHI_TRUE@am__append_31 = $(OT_DEP_AVAHI_LIBS)
@BUILDOPT_LIBSYSTEMD_TRUE@am__append_32 = $(LIBSYSTEMD_CFLAGS) @BUILDOPT_SYSTEMD_TRUE@am__append_32 = $(LIBSYSTEMD_CFLAGS)
@BUILDOPT_LIBSYSTEMD_TRUE@am__append_33 = $(LIBSYSTEMD_LIBS) @BUILDOPT_SYSTEMD_TRUE@am__append_33 = $(LIBSYSTEMD_LIBS)
@USE_CURL_OR_SOUP_TRUE@am__append_34 = \ @USE_CURL_OR_SOUP_TRUE@am__append_34 = \
@USE_CURL_OR_SOUP_TRUE@ src/libostree/ostree-fetcher.h \ @USE_CURL_OR_SOUP_TRUE@ src/libostree/ostree-fetcher.h \
@USE_CURL_OR_SOUP_TRUE@ src/libostree/ostree-fetcher-util.h \ @USE_CURL_OR_SOUP_TRUE@ src/libostree/ostree-fetcher-util.h \
@ -620,6 +620,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
$(am__configure_deps) $(dist_completions_DATA) \ $(am__configure_deps) $(dist_completions_DATA) \
$(am__dist_gpginsttest_DATA_DIST) \ $(am__dist_gpginsttest_DATA_DIST) \
$(am__dist_gpginsttest_revoc_DATA_DIST) \
$(am__dist_gpginsttest_trusted_DATA_DIST) \ $(am__dist_gpginsttest_trusted_DATA_DIST) \
$(am__dist_gpgvinsttest_DATA_DIST) \ $(am__dist_gpgvinsttest_DATA_DIST) \
$(am__dist_systemdtmpfiles_DATA_DIST) \ $(am__dist_systemdtmpfiles_DATA_DIST) \
@ -644,6 +645,7 @@ am__installdirs = "$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" \ "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" \
"$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" \ "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" \
"$(DESTDIR)$(completionsdir)" "$(DESTDIR)$(gpginsttestdir)" \ "$(DESTDIR)$(completionsdir)" "$(DESTDIR)$(gpginsttestdir)" \
"$(DESTDIR)$(gpginsttest_revocdir)" \
"$(DESTDIR)$(gpginsttest_trusteddir)" \ "$(DESTDIR)$(gpginsttest_trusteddir)" \
"$(DESTDIR)$(gpgvinsttestdir)" \ "$(DESTDIR)$(gpgvinsttestdir)" \
"$(DESTDIR)$(systemdtmpfilesdir)" "$(DESTDIR)$(dracutconfdir)" \ "$(DESTDIR)$(systemdtmpfilesdir)" "$(DESTDIR)$(dracutconfdir)" \
@ -762,7 +764,7 @@ libglnx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
@USE_GPGME_TRUE@ $(am__DEPENDENCIES_1) @USE_GPGME_TRUE@ $(am__DEPENDENCIES_1)
@USE_LIBARCHIVE_TRUE@am__DEPENDENCIES_4 = $(am__DEPENDENCIES_1) @USE_LIBARCHIVE_TRUE@am__DEPENDENCIES_4 = $(am__DEPENDENCIES_1)
@USE_AVAHI_TRUE@am__DEPENDENCIES_5 = $(am__DEPENDENCIES_1) @USE_AVAHI_TRUE@am__DEPENDENCIES_5 = $(am__DEPENDENCIES_1)
@BUILDOPT_LIBSYSTEMD_TRUE@am__DEPENDENCIES_6 = $(am__DEPENDENCIES_1) @BUILDOPT_SYSTEMD_TRUE@am__DEPENDENCIES_6 = $(am__DEPENDENCIES_1)
@USE_CURL_TRUE@am__DEPENDENCIES_7 = $(am__DEPENDENCIES_1) @USE_CURL_TRUE@am__DEPENDENCIES_7 = $(am__DEPENDENCIES_1)
@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__DEPENDENCIES_8 = \ @USE_CURL_FALSE@@USE_LIBSOUP_TRUE@am__DEPENDENCIES_8 = \
@USE_CURL_FALSE@@USE_LIBSOUP_TRUE@ $(am__DEPENDENCIES_2) @USE_CURL_FALSE@@USE_LIBSOUP_TRUE@ $(am__DEPENDENCIES_2)
@ -1166,7 +1168,7 @@ am_ostree_remount_OBJECTS = \
src/switchroot/ostree_remount-ostree-remount.$(OBJEXT) \ src/switchroot/ostree_remount-ostree-remount.$(OBJEXT) \
$(am__objects_1) $(am__objects_1)
ostree_remount_OBJECTS = $(am_ostree_remount_OBJECTS) ostree_remount_OBJECTS = $(am_ostree_remount_OBJECTS)
ostree_remount_LDADD = $(LDADD) ostree_remount_DEPENDENCIES = $(am__DEPENDENCIES_2) libglnx.la
am__ostree_system_generator_SOURCES_DIST = \ am__ostree_system_generator_SOURCES_DIST = \
src/switchroot/ostree-mount-util.h \ src/switchroot/ostree-mount-util.h \
src/switchroot/ostree-system-generator.c src/switchroot/ostree-system-generator.c
@ -1294,6 +1296,7 @@ tests_test_bsdiff_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
-o $@ -o $@
am_tests_test_checksum_OBJECTS = \ am_tests_test_checksum_OBJECTS = \
src/libostree/tests_test_checksum-ostree-core.$(OBJEXT) \ src/libostree/tests_test_checksum-ostree-core.$(OBJEXT) \
src/libostree/tests_test_checksum-ostree-varint.$(OBJEXT) \
tests/test_checksum-test-checksum.$(OBJEXT) tests/test_checksum-test-checksum.$(OBJEXT)
tests_test_checksum_OBJECTS = $(am_tests_test_checksum_OBJECTS) tests_test_checksum_OBJECTS = $(am_tests_test_checksum_OBJECTS)
tests_test_checksum_DEPENDENCIES = $(am__DEPENDENCIES_13) tests_test_checksum_DEPENDENCIES = $(am__DEPENDENCIES_13)
@ -1580,6 +1583,7 @@ am__depfiles_remade = bsdiff/$(DEPDIR)/libbsdiff_la-bsdiff.Plo \
src/libostree/$(DEPDIR)/libostree_1_la-ostree-varint.Plo \ src/libostree/$(DEPDIR)/libostree_1_la-ostree-varint.Plo \
src/libostree/$(DEPDIR)/tests_test_bloom-ostree-bloom.Po \ src/libostree/$(DEPDIR)/tests_test_bloom-ostree-bloom.Po \
src/libostree/$(DEPDIR)/tests_test_checksum-ostree-core.Po \ src/libostree/$(DEPDIR)/tests_test_checksum-ostree-core.Po \
src/libostree/$(DEPDIR)/tests_test_checksum-ostree-varint.Po \
src/libostree/$(DEPDIR)/tests_test_kargs-ostree-kernel-args.Po \ src/libostree/$(DEPDIR)/tests_test_kargs-ostree-kernel-args.Po \
src/libostree/$(DEPDIR)/tests_test_lzma-ostree-lzma-common.Po \ src/libostree/$(DEPDIR)/tests_test_lzma-ostree-lzma-common.Po \
src/libostree/$(DEPDIR)/tests_test_lzma-ostree-lzma-compressor.Po \ src/libostree/$(DEPDIR)/tests_test_lzma-ostree-lzma-compressor.Po \
@ -1788,12 +1792,18 @@ am__dist_gpginsttest_DATA_DIST = tests/gpghome/secring.gpg \
tests/gpghome/pubring.gpg tests/gpghome/trustdb.gpg \ tests/gpghome/pubring.gpg tests/gpghome/trustdb.gpg \
tests/gpghome/key1.asc tests/gpghome/key2.asc \ tests/gpghome/key1.asc tests/gpghome/key2.asc \
tests/gpghome/key3.asc tests/gpghome/key3.asc
am__dist_gpginsttest_revoc_DATA_DIST = \
tests/gpghome/revocations/key1.rev \
tests/gpghome/revocations/key2.rev \
tests/gpghome/revocations/key3.rev
am__dist_gpginsttest_trusted_DATA_DIST = \ am__dist_gpginsttest_trusted_DATA_DIST = \
tests/gpghome/trusted/pubring.gpg tests/gpghome/trusted/pubring.gpg
am__dist_gpgvinsttest_DATA_DIST = $(addprefix tests/gpg-verify-data/, \ am__dist_gpgvinsttest_DATA_DIST = $(addprefix tests/gpg-verify-data/, \
gpg.conf lgpl2 lgpl2.sig pubring.gpg secring.gpg trustdb.gpg) gpg.conf lgpl2 lgpl2.sig lgpl2.sig0 lgpl2.sig1 lgpl2.sig2 \
lgpl2.sig3 lgpl2.sig4 pubring.gpg secring.gpg trustdb.gpg)
am__dist_systemdtmpfiles_DATA_DIST = src/boot/ostree-tmpfiles.conf am__dist_systemdtmpfiles_DATA_DIST = src/boot/ostree-tmpfiles.conf
DATA = $(dist_completions_DATA) $(dist_gpginsttest_DATA) \ DATA = $(dist_completions_DATA) $(dist_gpginsttest_DATA) \
$(dist_gpginsttest_revoc_DATA) \
$(dist_gpginsttest_trusted_DATA) $(dist_gpgvinsttest_DATA) \ $(dist_gpginsttest_trusted_DATA) $(dist_gpgvinsttest_DATA) \
$(dist_systemdtmpfiles_DATA) $(dracutconf_DATA) $(gir_DATA) \ $(dist_systemdtmpfiles_DATA) $(dracutconf_DATA) $(gir_DATA) \
$(gpgreadme_DATA) $(installed_test_DATA) \ $(gpgreadme_DATA) $(installed_test_DATA) \
@ -2009,9 +2019,9 @@ am__EXEEXT_25 = tests/test-basic.sh tests/test-basic-user.sh \
tests/test-pull-large-metadata.sh tests/test-pull-metalink.sh \ tests/test-pull-large-metadata.sh tests/test-pull-metalink.sh \
tests/test-pull-summary-sigs.sh tests/test-pull-resume.sh \ tests/test-pull-summary-sigs.sh tests/test-pull-resume.sh \
tests/test-pull-basicauth.sh tests/test-pull-repeated.sh \ tests/test-pull-basicauth.sh tests/test-pull-repeated.sh \
tests/test-pull-untrusted.sh tests/test-pull-override-url.sh \ tests/test-pull-sizes.sh tests/test-pull-untrusted.sh \
tests/test-pull-localcache.sh tests/test-local-pull.sh \ tests/test-pull-override-url.sh tests/test-pull-localcache.sh \
tests/test-local-pull-depth.sh \ tests/test-local-pull.sh tests/test-local-pull-depth.sh \
tests/test-admin-upgrade-unconfigured.sh \ tests/test-admin-upgrade-unconfigured.sh \
tests/test-admin-upgrade-endoflife.sh \ tests/test-admin-upgrade-endoflife.sh \
tests/test-admin-upgrade-systemd-update.sh \ tests/test-admin-upgrade-systemd-update.sh \
@ -2799,8 +2809,10 @@ ostree_remount_SOURCES = \
src/switchroot/ostree-remount.c \ src/switchroot/ostree-remount.c \
$(NULL) $(NULL)
ostree_remount_CPPFLAGS = $(AM_CPPFLAGS) -Isrc/switchroot \ ostree_remount_CPPFLAGS = $(AM_CPPFLAGS) \
$(am__append_67) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -Isrc/switchroot \
-I$(srcdir)/libglnx $(am__append_67)
ostree_remount_LDADD = $(AM_LDFLAGS) $(OT_INTERNAL_GIO_UNIX_LIBS) libglnx.la
@BUILDOPT_SYSTEMD_TRUE@ostree_prepare_root_LDADD = $(AM_LDFLAGS) $(LIBSYSTEMD_LIBS) @BUILDOPT_SYSTEMD_TRUE@ostree_prepare_root_LDADD = $(AM_LDFLAGS) $(LIBSYSTEMD_LIBS)
@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@ostree_system_generator_SOURCES = src/switchroot/ostree-mount-util.h \ @BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@ostree_system_generator_SOURCES = src/switchroot/ostree-mount-util.h \
@BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@ src/switchroot/ostree-system-generator.c @BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE@ src/switchroot/ostree-system-generator.c
@ -2843,9 +2855,9 @@ _installed_or_uninstalled_test_scripts = tests/test-basic.sh \
tests/test-pull-large-metadata.sh tests/test-pull-metalink.sh \ tests/test-pull-large-metadata.sh tests/test-pull-metalink.sh \
tests/test-pull-summary-sigs.sh tests/test-pull-resume.sh \ tests/test-pull-summary-sigs.sh tests/test-pull-resume.sh \
tests/test-pull-basicauth.sh tests/test-pull-repeated.sh \ tests/test-pull-basicauth.sh tests/test-pull-repeated.sh \
tests/test-pull-untrusted.sh tests/test-pull-override-url.sh \ tests/test-pull-sizes.sh tests/test-pull-untrusted.sh \
tests/test-pull-localcache.sh tests/test-local-pull.sh \ tests/test-pull-override-url.sh tests/test-pull-localcache.sh \
tests/test-local-pull-depth.sh \ tests/test-local-pull.sh tests/test-local-pull-depth.sh \
tests/test-admin-upgrade-unconfigured.sh \ tests/test-admin-upgrade-unconfigured.sh \
tests/test-admin-upgrade-endoflife.sh \ tests/test-admin-upgrade-endoflife.sh \
tests/test-admin-upgrade-systemd-update.sh \ tests/test-admin-upgrade-systemd-update.sh \
@ -2928,9 +2940,17 @@ dist_test_extra_scripts = \
@ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@gpginsttest_trusteddir = $(installed_testdir)/gpghome/trusted @ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@gpginsttest_trusteddir = $(installed_testdir)/gpghome/trusted
@ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@dist_gpginsttest_trusted_DATA = tests/gpghome/trusted/pubring.gpg @ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@dist_gpginsttest_trusted_DATA = tests/gpghome/trusted/pubring.gpg
@ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@gpginsttest_revocdir = $(installed_testdir)/gpghome/revocations
@ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@dist_gpginsttest_revoc_DATA = \
@ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@ tests/gpghome/revocations/key1.rev \
@ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@ tests/gpghome/revocations/key2.rev \
@ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@ tests/gpghome/revocations/key3.rev \
@ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@ $(NULL)
@ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@gpgvinsttestdir = $(installed_testdir)/gpg-verify-data @ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@gpgvinsttestdir = $(installed_testdir)/gpg-verify-data
@ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@dist_gpgvinsttest_DATA = $(addprefix tests/gpg-verify-data/, \ @ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@dist_gpgvinsttest_DATA = $(addprefix tests/gpg-verify-data/, \
@ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@ gpg.conf lgpl2 lgpl2.sig pubring.gpg secring.gpg trustdb.gpg) @ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@ gpg.conf lgpl2 lgpl2.sig lgpl2.sig0 lgpl2.sig1 lgpl2.sig2 lgpl2.sig3 \
@ENABLE_INSTALLED_TESTS_TRUE@@USE_GPGME_TRUE@ lgpl2.sig4 pubring.gpg secring.gpg trustdb.gpg)
js_installed_tests = \ js_installed_tests = \
tests/test-core.js \ tests/test-core.js \
@ -3008,7 +3028,11 @@ tests_test_varint_CFLAGS = $(TESTS_CFLAGS)
tests_test_varint_LDADD = $(TESTS_LDADD) tests_test_varint_LDADD = $(TESTS_LDADD)
tests_test_bsdiff_CFLAGS = $(TESTS_CFLAGS) tests_test_bsdiff_CFLAGS = $(TESTS_CFLAGS)
tests_test_bsdiff_LDADD = libbsdiff.la $(TESTS_LDADD) tests_test_bsdiff_LDADD = libbsdiff.la $(TESTS_LDADD)
tests_test_checksum_SOURCES = src/libostree/ostree-core.c tests/test-checksum.c tests_test_checksum_SOURCES = \
src/libostree/ostree-core.c \
src/libostree/ostree-varint.c \
tests/test-checksum.c
tests_test_checksum_CFLAGS = $(TESTS_CFLAGS) $(libglnx_cflags) tests_test_checksum_CFLAGS = $(TESTS_CFLAGS) $(libglnx_cflags)
tests_test_checksum_LDADD = $(TESTS_LDADD) tests_test_checksum_LDADD = $(TESTS_LDADD)
tests_test_libarchive_import_SOURCES = tests/test-libarchive-import.c tests_test_libarchive_import_SOURCES = tests/test-libarchive-import.c
@ -4268,6 +4292,9 @@ tests/test-bsdiff$(EXEEXT): $(tests_test_bsdiff_OBJECTS) $(tests_test_bsdiff_DEP
src/libostree/tests_test_checksum-ostree-core.$(OBJEXT): \ src/libostree/tests_test_checksum-ostree-core.$(OBJEXT): \
src/libostree/$(am__dirstamp) \ src/libostree/$(am__dirstamp) \
src/libostree/$(DEPDIR)/$(am__dirstamp) src/libostree/$(DEPDIR)/$(am__dirstamp)
src/libostree/tests_test_checksum-ostree-varint.$(OBJEXT): \
src/libostree/$(am__dirstamp) \
src/libostree/$(DEPDIR)/$(am__dirstamp)
tests/test_checksum-test-checksum.$(OBJEXT): tests/$(am__dirstamp) \ tests/test_checksum-test-checksum.$(OBJEXT): tests/$(am__dirstamp) \
tests/$(DEPDIR)/$(am__dirstamp) tests/$(DEPDIR)/$(am__dirstamp)
@ -4731,6 +4758,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-varint.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-varint.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/tests_test_bloom-ostree-bloom.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/tests_test_bloom-ostree-bloom.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/tests_test_checksum-ostree-core.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/tests_test_checksum-ostree-core.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/tests_test_checksum-ostree-varint.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/tests_test_kargs-ostree-kernel-args.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/tests_test_kargs-ostree-kernel-args.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/tests_test_lzma-ostree-lzma-common.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/tests_test_lzma-ostree-lzma-common.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/tests_test_lzma-ostree-lzma-compressor.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/tests_test_lzma-ostree-lzma-compressor.Po@am__quote@ # am--include-marker
@ -6645,6 +6673,20 @@ src/libostree/tests_test_checksum-ostree-core.obj: src/libostree/ostree-core.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_test_checksum_CFLAGS) $(CFLAGS) -c -o src/libostree/tests_test_checksum-ostree-core.obj `if test -f 'src/libostree/ostree-core.c'; then $(CYGPATH_W) 'src/libostree/ostree-core.c'; else $(CYGPATH_W) '$(srcdir)/src/libostree/ostree-core.c'; fi` @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_test_checksum_CFLAGS) $(CFLAGS) -c -o src/libostree/tests_test_checksum-ostree-core.obj `if test -f 'src/libostree/ostree-core.c'; then $(CYGPATH_W) 'src/libostree/ostree-core.c'; else $(CYGPATH_W) '$(srcdir)/src/libostree/ostree-core.c'; fi`
src/libostree/tests_test_checksum-ostree-varint.o: src/libostree/ostree-varint.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_test_checksum_CFLAGS) $(CFLAGS) -MT src/libostree/tests_test_checksum-ostree-varint.o -MD -MP -MF src/libostree/$(DEPDIR)/tests_test_checksum-ostree-varint.Tpo -c -o src/libostree/tests_test_checksum-ostree-varint.o `test -f 'src/libostree/ostree-varint.c' || echo '$(srcdir)/'`src/libostree/ostree-varint.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libostree/$(DEPDIR)/tests_test_checksum-ostree-varint.Tpo src/libostree/$(DEPDIR)/tests_test_checksum-ostree-varint.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libostree/ostree-varint.c' object='src/libostree/tests_test_checksum-ostree-varint.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_test_checksum_CFLAGS) $(CFLAGS) -c -o src/libostree/tests_test_checksum-ostree-varint.o `test -f 'src/libostree/ostree-varint.c' || echo '$(srcdir)/'`src/libostree/ostree-varint.c
src/libostree/tests_test_checksum-ostree-varint.obj: src/libostree/ostree-varint.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_test_checksum_CFLAGS) $(CFLAGS) -MT src/libostree/tests_test_checksum-ostree-varint.obj -MD -MP -MF src/libostree/$(DEPDIR)/tests_test_checksum-ostree-varint.Tpo -c -o src/libostree/tests_test_checksum-ostree-varint.obj `if test -f 'src/libostree/ostree-varint.c'; then $(CYGPATH_W) 'src/libostree/ostree-varint.c'; else $(CYGPATH_W) '$(srcdir)/src/libostree/ostree-varint.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libostree/$(DEPDIR)/tests_test_checksum-ostree-varint.Tpo src/libostree/$(DEPDIR)/tests_test_checksum-ostree-varint.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libostree/ostree-varint.c' object='src/libostree/tests_test_checksum-ostree-varint.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_test_checksum_CFLAGS) $(CFLAGS) -c -o src/libostree/tests_test_checksum-ostree-varint.obj `if test -f 'src/libostree/ostree-varint.c'; then $(CYGPATH_W) 'src/libostree/ostree-varint.c'; else $(CYGPATH_W) '$(srcdir)/src/libostree/ostree-varint.c'; fi`
tests/test_checksum-test-checksum.o: tests/test-checksum.c tests/test_checksum-test-checksum.o: tests/test-checksum.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_test_checksum_CFLAGS) $(CFLAGS) -MT tests/test_checksum-test-checksum.o -MD -MP -MF tests/$(DEPDIR)/test_checksum-test-checksum.Tpo -c -o tests/test_checksum-test-checksum.o `test -f 'tests/test-checksum.c' || echo '$(srcdir)/'`tests/test-checksum.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_test_checksum_CFLAGS) $(CFLAGS) -MT tests/test_checksum-test-checksum.o -MD -MP -MF tests/$(DEPDIR)/test_checksum-test-checksum.Tpo -c -o tests/test_checksum-test-checksum.o `test -f 'tests/test-checksum.c' || echo '$(srcdir)/'`tests/test-checksum.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/test_checksum-test-checksum.Tpo tests/$(DEPDIR)/test_checksum-test-checksum.Po @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/test_checksum-test-checksum.Tpo tests/$(DEPDIR)/test_checksum-test-checksum.Po
@ -7174,6 +7216,27 @@ uninstall-dist_gpginsttestDATA:
@list='$(dist_gpginsttest_DATA)'; test -n "$(gpginsttestdir)" || list=; \ @list='$(dist_gpginsttest_DATA)'; test -n "$(gpginsttestdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(gpginsttestdir)'; $(am__uninstall_files_from_dir) dir='$(DESTDIR)$(gpginsttestdir)'; $(am__uninstall_files_from_dir)
install-dist_gpginsttest_revocDATA: $(dist_gpginsttest_revoc_DATA)
@$(NORMAL_INSTALL)
@list='$(dist_gpginsttest_revoc_DATA)'; test -n "$(gpginsttest_revocdir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(gpginsttest_revocdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(gpginsttest_revocdir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(gpginsttest_revocdir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(gpginsttest_revocdir)" || exit $$?; \
done
uninstall-dist_gpginsttest_revocDATA:
@$(NORMAL_UNINSTALL)
@list='$(dist_gpginsttest_revoc_DATA)'; test -n "$(gpginsttest_revocdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(gpginsttest_revocdir)'; $(am__uninstall_files_from_dir)
install-dist_gpginsttest_trustedDATA: $(dist_gpginsttest_trusted_DATA) install-dist_gpginsttest_trustedDATA: $(dist_gpginsttest_trusted_DATA)
@$(NORMAL_INSTALL) @$(NORMAL_INSTALL)
@list='$(dist_gpginsttest_trusted_DATA)'; test -n "$(gpginsttest_trusteddir)" || list=; \ @list='$(dist_gpginsttest_trusted_DATA)'; test -n "$(gpginsttest_trusteddir)" || list=; \
@ -8055,6 +8118,13 @@ tests/test-pull-repeated.sh.log: tests/test-pull-repeated.sh
--log-file $$b.log --trs-file $$b.trs \ --log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT) "$$tst" $(AM_TESTS_FD_REDIRECT)
tests/test-pull-sizes.sh.log: tests/test-pull-sizes.sh
@p='tests/test-pull-sizes.sh'; \
b='tests/test-pull-sizes.sh'; \
$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
tests/test-pull-untrusted.sh.log: tests/test-pull-untrusted.sh tests/test-pull-untrusted.sh.log: tests/test-pull-untrusted.sh
@p='tests/test-pull-untrusted.sh'; \ @p='tests/test-pull-untrusted.sh'; \
b='tests/test-pull-untrusted.sh'; \ b='tests/test-pull-untrusted.sh'; \
@ -8753,7 +8823,7 @@ install-binPROGRAMS: install-libLTLIBRARIES
installdirs: installdirs-recursive installdirs: installdirs-recursive
installdirs-am: installdirs-am:
for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(systemdsystemgeneratordir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(privlibdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(dracutmoddir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(mkinitcpioinstalldir)" "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(completionsdir)" "$(DESTDIR)$(gpginsttestdir)" "$(DESTDIR)$(gpginsttest_trusteddir)" "$(DESTDIR)$(gpgvinsttestdir)" "$(DESTDIR)$(systemdtmpfilesdir)" "$(DESTDIR)$(dracutconfdir)" "$(DESTDIR)$(girdir)" "$(DESTDIR)$(gpgreadmedir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(installed_test_metadir)" "$(DESTDIR)$(mkinitcpioconfdir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(systemdsystemunitdir)" "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(libostreeincludedir)"; do \ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(systemdsystemgeneratordir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(privlibdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(dracutmoddir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(mkinitcpioinstalldir)" "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(completionsdir)" "$(DESTDIR)$(gpginsttestdir)" "$(DESTDIR)$(gpginsttest_revocdir)" "$(DESTDIR)$(gpginsttest_trusteddir)" "$(DESTDIR)$(gpgvinsttestdir)" "$(DESTDIR)$(systemdtmpfilesdir)" "$(DESTDIR)$(dracutconfdir)" "$(DESTDIR)$(girdir)" "$(DESTDIR)$(gpgreadmedir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(installed_test_metadir)" "$(DESTDIR)$(mkinitcpioconfdir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(systemdsystemunitdir)" "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(libostreeincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done done
install: $(BUILT_SOURCES) install: $(BUILT_SOURCES)
@ -8912,6 +8982,7 @@ distclean: distclean-recursive
-rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-varint.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-varint.Plo
-rm -f src/libostree/$(DEPDIR)/tests_test_bloom-ostree-bloom.Po -rm -f src/libostree/$(DEPDIR)/tests_test_bloom-ostree-bloom.Po
-rm -f src/libostree/$(DEPDIR)/tests_test_checksum-ostree-core.Po -rm -f src/libostree/$(DEPDIR)/tests_test_checksum-ostree-core.Po
-rm -f src/libostree/$(DEPDIR)/tests_test_checksum-ostree-varint.Po
-rm -f src/libostree/$(DEPDIR)/tests_test_kargs-ostree-kernel-args.Po -rm -f src/libostree/$(DEPDIR)/tests_test_kargs-ostree-kernel-args.Po
-rm -f src/libostree/$(DEPDIR)/tests_test_lzma-ostree-lzma-common.Po -rm -f src/libostree/$(DEPDIR)/tests_test_lzma-ostree-lzma-common.Po
-rm -f src/libostree/$(DEPDIR)/tests_test_lzma-ostree-lzma-compressor.Po -rm -f src/libostree/$(DEPDIR)/tests_test_lzma-ostree-lzma-compressor.Po
@ -9042,6 +9113,7 @@ info-am:
install-data-am: install-dist_completionsDATA \ install-data-am: install-dist_completionsDATA \
install-dist_gpginsttestDATA \ install-dist_gpginsttestDATA \
install-dist_gpginsttest_revocDATA \
install-dist_gpginsttest_trustedDATA \ install-dist_gpginsttest_trustedDATA \
install-dist_gpgvinsttestDATA install-dist_systemdtmpfilesDATA \ install-dist_gpgvinsttestDATA install-dist_systemdtmpfilesDATA \
install-dracutconfDATA install-dracutmodSCRIPTS \ install-dracutconfDATA install-dracutmodSCRIPTS \
@ -9178,6 +9250,7 @@ maintainer-clean: maintainer-clean-recursive
-rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-varint.Plo -rm -f src/libostree/$(DEPDIR)/libostree_1_la-ostree-varint.Plo
-rm -f src/libostree/$(DEPDIR)/tests_test_bloom-ostree-bloom.Po -rm -f src/libostree/$(DEPDIR)/tests_test_bloom-ostree-bloom.Po
-rm -f src/libostree/$(DEPDIR)/tests_test_checksum-ostree-core.Po -rm -f src/libostree/$(DEPDIR)/tests_test_checksum-ostree-core.Po
-rm -f src/libostree/$(DEPDIR)/tests_test_checksum-ostree-varint.Po
-rm -f src/libostree/$(DEPDIR)/tests_test_kargs-ostree-kernel-args.Po -rm -f src/libostree/$(DEPDIR)/tests_test_kargs-ostree-kernel-args.Po
-rm -f src/libostree/$(DEPDIR)/tests_test_lzma-ostree-lzma-common.Po -rm -f src/libostree/$(DEPDIR)/tests_test_lzma-ostree-lzma-common.Po
-rm -f src/libostree/$(DEPDIR)/tests_test_lzma-ostree-lzma-compressor.Po -rm -f src/libostree/$(DEPDIR)/tests_test_lzma-ostree-lzma-compressor.Po
@ -9308,6 +9381,7 @@ ps-am:
uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \ uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
uninstall-dist_completionsDATA uninstall-dist_gpginsttestDATA \ uninstall-dist_completionsDATA uninstall-dist_gpginsttestDATA \
uninstall-dist_gpginsttest_revocDATA \
uninstall-dist_gpginsttest_trustedDATA \ uninstall-dist_gpginsttest_trustedDATA \
uninstall-dist_gpgvinsttestDATA \ uninstall-dist_gpgvinsttestDATA \
uninstall-dist_systemdtmpfilesDATA uninstall-dracutconfDATA \ uninstall-dist_systemdtmpfilesDATA uninstall-dracutconfDATA \
@ -9351,6 +9425,7 @@ uninstall-man: uninstall-man1 uninstall-man5
install install-am install-binPROGRAMS install-binSCRIPTS \ install install-am install-binPROGRAMS install-binSCRIPTS \
install-data install-data-am install-data-hook \ install-data install-data-am install-data-hook \
install-dist_completionsDATA install-dist_gpginsttestDATA \ install-dist_completionsDATA install-dist_gpginsttestDATA \
install-dist_gpginsttest_revocDATA \
install-dist_gpginsttest_trustedDATA \ install-dist_gpginsttest_trustedDATA \
install-dist_gpgvinsttestDATA install-dist_systemdtmpfilesDATA \ install-dist_gpgvinsttestDATA install-dist_systemdtmpfilesDATA \
install-dracutconfDATA install-dracutmodSCRIPTS install-dvi \ install-dracutconfDATA install-dracutmodSCRIPTS install-dvi \
@ -9376,6 +9451,7 @@ uninstall-man: uninstall-man1 uninstall-man5
recheck tags tags-am uninstall uninstall-am \ recheck tags tags-am uninstall uninstall-am \
uninstall-binPROGRAMS uninstall-binSCRIPTS \ uninstall-binPROGRAMS uninstall-binSCRIPTS \
uninstall-dist_completionsDATA uninstall-dist_gpginsttestDATA \ uninstall-dist_completionsDATA uninstall-dist_gpginsttestDATA \
uninstall-dist_gpginsttest_revocDATA \
uninstall-dist_gpginsttest_trustedDATA \ uninstall-dist_gpginsttest_trustedDATA \
uninstall-dist_gpgvinsttestDATA \ uninstall-dist_gpgvinsttestDATA \
uninstall-dist_systemdtmpfilesDATA uninstall-dracutconfDATA \ uninstall-dist_systemdtmpfilesDATA uninstall-dracutconfDATA \

View File

@ -14,7 +14,7 @@
<div class="titlepage"> <div class="titlepage">
<div> <div>
<div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">OSTree API references</p></th></tr></table></div> <div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">OSTree API references</p></th></tr></table></div>
<div><p class="releaseinfo">for OSTree 2019.6</p></div> <div><p class="releaseinfo">for OSTree 2019.7</p></div>
</div> </div>
<hr> <hr>
</div> </div>

View File

@ -430,6 +430,38 @@
<span class="returnvalue">gboolean</span> <span class="returnvalue">gboolean</span>
</td> </td>
<td class="function_name"> <td class="function_name">
<a class="link" href="ostree-Core-repository-independent-functions.html#ostree-commit-get-object-sizes" title="ostree_commit_get_object_sizes ()">ostree_commit_get_object_sizes</a> <span class="c_punctuation">()</span>
</td>
</tr>
<tr>
<td class="function_type">
<a class="link" href="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry" title="OstreeCommitSizesEntry"><span class="returnvalue">OstreeCommitSizesEntry</span></a> *
</td>
<td class="function_name">
<a class="link" href="ostree-Core-repository-independent-functions.html#ostree-commit-sizes-entry-new" title="ostree_commit_sizes_entry_new ()">ostree_commit_sizes_entry_new</a> <span class="c_punctuation">()</span>
</td>
</tr>
<tr>
<td class="function_type">
<a class="link" href="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry" title="OstreeCommitSizesEntry"><span class="returnvalue">OstreeCommitSizesEntry</span></a> *
</td>
<td class="function_name">
<a class="link" href="ostree-Core-repository-independent-functions.html#ostree-commit-sizes-entry-copy" title="ostree_commit_sizes_entry_copy ()">ostree_commit_sizes_entry_copy</a> <span class="c_punctuation">()</span>
</td>
</tr>
<tr>
<td class="function_type">
<span class="returnvalue">void</span>
</td>
<td class="function_name">
<a class="link" href="ostree-Core-repository-independent-functions.html#ostree-commit-sizes-entry-free" title="ostree_commit_sizes_entry_free ()">ostree_commit_sizes_entry_free</a> <span class="c_punctuation">()</span>
</td>
</tr>
<tr>
<td class="function_type">
<span class="returnvalue">gboolean</span>
</td>
<td class="function_name">
<a class="link" href="ostree-Core-repository-independent-functions.html#ostree-check-version" title="ostree_check_version ()">ostree_check_version</a> <span class="c_punctuation">()</span> <a class="link" href="ostree-Core-repository-independent-functions.html#ostree-check-version" title="ostree_check_version ()">ostree_check_version</a> <span class="c_punctuation">()</span>
</td> </td>
</tr> </tr>
@ -500,6 +532,10 @@
<td class="define_keyword">#define</td> <td class="define_keyword">#define</td>
<td class="function_name"><a class="link" href="ostree-Core-repository-independent-functions.html#OSTREE-SUMMARY-GVARIANT-FORMAT:CAPS" title="OSTREE_SUMMARY_GVARIANT_FORMAT">OSTREE_SUMMARY_GVARIANT_FORMAT</a></td> <td class="function_name"><a class="link" href="ostree-Core-repository-independent-functions.html#OSTREE-SUMMARY-GVARIANT-FORMAT:CAPS" title="OSTREE_SUMMARY_GVARIANT_FORMAT">OSTREE_SUMMARY_GVARIANT_FORMAT</a></td>
</tr> </tr>
<tr>
<td class="datatype_keyword"> </td>
<td class="function_name"><a class="link" href="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry" title="OstreeCommitSizesEntry">OstreeCommitSizesEntry</a></td>
</tr>
</tbody> </tbody>
</table></div> </table></div>
</div> </div>
@ -2386,6 +2422,151 @@ is not well-formed. </p>
</div> </div>
<hr> <hr>
<div class="refsect2"> <div class="refsect2">
<a name="ostree-commit-get-object-sizes"></a><h3>ostree_commit_get_object_sizes ()</h3>
<pre class="programlisting"><span class="returnvalue">gboolean</span>
ostree_commit_get_object_sizes (<em class="parameter"><code><span class="type">GVariant</span> *commit_variant</code></em>,
<em class="parameter"><code><span class="type">GPtrArray</span> **out_sizes_entries</code></em>,
<em class="parameter"><code><span class="type">GError</span> **error</code></em>);</pre>
<p>Reads a commit's "ostree.sizes" metadata and returns an array of
<a class="link" href="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry" title="OstreeCommitSizesEntry"><span class="type">OstreeCommitSizesEntry</span></a> in <em class="parameter"><code>out_sizes_entries</code></em>
. Each element
represents an object in the commit. If the commit does not contain
the "ostree.sizes" metadata, a <code class="literal">G_IO_ERROR_NOT_FOUND</code> error will be
returned.</p>
<div class="refsect3">
<a name="ostree-commit-get-object-sizes.parameters"></a><h4>Parameters</h4>
<div class="informaltable"><table class="informaltable" width="100%" border="0">
<colgroup>
<col width="150px" class="parameters_name">
<col class="parameters_description">
<col width="200px" class="parameters_annotations">
</colgroup>
<tbody>
<tr>
<td class="parameter_name"><p>commit_variant</p></td>
<td class="parameter_description"><p>variant of type <a class="link" href="ostree-Core-repository-independent-functions.html#OSTREE-OBJECT-TYPE-COMMIT:CAPS"><code class="literal">OSTREE_OBJECT_TYPE_COMMIT</code></a>. </p></td>
<td class="parameter_annotations"><span class="annotation">[<a href="http://foldoc.org/not%20nullable"><span class="acronym">not nullable</span></a>]</span></td>
</tr>
<tr>
<td class="parameter_name"><p>out_sizes_entries</p></td>
<td class="parameter_description"><p>return location for an array of object size entries. </p></td>
<td class="parameter_annotations"><span class="annotation">[<a href="http://foldoc.org/out"><span class="acronym">out</span></a>][<a href="http://foldoc.org/element-type"><span class="acronym">element-type</span></a> OstreeCommitSizesEntry][<a href="http://foldoc.org/transfer%20container"><span class="acronym">transfer container</span></a>][<a href="http://foldoc.org/optional"><span class="acronym">optional</span></a>]</span></td>
</tr>
<tr>
<td class="parameter_name"><p>error</p></td>
<td class="parameter_description"><p>Error</p></td>
<td class="parameter_annotations"> </td>
</tr>
</tbody>
</table></div>
</div>
<p class="since">Since: 2020.1</p>
</div>
<hr>
<div class="refsect2">
<a name="ostree-commit-sizes-entry-new"></a><h3>ostree_commit_sizes_entry_new ()</h3>
<pre class="programlisting"><a class="link" href="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry" title="OstreeCommitSizesEntry"><span class="returnvalue">OstreeCommitSizesEntry</span></a> *
ostree_commit_sizes_entry_new (<em class="parameter"><code>const <span class="type">gchar</span> *checksum</code></em>,
<em class="parameter"><code><a class="link" href="ostree-Core-repository-independent-functions.html#OstreeObjectType" title="enum OstreeObjectType"><span class="type">OstreeObjectType</span></a> objtype</code></em>,
<em class="parameter"><code><span class="type">guint64</span> unpacked</code></em>,
<em class="parameter"><code><span class="type">guint64</span> archived</code></em>);</pre>
<p>Create a new <a class="link" href="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry" title="OstreeCommitSizesEntry"><span class="type">OstreeCommitSizesEntry</span></a> for representing an object in a
commit's "ostree.sizes" metadata.</p>
<div class="refsect3">
<a name="ostree-commit-sizes-entry-new.parameters"></a><h4>Parameters</h4>
<div class="informaltable"><table class="informaltable" width="100%" border="0">
<colgroup>
<col width="150px" class="parameters_name">
<col class="parameters_description">
<col width="200px" class="parameters_annotations">
</colgroup>
<tbody>
<tr>
<td class="parameter_name"><p>checksum</p></td>
<td class="parameter_description"><p>object checksum. </p></td>
<td class="parameter_annotations"><span class="annotation">[<a href="http://foldoc.org/not%20nullable"><span class="acronym">not nullable</span></a>]</span></td>
</tr>
<tr>
<td class="parameter_name"><p>objtype</p></td>
<td class="parameter_description"><p>object type</p></td>
<td class="parameter_annotations"> </td>
</tr>
<tr>
<td class="parameter_name"><p>unpacked</p></td>
<td class="parameter_description"><p>unpacked object size</p></td>
<td class="parameter_annotations"> </td>
</tr>
<tr>
<td class="parameter_name"><p>archived</p></td>
<td class="parameter_description"><p>compressed object size</p></td>
<td class="parameter_annotations"> </td>
</tr>
</tbody>
</table></div>
</div>
<div class="refsect3">
<a name="ostree-commit-sizes-entry-new.returns"></a><h4>Returns</h4>
<p>a new <a class="link" href="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry" title="OstreeCommitSizesEntry"><span class="type">OstreeCommitSizesEntry</span></a>. </p>
<p><span class="annotation">[<a href="http://foldoc.org/transfer%20full"><span class="acronym">transfer full</span></a>][<a href="http://foldoc.org/nullable"><span class="acronym">nullable</span></a>]</span></p>
</div>
<p class="since">Since: 2020.1</p>
</div>
<hr>
<div class="refsect2">
<a name="ostree-commit-sizes-entry-copy"></a><h3>ostree_commit_sizes_entry_copy ()</h3>
<pre class="programlisting"><a class="link" href="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry" title="OstreeCommitSizesEntry"><span class="returnvalue">OstreeCommitSizesEntry</span></a> *
ostree_commit_sizes_entry_copy (<em class="parameter"><code>const <a class="link" href="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry" title="OstreeCommitSizesEntry"><span class="type">OstreeCommitSizesEntry</span></a> *entry</code></em>);</pre>
<p>Create a copy of the given <em class="parameter"><code>entry</code></em>
.</p>
<div class="refsect3">
<a name="ostree-commit-sizes-entry-copy.parameters"></a><h4>Parameters</h4>
<div class="informaltable"><table class="informaltable" width="100%" border="0">
<colgroup>
<col width="150px" class="parameters_name">
<col class="parameters_description">
<col width="200px" class="parameters_annotations">
</colgroup>
<tbody><tr>
<td class="parameter_name"><p>entry</p></td>
<td class="parameter_description"><p>an <a class="link" href="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry" title="OstreeCommitSizesEntry"><span class="type">OstreeCommitSizesEntry</span></a>. </p></td>
<td class="parameter_annotations"><span class="annotation">[<a href="http://foldoc.org/not%20nullable"><span class="acronym">not nullable</span></a>]</span></td>
</tr></tbody>
</table></div>
</div>
<div class="refsect3">
<a name="ostree-commit-sizes-entry-copy.returns"></a><h4>Returns</h4>
<p>a new copy of <em class="parameter"><code>entry</code></em>
. </p>
<p><span class="annotation">[<a href="http://foldoc.org/transfer%20full"><span class="acronym">transfer full</span></a>][<a href="http://foldoc.org/nullable"><span class="acronym">nullable</span></a>]</span></p>
</div>
<p class="since">Since: 2020.1</p>
</div>
<hr>
<div class="refsect2">
<a name="ostree-commit-sizes-entry-free"></a><h3>ostree_commit_sizes_entry_free ()</h3>
<pre class="programlisting"><span class="returnvalue">void</span>
ostree_commit_sizes_entry_free (<em class="parameter"><code><a class="link" href="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry" title="OstreeCommitSizesEntry"><span class="type">OstreeCommitSizesEntry</span></a> *entry</code></em>);</pre>
<p>Free given <em class="parameter"><code>entry</code></em>
.</p>
<div class="refsect3">
<a name="ostree-commit-sizes-entry-free.parameters"></a><h4>Parameters</h4>
<div class="informaltable"><table class="informaltable" width="100%" border="0">
<colgroup>
<col width="150px" class="parameters_name">
<col class="parameters_description">
<col width="200px" class="parameters_annotations">
</colgroup>
<tbody><tr>
<td class="parameter_name"><p>entry</p></td>
<td class="parameter_description"><p>an <a class="link" href="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry" title="OstreeCommitSizesEntry"><span class="type">OstreeCommitSizesEntry</span></a>. </p></td>
<td class="parameter_annotations"><span class="annotation">[<a href="http://foldoc.org/transfer%20full"><span class="acronym">transfer full</span></a>]</span></td>
</tr></tbody>
</table></div>
</div>
<p class="since">Since: 2020.1</p>
</div>
<hr>
<div class="refsect2">
<a name="ostree-check-version"></a><h3>ostree_check_version ()</h3> <a name="ostree-check-version"></a><h3>ostree_check_version ()</h3>
<pre class="programlisting"><span class="returnvalue">gboolean</span> <pre class="programlisting"><span class="returnvalue">gboolean</span>
ostree_check_version (<em class="parameter"><code><span class="type">guint</span> required_year</code></em>, ostree_check_version (<em class="parameter"><code><span class="type">guint</span> required_year</code></em>,
@ -2620,6 +2801,52 @@ stale and should be re-downloaded if possible (similar to the HTTP
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>key: <code class="literal">ostree.commit.timestamp</code>, value: <code class="literal">t</code>, timestamp (seconds since the <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>key: <code class="literal">ostree.commit.timestamp</code>, value: <code class="literal">t</code>, timestamp (seconds since the
Unix epoch in UTC, big-endian) when the commit was committed</p></li></ul></div> Unix epoch in UTC, big-endian) when the commit was committed</p></li></ul></div>
</div> </div>
<hr>
<div class="refsect2">
<a name="OstreeCommitSizesEntry"></a><h3>OstreeCommitSizesEntry</h3>
<pre class="programlisting">typedef struct {
gchar *checksum;
OstreeObjectType objtype;
guint64 unpacked;
guint64 archived;
} OstreeCommitSizesEntry;
</pre>
<p>Structure representing an entry in the "ostree.sizes" commit metadata. Each
entry corresponds to an object in the associated commit.</p>
<div class="refsect3">
<a name="OstreeCommitSizesEntry.members"></a><h4>Members</h4>
<div class="informaltable"><table class="informaltable" width="100%" border="0">
<colgroup>
<col width="300px" class="struct_members_name">
<col class="struct_members_description">
<col width="200px" class="struct_members_annotations">
</colgroup>
<tbody>
<tr>
<td class="struct_member_name"><p><span class="type">gchar</span> *<em class="structfield"><code><a name="OstreeCommitSizesEntry.checksum"></a>checksum</code></em>;</p></td>
<td class="struct_member_description"><p>object checksum. </p></td>
<td class="struct_member_annotations"><span class="annotation">[<a href="http://foldoc.org/not%20nullable"><span class="acronym">not nullable</span></a>]</span></td>
</tr>
<tr>
<td class="struct_member_name"><p><a class="link" href="ostree-Core-repository-independent-functions.html#OstreeObjectType" title="enum OstreeObjectType"><span class="type">OstreeObjectType</span></a> <em class="structfield"><code><a name="OstreeCommitSizesEntry.objtype"></a>objtype</code></em>;</p></td>
<td class="struct_member_description"><p>object type</p></td>
<td class="struct_member_annotations"> </td>
</tr>
<tr>
<td class="struct_member_name"><p><span class="type">guint64</span> <em class="structfield"><code><a name="OstreeCommitSizesEntry.unpacked"></a>unpacked</code></em>;</p></td>
<td class="struct_member_description"><p>unpacked object size</p></td>
<td class="struct_member_annotations"> </td>
</tr>
<tr>
<td class="struct_member_name"><p><span class="type">guint64</span> <em class="structfield"><code><a name="OstreeCommitSizesEntry.archived"></a>archived</code></em>;</p></td>
<td class="struct_member_description"><p>compressed object size</p></td>
<td class="struct_member_annotations"> </td>
</tr>
</tbody>
</table></div>
</div>
<p class="since">Since: 2020.1</p>
</div>
</div> </div>
</div> </div>
<div class="footer"> <div class="footer">

View File

@ -553,6 +553,29 @@ These may be returned by any API which creates or verifies signatures.</p>
</td> </td>
<td class="enum_member_annotations"> </td> <td class="enum_member_annotations"> </td>
</tr> </tr>
<tr>
<td class="enum_member_name"><p><a name="OSTREE-GPG-ERROR-EXPIRED-SIGNATURE:CAPS"></a>OSTREE_GPG_ERROR_EXPIRED_SIGNATURE</p></td>
<td class="enum_member_description">
<p>A signature was expired. Since: 2020.1.</p>
</td>
<td class="enum_member_annotations"> </td>
</tr>
<tr>
<td class="enum_member_name"><p><a name="OSTREE-GPG-ERROR-EXPIRED-KEY:CAPS"></a>OSTREE_GPG_ERROR_EXPIRED_KEY</p></td>
<td class="enum_member_description">
<p>A signature was found, but the key used to
sign it has expired. Since: 2020.1.</p>
</td>
<td class="enum_member_annotations"> </td>
</tr>
<tr>
<td class="enum_member_name"><p><a name="OSTREE-GPG-ERROR-REVOKED-KEY:CAPS"></a>OSTREE_GPG_ERROR_REVOKED_KEY</p></td>
<td class="enum_member_description">
<p>A signature was found, but the key used to
sign it has been revoked. Since: 2020.1.</p>
</td>
<td class="enum_member_annotations"> </td>
</tr>
</tbody> </tbody>
</table></div> </table></div>
</div> </div>

View File

@ -57,6 +57,14 @@
</tr> </tr>
<tr> <tr>
<td class="function_type"> <td class="function_type">
<span class="returnvalue">gboolean</span>
</td>
<td class="function_name">
<a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-initialize" title="ostree_sysroot_initialize ()">ostree_sysroot_initialize</a> <span class="c_punctuation">()</span>
</td>
</tr>
<tr>
<td class="function_type">
<span class="returnvalue">GFile</span> * <span class="returnvalue">GFile</span> *
</td> </td>
<td class="function_name"> <td class="function_name">
@ -129,6 +137,22 @@
</tr> </tr>
<tr> <tr>
<td class="function_type"> <td class="function_type">
<span class="returnvalue">void</span>
</td>
<td class="function_name">
<a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-set-mount-namespace-in-use" title="ostree_sysroot_set_mount_namespace_in_use ()">ostree_sysroot_set_mount_namespace_in_use</a> <span class="c_punctuation">()</span>
</td>
</tr>
<tr>
<td class="function_type">
<span class="returnvalue">gboolean</span>
</td>
<td class="function_name">
<a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-is-booted" title="ostree_sysroot_is_booted ()">ostree_sysroot_is_booted</a> <span class="c_punctuation">()</span>
</td>
</tr>
<tr>
<td class="function_type">
<span class="returnvalue">int</span> <span class="returnvalue">int</span>
</td> </td>
<td class="function_name"> <td class="function_name">
@ -438,6 +462,33 @@ ostree_sysroot_new_default (<em class="parameter"><code><span class="type">void<
</div> </div>
<hr> <hr>
<div class="refsect2"> <div class="refsect2">
<a name="ostree-sysroot-initialize"></a><h3>ostree_sysroot_initialize ()</h3>
<pre class="programlisting"><span class="returnvalue">gboolean</span>
ostree_sysroot_initialize (<em class="parameter"><code><a class="link" href="ostree-Root-partition-mount-point.html#OstreeSysroot" title="OstreeSysroot"><span class="type">OstreeSysroot</span></a> *self</code></em>,
<em class="parameter"><code><span class="type">GError</span> **error</code></em>);</pre>
<p>Subset of <a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-load" title="ostree_sysroot_load ()"><code class="function">ostree_sysroot_load()</code></a>; performs basic initialization. Notably, one
can invoke <code class="literal"><a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-get-fd" title="ostree_sysroot_get_fd ()"><code class="function">ostree_sysroot_get_fd()</code></a></code> after calling this function.</p>
<p>It is not necessary to call this function if <a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-load" title="ostree_sysroot_load ()"><code class="function">ostree_sysroot_load()</code></a> is
invoked.</p>
<div class="refsect3">
<a name="ostree-sysroot-initialize.parameters"></a><h4>Parameters</h4>
<div class="informaltable"><table class="informaltable" width="100%" border="0">
<colgroup>
<col width="150px" class="parameters_name">
<col class="parameters_description">
<col width="200px" class="parameters_annotations">
</colgroup>
<tbody><tr>
<td class="parameter_name"><p>self</p></td>
<td class="parameter_description"><p>sysroot</p></td>
<td class="parameter_annotations"> </td>
</tr></tbody>
</table></div>
</div>
<p class="since">Since: 2020.1</p>
</div>
<hr>
<div class="refsect2">
<a name="ostree-sysroot-get-path"></a><h3>ostree_sysroot_get_path ()</h3> <a name="ostree-sysroot-get-path"></a><h3>ostree_sysroot_get_path ()</h3>
<pre class="programlisting"><span class="returnvalue">GFile</span> * <pre class="programlisting"><span class="returnvalue">GFile</span> *
ostree_sysroot_get_path (<em class="parameter"><code><a class="link" href="ostree-Root-partition-mount-point.html#OstreeSysroot" title="OstreeSysroot"><span class="type">OstreeSysroot</span></a> *self</code></em>);</pre> ostree_sysroot_get_path (<em class="parameter"><code><a class="link" href="ostree-Root-partition-mount-point.html#OstreeSysroot" title="OstreeSysroot"><span class="type">OstreeSysroot</span></a> *self</code></em>);</pre>
@ -737,12 +788,57 @@ may not be predictable.</p>
</div> </div>
<hr> <hr>
<div class="refsect2"> <div class="refsect2">
<a name="ostree-sysroot-set-mount-namespace-in-use"></a><h3>ostree_sysroot_set_mount_namespace_in_use ()</h3>
<pre class="programlisting"><span class="returnvalue">void</span>
ostree_sysroot_set_mount_namespace_in_use
(<em class="parameter"><code><a class="link" href="ostree-Root-partition-mount-point.html#OstreeSysroot" title="OstreeSysroot"><span class="type">OstreeSysroot</span></a> *self</code></em>);</pre>
<p>If this function is invoked, then libostree will assume that
a private Linux mount namespace has been created by the process.
The primary use case for this is to have e.g. /sysroot mounted
read-only by default.</p>
<p>If this function has been called, then when a function which requires
writable access is invoked, libostree will automatically remount as writable
any mount points on which it operates. This currently is just <code class="literal">/sysroot</code> and
<code class="literal">/boot</code>.</p>
<p>If you invoke this function, it must be before <a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-load" title="ostree_sysroot_load ()"><code class="function">ostree_sysroot_load()</code></a>; it may
be invoked before or after <a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-initialize" title="ostree_sysroot_initialize ()"><code class="function">ostree_sysroot_initialize()</code></a>.</p>
<p class="since">Since: 2020.1</p>
</div>
<hr>
<div class="refsect2">
<a name="ostree-sysroot-is-booted"></a><h3>ostree_sysroot_is_booted ()</h3>
<pre class="programlisting"><span class="returnvalue">gboolean</span>
ostree_sysroot_is_booted (<em class="parameter"><code><a class="link" href="ostree-Root-partition-mount-point.html#OstreeSysroot" title="OstreeSysroot"><span class="type">OstreeSysroot</span></a> *self</code></em>);</pre>
<p>Can only be invoked after <code class="literal"><a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-initialize" title="ostree_sysroot_initialize ()"><code class="function">ostree_sysroot_initialize()</code></a></code>.</p>
<div class="refsect3">
<a name="ostree-sysroot-is-booted.parameters"></a><h4>Parameters</h4>
<div class="informaltable"><table class="informaltable" width="100%" border="0">
<colgroup>
<col width="150px" class="parameters_name">
<col class="parameters_description">
<col width="200px" class="parameters_annotations">
</colgroup>
<tbody><tr>
<td class="parameter_name"><p>self</p></td>
<td class="parameter_description"><p>Sysroot</p></td>
<td class="parameter_annotations"> </td>
</tr></tbody>
</table></div>
</div>
<div class="refsect3">
<a name="ostree-sysroot-is-booted.returns"></a><h4>Returns</h4>
<p> <code class="literal">TRUE</code> iff the sysroot points to a booted deployment</p>
</div>
<p class="since">Since: 2020.1</p>
</div>
<hr>
<div class="refsect2">
<a name="ostree-sysroot-get-fd"></a><h3>ostree_sysroot_get_fd ()</h3> <a name="ostree-sysroot-get-fd"></a><h3>ostree_sysroot_get_fd ()</h3>
<pre class="programlisting"><span class="returnvalue">int</span> <pre class="programlisting"><span class="returnvalue">int</span>
ostree_sysroot_get_fd (<em class="parameter"><code><a class="link" href="ostree-Root-partition-mount-point.html#OstreeSysroot" title="OstreeSysroot"><span class="type">OstreeSysroot</span></a> *self</code></em>);</pre> ostree_sysroot_get_fd (<em class="parameter"><code><a class="link" href="ostree-Root-partition-mount-point.html#OstreeSysroot" title="OstreeSysroot"><span class="type">OstreeSysroot</span></a> *self</code></em>);</pre>
<p>Access a file descriptor that refers to the root directory of this <p>Access a file descriptor that refers to the root directory of this sysroot.
sysroot. <a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-load" title="ostree_sysroot_load ()"><code class="function">ostree_sysroot_load()</code></a> must have been invoked prior to <a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-initialize" title="ostree_sysroot_initialize ()"><code class="function">ostree_sysroot_initialize()</code></a> (or <a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-load" title="ostree_sysroot_load ()"><code class="function">ostree_sysroot_load()</code></a>) must have been invoked
calling this function.</p> prior to calling this function.</p>
<div class="refsect3"> <div class="refsect3">
<a name="ostree-sysroot-get-fd.parameters"></a><h4>Parameters</h4> <a name="ostree-sysroot-get-fd.parameters"></a><h4>Parameters</h4>
<div class="informaltable"><table class="informaltable" width="100%" border="0"> <div class="informaltable"><table class="informaltable" width="100%" border="0">
@ -1113,8 +1209,8 @@ flag in <em class="parameter"><code>options</code></em>
<pre class="programlisting"><a class="link" href="ostree-OstreeRepo.html#OstreeRepo" title="OstreeRepo"><span class="returnvalue">OstreeRepo</span></a> * <pre class="programlisting"><a class="link" href="ostree-OstreeRepo.html#OstreeRepo" title="OstreeRepo"><span class="returnvalue">OstreeRepo</span></a> *
ostree_sysroot_repo (<em class="parameter"><code><a class="link" href="ostree-Root-partition-mount-point.html#OstreeSysroot" title="OstreeSysroot"><span class="type">OstreeSysroot</span></a> *self</code></em>);</pre> ostree_sysroot_repo (<em class="parameter"><code><a class="link" href="ostree-Root-partition-mount-point.html#OstreeSysroot" title="OstreeSysroot"><span class="type">OstreeSysroot</span></a> *self</code></em>);</pre>
<p>This function is a variant of <a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-get-repo" title="ostree_sysroot_get_repo ()"><code class="function">ostree_sysroot_get_repo()</code></a> that cannot fail, and <p>This function is a variant of <a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-get-repo" title="ostree_sysroot_get_repo ()"><code class="function">ostree_sysroot_get_repo()</code></a> that cannot fail, and
returns a cached repository. Can only be called after <a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-load" title="ostree_sysroot_load ()"><code class="function">ostree_sysroot_load()</code></a> returns a cached repository. Can only be called after <a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-initialize" title="ostree_sysroot_initialize ()"><code class="function">ostree_sysroot_initialize()</code></a>
has been invoked successfully.</p> or <a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-load" title="ostree_sysroot_load ()"><code class="function">ostree_sysroot_load()</code></a> has been invoked successfully.</p>
<div class="refsect3"> <div class="refsect3">
<a name="ostree-sysroot-repo.parameters"></a><h4>Parameters</h4> <a name="ostree-sysroot-repo.parameters"></a><h4>Parameters</h4>
<div class="informaltable"><table class="informaltable" width="100%" border="0"> <div class="informaltable"><table class="informaltable" width="100%" border="0">

View File

@ -69,6 +69,10 @@
<keyword type="function" name="ostree_commit_get_parent ()" link="ostree-Core-repository-independent-functions.html#ostree-commit-get-parent"/> <keyword type="function" name="ostree_commit_get_parent ()" link="ostree-Core-repository-independent-functions.html#ostree-commit-get-parent"/>
<keyword type="function" name="ostree_commit_get_timestamp ()" link="ostree-Core-repository-independent-functions.html#ostree-commit-get-timestamp"/> <keyword type="function" name="ostree_commit_get_timestamp ()" link="ostree-Core-repository-independent-functions.html#ostree-commit-get-timestamp"/>
<keyword type="function" name="ostree_commit_get_content_checksum ()" link="ostree-Core-repository-independent-functions.html#ostree-commit-get-content-checksum" since="2018.2"/> <keyword type="function" name="ostree_commit_get_content_checksum ()" link="ostree-Core-repository-independent-functions.html#ostree-commit-get-content-checksum" since="2018.2"/>
<keyword type="function" name="ostree_commit_get_object_sizes ()" link="ostree-Core-repository-independent-functions.html#ostree-commit-get-object-sizes" since="2020.1"/>
<keyword type="function" name="ostree_commit_sizes_entry_new ()" link="ostree-Core-repository-independent-functions.html#ostree-commit-sizes-entry-new" since="2020.1"/>
<keyword type="function" name="ostree_commit_sizes_entry_copy ()" link="ostree-Core-repository-independent-functions.html#ostree-commit-sizes-entry-copy" since="2020.1"/>
<keyword type="function" name="ostree_commit_sizes_entry_free ()" link="ostree-Core-repository-independent-functions.html#ostree-commit-sizes-entry-free" since="2020.1"/>
<keyword type="function" name="ostree_check_version ()" link="ostree-Core-repository-independent-functions.html#ostree-check-version" since="2017.4"/> <keyword type="function" name="ostree_check_version ()" link="ostree-Core-repository-independent-functions.html#ostree-check-version" since="2017.4"/>
<keyword type="macro" name="OSTREE_MAX_METADATA_SIZE" link="ostree-Core-repository-independent-functions.html#OSTREE-MAX-METADATA-SIZE:CAPS"/> <keyword type="macro" name="OSTREE_MAX_METADATA_SIZE" link="ostree-Core-repository-independent-functions.html#OSTREE-MAX-METADATA-SIZE:CAPS"/>
<keyword type="macro" name="OSTREE_MAX_METADATA_WARN_SIZE" link="ostree-Core-repository-independent-functions.html#OSTREE-MAX-METADATA-WARN-SIZE:CAPS"/> <keyword type="macro" name="OSTREE_MAX_METADATA_WARN_SIZE" link="ostree-Core-repository-independent-functions.html#OSTREE-MAX-METADATA-WARN-SIZE:CAPS"/>
@ -84,6 +88,7 @@
<keyword type="macro" name="OSTREE_COMMIT_GVARIANT_FORMAT" link="ostree-Core-repository-independent-functions.html#OSTREE-COMMIT-GVARIANT-FORMAT:CAPS"/> <keyword type="macro" name="OSTREE_COMMIT_GVARIANT_FORMAT" link="ostree-Core-repository-independent-functions.html#OSTREE-COMMIT-GVARIANT-FORMAT:CAPS"/>
<keyword type="macro" name="OSTREE_SUMMARY_GVARIANT_STRING" link="ostree-Core-repository-independent-functions.html#OSTREE-SUMMARY-GVARIANT-STRING:CAPS"/> <keyword type="macro" name="OSTREE_SUMMARY_GVARIANT_STRING" link="ostree-Core-repository-independent-functions.html#OSTREE-SUMMARY-GVARIANT-STRING:CAPS"/>
<keyword type="macro" name="OSTREE_SUMMARY_GVARIANT_FORMAT" link="ostree-Core-repository-independent-functions.html#OSTREE-SUMMARY-GVARIANT-FORMAT:CAPS"/> <keyword type="macro" name="OSTREE_SUMMARY_GVARIANT_FORMAT" link="ostree-Core-repository-independent-functions.html#OSTREE-SUMMARY-GVARIANT-FORMAT:CAPS"/>
<keyword type="struct" name="OstreeCommitSizesEntry" link="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry" since="2020.1"/>
<keyword type="function" name="ostree_repo_mode_from_string ()" link="ostree-OstreeRepo.html#ostree-repo-mode-from-string"/> <keyword type="function" name="ostree_repo_mode_from_string ()" link="ostree-OstreeRepo.html#ostree-repo-mode-from-string"/>
<keyword type="function" name="ostree_repo_open_at ()" link="ostree-OstreeRepo.html#ostree-repo-open-at" since="2017.10"/> <keyword type="function" name="ostree_repo_open_at ()" link="ostree-OstreeRepo.html#ostree-repo-open-at" since="2017.10"/>
<keyword type="function" name="ostree_repo_new ()" link="ostree-OstreeRepo.html#ostree-repo-new"/> <keyword type="function" name="ostree_repo_new ()" link="ostree-OstreeRepo.html#ostree-repo-new"/>
@ -262,6 +267,7 @@
<keyword type="typedef" name="OstreeMutableTree" link="ostree-In-memory-modifiable-filesystem-tree.html#OstreeMutableTree"/> <keyword type="typedef" name="OstreeMutableTree" link="ostree-In-memory-modifiable-filesystem-tree.html#OstreeMutableTree"/>
<keyword type="function" name="ostree_sysroot_new ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-new"/> <keyword type="function" name="ostree_sysroot_new ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-new"/>
<keyword type="function" name="ostree_sysroot_new_default ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-new-default"/> <keyword type="function" name="ostree_sysroot_new_default ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-new-default"/>
<keyword type="function" name="ostree_sysroot_initialize ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-initialize" since="2020.1"/>
<keyword type="function" name="ostree_sysroot_get_path ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-get-path"/> <keyword type="function" name="ostree_sysroot_get_path ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-get-path"/>
<keyword type="function" name="ostree_sysroot_load ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-load"/> <keyword type="function" name="ostree_sysroot_load ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-load"/>
<keyword type="function" name="ostree_sysroot_load_if_changed ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-load-if-changed" since="2016.4"/> <keyword type="function" name="ostree_sysroot_load_if_changed ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-load-if-changed" since="2016.4"/>
@ -271,6 +277,8 @@
<keyword type="function" name="ostree_sysroot_lock_finish ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-lock-finish"/> <keyword type="function" name="ostree_sysroot_lock_finish ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-lock-finish"/>
<keyword type="function" name="ostree_sysroot_unlock ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-unlock"/> <keyword type="function" name="ostree_sysroot_unlock ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-unlock"/>
<keyword type="function" name="ostree_sysroot_unload ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-unload"/> <keyword type="function" name="ostree_sysroot_unload ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-unload"/>
<keyword type="function" name="ostree_sysroot_set_mount_namespace_in_use ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-set-mount-namespace-in-use" since="2020.1"/>
<keyword type="function" name="ostree_sysroot_is_booted ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-is-booted" since="2020.1"/>
<keyword type="function" name="ostree_sysroot_get_fd ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-get-fd"/> <keyword type="function" name="ostree_sysroot_get_fd ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-get-fd"/>
<keyword type="function" name="ostree_sysroot_ensure_initialized ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-ensure-initialized"/> <keyword type="function" name="ostree_sysroot_ensure_initialized ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-ensure-initialized"/>
<keyword type="function" name="ostree_sysroot_get_bootversion ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-get-bootversion"/> <keyword type="function" name="ostree_sysroot_get_bootversion ()" link="ostree-Root-partition-mount-point.html#ostree-sysroot-get-bootversion"/>
@ -488,6 +496,9 @@
<keyword type="constant" name="OSTREE_GPG_ERROR_NO_SIGNATURE" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-ERROR-NO-SIGNATURE:CAPS"/> <keyword type="constant" name="OSTREE_GPG_ERROR_NO_SIGNATURE" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-ERROR-NO-SIGNATURE:CAPS"/>
<keyword type="constant" name="OSTREE_GPG_ERROR_INVALID_SIGNATURE" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-ERROR-INVALID-SIGNATURE:CAPS"/> <keyword type="constant" name="OSTREE_GPG_ERROR_INVALID_SIGNATURE" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-ERROR-INVALID-SIGNATURE:CAPS"/>
<keyword type="constant" name="OSTREE_GPG_ERROR_MISSING_KEY" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-ERROR-MISSING-KEY:CAPS"/> <keyword type="constant" name="OSTREE_GPG_ERROR_MISSING_KEY" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-ERROR-MISSING-KEY:CAPS"/>
<keyword type="constant" name="OSTREE_GPG_ERROR_EXPIRED_SIGNATURE" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-ERROR-EXPIRED-SIGNATURE:CAPS"/>
<keyword type="constant" name="OSTREE_GPG_ERROR_EXPIRED_KEY" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-ERROR-EXPIRED-KEY:CAPS"/>
<keyword type="constant" name="OSTREE_GPG_ERROR_REVOKED_KEY" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-ERROR-REVOKED-KEY:CAPS"/>
<keyword type="constant" name="OSTREE_GPG_SIGNATURE_ATTR_VALID" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-SIGNATURE-ATTR-VALID:CAPS"/> <keyword type="constant" name="OSTREE_GPG_SIGNATURE_ATTR_VALID" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-SIGNATURE-ATTR-VALID:CAPS"/>
<keyword type="constant" name="OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-SIGNATURE-ATTR-SIG-EXPIRED:CAPS"/> <keyword type="constant" name="OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-SIGNATURE-ATTR-SIG-EXPIRED:CAPS"/>
<keyword type="constant" name="OSTREE_GPG_SIGNATURE_ATTR_KEY_EXPIRED" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-SIGNATURE-ATTR-KEY-EXPIRED:CAPS"/> <keyword type="constant" name="OSTREE_GPG_SIGNATURE_ATTR_KEY_EXPIRED" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-SIGNATURE-ATTR-KEY-EXPIRED:CAPS"/>
@ -506,6 +517,10 @@
<keyword type="constant" name="OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-SIGNATURE-FORMAT-DEFAULT:CAPS"/> <keyword type="constant" name="OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-SIGNATURE-FORMAT-DEFAULT:CAPS"/>
<keyword type="constant" name="OSTREE_DIFF_FLAGS_NONE" link="ostree-ostree-diff.html#OSTREE-DIFF-FLAGS-NONE:CAPS"/> <keyword type="constant" name="OSTREE_DIFF_FLAGS_NONE" link="ostree-ostree-diff.html#OSTREE-DIFF-FLAGS-NONE:CAPS"/>
<keyword type="constant" name="OSTREE_DIFF_FLAGS_IGNORE_XATTRS" link="ostree-ostree-diff.html#OSTREE-DIFF-FLAGS-IGNORE-XATTRS:CAPS"/> <keyword type="constant" name="OSTREE_DIFF_FLAGS_IGNORE_XATTRS" link="ostree-ostree-diff.html#OSTREE-DIFF-FLAGS-IGNORE-XATTRS:CAPS"/>
<keyword type="member" name="OstreeCommitSizesEntry.checksum" link="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry.checksum"/>
<keyword type="member" name="OstreeCommitSizesEntry.objtype" link="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry.objtype"/>
<keyword type="member" name="OstreeCommitSizesEntry.unpacked" link="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry.unpacked"/>
<keyword type="member" name="OstreeCommitSizesEntry.archived" link="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry.archived"/>
<keyword type="member" name="OstreeRepoTransactionStats.metadata-objects-total" link="ostree-OstreeRepo.html#OstreeRepoTransactionStats.metadata-objects-total"/> <keyword type="member" name="OstreeRepoTransactionStats.metadata-objects-total" link="ostree-OstreeRepo.html#OstreeRepoTransactionStats.metadata-objects-total"/>
<keyword type="member" name="OstreeRepoTransactionStats.metadata-objects-written" link="ostree-OstreeRepo.html#OstreeRepoTransactionStats.metadata-objects-written"/> <keyword type="member" name="OstreeRepoTransactionStats.metadata-objects-written" link="ostree-OstreeRepo.html#OstreeRepoTransactionStats.metadata-objects-written"/>
<keyword type="member" name="OstreeRepoTransactionStats.content-objects-total" link="ostree-OstreeRepo.html#OstreeRepoTransactionStats.content-objects-total"/> <keyword type="member" name="OstreeRepoTransactionStats.content-objects-total" link="ostree-OstreeRepo.html#OstreeRepoTransactionStats.content-objects-total"/>

View File

@ -302,10 +302,18 @@ ostree_collection_ref_new, function in ostree-ref
</dt> </dt>
<dd></dd> <dd></dd>
<dt> <dt>
<a class="link" href="ostree-Core-repository-independent-functions.html#OstreeCommitSizesEntry" title="OstreeCommitSizesEntry">OstreeCommitSizesEntry</a>, struct in <a class="link" href="ostree-Core-repository-independent-functions.html" title="Core repository-independent functions">Core repository-independent functions</a>
</dt>
<dd></dd>
<dt>
<a class="link" href="ostree-Core-repository-independent-functions.html#ostree-commit-get-content-checksum" title="ostree_commit_get_content_checksum ()">ostree_commit_get_content_checksum</a>, function in <a class="link" href="ostree-Core-repository-independent-functions.html" title="Core repository-independent functions">Core repository-independent functions</a> <a class="link" href="ostree-Core-repository-independent-functions.html#ostree-commit-get-content-checksum" title="ostree_commit_get_content_checksum ()">ostree_commit_get_content_checksum</a>, function in <a class="link" href="ostree-Core-repository-independent-functions.html" title="Core repository-independent functions">Core repository-independent functions</a>
</dt> </dt>
<dd></dd> <dd></dd>
<dt> <dt>
<a class="link" href="ostree-Core-repository-independent-functions.html#ostree-commit-get-object-sizes" title="ostree_commit_get_object_sizes ()">ostree_commit_get_object_sizes</a>, function in <a class="link" href="ostree-Core-repository-independent-functions.html" title="Core repository-independent functions">Core repository-independent functions</a>
</dt>
<dd></dd>
<dt>
<a class="link" href="ostree-Core-repository-independent-functions.html#ostree-commit-get-parent" title="ostree_commit_get_parent ()">ostree_commit_get_parent</a>, function in <a class="link" href="ostree-Core-repository-independent-functions.html" title="Core repository-independent functions">Core repository-independent functions</a> <a class="link" href="ostree-Core-repository-independent-functions.html#ostree-commit-get-parent" title="ostree_commit_get_parent ()">ostree_commit_get_parent</a>, function in <a class="link" href="ostree-Core-repository-independent-functions.html" title="Core repository-independent functions">Core repository-independent functions</a>
</dt> </dt>
<dd></dd> <dd></dd>
@ -322,6 +330,18 @@ ostree_collection_ref_new, function in ostree-ref
</dt> </dt>
<dd></dd> <dd></dd>
<dt> <dt>
<a class="link" href="ostree-Core-repository-independent-functions.html#ostree-commit-sizes-entry-copy" title="ostree_commit_sizes_entry_copy ()">ostree_commit_sizes_entry_copy</a>, function in <a class="link" href="ostree-Core-repository-independent-functions.html" title="Core repository-independent functions">Core repository-independent functions</a>
</dt>
<dd></dd>
<dt>
<a class="link" href="ostree-Core-repository-independent-functions.html#ostree-commit-sizes-entry-free" title="ostree_commit_sizes_entry_free ()">ostree_commit_sizes_entry_free</a>, function in <a class="link" href="ostree-Core-repository-independent-functions.html" title="Core repository-independent functions">Core repository-independent functions</a>
</dt>
<dd></dd>
<dt>
<a class="link" href="ostree-Core-repository-independent-functions.html#ostree-commit-sizes-entry-new" title="ostree_commit_sizes_entry_new ()">ostree_commit_sizes_entry_new</a>, function in <a class="link" href="ostree-Core-repository-independent-functions.html" title="Core repository-independent functions">Core repository-independent functions</a>
</dt>
<dd></dd>
<dt>
<a class="link" href="ostree-Core-repository-independent-functions.html#ostree-content-file-parse" title="ostree_content_file_parse ()">ostree_content_file_parse</a>, function in <a class="link" href="ostree-Core-repository-independent-functions.html" title="Core repository-independent functions">Core repository-independent functions</a> <a class="link" href="ostree-Core-repository-independent-functions.html#ostree-content-file-parse" title="ostree_content_file_parse ()">ostree_content_file_parse</a>, function in <a class="link" href="ostree-Core-repository-independent-functions.html" title="Core repository-independent functions">Core repository-independent functions</a>
</dt> </dt>
<dd></dd> <dd></dd>
@ -1724,10 +1744,18 @@ ostree_repo_transaction_set_collection_ref, function in ostree-misc-experimental
</dt> </dt>
<dd></dd> <dd></dd>
<dt> <dt>
<a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-initialize" title="ostree_sysroot_initialize ()">ostree_sysroot_initialize</a>, function in <a class="link" href="ostree-Root-partition-mount-point.html" title="Root partition mount point">Root partition mount point</a>
</dt>
<dd></dd>
<dt>
<a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-init-osname" title="ostree_sysroot_init_osname ()">ostree_sysroot_init_osname</a>, function in <a class="link" href="ostree-Root-partition-mount-point.html" title="Root partition mount point">Root partition mount point</a> <a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-init-osname" title="ostree_sysroot_init_osname ()">ostree_sysroot_init_osname</a>, function in <a class="link" href="ostree-Root-partition-mount-point.html" title="Root partition mount point">Root partition mount point</a>
</dt> </dt>
<dd></dd> <dd></dd>
<dt> <dt>
<a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-is-booted" title="ostree_sysroot_is_booted ()">ostree_sysroot_is_booted</a>, function in <a class="link" href="ostree-Root-partition-mount-point.html" title="Root partition mount point">Root partition mount point</a>
</dt>
<dd></dd>
<dt>
<a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-load" title="ostree_sysroot_load ()">ostree_sysroot_load</a>, function in <a class="link" href="ostree-Root-partition-mount-point.html" title="Root partition mount point">Root partition mount point</a> <a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-load" title="ostree_sysroot_load ()">ostree_sysroot_load</a>, function in <a class="link" href="ostree-Root-partition-mount-point.html" title="Root partition mount point">Root partition mount point</a>
</dt> </dt>
<dd></dd> <dd></dd>
@ -1772,6 +1800,10 @@ ostree_repo_transaction_set_collection_ref, function in ostree-misc-experimental
</dt> </dt>
<dd></dd> <dd></dd>
<dt> <dt>
<a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-set-mount-namespace-in-use" title="ostree_sysroot_set_mount_namespace_in_use ()">ostree_sysroot_set_mount_namespace_in_use</a>, function in <a class="link" href="ostree-Root-partition-mount-point.html" title="Root partition mount point">Root partition mount point</a>
</dt>
<dd></dd>
<dt>
<a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-simple-write-deployment" title="ostree_sysroot_simple_write_deployment ()">ostree_sysroot_simple_write_deployment</a>, function in <a class="link" href="ostree-Root-partition-mount-point.html" title="Root partition mount point">Root partition mount point</a> <a class="link" href="ostree-Root-partition-mount-point.html#ostree-sysroot-simple-write-deployment" title="ostree_sysroot_simple_write_deployment ()">ostree_sysroot_simple_write_deployment</a>, function in <a class="link" href="ostree-Root-partition-mount-point.html" title="Root partition mount point">Root partition mount point</a>
</dt> </dt>
<dd></dd> <dd></dd>

View File

@ -151,7 +151,14 @@ ostree_validate_structureof_dirmeta
ostree_commit_get_parent ostree_commit_get_parent
ostree_commit_get_timestamp ostree_commit_get_timestamp
ostree_commit_get_content_checksum ostree_commit_get_content_checksum
ostree_commit_get_object_sizes
OstreeCommitSizesEntry
ostree_commit_sizes_entry_new
ostree_commit_sizes_entry_copy
ostree_commit_sizes_entry_free
ostree_check_version ostree_check_version
<SUBSECTION Standard>
ostree_commit_sizes_entry_get_type
</SECTION> </SECTION>
<SECTION> <SECTION>
@ -499,6 +506,7 @@ ostree_sepolicy_get_type
OstreeSysroot OstreeSysroot
ostree_sysroot_new ostree_sysroot_new
ostree_sysroot_new_default ostree_sysroot_new_default
ostree_sysroot_initialize
ostree_sysroot_get_path ostree_sysroot_get_path
ostree_sysroot_load ostree_sysroot_load
ostree_sysroot_load_if_changed ostree_sysroot_load_if_changed
@ -508,6 +516,8 @@ ostree_sysroot_lock_async
ostree_sysroot_lock_finish ostree_sysroot_lock_finish
ostree_sysroot_unlock ostree_sysroot_unlock
ostree_sysroot_unload ostree_sysroot_unload
ostree_sysroot_set_mount_namespace_in_use
ostree_sysroot_is_booted
ostree_sysroot_get_fd ostree_sysroot_get_fd
ostree_sysroot_ensure_initialized ostree_sysroot_ensure_initialized
ostree_sysroot_get_bootversion ostree_sysroot_get_bootversion

View File

@ -4,6 +4,7 @@ ostree_bootconfig_parser_get_type
ostree_chain_input_stream_get_type ostree_chain_input_stream_get_type
ostree_checksum_input_stream_get_type ostree_checksum_input_stream_get_type
ostree_collection_ref_get_type ostree_collection_ref_get_type
ostree_commit_sizes_entry_get_type
ostree_deployment_get_type ostree_deployment_get_type
ostree_diff_item_get_type ostree_diff_item_get_type
ostree_gpg_verify_result_get_type ostree_gpg_verify_result_get_type

View File

@ -1 +1 @@
2019.6 2019.7

View File

@ -1445,6 +1445,7 @@ _ostree_show() {
local boolean_options=" local boolean_options="
$main_boolean_options $main_boolean_options
--print-related --print-related
--print-sizes
--raw --raw
" "

View File

@ -82,6 +82,9 @@
/* Define if we have libsystemd.pc */ /* Define if we have libsystemd.pc */
#undef HAVE_LIBSYSTEMD #undef HAVE_LIBSYSTEMD
/* Define to 1 if you have the <linux/fsverity.h> header file. */
#undef HAVE_LINUX_FSVERITY_H
/* Define to 1 if you have the <memory.h> header file. */ /* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H #undef HAVE_MEMORY_H

67
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for libostree 2019.6. # Generated by GNU Autoconf 2.69 for libostree 2020.2.
# #
# Report bugs to <walters@verbum.org>. # Report bugs to <walters@verbum.org>.
# #
@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='libostree' PACKAGE_NAME='libostree'
PACKAGE_TARNAME='libostree' PACKAGE_TARNAME='libostree'
PACKAGE_VERSION='2019.6' PACKAGE_VERSION='2020.2'
PACKAGE_STRING='libostree 2019.6' PACKAGE_STRING='libostree 2020.2'
PACKAGE_BUGREPORT='walters@verbum.org' PACKAGE_BUGREPORT='walters@verbum.org'
PACKAGE_URL='' PACKAGE_URL=''
@ -654,8 +654,6 @@ BUILDOPT_SYSTEMD_FALSE
BUILDOPT_SYSTEMD_TRUE BUILDOPT_SYSTEMD_TRUE
systemdsystemgeneratordir systemdsystemgeneratordir
systemdsystemunitdir systemdsystemunitdir
BUILDOPT_LIBSYSTEMD_FALSE
BUILDOPT_LIBSYSTEMD_TRUE
LIBSYSTEMD_LIBS LIBSYSTEMD_LIBS
LIBSYSTEMD_CFLAGS LIBSYSTEMD_CFLAGS
BUILDOPT_MKINITCPIO_FALSE BUILDOPT_MKINITCPIO_FALSE
@ -1554,7 +1552,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures libostree 2019.6 to adapt to many kinds of systems. \`configure' configures libostree 2020.2 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1624,7 +1622,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of libostree 2019.6:";; short | recursive ) echo "Configuration of libostree 2020.2:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1883,7 +1881,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
libostree configure 2019.6 libostree configure 2020.2
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
@ -2355,7 +2353,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by libostree $as_me 2019.6, which was It was created by libostree $as_me 2020.2, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@ -3223,7 +3221,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='libostree' PACKAGE='libostree'
VERSION='2019.6' VERSION='2020.2'
# Some tools Automake needs. # Some tools Automake needs.
@ -5955,11 +5953,11 @@ done
test -n "$YACC" || YACC="yacc" test -n "$YACC" || YACC="yacc"
YEAR_VERSION=2019 YEAR_VERSION=2020
RELEASE_VERSION=6 RELEASE_VERSION=2
PACKAGE_VERSION=2019.6 PACKAGE_VERSION=2020.2
if echo "$CFLAGS" | grep -q -E -e '-Werror($| )'; then : if echo "$CFLAGS" | grep -q -E -e '-Werror($| )'; then :
@ -16082,6 +16080,22 @@ LIBARCHIVE_DEPENDENCY="libarchive >= 2.8.0"
# What's in RHEL7.2. # What's in RHEL7.2.
FUSE_DEPENDENCY="fuse >= 2.9.2" FUSE_DEPENDENCY="fuse >= 2.9.2"
for ac_header in linux/fsverity.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "linux/fsverity.h" "ac_cv_header_linux_fsverity_h" "$ac_includes_default"
if test "x$ac_cv_header_linux_fsverity_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LINUX_FSVERITY_H 1
_ACEOF
fi
done
if test x$ac_cv_header_linux_fsverity_h = xyes ; then :
OSTREE_FEATURES="$OSTREE_FEATURES ex-fsverity"
fi
# check for gtk-doc # check for gtk-doc
@ -17865,18 +17879,9 @@ fi
else else
with_libsystemd=no with_libsystemd=no
fi fi
if test $with_libsystemd != no; then
BUILDOPT_LIBSYSTEMD_TRUE=
BUILDOPT_LIBSYSTEMD_FALSE='#'
else
BUILDOPT_LIBSYSTEMD_TRUE='#'
BUILDOPT_LIBSYSTEMD_FALSE=
fi
if test "x$with_libsystemd" = "xyes"; then :
if test "x$have_libsystemd" = "xyes"; then :
with_systemd=yes
# Check whether --with-systemdsystemunitdir was given. # Check whether --with-systemdsystemunitdir was given.
if test "${with_systemdsystemunitdir+set}" = set; then : if test "${with_systemdsystemunitdir+set}" = set; then :
@ -17907,7 +17912,7 @@ fi
fi fi
fi fi
if test x$with_systemd = xyes; then if test x$with_libsystemd = xyes; then
BUILDOPT_SYSTEMD_TRUE= BUILDOPT_SYSTEMD_TRUE=
BUILDOPT_SYSTEMD_FALSE='#' BUILDOPT_SYSTEMD_FALSE='#'
else else
@ -17915,7 +17920,7 @@ else
BUILDOPT_SYSTEMD_FALSE= BUILDOPT_SYSTEMD_FALSE=
fi fi
if test x$with_systemd = xyes && test x$with_libmount = xyes; then if test x$with_libsystemd = xyes && test x$with_libmount = xyes; then
BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE= BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE=
BUILDOPT_SYSTEMD_AND_LIBMOUNT_FALSE='#' BUILDOPT_SYSTEMD_AND_LIBMOUNT_FALSE='#'
else else
@ -17928,6 +17933,7 @@ if test -z "$BUILDOPT_SYSTEMD_AND_LIBMOUNT_TRUE"; then :
$as_echo "#define BUILDOPT_LIBSYSTEMD_AND_LIBMOUNT 1" >>confdefs.h $as_echo "#define BUILDOPT_LIBSYSTEMD_AND_LIBMOUNT 1" >>confdefs.h
fi fi
if test x$with_libsystemd = xyes; then OSTREE_FEATURES="$OSTREE_FEATURES systemd"; fi
# Check whether --with-builtin-grub2-mkconfig was given. # Check whether --with-builtin-grub2-mkconfig was given.
@ -18413,10 +18419,6 @@ if test -z "${BUILDOPT_MKINITCPIO_TRUE}" && test -z "${BUILDOPT_MKINITCPIO_FALSE
as_fn_error $? "conditional \"BUILDOPT_MKINITCPIO\" was never defined. as_fn_error $? "conditional \"BUILDOPT_MKINITCPIO\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5 Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi fi
if test -z "${BUILDOPT_LIBSYSTEMD_TRUE}" && test -z "${BUILDOPT_LIBSYSTEMD_FALSE}"; then
as_fn_error $? "conditional \"BUILDOPT_LIBSYSTEMD\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${BUILDOPT_SYSTEMD_TRUE}" && test -z "${BUILDOPT_SYSTEMD_FALSE}"; then if test -z "${BUILDOPT_SYSTEMD_TRUE}" && test -z "${BUILDOPT_SYSTEMD_FALSE}"; then
as_fn_error $? "conditional \"BUILDOPT_SYSTEMD\" was never defined. as_fn_error $? "conditional \"BUILDOPT_SYSTEMD\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@ -18842,7 +18844,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by libostree $as_me 2019.6, which was This file was extended by libostree $as_me 2020.2, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -18908,7 +18910,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
libostree config.status 2019.6 libostree config.status 2020.2
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"
@ -20610,8 +20612,9 @@ echo "
HTTP backend: $fetcher_backend HTTP backend: $fetcher_backend
\"ostree trivial-httpd\": $enable_trivial_httpd_cmdline \"ostree trivial-httpd\": $enable_trivial_httpd_cmdline
SELinux: $with_selinux SELinux: $with_selinux
fs-verity: $ac_cv_header_linux_fsverity_h
cryptographic checksums: $with_crypto cryptographic checksums: $with_crypto
systemd: $have_libsystemd systemd: $with_libsystemd
libmount: $with_libmount libmount: $with_libmount
libarchive (parse tar files directly): $with_libarchive libarchive (parse tar files directly): $with_libarchive
static deltas: yes (always enabled now) static deltas: yes (always enabled now)

View File

@ -2,12 +2,12 @@ AC_PREREQ([2.63])
dnl To do a release: follow the instructions to update libostree-released.sym from dnl To do a release: follow the instructions to update libostree-released.sym from
dnl libostree-devel.sym, update the checksum in test-symbols.sh, set is_release_build=yes dnl libostree-devel.sym, update the checksum in test-symbols.sh, set is_release_build=yes
dnl below. Then make another post-release commit to bump the version and set dnl below. Then make another post-release commit to bump the version and set
dnl is_release_build=no. dnl is_release_build=yes
dnl Seed the release notes with `git-shortlog-with-prs <previous-release>..`. Then use dnl Seed the release notes with `git-shortlog-with-prs <previous-release>..`. Then use
dnl `git-evtag` to create the tag and push it. Finally, create a GitHub release and attach dnl `git-evtag` to create the tag and push it. Finally, create a GitHub release and attach
dnl the tarball from `make dist`. dnl the tarball from `make dist`.
m4_define([year_version], [2019]) m4_define([year_version], [2020])
m4_define([release_version], [6]) m4_define([release_version], [2])
m4_define([package_version], [year_version.release_version]) m4_define([package_version], [year_version.release_version])
AC_INIT([libostree], [package_version], [walters@verbum.org]) AC_INIT([libostree], [package_version], [walters@verbum.org])
is_release_build=yes is_release_build=yes
@ -246,6 +246,10 @@ LIBARCHIVE_DEPENDENCY="libarchive >= 2.8.0"
# What's in RHEL7.2. # What's in RHEL7.2.
FUSE_DEPENDENCY="fuse >= 2.9.2" FUSE_DEPENDENCY="fuse >= 2.9.2"
AC_CHECK_HEADERS([linux/fsverity.h])
AS_IF([test x$ac_cv_header_linux_fsverity_h = xyes ],
[OSTREE_FEATURES="$OSTREE_FEATURES ex-fsverity"])
# check for gtk-doc # check for gtk-doc
m4_ifdef([GTK_DOC_CHECK], [ m4_ifdef([GTK_DOC_CHECK], [
GTK_DOC_CHECK([1.15], [--flavour no-tmpl]) GTK_DOC_CHECK([1.15], [--flavour no-tmpl])
@ -509,10 +513,8 @@ AS_IF([ test x$with_libsystemd != xno ], [
with_libsystemd=no with_libsystemd=no
]) ])
], [ with_libsystemd=no ]) ], [ with_libsystemd=no ])
AM_CONDITIONAL(BUILDOPT_LIBSYSTEMD, test $with_libsystemd != no)
AS_IF([test "x$have_libsystemd" = "xyes"], [ AS_IF([test "x$with_libsystemd" = "xyes"], [
with_systemd=yes
AC_ARG_WITH([systemdsystemunitdir], AC_ARG_WITH([systemdsystemunitdir],
AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]), AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
[], [],
@ -528,11 +530,12 @@ AS_IF([test "x$have_libsystemd" = "xyes"], [
AC_SUBST([systemdsystemgeneratordir], [$with_systemdsystemgeneratordir]) AC_SUBST([systemdsystemgeneratordir], [$with_systemdsystemgeneratordir])
]) ])
]) ])
AM_CONDITIONAL(BUILDOPT_SYSTEMD, test x$with_systemd = xyes) AM_CONDITIONAL(BUILDOPT_SYSTEMD, test x$with_libsystemd = xyes)
dnl If we have both, we use the "new /var" model with ostree-system-generator dnl If we have both, we use the "new /var" model with ostree-system-generator
AM_CONDITIONAL(BUILDOPT_SYSTEMD_AND_LIBMOUNT,[test x$with_systemd = xyes && test x$with_libmount = xyes]) AM_CONDITIONAL(BUILDOPT_SYSTEMD_AND_LIBMOUNT,[test x$with_libsystemd = xyes && test x$with_libmount = xyes])
AM_COND_IF(BUILDOPT_SYSTEMD_AND_LIBMOUNT, AM_COND_IF(BUILDOPT_SYSTEMD_AND_LIBMOUNT,
AC_DEFINE([BUILDOPT_LIBSYSTEMD_AND_LIBMOUNT], 1, [Define if systemd and libmount])) AC_DEFINE([BUILDOPT_LIBSYSTEMD_AND_LIBMOUNT], 1, [Define if systemd and libmount]))
if test x$with_libsystemd = xyes; then OSTREE_FEATURES="$OSTREE_FEATURES systemd"; fi
AC_ARG_WITH(builtin-grub2-mkconfig, AC_ARG_WITH(builtin-grub2-mkconfig,
AS_HELP_STRING([--with-builtin-grub2-mkconfig], AS_HELP_STRING([--with-builtin-grub2-mkconfig],
@ -619,8 +622,9 @@ echo "
HTTP backend: $fetcher_backend HTTP backend: $fetcher_backend
\"ostree trivial-httpd\": $enable_trivial_httpd_cmdline \"ostree trivial-httpd\": $enable_trivial_httpd_cmdline
SELinux: $with_selinux SELinux: $with_selinux
fs-verity: $ac_cv_header_linux_fsverity_h
cryptographic checksums: $with_crypto cryptographic checksums: $with_crypto
systemd: $have_libsystemd systemd: $with_libsystemd
libmount: $with_libmount libmount: $with_libmount
libarchive (parse tar files directly): $with_libarchive libarchive (parse tar files directly): $with_libarchive
static deltas: yes (always enabled now) static deltas: yes (always enabled now)

View File

@ -143,6 +143,14 @@ Boston, MA 02111-1307, USA.
<refsect1> <refsect1>
<title>Description</title> <title>Description</title>
<para>
Without --mirror, this command will create new refs
under <literal>remotes/REMOTE/</literal> directory
for each pulled branch unless they are already created. Such
refs can be then referenced by <literal>REMOTE:BRANCH</literal> in
<literal>ostree</literal> subcommands (e.g. <literal>ostree log origin:exampleos/x86_64/standard</literal>).
</para>
<para> <para>
This command can retrieve just a specific commit, or go all This command can retrieve just a specific commit, or go all
the way to performing a full mirror of the remote the way to performing a full mirror of the remote

View File

@ -99,6 +99,17 @@ Boston, MA 02111-1307, USA.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--print-sizes</option></term>
<listitem><para>
Show the commit size metadata. This in only supported for
commits that contain <varname>ostree.sizes</varname>
metadata. This can be included when creating commits with
<command>ostree commit --generate-sizes</command>.
</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>--raw</option></term> <term><option>--raw</option></term>

View File

@ -22,12 +22,12 @@ DefaultDependencies=no
ConditionKernelCommandLine=ostree ConditionKernelCommandLine=ostree
OnFailure=emergency.target OnFailure=emergency.target
Conflicts=umount.target Conflicts=umount.target
After=-.mount # Run after core mounts
After=-.mount var.mount
After=systemd-remount-fs.service After=systemd-remount-fs.service
# But we run *before* most other core bootup services that need write access to /etc and /var
Before=local-fs.target umount.target Before=local-fs.target umount.target
# Other early boot units that need to write to /var
Before=systemd-random-seed.service plymouth-read-write.service systemd-journal-flush.service Before=systemd-random-seed.service plymouth-read-write.service systemd-journal-flush.service
# tmpfiles.d usually needs write access to a few places
Before=systemd-tmpfiles-setup.service Before=systemd-tmpfiles-setup.service
[Service] [Service]

View File

@ -18,15 +18,17 @@
***/ ***/
/* Add new symbols here. Release commits should copy this section into -released.sym. */ /* Add new symbols here. Release commits should copy this section into -released.sym. */
LIBOSTREE_2019.7 { LIBOSTREE_2020.2 {
} LIBOSTREE_2019.6; global:
someostree_symbol_deleteme;
} LIBOSTREE_2020.1;
/* Stub section for the stable release *after* this development one; don't /* Stub section for the stable release *after* this development one; don't
* edit this other than to update the year. This is just a copy/paste * edit this other than to update the year. This is just a copy/paste
* source. Replace $LASTSTABLE with the last stable version, and $NEWVERSION * source. Replace $LASTSTABLE with the last stable version, and $NEWVERSION
* with whatever the next version with new symbols will be. * with whatever the next version with new symbols will be.
LIBOSTREE_2019.$NEWVERSION { LIBOSTREE_2020.$NEWVERSION {
global: global:
someostree_symbol_deleteme; someostree_symbol_deleteme;
} LIBOSTREE_2019.$LASTSTABLE; } LIBOSTREE_2020.$LASTSTABLE;
*/ */

View File

@ -581,6 +581,20 @@ LIBOSTREE_2019.6 {
ostree_async_progress_copy_state; ostree_async_progress_copy_state;
} LIBOSTREE_2019.4; } LIBOSTREE_2019.4;
LIBOSTREE_2020.1 {
global:
ostree_commit_get_object_sizes;
ostree_commit_sizes_entry_copy;
ostree_commit_sizes_entry_free;
ostree_commit_sizes_entry_get_type;
ostree_commit_sizes_entry_new;
ostree_sysroot_initialize;
ostree_sysroot_is_booted;
ostree_sysroot_set_mount_namespace_in_use;
} LIBOSTREE_2019.6;
/* No new symbols in 2020.2 */
/* NOTE: Only add more content here in release commits! See the /* NOTE: Only add more content here in release commits! See the
* comments at the top of this file. * comments at the top of this file.
*/ */

View File

@ -49,6 +49,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoDevInoCache, ostree_repo_devino_cache_u
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeAsyncProgress, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeAsyncProgress, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeBootconfigParser, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeBootconfigParser, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeCommitSizesEntry, ostree_commit_sizes_entry_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeDeployment, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeDeployment, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeGpgVerifyResult, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeGpgVerifyResult, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeKernelArgs, ostree_kernel_args_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeKernelArgs, ostree_kernel_args_free)

View File

@ -30,6 +30,12 @@ G_BEGIN_DECLS
/* It's what gzip does, 9 is too slow */ /* It's what gzip does, 9 is too slow */
#define OSTREE_ARCHIVE_DEFAULT_COMPRESSION_LEVEL (6) #define OSTREE_ARCHIVE_DEFAULT_COMPRESSION_LEVEL (6)
/* Note the permissive group bits. We want to be liberal here and let individual machines
* narrow permissions as needed via umask. This is important in setups where group ownership
* can matter for repo management (like OpenShift). */
#define DEFAULT_DIRECTORY_MODE 0775
#define DEFAULT_REGFILE_MODE 0660
/* This file contains private implementation data format definitions /* This file contains private implementation data format definitions
* read by multiple implementation .c files. * read by multiple implementation .c files.
*/ */
@ -102,6 +108,9 @@ _ostree_checksum_inplace_from_bytes_v (GVariant *csum_v, char *buf)
*/ */
#define _OSTREE_LOOSE_PATH_MAX (256) #define _OSTREE_LOOSE_PATH_MAX (256)
/* GVariant format for ostree.sizes metadata entries. */
#define _OSTREE_OBJECT_SIZES_ENTRY_SIGNATURE "ay"
char * char *
_ostree_get_relative_object_path (const char *checksum, _ostree_get_relative_object_path (const char *checksum,
OstreeObjectType type, OstreeObjectType type,

View File

@ -32,6 +32,7 @@
#include "ostree.h" #include "ostree.h"
#include "ostree-core-private.h" #include "ostree-core-private.h"
#include "ostree-chain-input-stream.h" #include "ostree-chain-input-stream.h"
#include "ostree-varint.h"
#include "otutil.h" #include "otutil.h"
/* Generic ABI checks */ /* Generic ABI checks */
@ -2430,6 +2431,187 @@ ostree_commit_get_content_checksum (GVariant *commit_variant)
return g_strdup (hexdigest); return g_strdup (hexdigest);
} }
G_DEFINE_BOXED_TYPE (OstreeCommitSizesEntry, ostree_commit_sizes_entry,
ostree_commit_sizes_entry_copy, ostree_commit_sizes_entry_free)
/**
* ostree_commit_sizes_entry_new:
* @checksum: (not nullable): object checksum
* @objtype: object type
* @unpacked: unpacked object size
* @archived: compressed object size
*
* Create a new #OstreeCommitSizesEntry for representing an object in a
* commit's "ostree.sizes" metadata.
*
* Returns: (transfer full) (nullable): a new #OstreeCommitSizesEntry
* Since: 2020.1
*/
OstreeCommitSizesEntry *
ostree_commit_sizes_entry_new (const gchar *checksum,
OstreeObjectType objtype,
guint64 unpacked,
guint64 archived)
{
g_return_val_if_fail (checksum == NULL || ostree_validate_checksum_string (checksum, NULL), NULL);
g_autoptr(OstreeCommitSizesEntry) entry = g_new0 (OstreeCommitSizesEntry, 1);
entry->checksum = g_strdup (checksum);
entry->objtype = objtype;
entry->unpacked = unpacked;
entry->archived = archived;
return g_steal_pointer (&entry);
}
/**
* ostree_commit_sizes_entry_copy:
* @entry: (not nullable): an #OstreeCommitSizesEntry
*
* Create a copy of the given @entry.
*
* Returns: (transfer full) (nullable): a new copy of @entry
* Since: 2020.1
*/
OstreeCommitSizesEntry *
ostree_commit_sizes_entry_copy (const OstreeCommitSizesEntry *entry)
{
g_return_val_if_fail (entry != NULL, NULL);
return ostree_commit_sizes_entry_new (entry->checksum,
entry->objtype,
entry->unpacked,
entry->archived);
}
/**
* ostree_commit_sizes_entry_free:
* @entry: (transfer full): an #OstreeCommitSizesEntry
*
* Free given @entry.
*
* Since: 2020.1
*/
void
ostree_commit_sizes_entry_free (OstreeCommitSizesEntry *entry)
{
g_return_if_fail (entry != NULL);
g_free (entry->checksum);
g_free (entry);
}
static gboolean
read_sizes_entry (GVariant *entry,
OstreeCommitSizesEntry **out_sizes,
GError **error)
{
gsize entry_size = g_variant_get_size (entry);
g_return_val_if_fail (entry_size >= OSTREE_SHA256_DIGEST_LEN + 2, FALSE);
const guchar *buffer = g_variant_get_data (entry);
if (buffer == NULL)
return glnx_throw (error, "Could not read ostree.sizes metadata entry");
char checksum[OSTREE_SHA256_STRING_LEN + 1];
ostree_checksum_inplace_from_bytes (buffer, checksum);
buffer += OSTREE_SHA256_DIGEST_LEN;
entry_size -= OSTREE_SHA256_DIGEST_LEN;
gsize bytes_read = 0;
guint64 archived = 0;
if (!_ostree_read_varuint64 (buffer, entry_size, &archived, &bytes_read))
return glnx_throw (error, "Unexpected EOF reading ostree.sizes varint");
buffer += bytes_read;
entry_size -= bytes_read;
guint64 unpacked = 0;
if (!_ostree_read_varuint64 (buffer, entry_size, &unpacked, &bytes_read))
return glnx_throw (error, "Unexpected EOF reading ostree.sizes varint");
buffer += bytes_read;
entry_size -= bytes_read;
/* On newer commits, an additional byte is used for the object type. */
OstreeObjectType objtype;
if (entry_size > 0)
{
objtype = *buffer;
if (objtype < OSTREE_OBJECT_TYPE_FILE || objtype > OSTREE_OBJECT_TYPE_LAST)
return glnx_throw (error, "Unexpected ostree.sizes object type %u",
objtype);
buffer++;
entry_size--;
}
else
{
/* Assume the object is a file. */
objtype = OSTREE_OBJECT_TYPE_FILE;
}
g_autoptr(OstreeCommitSizesEntry) sizes = ostree_commit_sizes_entry_new (checksum,
objtype,
unpacked,
archived);
if (out_sizes != NULL)
*out_sizes = g_steal_pointer (&sizes);
return TRUE;
}
/**
* ostree_commit_get_object_sizes:
* @commit_variant: (not nullable): variant of type %OSTREE_OBJECT_TYPE_COMMIT
* @out_sizes_entries: (out) (element-type OstreeCommitSizesEntry) (transfer container) (optional):
* return location for an array of object size entries
* @error: Error
*
* Reads a commit's "ostree.sizes" metadata and returns an array of
* #OstreeCommitSizesEntry in @out_sizes_entries. Each element
* represents an object in the commit. If the commit does not contain
* the "ostree.sizes" metadata, a %G_IO_ERROR_NOT_FOUND error will be
* returned.
*
* Since: 2020.1
*/
gboolean
ostree_commit_get_object_sizes (GVariant *commit_variant,
GPtrArray **out_sizes_entries,
GError **error)
{
g_return_val_if_fail (commit_variant != NULL, FALSE);
g_autoptr(GVariant) metadata = g_variant_get_child_value (commit_variant, 0);
g_autoptr(GVariant) sizes_variant =
g_variant_lookup_value (metadata, "ostree.sizes",
G_VARIANT_TYPE ("a" _OSTREE_OBJECT_SIZES_ENTRY_SIGNATURE));
if (sizes_variant == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"No metadata key ostree.sizes in commit");
return FALSE;
}
g_autoptr(GPtrArray) sizes_entries =
g_ptr_array_new_with_free_func ((GDestroyNotify) ostree_commit_sizes_entry_free);
g_autoptr(GVariant) entry = NULL;
GVariantIter entry_iter;
g_variant_iter_init (&entry_iter, sizes_variant);
while ((entry = g_variant_iter_next_value (&entry_iter)))
{
OstreeCommitSizesEntry *sizes_entry = NULL;
if (!read_sizes_entry (entry, &sizes_entry, error))
return FALSE;
g_clear_pointer (&entry, g_variant_unref);
g_ptr_array_add (sizes_entries, sizes_entry);
}
if (out_sizes_entries != NULL)
*out_sizes_entries = g_steal_pointer (&sizes_entries);
return TRUE;
}
/* Used in pull/deploy to validate we're not being downgraded */ /* Used in pull/deploy to validate we're not being downgraded */
gboolean gboolean
_ostree_compare_timestamps (const char *current_rev, _ostree_compare_timestamps (const char *current_rev,

View File

@ -521,6 +521,43 @@ guint64 ostree_commit_get_timestamp (GVariant *commit_variant);
_OSTREE_PUBLIC _OSTREE_PUBLIC
gchar * ostree_commit_get_content_checksum (GVariant *commit_variant); gchar * ostree_commit_get_content_checksum (GVariant *commit_variant);
/**
* OstreeCommitSizesEntry:
* @checksum: (not nullable): object checksum
* @objtype: object type
* @unpacked: unpacked object size
* @archived: compressed object size
*
* Structure representing an entry in the "ostree.sizes" commit metadata. Each
* entry corresponds to an object in the associated commit.
*
* Since: 2020.1
*/
typedef struct {
gchar *checksum;
OstreeObjectType objtype;
guint64 unpacked;
guint64 archived;
} OstreeCommitSizesEntry;
_OSTREE_PUBLIC
GType ostree_commit_sizes_entry_get_type (void);
_OSTREE_PUBLIC
OstreeCommitSizesEntry *ostree_commit_sizes_entry_new (const gchar *checksum,
OstreeObjectType objtype,
guint64 unpacked,
guint64 archived);
_OSTREE_PUBLIC
OstreeCommitSizesEntry *ostree_commit_sizes_entry_copy (const OstreeCommitSizesEntry *entry);
_OSTREE_PUBLIC
void ostree_commit_sizes_entry_free (OstreeCommitSizesEntry *entry);
_OSTREE_PUBLIC
gboolean ostree_commit_get_object_sizes (GVariant *commit_variant,
GPtrArray **out_sizes_entries,
GError **error);
_OSTREE_PUBLIC _OSTREE_PUBLIC
gboolean ostree_check_version (guint required_year, guint required_release); gboolean ostree_check_version (guint required_year, guint required_release);

View File

@ -548,14 +548,10 @@ append_expire_info (GString *output_buffer,
gint64 exp_timestamp, gint64 exp_timestamp,
gboolean expired) gboolean expired)
{ {
g_autoptr(GDateTime) date_time_utc = NULL;
g_autoptr(GDateTime) date_time_local = NULL;
g_autofree char *formatted_date_time = NULL;
if (line_prefix != NULL) if (line_prefix != NULL)
g_string_append (output_buffer, line_prefix); g_string_append (output_buffer, line_prefix);
date_time_utc = g_date_time_new_from_unix_utc (exp_timestamp); g_autoptr(GDateTime) date_time_utc = g_date_time_new_from_unix_utc (exp_timestamp);
if (date_time_utc == NULL) if (date_time_utc == NULL)
{ {
g_string_append_printf (output_buffer, g_string_append_printf (output_buffer,
@ -565,8 +561,8 @@ append_expire_info (GString *output_buffer,
return; return;
} }
date_time_local = g_date_time_to_local (date_time_utc); g_autoptr(GDateTime) date_time_local = g_date_time_to_local (date_time_utc);
formatted_date_time = g_date_time_format (date_time_local, "%c"); g_autofree char *formatted_date_time = g_date_time_format (date_time_local, "%c");
if (expired) if (expired)
{ {
@ -773,8 +769,58 @@ ostree_gpg_verify_result_require_valid_signature (OstreeGpgVerifyResult *result,
if (ostree_gpg_verify_result_count_valid (result) == 0) if (ostree_gpg_verify_result_count_valid (result) == 0)
{ {
g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_MISSING_KEY, /*
"GPG signatures found, but none are in trusted keyring"); * Join the description of each failed signature for the error message.
* Only one error code can be returned, so if there was more than one
* signature, use the error of the last one under the assumption that
* it's the most recent and hopefully most likely to be made with a
* valid key.
*/
gint code = OSTREE_GPG_ERROR_NO_SIGNATURE;
g_autoptr(GString) buffer = g_string_sized_new (256);
guint nsigs = ostree_gpg_verify_result_count_all (result);
if (nsigs == 0)
/* In case an empty result was passed in */
g_string_append (buffer, "No GPG signatures found");
else
{
for (int i = nsigs - 1; i >= 0; i--)
{
g_autoptr(GVariant) info = ostree_gpg_verify_result_get_all (result, i);
ostree_gpg_verify_result_describe_variant (info, buffer, "",
OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT);
if (i == nsigs - 1)
{
gboolean key_missing, key_revoked, key_expired, sig_expired;
g_variant_get_child (info, OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING,
"b", &key_missing);
g_variant_get_child (info, OSTREE_GPG_SIGNATURE_ATTR_KEY_REVOKED,
"b", &key_revoked);
g_variant_get_child (info, OSTREE_GPG_SIGNATURE_ATTR_KEY_EXPIRED,
"b", &key_expired);
g_variant_get_child (info, OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED,
"b", &sig_expired);
if (key_missing)
code = OSTREE_GPG_ERROR_MISSING_KEY;
else if (key_revoked)
code = OSTREE_GPG_ERROR_REVOKED_KEY;
else if (key_expired)
code = OSTREE_GPG_ERROR_EXPIRED_KEY;
else if (sig_expired)
code = OSTREE_GPG_ERROR_EXPIRED_SIGNATURE;
else
/* Assume any other issue is a bad signature */
code = OSTREE_GPG_ERROR_INVALID_SIGNATURE;
}
}
}
/* Strip any trailing newlines */
g_strchomp (buffer->str);
g_set_error_literal (error, OSTREE_GPG_ERROR, code, buffer->str);
return FALSE; return FALSE;
} }

View File

@ -159,6 +159,11 @@ gboolean ostree_gpg_verify_result_require_valid_signature (OstreeGpgVerifyResult
* @OSTREE_GPG_ERROR_NO_SIGNATURE: A signature was expected, but not found. * @OSTREE_GPG_ERROR_NO_SIGNATURE: A signature was expected, but not found.
* @OSTREE_GPG_ERROR_INVALID_SIGNATURE: A signature was malformed. * @OSTREE_GPG_ERROR_INVALID_SIGNATURE: A signature was malformed.
* @OSTREE_GPG_ERROR_MISSING_KEY: A signature was found, but was created with a key not in the configured keyrings. * @OSTREE_GPG_ERROR_MISSING_KEY: A signature was found, but was created with a key not in the configured keyrings.
* @OSTREE_GPG_ERROR_EXPIRED_SIGNATURE: A signature was expired. Since: 2020.1.
* @OSTREE_GPG_ERROR_EXPIRED_KEY: A signature was found, but the key used to
* sign it has expired. Since: 2020.1.
* @OSTREE_GPG_ERROR_REVOKED_KEY: A signature was found, but the key used to
* sign it has been revoked. Since: 2020.1.
* *
* Errors returned by signature creation and verification operations in OSTree. * Errors returned by signature creation and verification operations in OSTree.
* These may be returned by any API which creates or verifies signatures. * These may be returned by any API which creates or verifies signatures.
@ -169,6 +174,9 @@ typedef enum {
OSTREE_GPG_ERROR_NO_SIGNATURE = 0, OSTREE_GPG_ERROR_NO_SIGNATURE = 0,
OSTREE_GPG_ERROR_INVALID_SIGNATURE, OSTREE_GPG_ERROR_INVALID_SIGNATURE,
OSTREE_GPG_ERROR_MISSING_KEY, OSTREE_GPG_ERROR_MISSING_KEY,
OSTREE_GPG_ERROR_EXPIRED_SIGNATURE,
OSTREE_GPG_ERROR_EXPIRED_KEY,
OSTREE_GPG_ERROR_REVOKED_KEY,
} OstreeGpgError; } OstreeGpgError;
/** /**

View File

@ -28,6 +28,7 @@
#ifdef HAVE_LIBMOUNT #ifdef HAVE_LIBMOUNT
#include <libmount.h> #include <libmount.h>
#endif #endif
#include <sys/statvfs.h>
#include <stdbool.h> #include <stdbool.h>
#include "otutil.h" #include "otutil.h"
@ -189,8 +190,6 @@ _ostree_impl_system_generator (const char *ostree_cmdline,
"[Unit]\n" "[Unit]\n"
"Documentation=man:ostree(1)\n" "Documentation=man:ostree(1)\n"
"ConditionKernelCommandLine=!systemd.volatile\n" "ConditionKernelCommandLine=!systemd.volatile\n"
/* We need /sysroot mounted writable first */
"After=ostree-remount.service\n"
"Before=local-fs.target\n" "Before=local-fs.target\n"
"\n" "\n"
"[Mount]\n" "[Mount]\n"

View File

@ -68,6 +68,10 @@ _ostree_linuxfs_fd_alter_immutable_flag (int fd,
} }
else else
{ {
gboolean prev_immutable_state = (flags & EXT2_IMMUTABLE_FL) > 0;
if (prev_immutable_state == new_immutable_state)
return TRUE; /* Nothing to do */
if (new_immutable_state) if (new_immutable_state)
flags |= EXT2_IMMUTABLE_FL; flags |= EXT2_IMMUTABLE_FL;
else else

View File

@ -92,8 +92,8 @@ checkout_object_for_uncompressed_cache (OstreeRepo *self,
if (self->uncompressed_objects_dir_fd == -1) if (self->uncompressed_objects_dir_fd == -1)
{ {
if (!glnx_shutil_mkdir_p_at (self->repo_dir_fd, "uncompressed-objects-cache", 0755, if (!glnx_shutil_mkdir_p_at (self->repo_dir_fd, "uncompressed-objects-cache",
cancellable, error)) DEFAULT_DIRECTORY_MODE, cancellable, error))
return FALSE; return FALSE;
if (!glnx_opendirat (self->repo_dir_fd, "uncompressed-objects-cache", TRUE, if (!glnx_opendirat (self->repo_dir_fd, "uncompressed-objects-cache", TRUE,
&self->uncompressed_objects_dir_fd, &self->uncompressed_objects_dir_fd,

View File

@ -32,6 +32,10 @@
#include <glib/gprintf.h> #include <glib/gprintf.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <ext2fs/ext2_fs.h>
#ifdef HAVE_LINUX_FSVERITY_H
#include <linux/fsverity.h>
#endif
#include "otutil.h" #include "otutil.h"
#include "ostree.h" #include "ostree.h"
@ -168,6 +172,113 @@ ot_security_smack_reset_fd (int fd)
#endif #endif
} }
/* Wrapper around the fsverity ioctl, compressing the result to
* "success, unsupported or error". This is used for /boot where
* we enable verity if supported.
* */
gboolean
_ostree_tmpf_fsverity_core (GLnxTmpfile *tmpf,
_OstreeFeatureSupport fsverity_requested,
gboolean *supported,
GError **error)
{
/* Set this by default to simplify the code below */
if (supported)
*supported = FALSE;
if (fsverity_requested == _OSTREE_FEATURE_NO)
return TRUE;
#ifdef HAVE_LINUX_FSVERITY_H
GLNX_AUTO_PREFIX_ERROR ("fsverity", error);
/* fs-verity requires a read-only file descriptor */
if (!glnx_tmpfile_reopen_rdonly (tmpf, error))
return FALSE;
struct fsverity_enable_arg arg = { 0, };
arg.version = 1;
arg.hash_algorithm = FS_VERITY_HASH_ALG_SHA256; /* TODO configurable? */
arg.block_size = 4096; /* FIXME query */
arg.salt_size = 0; /* TODO store salt in ostree repo config */
arg.salt_ptr = 0;
arg.sig_size = 0; /* We don't currently expect use of in-kernel signature verification */
arg.sig_ptr = 0;
if (ioctl (tmpf->fd, FS_IOC_ENABLE_VERITY, &arg) < 0)
{
switch (errno)
{
case ENOTTY:
case EOPNOTSUPP:
return TRUE;
default:
return glnx_throw_errno_prefix (error, "ioctl(FS_IOC_ENABLE_VERITY)");
}
}
if (supported)
*supported = TRUE;
#endif
return TRUE;
}
/* Enable verity on a file, respecting the "wanted" and "supported" states.
* The main idea here is to optimize out pointlessly calling the ioctl()
* over and over in cases where it's not supported for the repo's filesystem,
* as well as to support "opportunistic" use (requested and if filesystem supports).
* */
gboolean
_ostree_tmpf_fsverity (OstreeRepo *self,
GLnxTmpfile *tmpf,
GError **error)
{
#ifdef HAVE_LINUX_FSVERITY_H
g_mutex_lock (&self->txn_lock);
_OstreeFeatureSupport fsverity_wanted = self->fs_verity_wanted;
_OstreeFeatureSupport fsverity_supported = self->fs_verity_supported;
g_mutex_unlock (&self->txn_lock);
switch (fsverity_wanted)
{
case _OSTREE_FEATURE_YES:
{
if (fsverity_supported == _OSTREE_FEATURE_NO)
return glnx_throw (error, "fsverity required but filesystem does not support it");
}
break;
case _OSTREE_FEATURE_MAYBE:
break;
case _OSTREE_FEATURE_NO:
return TRUE;
}
gboolean supported = FALSE;
if (!_ostree_tmpf_fsverity_core (tmpf, fsverity_wanted, &supported, error))
return FALSE;
if (!supported)
{
if (G_UNLIKELY (fsverity_wanted == _OSTREE_FEATURE_YES))
return glnx_throw (error, "fsverity required but filesystem does not support it");
/* If we got here, we must be trying "opportunistic" use of fs-verity */
g_assert_cmpint (fsverity_wanted, ==, _OSTREE_FEATURE_MAYBE);
g_mutex_lock (&self->txn_lock);
self->fs_verity_supported = _OSTREE_FEATURE_NO;
g_mutex_unlock (&self->txn_lock);
return TRUE;
}
g_mutex_lock (&self->txn_lock);
self->fs_verity_supported = _OSTREE_FEATURE_YES;
g_mutex_unlock (&self->txn_lock);
#else
g_assert_cmpint (self->fs_verity_wanted, !=, _OSTREE_FEATURE_YES);
#endif
return TRUE;
}
/* Given an O_TMPFILE regular file, link it into place. */ /* Given an O_TMPFILE regular file, link it into place. */
gboolean gboolean
_ostree_repo_commit_tmpf_final (OstreeRepo *self, _ostree_repo_commit_tmpf_final (OstreeRepo *self,
@ -185,6 +296,9 @@ _ostree_repo_commit_tmpf_final (OstreeRepo *self,
cancellable, error)) cancellable, error))
return FALSE; return FALSE;
if (!_ostree_tmpf_fsverity (self, tmpf, error))
return FALSE;
if (!glnx_link_tmpfile_at (tmpf, GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST, if (!glnx_link_tmpfile_at (tmpf, GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST,
dest_dfd, tmpbuf, error)) dest_dfd, tmpbuf, error))
return FALSE; return FALSE;
@ -322,16 +436,19 @@ commit_loose_regfile_object (OstreeRepo *self,
/* This is used by OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES */ /* This is used by OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES */
typedef struct typedef struct
{ {
OstreeObjectType objtype;
goffset unpacked; goffset unpacked;
goffset archived; goffset archived;
} OstreeContentSizeCacheEntry; } OstreeContentSizeCacheEntry;
static OstreeContentSizeCacheEntry * static OstreeContentSizeCacheEntry *
content_size_cache_entry_new (goffset unpacked, content_size_cache_entry_new (OstreeObjectType objtype,
goffset unpacked,
goffset archived) goffset archived)
{ {
OstreeContentSizeCacheEntry *entry = g_slice_new0 (OstreeContentSizeCacheEntry); OstreeContentSizeCacheEntry *entry = g_slice_new0 (OstreeContentSizeCacheEntry);
entry->objtype = objtype;
entry->unpacked = unpacked; entry->unpacked = unpacked;
entry->archived = archived; entry->archived = archived;
@ -345,19 +462,61 @@ content_size_cache_entry_free (gpointer entry)
g_slice_free (OstreeContentSizeCacheEntry, entry); g_slice_free (OstreeContentSizeCacheEntry, entry);
} }
void
_ostree_repo_setup_generate_sizes (OstreeRepo *self,
OstreeRepoCommitModifier *modifier)
{
if (modifier && modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES)
{
if (ostree_repo_get_mode (self) == OSTREE_REPO_MODE_ARCHIVE)
{
self->generate_sizes = TRUE;
/* Clear any stale data in the object sizes hash table */
if (self->object_sizes != NULL)
g_hash_table_remove_all (self->object_sizes);
}
else
g_debug ("Not generating sizes for non-archive repo");
}
}
static void static void
repo_store_size_entry (OstreeRepo *self, repo_ensure_size_entries (OstreeRepo *self)
const gchar *checksum,
goffset unpacked,
goffset archived)
{ {
if (G_UNLIKELY (self->object_sizes == NULL)) if (G_UNLIKELY (self->object_sizes == NULL))
self->object_sizes = g_hash_table_new_full (g_str_hash, g_str_equal, self->object_sizes = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, content_size_cache_entry_free); g_free, content_size_cache_entry_free);
}
static gboolean
repo_has_size_entry (OstreeRepo *self,
OstreeObjectType objtype,
const gchar *checksum)
{
/* Only file, dirtree and dirmeta objects appropriate for size metadata */
if (objtype > OSTREE_OBJECT_TYPE_DIR_META)
return TRUE;
repo_ensure_size_entries (self);
return (g_hash_table_lookup (self->object_sizes, checksum) != NULL);
}
static void
repo_store_size_entry (OstreeRepo *self,
OstreeObjectType objtype,
const gchar *checksum,
goffset unpacked,
goffset archived)
{
/* Only file, dirtree and dirmeta objects appropriate for size metadata */
if (objtype > OSTREE_OBJECT_TYPE_DIR_META)
return;
repo_ensure_size_entries (self);
g_hash_table_replace (self->object_sizes, g_hash_table_replace (self->object_sizes,
g_strdup (checksum), g_strdup (checksum),
content_size_cache_entry_new (unpacked, archived)); content_size_cache_entry_new (objtype, unpacked, archived));
} }
static int static int
@ -408,6 +567,7 @@ add_size_index_to_metadata (OstreeRepo *self,
g_hash_table_lookup (self->object_sizes, e_checksum); g_hash_table_lookup (self->object_sizes, e_checksum);
_ostree_write_varuint64 (buffer, e_size->archived); _ostree_write_varuint64 (buffer, e_size->archived);
_ostree_write_varuint64 (buffer, e_size->unpacked); _ostree_write_varuint64 (buffer, e_size->unpacked);
g_string_append_c (buffer, (gchar) e_size->objtype);
g_variant_builder_add (&index_builder, "@ay", g_variant_builder_add (&index_builder, "@ay",
ot_gvariant_new_bytearray ((guint8*)buffer->str, buffer->len)); ot_gvariant_new_bytearray ((guint8*)buffer->str, buffer->len));
@ -415,6 +575,9 @@ add_size_index_to_metadata (OstreeRepo *self,
g_variant_builder_add (builder, "{sv}", "ostree.sizes", g_variant_builder_add (builder, "{sv}", "ostree.sizes",
g_variant_builder_end (&index_builder)); g_variant_builder_end (&index_builder));
/* Clear the object sizes hash table for a subsequent commit. */
g_hash_table_remove_all (self->object_sizes);
} }
return g_variant_ref_sink (g_variant_builder_end (builder)); return g_variant_ref_sink (g_variant_builder_end (builder));
@ -956,7 +1119,6 @@ write_content_object (OstreeRepo *self,
g_auto(OtCleanupUnlinkat) tmp_unlinker = { commit_tmp_dfd (self), NULL }; g_auto(OtCleanupUnlinkat) tmp_unlinker = { commit_tmp_dfd (self), NULL };
g_auto(GLnxTmpfile) tmpf = { 0, }; g_auto(GLnxTmpfile) tmpf = { 0, };
goffset unpacked_size = 0; goffset unpacked_size = 0;
gboolean indexable = FALSE;
/* Is it a symlink physically? */ /* Is it a symlink physically? */
if (phys_object_is_symlink) if (phys_object_is_symlink)
{ {
@ -982,9 +1144,6 @@ write_content_object (OstreeRepo *self,
g_assert (repo_mode == OSTREE_REPO_MODE_ARCHIVE); g_assert (repo_mode == OSTREE_REPO_MODE_ARCHIVE);
if (self->generate_sizes)
indexable = TRUE;
if (!glnx_open_tmpfile_linkable_at (commit_tmp_dfd (self), ".", O_WRONLY|O_CLOEXEC, if (!glnx_open_tmpfile_linkable_at (commit_tmp_dfd (self), ".", O_WRONLY|O_CLOEXEC,
&tmpf, error)) &tmpf, error))
return FALSE; return FALSE;
@ -1013,6 +1172,11 @@ write_content_object (OstreeRepo *self,
unpacked_size = g_file_info_get_size (file_info); unpacked_size = g_file_info_get_size (file_info);
} }
else
{
/* For a symlink, the size is the length of the target */
unpacked_size = strlen (g_file_info_get_symlink_target (file_info));
}
if (!g_output_stream_flush (temp_out, cancellable, error)) if (!g_output_stream_flush (temp_out, cancellable, error))
return FALSE; return FALSE;
@ -1042,6 +1206,19 @@ write_content_object (OstreeRepo *self,
g_assert (actual_checksum != NULL); /* Pacify static analysis */ g_assert (actual_checksum != NULL); /* Pacify static analysis */
/* Update size metadata if configured and entry missing */
if (self->generate_sizes &&
!repo_has_size_entry (self, OSTREE_OBJECT_TYPE_FILE, actual_checksum))
{
struct stat stbuf;
if (!glnx_fstat (tmpf.fd, &stbuf, error))
return FALSE;
repo_store_size_entry (self, OSTREE_OBJECT_TYPE_FILE, actual_checksum,
unpacked_size, stbuf.st_size);
}
/* See whether or not we have the object, now that we know the /* See whether or not we have the object, now that we know the
* checksum. * checksum.
*/ */
@ -1107,17 +1284,6 @@ write_content_object (OstreeRepo *self,
} }
else else
{ {
/* Update size metadata if configured */
if (indexable && object_file_type == G_FILE_TYPE_REGULAR)
{
struct stat stbuf;
if (!glnx_fstat (tmpf.fd, &stbuf, error))
return FALSE;
repo_store_size_entry (self, actual_checksum, unpacked_size, stbuf.st_size);
}
/* Check if a file with the same payload is present in the repository, /* Check if a file with the same payload is present in the repository,
and in case try to reflink it */ and in case try to reflink it */
if (actual_payload_checksum && !_try_clone_from_payload_link (self, self, actual_payload_checksum, file_info, &tmpf, cancellable, error)) if (actual_payload_checksum && !_try_clone_from_payload_link (self, self, actual_payload_checksum, file_info, &tmpf, cancellable, error))
@ -1309,6 +1475,11 @@ write_metadata_object (OstreeRepo *self,
*/ */
if (have_obj) if (have_obj)
{ {
/* Update size metadata if needed */
if (self->generate_sizes &&
!repo_has_size_entry (self, objtype, actual_checksum))
repo_store_size_entry (self, objtype, actual_checksum, len, len);
g_mutex_lock (&self->txn_lock); g_mutex_lock (&self->txn_lock);
self->txn.stats.metadata_objects_total++; self->txn.stats.metadata_objects_total++;
g_mutex_unlock (&self->txn_lock); g_mutex_unlock (&self->txn_lock);
@ -1330,6 +1501,11 @@ write_metadata_object (OstreeRepo *self,
gsize len; gsize len;
const guint8 *bufp = g_bytes_get_data (buf, &len); const guint8 *bufp = g_bytes_get_data (buf, &len);
/* Update size metadata if needed */
if (self->generate_sizes &&
!repo_has_size_entry (self, objtype, actual_checksum))
repo_store_size_entry (self, objtype, actual_checksum, len, len);
/* Write the metadata to a temporary file */ /* Write the metadata to a temporary file */
g_auto(GLnxTmpfile) tmpf = { 0, }; g_auto(GLnxTmpfile) tmpf = { 0, };
if (!glnx_open_tmpfile_linkable_at (commit_tmp_dfd (self), ".", O_WRONLY|O_CLOEXEC, if (!glnx_open_tmpfile_linkable_at (commit_tmp_dfd (self), ".", O_WRONLY|O_CLOEXEC,
@ -2345,6 +2521,16 @@ ostree_repo_write_metadata (OstreeRepo *self,
return FALSE; return FALSE;
if (have_obj) if (have_obj)
{ {
/* Update size metadata if needed */
if (self->generate_sizes &&
!repo_has_size_entry (self, objtype, expected_checksum))
{
/* Make sure we have a fully serialized object */
g_autoptr(GVariant) trusted = g_variant_get_normal_form (object);
gsize size = g_variant_get_size (trusted);
repo_store_size_entry (self, objtype, expected_checksum, size, size);
}
if (out_csum) if (out_csum)
*out_csum = ostree_checksum_to_bytes (expected_checksum); *out_csum = ostree_checksum_to_bytes (expected_checksum);
return TRUE; return TRUE;
@ -2620,8 +2806,11 @@ ostree_repo_write_content (OstreeRepo *self,
{ {
/* First, if we have an expected checksum, see if we already have this /* First, if we have an expected checksum, see if we already have this
* object. This mirrors the same logic in ostree_repo_write_metadata(). * object. This mirrors the same logic in ostree_repo_write_metadata().
*
* If size metadata is needed, fall through to write_content_object()
* where the entries are made.
*/ */
if (expected_checksum) if (expected_checksum && !self->generate_sizes)
{ {
gboolean have_obj; gboolean have_obj;
if (!_ostree_repo_has_loose_object (self, expected_checksum, if (!_ostree_repo_has_loose_object (self, expected_checksum,
@ -3848,8 +4037,7 @@ ostree_repo_write_directory_to_mtree (OstreeRepo *self,
} }
else else
{ {
if (modifier && modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES) _ostree_repo_setup_generate_sizes (self, modifier);
self->generate_sizes = TRUE;
g_autoptr(GPtrArray) path = g_ptr_array_new (); g_autoptr(GPtrArray) path = g_ptr_array_new ();
if (!write_directory_to_mtree_internal (self, dir, mtree, modifier, path, if (!write_directory_to_mtree_internal (self, dir, mtree, modifier, path,
@ -3883,8 +4071,7 @@ ostree_repo_write_dfd_to_mtree (OstreeRepo *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
if (modifier && modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES) _ostree_repo_setup_generate_sizes (self, modifier);
self->generate_sizes = TRUE;
g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
if (!glnx_dirfd_iterator_init_at (dfd, path, FALSE, &dfd_iter, error)) if (!glnx_dirfd_iterator_init_at (dfd, path, FALSE, &dfd_iter, error))

View File

@ -844,6 +844,8 @@ ostree_repo_import_archive_to_mtree (OstreeRepo *self,
.modifier = modifier .modifier = modifier
}; };
_ostree_repo_setup_generate_sizes (self, modifier);
while (TRUE) while (TRUE)
{ {
int r = archive_read_next_header (a, &aictx.entry); int r = archive_read_next_header (a, &aictx.entry);

View File

@ -22,6 +22,7 @@
#pragma once #pragma once
#include <sys/statvfs.h> #include <sys/statvfs.h>
#include "config.h"
#include "otutil.h" #include "otutil.h"
#include "ostree-ref.h" #include "ostree-ref.h"
#include "ostree-repo.h" #include "ostree-repo.h"
@ -31,8 +32,6 @@ G_BEGIN_DECLS
#define OSTREE_DELTAPART_VERSION (0) #define OSTREE_DELTAPART_VERSION (0)
#define _OSTREE_OBJECT_SIZES_ENTRY_SIGNATURE "ay"
#define _OSTREE_SUMMARY_CACHE_DIR "summaries" #define _OSTREE_SUMMARY_CACHE_DIR "summaries"
#define _OSTREE_CACHE_DIR "cache" #define _OSTREE_CACHE_DIR "cache"
@ -97,6 +96,12 @@ typedef struct {
fsblkcnt_t max_blocks; fsblkcnt_t max_blocks;
} OstreeRepoTxn; } OstreeRepoTxn;
typedef enum {
_OSTREE_FEATURE_NO,
_OSTREE_FEATURE_MAYBE,
_OSTREE_FEATURE_YES,
} _OstreeFeatureSupport;
/** /**
* OstreeRepo: * OstreeRepo:
* *
@ -127,6 +132,8 @@ struct OstreeRepo {
GMutex txn_lock; GMutex txn_lock;
OstreeRepoTxn txn; OstreeRepoTxn txn;
gboolean txn_locked; gboolean txn_locked;
_OstreeFeatureSupport fs_verity_wanted;
_OstreeFeatureSupport fs_verity_supported;
GMutex cache_lock; GMutex cache_lock;
guint dirmeta_cache_refcount; guint dirmeta_cache_refcount;
@ -143,6 +150,14 @@ struct OstreeRepo {
guint zlib_compression_level; guint zlib_compression_level;
GHashTable *loose_object_devino_hash; GHashTable *loose_object_devino_hash;
GHashTable *updated_uncompressed_dirs; GHashTable *updated_uncompressed_dirs;
/* FIXME: The object sizes hash table is really per-commit state, not repo
* state. Using a single table for the repo means that commits cannot be
* built simultaneously if they're adding size information. This data should
* probably be in OstreeMutableTree, but that's gone by the time the actual
* commit is constructed. At that point the only commit state is in the root
* OstreeRepoFile.
*/
GHashTable *object_sizes; GHashTable *object_sizes;
/* Cache the repo's device/inode to use for comparisons elsewhere */ /* Cache the repo's device/inode to use for comparisons elsewhere */
@ -329,6 +344,10 @@ _ostree_repo_commit_modifier_apply (OstreeRepo *self,
GFileInfo *file_info, GFileInfo *file_info,
GFileInfo **out_modified_info); GFileInfo **out_modified_info);
void
_ostree_repo_setup_generate_sizes (OstreeRepo *self,
OstreeRepoCommitModifier *modifier);
gboolean gboolean
_ostree_repo_remote_name_is_file (const char *remote_name); _ostree_repo_remote_name_is_file (const char *remote_name);
@ -471,4 +490,15 @@ OstreeRepoAutoLock * _ostree_repo_auto_lock_push (OstreeRepo *self,
void _ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *lock); void _ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *lock);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoAutoLock, _ostree_repo_auto_lock_cleanup) G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoAutoLock, _ostree_repo_auto_lock_cleanup)
gboolean
_ostree_tmpf_fsverity_core (GLnxTmpfile *tmpf,
_OstreeFeatureSupport fsverity_requested,
gboolean *supported,
GError **error);
gboolean
_ostree_tmpf_fsverity (OstreeRepo *self,
GLnxTmpfile *tmpf,
GError **error);
G_END_DECLS G_END_DECLS

View File

@ -2925,7 +2925,7 @@ _ostree_repo_cache_summary (OstreeRepo *self,
if (self->cache_dir_fd == -1) if (self->cache_dir_fd == -1)
return TRUE; return TRUE;
if (!glnx_shutil_mkdir_p_at (self->cache_dir_fd, _OSTREE_SUMMARY_CACHE_DIR, 0775, cancellable, error)) if (!glnx_shutil_mkdir_p_at (self->cache_dir_fd, _OSTREE_SUMMARY_CACHE_DIR, DEFAULT_DIRECTORY_MODE, cancellable, error))
return FALSE; return FALSE;
const char *summary_cache_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote); const char *summary_cache_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote);

View File

@ -1181,7 +1181,7 @@ _ostree_repo_write_ref (OstreeRepo *self,
char *parent = strdupa (ref->ref_name); char *parent = strdupa (ref->ref_name);
parent[lastslash - ref->ref_name] = '\0'; parent[lastslash - ref->ref_name] = '\0';
if (!glnx_shutil_mkdir_p_at (dfd, parent, 0755, cancellable, error)) if (!glnx_shutil_mkdir_p_at (dfd, parent, DEFAULT_DIRECTORY_MODE, cancellable, error))
return FALSE; return FALSE;
} }

View File

@ -1427,7 +1427,7 @@ ostree_repo_static_delta_generate (OstreeRepo *self,
g_autofree char *dnbuf = g_strdup (descriptor_relpath); g_autofree char *dnbuf = g_strdup (descriptor_relpath);
const char *dn = dirname (dnbuf); const char *dn = dirname (dnbuf);
if (!glnx_shutil_mkdir_p_at (self->repo_dir_fd, dn, 0755, cancellable, error)) if (!glnx_shutil_mkdir_p_at (self->repo_dir_fd, dn, DEFAULT_DIRECTORY_MODE, cancellable, error))
goto out; goto out;
if (!glnx_opendirat (self->repo_dir_fd, dn, TRUE, &descriptor_dfd, error)) if (!glnx_opendirat (self->repo_dir_fd, dn, TRUE, &descriptor_dfd, error))
goto out; goto out;

View File

@ -31,6 +31,7 @@
#include "libglnx.h" #include "libglnx.h"
#include "otutil.h" #include "otutil.h"
#include <glnx-console.h> #include <glnx-console.h>
#include <linux/magic.h>
#include "ostree-core-private.h" #include "ostree-core-private.h"
#include "ostree-sysroot-private.h" #include "ostree-sysroot-private.h"
@ -47,6 +48,7 @@
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include <sys/file.h> #include <sys/file.h>
#include <sys/statvfs.h> #include <sys/statvfs.h>
#include <sys/statfs.h>
#define REPO_LOCK_DISABLED (-2) #define REPO_LOCK_DISABLED (-2)
#define REPO_LOCK_BLOCKING (-1) #define REPO_LOCK_BLOCKING (-1)
@ -357,7 +359,7 @@ push_repo_lock (OstreeRepo *self,
g_debug ("Opening repo lock file"); g_debug ("Opening repo lock file");
lock->fd = TEMP_FAILURE_RETRY (openat (self->repo_dir_fd, ".lock", lock->fd = TEMP_FAILURE_RETRY (openat (self->repo_dir_fd, ".lock",
O_CREAT | O_RDWR | O_CLOEXEC, O_CREAT | O_RDWR | O_CLOEXEC,
0600)); DEFAULT_REGFILE_MODE));
if (lock->fd < 0) if (lock->fd < 0)
{ {
free_repo_lock (lock); free_repo_lock (lock);
@ -2489,7 +2491,7 @@ repo_create_at_internal (int dfd,
} }
} }
if (mkdirat (dfd, path, 0755) != 0) if (mkdirat (dfd, path, DEFAULT_DIRECTORY_MODE) != 0)
{ {
if (G_UNLIKELY (errno != EEXIST)) if (G_UNLIKELY (errno != EEXIST))
return glnx_throw_errno_prefix (error, "mkdirat"); return glnx_throw_errno_prefix (error, "mkdirat");
@ -2527,7 +2529,7 @@ repo_create_at_internal (int dfd,
for (guint i = 0; i < G_N_ELEMENTS (state_dirs); i++) for (guint i = 0; i < G_N_ELEMENTS (state_dirs); i++)
{ {
const char *elt = state_dirs[i]; const char *elt = state_dirs[i];
if (mkdirat (repo_dfd, elt, 0755) == -1) if (mkdirat (repo_dfd, elt, DEFAULT_DIRECTORY_MODE) == -1)
{ {
if (G_UNLIKELY (errno != EEXIST)) if (G_UNLIKELY (errno != EEXIST))
return glnx_throw_errno_prefix (error, "mkdirat"); return glnx_throw_errno_prefix (error, "mkdirat");
@ -3033,6 +3035,34 @@ reload_core_config (OstreeRepo *self,
} }
} }
/* Currently experimental */
static const char fsverity_key[] = "ex-fsverity";
self->fs_verity_wanted = _OSTREE_FEATURE_NO;
#ifdef HAVE_LINUX_FSVERITY_H
self->fs_verity_supported = _OSTREE_FEATURE_MAYBE;
#else
self->fs_verity_supported = _OSTREE_FEATURE_NO;
#endif
gboolean fsverity_required = FALSE;
if (!ot_keyfile_get_boolean_with_default (self->config, fsverity_key, "required",
FALSE, &fsverity_required, error))
return FALSE;
if (fsverity_required)
{
self->fs_verity_wanted = _OSTREE_FEATURE_YES;
if (self->fs_verity_supported == _OSTREE_FEATURE_NO)
return glnx_throw (error, "fsverity required, but libostree compiled without support");
}
else
{
gboolean fsverity_opportunistic = FALSE;
if (!ot_keyfile_get_boolean_with_default (self->config, fsverity_key, "opportunistic",
FALSE, &fsverity_opportunistic, error))
return FALSE;
if (fsverity_opportunistic)
self->fs_verity_wanted = _OSTREE_FEATURE_MAYBE;
}
{ {
g_clear_pointer (&self->collection_id, g_free); g_clear_pointer (&self->collection_id, g_free);
if (!ot_keyfile_get_value_with_default (self->config, "core", "collection-id", if (!ot_keyfile_get_value_with_default (self->config, "core", "collection-id",
@ -3295,7 +3325,7 @@ ostree_repo_open (OstreeRepo *self,
* *
* https://github.com/ostreedev/ostree/issues/1018 * https://github.com/ostreedev/ostree/issues/1018
*/ */
if (mkdirat (self->repo_dir_fd, "tmp", 0755) == -1) if (mkdirat (self->repo_dir_fd, "tmp", DEFAULT_DIRECTORY_MODE) == -1)
{ {
if (G_UNLIKELY (errno != EEXIST)) if (G_UNLIKELY (errno != EEXIST))
return glnx_throw_errno_prefix (error, "mkdir(tmp)"); return glnx_throw_errno_prefix (error, "mkdir(tmp)");
@ -3307,7 +3337,7 @@ ostree_repo_open (OstreeRepo *self,
if (self->writable) if (self->writable)
{ {
if (!glnx_shutil_mkdir_p_at (self->tmp_dir_fd, _OSTREE_CACHE_DIR, 0775, cancellable, error)) if (!glnx_shutil_mkdir_p_at (self->tmp_dir_fd, _OSTREE_CACHE_DIR, DEFAULT_DIRECTORY_MODE, cancellable, error))
return FALSE; return FALSE;
if (!glnx_opendirat (self->tmp_dir_fd, _OSTREE_CACHE_DIR, TRUE, &self->cache_dir_fd, error)) if (!glnx_opendirat (self->tmp_dir_fd, _OSTREE_CACHE_DIR, TRUE, &self->cache_dir_fd, error))
@ -6099,7 +6129,7 @@ _ostree_repo_allocate_tmpdir (int tmpdir_dfd,
{ {
g_auto(GLnxTmpDir) new_tmpdir = { 0, }; g_auto(GLnxTmpDir) new_tmpdir = { 0, };
/* No existing tmpdir found, create a new */ /* No existing tmpdir found, create a new */
if (!glnx_mkdtempat (tmpdir_dfd, tmpdir_name_template, 0755, if (!glnx_mkdtempat (tmpdir_dfd, tmpdir_name_template, DEFAULT_DIRECTORY_MODE,
&new_tmpdir, error)) &new_tmpdir, error))
return FALSE; return FALSE;

View File

@ -455,6 +455,9 @@ ostree_sysroot_cleanup_prune_repo (OstreeSysroot *sysroot,
OstreeRepo *repo = ostree_sysroot_repo (sysroot); OstreeRepo *repo = ostree_sysroot_repo (sysroot);
const guint depth = 0; /* Historical default */ const guint depth = 0; /* Historical default */
if (!_ostree_sysroot_ensure_writable (sysroot, error))
return FALSE;
/* Hold an exclusive lock by default across gathering refs and doing /* Hold an exclusive lock by default across gathering refs and doing
* the prune. * the prune.
*/ */
@ -535,7 +538,10 @@ _ostree_sysroot_cleanup_internal (OstreeSysroot *self,
GError **error) GError **error)
{ {
g_return_val_if_fail (OSTREE_IS_SYSROOT (self), FALSE); g_return_val_if_fail (OSTREE_IS_SYSROOT (self), FALSE);
g_return_val_if_fail (self->loaded, FALSE); g_return_val_if_fail (self->loadstate == OSTREE_SYSROOT_LOAD_STATE_LOADED, FALSE);
if (!_ostree_sysroot_ensure_writable (self, error))
return FALSE;
if (!cleanup_other_bootversions (self, cancellable, error)) if (!cleanup_other_bootversions (self, cancellable, error))
return glnx_prefix_error (error, "Cleaning bootversions"); return glnx_prefix_error (error, "Cleaning bootversions");

View File

@ -41,6 +41,7 @@
#include "otutil.h" #include "otutil.h"
#include "ostree.h" #include "ostree.h"
#include "ostree-repo-private.h"
#include "ostree-sysroot-private.h" #include "ostree-sysroot-private.h"
#include "ostree-sepolicy-private.h" #include "ostree-sepolicy-private.h"
#include "ostree-bootloader-zipl.h" #include "ostree-bootloader-zipl.h"
@ -56,6 +57,9 @@
#define OSTREE_DEPLOYMENT_FINALIZING_ID SD_ID128_MAKE(e8,64,6c,d6,3d,ff,46,25,b7,79,09,a8,e7,a4,09,94) #define OSTREE_DEPLOYMENT_FINALIZING_ID SD_ID128_MAKE(e8,64,6c,d6,3d,ff,46,25,b7,79,09,a8,e7,a4,09,94)
#endif #endif
static gboolean
is_ro_mount (const char *path);
/* /*
* Like symlinkat() but overwrites (atomically) an existing * Like symlinkat() but overwrites (atomically) an existing
* symlink. * symlink.
@ -101,7 +105,8 @@ sysroot_flags_to_copy_flags (GLnxFileCopyFlags defaults,
* hardlink if we're on the same partition. * hardlink if we're on the same partition.
*/ */
static gboolean static gboolean
install_into_boot (OstreeSePolicy *sepolicy, install_into_boot (OstreeRepo *repo,
OstreeSePolicy *sepolicy,
int src_dfd, int src_dfd,
const char *src_subpath, const char *src_subpath,
int dest_dfd, int dest_dfd,
@ -110,10 +115,20 @@ install_into_boot (OstreeSePolicy *sepolicy,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
if (linkat (src_dfd, src_subpath, dest_dfd, dest_subpath, 0) != 0) if (linkat (src_dfd, src_subpath, dest_dfd, dest_subpath, 0) == 0)
{ return TRUE; /* Note early return */
if (G_IN_SET (errno, EMLINK, EXDEV)) if (!G_IN_SET (errno, EMLINK, EXDEV))
{ return glnx_throw_errno_prefix (error, "linkat(%s)", dest_subpath);
/* Otherwise, copy */
struct stat src_stbuf;
if (!glnx_fstatat (src_dfd, src_subpath, &src_stbuf, AT_SYMLINK_NOFOLLOW, error))
return FALSE;
glnx_autofd int src_fd = -1;
if (!glnx_openat_rdonly (src_dfd, src_subpath, FALSE, &src_fd, error))
return FALSE;
/* Be sure we relabel when copying the kernel, as in current /* Be sure we relabel when copying the kernel, as in current
* e.g. Fedora it might be labeled module_object_t or usr_t, * e.g. Fedora it might be labeled module_object_t or usr_t,
* but policy may not allow other processes to read from that * but policy may not allow other processes to read from that
@ -129,13 +144,38 @@ install_into_boot (OstreeSePolicy *sepolicy,
boot_path, S_IFREG | 0644, boot_path, S_IFREG | 0644,
error)) error))
return FALSE; return FALSE;
return glnx_file_copy_at (src_dfd, src_subpath, NULL, dest_dfd, dest_subpath,
GLNX_FILE_COPY_NOXATTRS | GLNX_FILE_COPY_DATASYNC, g_auto(GLnxTmpfile) tmp_dest = { 0, };
cancellable, error); if (!glnx_open_tmpfile_linkable_at (dest_dfd, ".", O_WRONLY | O_CLOEXEC,
} &tmp_dest, error))
else return FALSE;
return glnx_throw_errno_prefix (error, "linkat(%s)", dest_subpath);
} if (glnx_regfile_copy_bytes (src_fd, tmp_dest.fd, (off_t) -1) < 0)
return glnx_throw_errno_prefix (error, "regfile copy");
/* Kernel data should always be root-owned */
if (fchown (tmp_dest.fd, src_stbuf.st_uid, src_stbuf.st_gid) != 0)
return glnx_throw_errno_prefix (error, "fchown");
if (fchmod (tmp_dest.fd, src_stbuf.st_mode & 07777) != 0)
return glnx_throw_errno_prefix (error, "fchmod");
if (fdatasync (tmp_dest.fd) < 0)
return glnx_throw_errno_prefix (error, "fdatasync");
/* Today we don't have a config flag to *require* verity on /boot,
* and at least for Fedora CoreOS we're not likely to do fsverity on
* /boot soon due to wanting to support mounting it from old Linux
* kernels. So change "required" to "maybe".
*/
_OstreeFeatureSupport boot_verity = _OSTREE_FEATURE_NO;
if (repo->fs_verity_wanted != _OSTREE_FEATURE_NO)
boot_verity = _OSTREE_FEATURE_MAYBE;
if (!_ostree_tmpf_fsverity_core (&tmp_dest, boot_verity, NULL, error))
return FALSE;
if (!glnx_link_tmpfile_at (&tmp_dest, GLNX_LINK_TMPFILE_NOREPLACE, dest_dfd, dest_subpath, error))
return FALSE;
return TRUE; return TRUE;
} }
@ -806,6 +846,9 @@ write_origin_file_internal (OstreeSysroot *sysroot,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
if (!_ostree_sysroot_ensure_writable (sysroot, error))
return FALSE;
GLNX_AUTO_PREFIX_ERROR ("Writing out origin file", error); GLNX_AUTO_PREFIX_ERROR ("Writing out origin file", error);
GKeyFile *origin = GKeyFile *origin =
new_origin ? new_origin : ostree_deployment_get_origin (deployment); new_origin ? new_origin : ostree_deployment_get_origin (deployment);
@ -1660,7 +1703,7 @@ install_deployment_kernel (OstreeSysroot *sysroot,
return FALSE; return FALSE;
if (errno == ENOENT) if (errno == ENOENT)
{ {
if (!install_into_boot (sepolicy, kernel_layout->boot_dfd, kernel_layout->kernel_srcpath, if (!install_into_boot (repo, sepolicy, kernel_layout->boot_dfd, kernel_layout->kernel_srcpath,
bootcsum_dfd, kernel_layout->kernel_namever, bootcsum_dfd, kernel_layout->kernel_namever,
sysroot->debug_flags, sysroot->debug_flags,
cancellable, error)) cancellable, error))
@ -1677,7 +1720,7 @@ install_deployment_kernel (OstreeSysroot *sysroot,
return FALSE; return FALSE;
if (errno == ENOENT) if (errno == ENOENT)
{ {
if (!install_into_boot (sepolicy, kernel_layout->boot_dfd, kernel_layout->initramfs_srcpath, if (!install_into_boot (repo, sepolicy, kernel_layout->boot_dfd, kernel_layout->initramfs_srcpath,
bootcsum_dfd, kernel_layout->initramfs_namever, bootcsum_dfd, kernel_layout->initramfs_namever,
sysroot->debug_flags, sysroot->debug_flags,
cancellable, error)) cancellable, error))
@ -1692,7 +1735,7 @@ install_deployment_kernel (OstreeSysroot *sysroot,
return FALSE; return FALSE;
if (errno == ENOENT) if (errno == ENOENT)
{ {
if (!install_into_boot (sepolicy, kernel_layout->boot_dfd, kernel_layout->devicetree_srcpath, if (!install_into_boot (repo, sepolicy, kernel_layout->boot_dfd, kernel_layout->devicetree_srcpath,
bootcsum_dfd, kernel_layout->devicetree_namever, bootcsum_dfd, kernel_layout->devicetree_namever,
sysroot->debug_flags, sysroot->debug_flags,
cancellable, error)) cancellable, error))
@ -1706,7 +1749,7 @@ install_deployment_kernel (OstreeSysroot *sysroot,
return FALSE; return FALSE;
if (errno == ENOENT) if (errno == ENOENT)
{ {
if (!install_into_boot (sepolicy, kernel_layout->boot_dfd, kernel_layout->kernel_hmac_srcpath, if (!install_into_boot (repo, sepolicy, kernel_layout->boot_dfd, kernel_layout->kernel_hmac_srcpath,
bootcsum_dfd, kernel_layout->kernel_hmac_namever, bootcsum_dfd, kernel_layout->kernel_hmac_namever,
sysroot->debug_flags, sysroot->debug_flags,
cancellable, error)) cancellable, error))
@ -2217,7 +2260,10 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
g_assert (self->loaded); g_assert (self->loadstate == OSTREE_SYSROOT_LOAD_STATE_LOADED);
if (!_ostree_sysroot_ensure_writable (self, error))
return FALSE;
/* Dealing with the staged deployment is quite tricky here. This function is /* Dealing with the staged deployment is quite tricky here. This function is
* primarily concerned with writing out "finalized" deployments which have * primarily concerned with writing out "finalized" deployments which have
@ -2374,7 +2420,6 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self,
if (boot_was_ro_mount) if (boot_was_ro_mount)
{ {
/* TODO: Use new mount namespace. https://github.com/ostreedev/ostree/issues/1265 */
if (mount ("/boot", "/boot", NULL, MS_REMOUNT | MS_SILENT, NULL) < 0) if (mount ("/boot", "/boot", NULL, MS_REMOUNT | MS_SILENT, NULL) < 0)
return glnx_throw_errno_prefix (error, "Remounting /boot read-write"); return glnx_throw_errno_prefix (error, "Remounting /boot read-write");
} }
@ -2408,8 +2453,10 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self,
/* Note equivalent of try/finally here */ /* Note equivalent of try/finally here */
gboolean success = write_deployments_bootswap (self, new_deployments, opts, bootloader, gboolean success = write_deployments_bootswap (self, new_deployments, opts, bootloader,
&syncstats, cancellable, error); &syncstats, cancellable, error);
/* Below here don't set GError until the if (!success) check */ /* Below here don't set GError until the if (!success) check.
if (boot_was_ro_mount) * Note we only bother remounting if a mount namespace isn't in use.
* */
if (boot_was_ro_mount && !self->mount_namespace_in_use)
{ {
if (mount ("/boot", "/boot", NULL, MS_REMOUNT | MS_RDONLY | MS_SILENT, NULL) < 0) if (mount ("/boot", "/boot", NULL, MS_REMOUNT | MS_RDONLY | MS_SILENT, NULL) < 0)
{ {
@ -2716,6 +2763,9 @@ ostree_sysroot_deploy_tree (OstreeSysroot *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
if (!_ostree_sysroot_ensure_writable (self, error))
return FALSE;
g_autoptr(OstreeDeployment) deployment = NULL; g_autoptr(OstreeDeployment) deployment = NULL;
if (!sysroot_initialize_deployment (self, osname, revision, origin, override_kernel_argv, if (!sysroot_initialize_deployment (self, osname, revision, origin, override_kernel_argv,
&deployment, cancellable, error)) &deployment, cancellable, error))
@ -2817,6 +2867,9 @@ ostree_sysroot_stage_tree (OstreeSysroot *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
if (!_ostree_sysroot_ensure_writable (self, error))
return FALSE;
OstreeDeployment *booted_deployment = ostree_sysroot_get_booted_deployment (self); OstreeDeployment *booted_deployment = ostree_sysroot_get_booted_deployment (self);
if (booted_deployment == NULL) if (booted_deployment == NULL)
return glnx_throw (error, "Cannot stage a deployment when not currently booted into an OSTree system"); return glnx_throw (error, "Cannot stage a deployment when not currently booted into an OSTree system");
@ -3043,6 +3096,9 @@ ostree_sysroot_deployment_set_kargs (OstreeSysroot *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
if (!_ostree_sysroot_ensure_writable (self, error))
return FALSE;
/* For now; instead of this do a redeployment */ /* For now; instead of this do a redeployment */
g_assert (!ostree_deployment_is_staged (deployment)); g_assert (!ostree_deployment_is_staged (deployment));
@ -3090,6 +3146,8 @@ ostree_sysroot_deployment_set_mutable (OstreeSysroot *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
if (!_ostree_sysroot_ensure_writable (self, error))
return FALSE;
if (g_cancellable_set_error_if_cancelled (cancellable, error)) if (g_cancellable_set_error_if_cancelled (cancellable, error))
return FALSE; return FALSE;

View File

@ -40,6 +40,12 @@ typedef enum {
OSTREE_SYSROOT_DEBUG_TEST_STAGED_PATH = 1 << 3, OSTREE_SYSROOT_DEBUG_TEST_STAGED_PATH = 1 << 3,
} OstreeSysrootDebugFlags; } OstreeSysrootDebugFlags;
typedef enum {
OSTREE_SYSROOT_LOAD_STATE_NONE, /* ostree_sysroot_new() was called */
OSTREE_SYSROOT_LOAD_STATE_INIT, /* We've loaded basic sysroot state and have an fd */
OSTREE_SYSROOT_LOAD_STATE_LOADED, /* We've loaded all of the deployments */
} OstreeSysrootLoadState;
/** /**
* OstreeSysroot: * OstreeSysroot:
* Internal struct * Internal struct
@ -51,7 +57,8 @@ struct OstreeSysroot {
int sysroot_fd; int sysroot_fd;
GLnxLockFile lock; GLnxLockFile lock;
gboolean loaded; OstreeSysrootLoadState loadstate;
gboolean mount_namespace_in_use; /* TRUE if caller has told us they used CLONE_NEWNS */
gboolean root_is_ostree_booted; /* TRUE if sysroot is / and we are booted via ostree */ gboolean root_is_ostree_booted; /* TRUE if sysroot is / and we are booted via ostree */
/* The device/inode for /, used to detect booted deployment */ /* The device/inode for /, used to detect booted deployment */
dev_t root_device; dev_t root_device;
@ -79,6 +86,10 @@ struct OstreeSysroot {
#define _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_DIR "/run/ostree/deployment-state/" #define _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_DIR "/run/ostree/deployment-state/"
#define _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_FLAG_DEVELOPMENT "unlocked-development" #define _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_FLAG_DEVELOPMENT "unlocked-development"
gboolean
_ostree_sysroot_ensure_writable (OstreeSysroot *self,
GError **error);
void void
_ostree_sysroot_emit_journal_msg (OstreeSysroot *self, _ostree_sysroot_emit_journal_msg (OstreeSysroot *self,
const char *msg); const char *msg);

View File

@ -226,6 +226,33 @@ ostree_sysroot_new_default (void)
return ostree_sysroot_new (NULL); return ostree_sysroot_new (NULL);
} }
/**
* ostree_sysroot_set_mount_namespace_in_use:
*
* If this function is invoked, then libostree will assume that
* a private Linux mount namespace has been created by the process.
* The primary use case for this is to have e.g. /sysroot mounted
* read-only by default.
*
* If this function has been called, then when a function which requires
* writable access is invoked, libostree will automatically remount as writable
* any mount points on which it operates. This currently is just `/sysroot` and
* `/boot`.
*
* If you invoke this function, it must be before ostree_sysroot_load(); it may
* be invoked before or after ostree_sysroot_initialize().
*
* Since: 2020.1
*/
void
ostree_sysroot_set_mount_namespace_in_use (OstreeSysroot *self)
{
/* Must be before we're loaded, as otherwise we'd have to close/reopen all our
fds, e.g. the repo */
g_return_if_fail (self->loadstate < OSTREE_SYSROOT_LOAD_STATE_LOADED);
self->mount_namespace_in_use = TRUE;
}
/** /**
* ostree_sysroot_get_path: * ostree_sysroot_get_path:
* @self: * @self:
@ -238,6 +265,7 @@ ostree_sysroot_get_path (OstreeSysroot *self)
return self->path; return self->path;
} }
/* Open a directory file descriptor for the sysroot if we haven't yet */
static gboolean static gboolean
ensure_sysroot_fd (OstreeSysroot *self, ensure_sysroot_fd (OstreeSysroot *self,
GError **error) GError **error)
@ -251,13 +279,51 @@ ensure_sysroot_fd (OstreeSysroot *self,
return TRUE; return TRUE;
} }
/* Remount /sysroot read-write if necessary */
gboolean
_ostree_sysroot_ensure_writable (OstreeSysroot *self,
GError **error)
{
/* Do nothing if no mount namespace is in use */
if (!self->mount_namespace_in_use)
return TRUE;
/* If a mount namespace is in use, ensure we're initialized */
if (!ostree_sysroot_initialize (self, error))
return FALSE;
/* If we aren't operating on a booted system, then we don't
* do anything with mounts.
*/
if (!self->root_is_ostree_booted)
return TRUE;
/* Check if /sysroot is a read-only mountpoint */
struct statvfs stvfsbuf;
if (statvfs ("/sysroot", &stvfsbuf) < 0)
return glnx_throw_errno_prefix (error, "fstatvfs(/sysroot)");
if ((stvfsbuf.f_flag & ST_RDONLY) == 0)
return TRUE;
/* OK, let's remount writable. */
if (mount ("/sysroot", "/sysroot", NULL, MS_REMOUNT | MS_RELATIME, "") < 0)
return glnx_throw_errno_prefix (error, "Remounting /sysroot read-write");
/* Reopen our fd */
glnx_close_fd (&self->sysroot_fd);
if (!ensure_sysroot_fd (self, error))
return FALSE;
return TRUE;
}
/** /**
* ostree_sysroot_get_fd: * ostree_sysroot_get_fd:
* @self: Sysroot * @self: Sysroot
* *
* Access a file descriptor that refers to the root directory of this * Access a file descriptor that refers to the root directory of this sysroot.
* sysroot. ostree_sysroot_load() must have been invoked prior to * ostree_sysroot_initialize() (or ostree_sysroot_load()) must have been invoked
* calling this function. * prior to calling this function.
* *
* Returns: A file descriptor valid for the lifetime of @self * Returns: A file descriptor valid for the lifetime of @self
*/ */
@ -268,6 +334,22 @@ ostree_sysroot_get_fd (OstreeSysroot *self)
return self->sysroot_fd; return self->sysroot_fd;
} }
/**
* ostree_sysroot_is_booted:
* @self: Sysroot
*
* Can only be invoked after `ostree_sysroot_initialize()`.
*
* Returns: %TRUE iff the sysroot points to a booted deployment
* Since: 2020.1
*/
gboolean
ostree_sysroot_is_booted (OstreeSysroot *self)
{
g_return_val_if_fail (self->loadstate >= OSTREE_SYSROOT_LOAD_STATE_INIT, FALSE);
return self->root_is_ostree_booted;
}
gboolean gboolean
_ostree_sysroot_bump_mtime (OstreeSysroot *self, _ostree_sysroot_bump_mtime (OstreeSysroot *self,
GError **error) GError **error)
@ -798,6 +880,57 @@ ensure_repo (OstreeSysroot *self,
return TRUE; return TRUE;
} }
/**
* ostree_sysroot_initialize:
* @self: sysroot
*
* Subset of ostree_sysroot_load(); performs basic initialization. Notably, one
* can invoke `ostree_sysroot_get_fd()` after calling this function.
*
* It is not necessary to call this function if ostree_sysroot_load() is
* invoked.
*
* Since: 2020.1
*/
gboolean
ostree_sysroot_initialize (OstreeSysroot *self,
GError **error)
{
if (!ensure_sysroot_fd (self, error))
return FALSE;
if (self->loadstate < OSTREE_SYSROOT_LOAD_STATE_INIT)
{
/* Gather some global state; first if we have the global ostree-booted flag;
* we'll use it to sanity check that we found a booted deployment for example.
* Second, we also find out whether sysroot == /.
*/
if (!glnx_fstatat_allow_noent (AT_FDCWD, "/run/ostree-booted", NULL, 0, error))
return FALSE;
const gboolean ostree_booted = (errno == 0);
{ struct stat root_stbuf;
if (!glnx_fstatat (AT_FDCWD, "/", &root_stbuf, 0, error))
return FALSE;
self->root_device = root_stbuf.st_dev;
self->root_inode = root_stbuf.st_ino;
}
struct stat self_stbuf;
if (!glnx_fstatat (AT_FDCWD, gs_file_get_path_cached (self->path), &self_stbuf, 0, error))
return FALSE;
const gboolean root_is_sysroot =
(self->root_device == self_stbuf.st_dev &&
self->root_inode == self_stbuf.st_ino);
self->root_is_ostree_booted = (ostree_booted && root_is_sysroot);
self->loadstate = OSTREE_SYSROOT_LOAD_STATE_INIT;
}
return TRUE;
}
/* Reload the staged deployment from the file in /run */ /* Reload the staged deployment from the file in /run */
gboolean gboolean
_ostree_sysroot_reload_staged (OstreeSysroot *self, _ostree_sysroot_reload_staged (OstreeSysroot *self,
@ -870,7 +1003,7 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
if (!ensure_sysroot_fd (self, error)) if (!ostree_sysroot_initialize (self, error))
return FALSE; return FALSE;
/* Here we also lazily initialize the repository. We didn't do this /* Here we also lazily initialize the repository. We didn't do this
@ -880,34 +1013,6 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self,
if (!ensure_repo (self, error)) if (!ensure_repo (self, error))
return FALSE; return FALSE;
/* Gather some global state; first if we have the global ostree-booted flag;
* we'll use it to sanity check that we found a booted deployment for example.
* Second, we also find out whether sysroot == /.
*/
if (!self->loaded)
{
if (!glnx_fstatat_allow_noent (AT_FDCWD, "/run/ostree-booted", NULL, 0, error))
return FALSE;
const gboolean ostree_booted = (errno == 0);
{ struct stat root_stbuf;
if (!glnx_fstatat (AT_FDCWD, "/", &root_stbuf, 0, error))
return FALSE;
self->root_device = root_stbuf.st_dev;
self->root_inode = root_stbuf.st_ino;
}
struct stat self_stbuf;
if (!glnx_fstat (self->sysroot_fd, &self_stbuf, error))
return FALSE;
const gboolean root_is_sysroot =
(self->root_device == self_stbuf.st_dev &&
self->root_inode == self_stbuf.st_ino);
self->root_is_ostree_booted = (ostree_booted && root_is_sysroot);
}
int bootversion = 0; int bootversion = 0;
if (!read_current_bootversion (self, &bootversion, cancellable, error)) if (!read_current_bootversion (self, &bootversion, cancellable, error))
return FALSE; return FALSE;
@ -990,8 +1095,8 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self,
ostree_deployment_set_index (deployment, i); ostree_deployment_set_index (deployment, i);
} }
/* Determine whether we're "physical" or not, the first time we initialize */ /* Determine whether we're "physical" or not, the first time we load deployments */
if (!self->loaded) if (self->loadstate < OSTREE_SYSROOT_LOAD_STATE_LOADED)
{ {
/* If we have a booted deployment, the sysroot is / and we're definitely /* If we have a booted deployment, the sysroot is / and we're definitely
* not physical. * not physical.
@ -1009,13 +1114,14 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self,
self->is_physical = TRUE; self->is_physical = TRUE;
} }
/* Otherwise, the default is FALSE */ /* Otherwise, the default is FALSE */
self->loadstate = OSTREE_SYSROOT_LOAD_STATE_LOADED;
} }
self->bootversion = bootversion; self->bootversion = bootversion;
self->subbootversion = subbootversion; self->subbootversion = subbootversion;
self->deployments = deployments; self->deployments = deployments;
deployments = NULL; /* Transfer ownership */ deployments = NULL; /* Transfer ownership */
self->loaded = TRUE;
self->loaded_ts = stbuf.st_mtim; self->loaded_ts = stbuf.st_mtim;
if (out_changed) if (out_changed)
@ -1044,7 +1150,7 @@ ostree_sysroot_get_subbootversion (OstreeSysroot *self)
OstreeDeployment * OstreeDeployment *
ostree_sysroot_get_booted_deployment (OstreeSysroot *self) ostree_sysroot_get_booted_deployment (OstreeSysroot *self)
{ {
g_return_val_if_fail (self->loaded, NULL); g_return_val_if_fail (self->loadstate == OSTREE_SYSROOT_LOAD_STATE_LOADED, NULL);
return self->booted_deployment; return self->booted_deployment;
} }
@ -1060,7 +1166,7 @@ ostree_sysroot_get_booted_deployment (OstreeSysroot *self)
OstreeDeployment * OstreeDeployment *
ostree_sysroot_get_staged_deployment (OstreeSysroot *self) ostree_sysroot_get_staged_deployment (OstreeSysroot *self)
{ {
g_return_val_if_fail (self->loaded, NULL); g_return_val_if_fail (self->loadstate == OSTREE_SYSROOT_LOAD_STATE_LOADED, NULL);
return self->staged_deployment; return self->staged_deployment;
} }
@ -1074,7 +1180,7 @@ ostree_sysroot_get_staged_deployment (OstreeSysroot *self)
GPtrArray * GPtrArray *
ostree_sysroot_get_deployments (OstreeSysroot *self) ostree_sysroot_get_deployments (OstreeSysroot *self)
{ {
g_return_val_if_fail (self->loaded, NULL); g_return_val_if_fail (self->loadstate == OSTREE_SYSROOT_LOAD_STATE_LOADED, NULL);
GPtrArray *copy = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref); GPtrArray *copy = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
for (guint i = 0; i < self->deployments->len; i++) for (guint i = 0; i < self->deployments->len; i++)
@ -1163,8 +1269,8 @@ ostree_sysroot_get_repo (OstreeSysroot *self,
* @self: Sysroot * @self: Sysroot
* *
* This function is a variant of ostree_sysroot_get_repo() that cannot fail, and * This function is a variant of ostree_sysroot_get_repo() that cannot fail, and
* returns a cached repository. Can only be called after ostree_sysroot_load() * returns a cached repository. Can only be called after ostree_sysroot_initialize()
* has been invoked successfully. * or ostree_sysroot_load() has been invoked successfully.
* *
* Returns: (transfer none): The OSTree repository in sysroot @self. * Returns: (transfer none): The OSTree repository in sysroot @self.
* *
@ -1173,7 +1279,7 @@ ostree_sysroot_get_repo (OstreeSysroot *self,
OstreeRepo * OstreeRepo *
ostree_sysroot_repo (OstreeSysroot *self) ostree_sysroot_repo (OstreeSysroot *self)
{ {
g_return_val_if_fail (self->loaded, NULL); g_return_val_if_fail (self->loadstate >= OSTREE_SYSROOT_LOAD_STATE_LOADED, NULL);
g_assert (self->repo); g_assert (self->repo);
return self->repo; return self->repo;
} }
@ -1368,6 +1474,10 @@ ostree_sysroot_lock (OstreeSysroot *self,
{ {
if (!ensure_sysroot_fd (self, error)) if (!ensure_sysroot_fd (self, error))
return FALSE; return FALSE;
if (!_ostree_sysroot_ensure_writable (self, error))
return FALSE;
return glnx_make_lock_file (self->sysroot_fd, OSTREE_SYSROOT_LOCKFILE, return glnx_make_lock_file (self->sysroot_fd, OSTREE_SYSROOT_LOCKFILE,
LOCK_EX, &self->lock, error); LOCK_EX, &self->lock, error);
} }
@ -1391,12 +1501,14 @@ ostree_sysroot_try_lock (OstreeSysroot *self,
gboolean *out_acquired, gboolean *out_acquired,
GError **error) GError **error)
{ {
g_autoptr(GError) local_error = NULL;
if (!ensure_sysroot_fd (self, error)) if (!ensure_sysroot_fd (self, error))
return FALSE; return FALSE;
if (!_ostree_sysroot_ensure_writable (self, error))
return FALSE;
/* Note use of LOCK_NB */ /* Note use of LOCK_NB */
g_autoptr(GError) local_error = NULL;
if (!glnx_make_lock_file (self->sysroot_fd, OSTREE_SYSROOT_LOCKFILE, if (!glnx_make_lock_file (self->sysroot_fd, OSTREE_SYSROOT_LOCKFILE,
LOCK_EX | LOCK_NB, &self->lock, &local_error)) LOCK_EX | LOCK_NB, &self->lock, &local_error))
{ {
@ -1509,7 +1621,7 @@ ostree_sysroot_init_osname (OstreeSysroot *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
if (!ensure_sysroot_fd (self, error)) if (!_ostree_sysroot_ensure_writable (self, error))
return FALSE; return FALSE;
const char *deploydir = glnx_strjoina ("ostree/deploy/", osname); const char *deploydir = glnx_strjoina ("ostree/deploy/", osname);

View File

@ -41,12 +41,22 @@ OstreeSysroot* ostree_sysroot_new (GFile *path);
_OSTREE_PUBLIC _OSTREE_PUBLIC
OstreeSysroot* ostree_sysroot_new_default (void); OstreeSysroot* ostree_sysroot_new_default (void);
_OSTREE_PUBLIC
void ostree_sysroot_set_mount_namespace_in_use (OstreeSysroot *self);
_OSTREE_PUBLIC _OSTREE_PUBLIC
GFile *ostree_sysroot_get_path (OstreeSysroot *self); GFile *ostree_sysroot_get_path (OstreeSysroot *self);
_OSTREE_PUBLIC
gboolean ostree_sysroot_is_booted (OstreeSysroot *self);
_OSTREE_PUBLIC _OSTREE_PUBLIC
int ostree_sysroot_get_fd (OstreeSysroot *self); int ostree_sysroot_get_fd (OstreeSysroot *self);
_OSTREE_PUBLIC
gboolean ostree_sysroot_initialize (OstreeSysroot *self,
GError **error);
_OSTREE_PUBLIC _OSTREE_PUBLIC
gboolean ostree_sysroot_load (OstreeSysroot *self, gboolean ostree_sysroot_load (OstreeSysroot *self,
GCancellable *cancellable, GCancellable *cancellable,
@ -90,6 +100,10 @@ GFile * ostree_sysroot_get_deployment_origin_path (GFile *deployment_path);
_OSTREE_PUBLIC _OSTREE_PUBLIC
gboolean ostree_sysroot_lock (OstreeSysroot *self, GError **error); gboolean ostree_sysroot_lock (OstreeSysroot *self, GError **error);
_OSTREE_PUBLIC
gboolean ostree_sysroot_lock_with_mount_namespace (OstreeSysroot *self, GError **error);
_OSTREE_PUBLIC _OSTREE_PUBLIC
gboolean ostree_sysroot_try_lock (OstreeSysroot *self, gboolean ostree_sysroot_try_lock (OstreeSysroot *self,
gboolean *out_acquired, gboolean *out_acquired,

View File

@ -34,7 +34,7 @@
* *
* Since: 2017.4 * Since: 2017.4
*/ */
#define OSTREE_YEAR_VERSION (2019) #define OSTREE_YEAR_VERSION (2020)
/** /**
* OSTREE_RELEASE_VERSION: * OSTREE_RELEASE_VERSION:
@ -43,7 +43,7 @@
* *
* Since: 2017.4 * Since: 2017.4
*/ */
#define OSTREE_RELEASE_VERSION (6) #define OSTREE_RELEASE_VERSION (2)
/** /**
* OSTREE_VERSION * OSTREE_VERSION
@ -52,7 +52,7 @@
* *
* Since: 2017.4 * Since: 2017.4
*/ */
#define OSTREE_VERSION (2019.6) #define OSTREE_VERSION (2020.2)
/** /**
* OSTREE_VERSION_S: * OSTREE_VERSION_S:
@ -62,7 +62,7 @@
* *
* Since: 2017.4 * Since: 2017.4
*/ */
#define OSTREE_VERSION_S "2019.6" #define OSTREE_VERSION_S "2020.2"
#define OSTREE_ENCODE_VERSION(year,release) \ #define OSTREE_ENCODE_VERSION(year,release) \
((year) << 16 | (release)) ((year) << 16 | (release))
@ -100,4 +100,4 @@
* *
* Since: 2019.3 * Since: 2019.3
*/ */
#define OSTREE_BUILT_FEATURES "libcurl libsoup gpgme libarchive selinux openssl libmount release p2p" #define OSTREE_BUILT_FEATURES "libcurl libsoup gpgme ex-fsverity libarchive selinux openssl libmount systemd release p2p"

View File

@ -494,6 +494,7 @@ on_dir_changed (GFileMonitor *mon,
if (event == G_FILE_MONITOR_EVENT_DELETED) if (event == G_FILE_MONITOR_EVENT_DELETED)
{ {
httpd_log (self, "root directory removed, exiting\n");
self->running = FALSE; self->running = FALSE;
g_main_context_wakeup (NULL); g_main_context_wakeup (NULL);
} }
@ -507,6 +508,7 @@ run (int argc, char **argv, GCancellable *cancellable, GError **error)
const char *dirpath; const char *dirpath;
OtTrivialHttpd appstruct = { 0, }; OtTrivialHttpd appstruct = { 0, };
OtTrivialHttpd *app = &appstruct; OtTrivialHttpd *app = &appstruct;
int pipefd[2] = { -1, -1 };
glnx_unref_object SoupServer *server = NULL; glnx_unref_object SoupServer *server = NULL;
g_autoptr(GFileMonitor) dirmon = NULL; g_autoptr(GFileMonitor) dirmon = NULL;
@ -540,17 +542,86 @@ run (int argc, char **argv, GCancellable *cancellable, GError **error)
goto out; goto out;
} }
if (opt_daemonize && (g_strcmp0 (opt_log, "-") == 0))
{
ot_util_usage_error (context, "Cannot use --log-file=- and --daemonize at the same time", error);
goto out;
}
/* Fork early before glib sets up its worker context and thread since they'll
* be gone once the parent exits. The parent waits on a pipe with the child to
* handle setup errors. The child writes a 0 when setup is successful and a 1
* otherwise.
*/
if (opt_daemonize)
{
if (pipe (pipefd) == -1)
{
glnx_set_error_from_errno (error);
goto out;
}
pid_t pid = fork();
if (pid == -1)
{
glnx_set_error_from_errno (error);
goto out;
}
else if (pid > 0)
{
/* Parent, read the child status from the pipe */
glnx_close_fd (&pipefd[1]);
guint8 buf;
int res = TEMP_FAILURE_RETRY (read (pipefd[0], &buf, 1));
if (res < 0)
{
glnx_set_error_from_errno (error);
goto out;
}
else if (res == 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Child process closed pipe without writing status");
goto out;
}
g_debug ("Read %u from child", buf);
if (buf > 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Child process failed during setup");
goto out;
}
glnx_close_fd (&pipefd[0]);
ret = TRUE;
goto out;
}
/* Child, continue */
glnx_close_fd (&pipefd[0]);
}
else
{
/* Since we're used for testing purposes, let's just do this by
* default. This ensures we exit when our parent does.
*/
if (prctl (PR_SET_PDEATHSIG, SIGTERM) != 0)
{
if (errno != ENOSYS)
{
glnx_set_error_from_errno (error);
goto out;
}
}
}
if (opt_log) if (opt_log)
{ {
GOutputStream *stream = NULL; GOutputStream *stream = NULL;
if (g_strcmp0 (opt_log, "-") == 0) if (g_strcmp0 (opt_log, "-") == 0)
{ {
if (opt_daemonize)
{
ot_util_usage_error (context, "Cannot use --log-file=- and --daemonize at the same time", error);
goto out;
}
stream = G_OUTPUT_STREAM (g_unix_output_stream_new (STDOUT_FILENO, FALSE)); stream = G_OUTPUT_STREAM (g_unix_output_stream_new (STDOUT_FILENO, FALSE));
} }
else else
@ -628,42 +699,36 @@ run (int argc, char **argv, GCancellable *cancellable, GError **error)
if (opt_daemonize) if (opt_daemonize)
{ {
pid_t pid = fork(); /* Write back a 0 to the pipe to indicate setup was successful. */
if (pid == -1) guint8 buf = 0;
{ g_debug ("Writing %u to parent", buf);
int errsv = errno; if (TEMP_FAILURE_RETRY (write (pipefd[1], &buf, 1)) == -1)
g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv),
g_strerror (errsv));
goto out;
}
else if (pid > 0)
{
ret = TRUE;
goto out;
}
/* Child, continue */
if (setsid () < 0)
err (1, "setsid");
/* Daemonising: close stdout/stderr so $() et al work on us */
if (freopen("/dev/null", "r", stdin) == NULL)
err (1, "freopen");
if (freopen("/dev/null", "w", stdout) == NULL)
err (1, "freopen");
if (freopen("/dev/null", "w", stderr) == NULL)
err (1, "freopen");
}
else
{
/* Since we're used for testing purposes, let's just do this by
* default. This ensures we exit when our parent does.
*/
if (prctl (PR_SET_PDEATHSIG, SIGTERM) != 0)
{
if (errno != ENOSYS)
{ {
glnx_set_error_from_errno (error); glnx_set_error_from_errno (error);
goto out; goto out;
} }
glnx_close_fd (&pipefd[1]);
if (setsid () < 0)
{
glnx_set_prefix_error_from_errno (error, "%s", "setsid: ");
goto out;
}
/* Daemonising: close stdout/stderr so $() et al work on us */
if (freopen("/dev/null", "r", stdin) == NULL)
{
glnx_set_prefix_error_from_errno (error, "%s", "freopen: ");
goto out;
}
if (freopen("/dev/null", "w", stdout) == NULL)
{
glnx_set_prefix_error_from_errno (error, "%s", "freopen: ");
goto out;
}
if (freopen("/dev/null", "w", stderr) == NULL)
{
glnx_set_prefix_error_from_errno (error, "%s", "freopen: ");
goto out;
} }
} }
@ -699,6 +764,21 @@ run (int argc, char **argv, GCancellable *cancellable, GError **error)
ret = TRUE; ret = TRUE;
out: out:
if (pipefd[0] >= 0)
{
/* Read end in the parent. This should only be open on errors. */
g_assert_false (ret);
glnx_close_fd (&pipefd[0]);
}
if (pipefd[1] >= 0)
{
/* Write end in the child. This should only be open on errors. */
g_assert_false (ret);
guint8 buf = 1;
g_debug ("Writing %u to parent", buf);
(void) TEMP_FAILURE_RETRY (write (pipefd[1], &buf, 1));
glnx_close_fd (&pipefd[1]);
}
if (app->root_dfd != -1) if (app->root_dfd != -1)
(void) close (app->root_dfd); (void) close (app->root_dfd);
g_clear_object (&app->log); g_clear_object (&app->log);

View File

@ -34,6 +34,10 @@
#include "ostree-cmdprivate.h" #include "ostree-cmdprivate.h"
#include "ostree.h" #include "ostree.h"
static GOptionEntry options[] = {
{ NULL }
};
/* Called by ostree-finalize-staged.service, and in turn /* Called by ostree-finalize-staged.service, and in turn
* invokes a cmdprivate function inside the shared library. * invokes a cmdprivate function inside the shared library.
*/ */
@ -46,11 +50,13 @@ ot_admin_builtin_finalize_staged (int argc, char **argv, OstreeCommandInvocation
if (fstatat (AT_FDCWD, "/run/ostree-booted", &stbuf, 0) < 0) if (fstatat (AT_FDCWD, "/run/ostree-booted", &stbuf, 0) < 0)
return TRUE; return TRUE;
g_autoptr(GFile) sysroot_file = g_file_new_for_path ("/"); g_autoptr(GOptionContext) context = g_option_context_new ("");
g_autoptr(OstreeSysroot) sysroot = ostree_sysroot_new (sysroot_file); g_autoptr(OstreeSysroot) sysroot = NULL;
if (!ostree_admin_option_context_parse (context, options, &argc, &argv,
if (!ostree_sysroot_load (sysroot, cancellable, error)) OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER,
invocation, &sysroot, cancellable, error))
return FALSE; return FALSE;
if (!ostree_cmd__private__()->ostree_finalize_staged (sysroot, cancellable, error)) if (!ostree_cmd__private__()->ostree_finalize_staged (sysroot, cancellable, error))
return FALSE; return FALSE;

View File

@ -33,6 +33,7 @@ static gboolean opt_print_related;
static char* opt_print_variant_type; static char* opt_print_variant_type;
static char* opt_print_metadata_key; static char* opt_print_metadata_key;
static char* opt_print_detached_metadata_key; static char* opt_print_detached_metadata_key;
static gboolean opt_print_sizes;
static gboolean opt_raw; static gboolean opt_raw;
static gboolean opt_no_byteswap; static gboolean opt_no_byteswap;
static char *opt_gpg_homedir; static char *opt_gpg_homedir;
@ -48,6 +49,7 @@ static GOptionEntry options[] = {
{ "print-variant-type", 0, 0, G_OPTION_ARG_STRING, &opt_print_variant_type, "Memory map OBJECT (in this case a filename) to the GVariant type string", "TYPE" }, { "print-variant-type", 0, 0, G_OPTION_ARG_STRING, &opt_print_variant_type, "Memory map OBJECT (in this case a filename) to the GVariant type string", "TYPE" },
{ "print-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_metadata_key, "Print string value of metadata key", "KEY" }, { "print-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_metadata_key, "Print string value of metadata key", "KEY" },
{ "print-detached-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_detached_metadata_key, "Print string value of detached metadata key", "KEY" }, { "print-detached-metadata-key", 0, 0, G_OPTION_ARG_STRING, &opt_print_detached_metadata_key, "Print string value of detached metadata key", "KEY" },
{ "print-sizes", 0, 0, G_OPTION_ARG_NONE, &opt_print_sizes, "Show the commit size metadata", NULL },
{ "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "Show raw variant data" }, { "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "Show raw variant data" },
{ "no-byteswap", 'B', 0, G_OPTION_ARG_NONE, &opt_no_byteswap, "Do not automatically convert variant data from big endian" }, { "no-byteswap", 'B', 0, G_OPTION_ARG_NONE, &opt_no_byteswap, "Do not automatically convert variant data from big endian" },
{ "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR"}, { "gpg-homedir", 0, 0, G_OPTION_ARG_FILENAME, &opt_gpg_homedir, "GPG Homedir to use when looking for keyrings", "HOMEDIR"},
@ -146,6 +148,65 @@ do_print_metadata_key (OstreeRepo *repo,
return TRUE; return TRUE;
} }
static gboolean
do_print_sizes (OstreeRepo *repo,
const char *rev,
GError **error)
{
g_autoptr(GVariant) commit = NULL;
if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, rev,
&commit, error))
{
g_prefix_error (error, "Failed to read commit: ");
return FALSE;
}
g_autoptr(GPtrArray) sizes = NULL;
if (!ostree_commit_get_object_sizes (commit, &sizes, error))
return FALSE;
gint64 new_archived = 0;
gint64 new_unpacked = 0;
gsize new_objects = 0;
gint64 archived = 0;
gint64 unpacked = 0;
gsize objects = 0;
for (guint i = 0; i < sizes->len; i++)
{
OstreeCommitSizesEntry *entry = sizes->pdata[i];
archived += entry->archived;
unpacked += entry->unpacked;
objects++;
gboolean exists;
if (!ostree_repo_has_object (repo, entry->objtype, entry->checksum,
&exists, NULL, error))
return FALSE;
if (!exists)
{
/* Object not in local repo */
new_archived += entry->archived;
new_unpacked += entry->unpacked;
new_objects++;
}
}
g_autofree char *new_archived_str = g_format_size (new_archived);
g_autofree char *archived_str = g_format_size (archived);
g_autofree char *new_unpacked_str = g_format_size (new_unpacked);
g_autofree char *unpacked_str = g_format_size (unpacked);
g_print ("Compressed size (needed/total): %s/%s\n"
"Unpacked size (needed/total): %s/%s\n"
"Number of objects (needed/total): %" G_GSIZE_FORMAT "/%" G_GSIZE_FORMAT "\n",
new_archived_str, archived_str,
new_unpacked_str, unpacked_str,
new_objects, objects);
return TRUE;
}
static gboolean static gboolean
print_object (OstreeRepo *repo, print_object (OstreeRepo *repo,
OstreeObjectType objtype, OstreeObjectType objtype,
@ -279,6 +340,14 @@ ostree_builtin_show (int argc, char **argv, OstreeCommandInvocation *invocation,
if (!do_print_variant_generic (G_VARIANT_TYPE (opt_print_variant_type), rev, error)) if (!do_print_variant_generic (G_VARIANT_TYPE (opt_print_variant_type), rev, error))
return FALSE; return FALSE;
} }
else if (opt_print_sizes)
{
if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error))
return FALSE;
if (!do_print_sizes (repo, resolved_rev, error))
return FALSE;
}
else else
{ {
gboolean found = FALSE; gboolean found = FALSE;

View File

@ -27,6 +27,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/statvfs.h>
#include "ot-main.h" #include "ot-main.h"
#include "ostree.h" #include "ostree.h"
@ -434,10 +435,46 @@ ostree_admin_option_context_parse (GOptionContext *context,
sysroot_path = g_file_new_for_path (opt_sysroot); sysroot_path = g_file_new_for_path (opt_sysroot);
g_autoptr(OstreeSysroot) sysroot = ostree_sysroot_new (sysroot_path); g_autoptr(OstreeSysroot) sysroot = ostree_sysroot_new (sysroot_path);
if (!ostree_sysroot_initialize (sysroot, error))
return FALSE;
g_signal_connect (sysroot, "journal-msg", G_CALLBACK (on_sysroot_journal_msg), NULL); g_signal_connect (sysroot, "journal-msg", G_CALLBACK (on_sysroot_journal_msg), NULL);
if ((flags & OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED) == 0) if ((flags & OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED) == 0)
{ {
/* If we're requested to lock the sysroot, first check if we're operating
* on a booted (not physical) sysroot. Then find out if the /sysroot
* subdir is a read-only mount point, and if so, create a new mount
* namespace and tell the sysroot that we've done so. See the docs for
* ostree_sysroot_set_mount_namespace_in_use().
*
* This is a conservative approach; we could just always
* unshare() too.
*/
if (ostree_sysroot_is_booted (sysroot))
{
int sysroot_fd = ostree_sysroot_get_fd (sysroot);
g_assert_cmpint (sysroot_fd, !=, -1);
glnx_autofd int sysroot_subdir_fd = glnx_opendirat_with_errno (sysroot_fd, "sysroot", TRUE);
if (sysroot_subdir_fd < 0)
{
if (errno != ENOENT)
return glnx_throw_errno_prefix (error, "opendirat");
}
else if (getuid () == 0)
{
struct statvfs stvfs;
if (fstatvfs (sysroot_subdir_fd, &stvfs) < 0)
return glnx_throw_errno_prefix (error, "fstatvfs");
if (stvfs.f_flag & ST_RDONLY)
{
if (unshare (CLONE_NEWNS) < 0)
return glnx_throw_errno_prefix (error, "preparing writable sysroot: unshare (CLONE_NEWNS)");
ostree_sysroot_set_mount_namespace_in_use (sysroot);
}
}
}
/* Released when sysroot is finalized, or on process exit */ /* Released when sysroot is finalized, or on process exit */
if (!ot_admin_sysroot_lock (sysroot, error)) if (!ot_admin_sysroot_lock (sysroot, error))
return FALSE; return FALSE;

View File

@ -29,6 +29,28 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
/* The high level goal of ostree-prepare-root.service is to run inside
* the initial ram disk (if one is in use) and set up the `/` mountpoint
* to be the deployment root, using the ostree= kernel commandline
* argument to find the target deployment root.
*
* It's really the heart of how ostree works - basically multiple
* hardlinked chroot() targets are maintained, this one does the equivalent
* of chroot().
*
* If using systemd, an excellent reference is `man bootup`. This
* service runs Before=initrd-root-fs.target. At this point it's
* assumed that the block storage and root filesystem are mounted at
* /sysroot - i.e. /sysroot points to the *physical* root before
* this service runs. After, `/` is the deployment root.
*
* There is also a secondary mode for this service when an initrd isn't
* used - instead the binary must be statically linked (and the kernel
* must have mounted the rootfs itself) - then we set things up and
* exec the real init directly. This can be popular in embedded
* systems to increase bootup speed.
*/
#include "config.h" #include "config.h"
#include <sys/mount.h> #include <sys/mount.h>

View File

@ -26,6 +26,7 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/mount.h> #include <sys/mount.h>
@ -37,10 +38,14 @@
#include <err.h> #include <err.h>
#include <errno.h> #include <errno.h>
#include <glib.h>
#include "ostree-mount-util.h" #include "ostree-mount-util.h"
#include "glnx-backport-autocleanups.h"
static void static void
do_remount (const char *target) do_remount (const char *target,
bool writable)
{ {
struct stat stbuf; struct stat stbuf;
if (lstat (target, &stbuf) < 0) if (lstat (target, &stbuf) < 0)
@ -54,20 +59,41 @@ do_remount (const char *target)
struct statvfs stvfsbuf; struct statvfs stvfsbuf;
if (statvfs (target, &stvfsbuf) == -1) if (statvfs (target, &stvfsbuf) == -1)
return; return;
/* If no read-only flag, skip it */
if ((stvfsbuf.f_flag & ST_RDONLY) == 0) const bool currently_writable = ((stvfsbuf.f_flag & ST_RDONLY) == 0);
if (writable == currently_writable)
return; return;
/* It's a mounted, read-only fs; remount it */
if (mount (target, target, NULL, MS_REMOUNT | MS_SILENT, NULL) < 0) int mnt_flags = MS_REMOUNT | MS_SILENT;
if (!writable)
mnt_flags |= MS_RDONLY;
if (mount (target, target, NULL, mnt_flags, NULL) < 0)
{ {
/* Also ignore EINVAL - if the target isn't a mountpoint /* Also ignore EINVAL - if the target isn't a mountpoint
* already, then assume things are OK. * already, then assume things are OK.
*/ */
if (errno != EINVAL) if (errno != EINVAL)
err (EXIT_FAILURE, "failed to remount %s", target); err (EXIT_FAILURE, "failed to remount(%s) %s", writable ? "rw" : "ro", target);
}
else else
printf ("Remounted: %s\n", target); return;
}
printf ("Remounted %s: %s\n", writable ? "rw" : "ro", target);
}
static bool
sysroot_is_configured_ro (void)
{
struct stat stbuf;
static const char config_path[] = "/ostree/repo/config";
if (stat (config_path, &stbuf) != 0)
return false;
g_autoptr(GKeyFile) keyfile = g_key_file_new ();
if (!g_key_file_load_from_file (keyfile, config_path, 0, NULL))
return false;
return g_key_file_get_boolean (keyfile, "sysroot", "readonly", NULL);
} }
int int
@ -95,8 +121,38 @@ main(int argc, char *argv[])
exit (EXIT_SUCCESS); exit (EXIT_SUCCESS);
} }
do_remount ("/sysroot"); /* Query the repository configuration - this is an operating system builder
do_remount ("/var"); * choice.
* */
const bool sysroot_readonly = sysroot_is_configured_ro ();
/* Mount the sysroot read-only if we're configured to do so.
* Note we only get here if / is already writable.
*/
do_remount ("/sysroot", !sysroot_readonly);
if (sysroot_readonly)
{
/* Now, /etc is not normally a bind mount, but remounting the
* sysroot above made it read-only since it's on the same filesystem.
* Make it a self-bind mount, so we can then mount it read-write.
*/
if (mount ("/etc", "/etc", NULL, MS_BIND, NULL) < 0)
err (EXIT_FAILURE, "failed to make /etc a bind mount");
do_remount ("/etc", true);
}
/* If /var was created as as an OSTree default bind mount (instead of being a separate filesystem)
* then remounting the root mount read-only also remounted it.
* So just like /etc, we need to make it read-write by default.
* If it was a separate filesystem, we expect it to be writable anyways,
* so it doesn't hurt to remount it if so.
*
* And if we started out with a writable system root, then we need
* to ensure that the /var bind mount created by the systemd generator
* is writable too.
*/
do_remount ("/var", true);
exit (EXIT_SUCCESS); exit (EXIT_SUCCESS);
} }

View File

@ -1,5 +1,7 @@
This is a GPG config directory for use with the OstreeGpgVerifyResult This is a GPG config directory for use with the OstreeGpgVerifyResult
test cases. The test data (`lgplv2`) is signed with a variety of valid test cases. The test data (`lgpl2`) is signed with a variety of valid
and invalid GPG keys in a detached signature file (`lgplv2.sig`). and invalid GPG keys in a detached signature file (`lgpl2.sig`). In
addition, each detached signature is available in a separate file
(`lgpgl2.sig<N>`).
The passphrase for all the keys is `redhat`. The passphrase for all the keys is `redhat`.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,12 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: This is a revocation certificate
iQE9BCABCgAnFiEEXmXedascUBhi1HY0f8oj2Ecs2voFAl0MvqgJHQBUZXN0aW5n
AAoJEH/KI9hHLNr6/dQH/iPZjfJgFAc/TIR4xE4kB0yL4zdMqxgV1ef/atQDLEN4
MBiqIltzb8WyG+cpNfNZgFmqXmCRN+1IAla9piixe76ZwOqcQ6S5MU/8nMcyMsD9
edg+9sg0DH8SEzejVma3ZLfaJ/6ZpU7c6a4vCPNcRBC7PxAvAc0LnAN6KQYGU7GR
gv2k/JsGYgvmUAajhVFy0jc4jGkhRBHMDksGGFdYY94RATFF4gWtlUXyRYMTXBCf
eM3bxEeSMbU7lXCZg9zjoxP6XzJuNW1SLz3zL90GnO19uNh8Pf6pHmkCNTO/L1Ua
Cc6fb3ubtdqgs6an84U/aod1VcK7BNASqZ2gYUsF2KE=
=owvo
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -0,0 +1,12 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: This is a revocation certificate
iQE9BCABCgAnFiEEezsQINdEeWh/2yJz2CKM/sqVDUEFAl0Mvs4JHQBUZXN0aW5n
AAoJENgijP7KlQ1BzH4IAMUoTrW6XraDYq/d/b0qa3sZ1NTBPUXLp4gFaedZwKk/
AKSUCK05RWRQO3HrSvmhdSUF6/9tFLGpbu7P56ihjAnq2vpzRyeNTEGQ02IzfCpM
SJup0R6iA7KmjiDutDoEgjhAzxCKbnU71SQ3PmjyaQT1KCBCDJVptcY6HDbo0dRN
vcjTfjtFqkPgqbHyXwGv3rlm4uctSVfACrOS/fKF4Q9Fs4prsUXjQpGLaTHdxhiL
pMRCTfZ4DBEMwAY7s9FpMpIh9rdOwE+zkv5CsE0uJVZq0WW5r0CBDCta6Sopt6uk
pIA+QHL9GPOrG2E3SJxyIBC37Sl40MGAJQ1djmecIGk=
=0KEe
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -0,0 +1,12 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: This is a revocation certificate
iQE9BCABCgAnFiEEfSnPBguCac32O/vdDRX6599ETWcFAl0MvuYJHQBUZXN0aW5n
AAoJEA0V+uffRE1n/p8H/3mmSK2gtbxJ5sfu1z44ra82fLRAUupJzf53dAvvJCEK
4RSJFtHYu+hoPVFd9bmToxo2YQWe67MMZW7cHtq9D/a755SYOrty//KpXsGS22W/
ZGatBjl36zuE6BoR18Q6VAMgVBwovPSlSuCEW+Ro8JZYyA/LbA95AnMprNod6Jw9
VSsGC39au5rUlhEOHLL1Iw3dl4blxa6tf/roljbXzaN+Qh2/ez7Cy532oocak2FL
bbblBGrIdfYLAXpLqhnQk2vgEHZ+ZylvStBndpLWwEskXhmaHpW7+WapFhLCUOr+
arzbc9XQ7ghhF9hSoKiToJqU5PRjaOex85BEDwE5gWY=
=ykAF
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -41,7 +41,7 @@ assert_not_reached () {
# If we can't find the locale command assume we have support for C.UTF-8 # If we can't find the locale command assume we have support for C.UTF-8
# (e.g. musl based systems) # (e.g. musl based systems)
if type -p locale >/dev/null; then if type -p locale >/dev/null; then
export LC_ALL=$(locale -a | grep -Ee '\.(UTF-8|utf8)' | grep -iEe '^(C|en_US)' | head -1 || true) export LC_ALL=$(locale -a | grep -iEe '^(C|en_US)\.(UTF-8|utf8)$' | head -n1 || true)
if [ -z "${LC_ALL}" ]; then fatal "Can't find suitable UTF-8 locale"; fi if [ -z "${LC_ALL}" ]; then fatal "Can't find suitable UTF-8 locale"; fi
else else
export LC_ALL=C.UTF-8 export LC_ALL=C.UTF-8

View File

@ -78,16 +78,20 @@ unset TAR_OPTIONS
# easily clean up. # easily clean up.
export OSTREE_SYSROOT_DEBUG=mutable-deployments export OSTREE_SYSROOT_DEBUG=mutable-deployments
export TEST_GPG_KEYID_1="472CDAFA" export TEST_GPG_KEYID_1="7FCA23D8472CDAFA"
export TEST_GPG_KEYID_2="CA950D41" export TEST_GPG_KEYFPR_1="5E65DE75AB1C501862D476347FCA23D8472CDAFA"
export TEST_GPG_KEYID_3="DF444D67" export TEST_GPG_KEYID_2="D8228CFECA950D41"
export TEST_GPG_KEYFPR_2="7B3B1020D74479687FDB2273D8228CFECA950D41"
export TEST_GPG_KEYID_3="0D15FAE7DF444D67"
export TEST_GPG_KEYFPR_3="7D29CF060B8269CDF63BFBDD0D15FAE7DF444D67"
# GPG when creating signatures demands a writable # GPG when creating signatures demands a private writable
# homedir in order to create lockfiles. Work around # homedir in order to create lockfiles. Work around
# this by copying locally. # this by copying locally.
echo "Copying gpghome to ${test_tmpdir}" echo "Copying gpghome to ${test_tmpdir}"
cp -a "${test_srcdir}/gpghome" ${test_tmpdir} cp -a "${test_srcdir}/gpghome" ${test_tmpdir}
chmod -R u+w "${test_tmpdir}" chmod -R u+w "${test_tmpdir}"
chmod 700 "${test_tmpdir}/gpghome"
export TEST_GPG_KEYHOME=${test_tmpdir}/gpghome export TEST_GPG_KEYHOME=${test_tmpdir}/gpghome
export OSTREE_GPG_HOME=${test_tmpdir}/gpghome/trusted export OSTREE_GPG_HOME=${test_tmpdir}/gpghome/trusted
@ -559,6 +563,18 @@ skip_without_user_xattrs () {
fi fi
} }
_have_systemd_and_libmount=''
have_systemd_and_libmount() {
if test "${_have_systemd_and_libmount}" = ''; then
if [ $(ostree --version | grep -c -e '- systemd' -e '- libmount') -eq 2 ]; then
_have_systemd_and_libmount=yes
else
_have_systemd_and_libmount=no
fi
fi
test ${_have_systemd_and_libmount} = yes
}
# Skip unless SELinux is disabled, or we can relabel. # Skip unless SELinux is disabled, or we can relabel.
# Default Docker has security.selinux xattrs, but returns # Default Docker has security.selinux xattrs, but returns
# EOPNOTSUPP when trying to set them, even to the existing value. # EOPNOTSUPP when trying to set them, even to the existing value.

View File

@ -36,6 +36,18 @@
} \ } \
} G_STMT_END } G_STMT_END
#define assert_str_contains(s1, s2) \
G_STMT_START { \
const char *__s1 = (s1), *__s2 = (s2); \
if (strstr (__s1, __s2) == NULL) { \
g_autoptr(GString) string = g_string_new ("assertion failed (" #s1 " contains " #s2 "): "); \
g_autofree char *__es1 = g_strescape (__s1, NULL); \
g_autofree char *__es2 = g_strescape (__s2, NULL); \
g_string_append_printf (string, "(\"%s\", \"%s\")", __es1, __es2); \
g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, string->str); \
} \
} G_STMT_END
typedef struct { typedef struct {
OstreeGpgVerifyResult *result; OstreeGpgVerifyResult *result;
} TestFixture; } TestFixture;
@ -53,12 +65,12 @@ static void
test_fixture_setup (TestFixture *fixture, test_fixture_setup (TestFixture *fixture,
gconstpointer user_data) gconstpointer user_data)
{ {
const char * const *sig_files = user_data;
gpgme_error_t gpg_error; gpgme_error_t gpg_error;
gpgme_data_t data_buffer; gpgme_data_t data_buffer;
gpgme_data_t signature_buffer; gpgme_data_t signature_buffer;
OstreeGpgVerifyResult *result; OstreeGpgVerifyResult *result;
g_autofree char *homedir = NULL; g_autofree char *homedir = NULL;
g_autofree char *filename = NULL;
GError *local_error = NULL; GError *local_error = NULL;
/* Mimic what OstreeGpgVerifier does to create OstreeGpgVerifyResult. /* Mimic what OstreeGpgVerifier does to create OstreeGpgVerifyResult.
@ -74,15 +86,47 @@ test_fixture_setup (TestFixture *fixture,
NULL, &local_error, NULL); NULL, &local_error, NULL);
g_assert_no_error (local_error); g_assert_no_error (local_error);
filename = g_build_filename (homedir, "lgpl2", NULL); g_autofree char *data_filename = g_build_filename (homedir, "lgpl2", NULL);
gpg_error = gpgme_data_new_from_file (&data_buffer, filename, 1); gpg_error = gpgme_data_new_from_file (&data_buffer, data_filename, 1);
assert_no_gpg_error (gpg_error, filename); assert_no_gpg_error (gpg_error, data_filename);
g_clear_pointer (&filename, g_free); if (sig_files == NULL)
{
filename = g_build_filename (homedir, "lgpl2.sig", NULL); /* No signature files specified, use full lgpl2.sig file */
g_autofree char *filename = g_build_filename (homedir, "lgpl2.sig", NULL);
gpg_error = gpgme_data_new_from_file (&signature_buffer, filename, 1); gpg_error = gpgme_data_new_from_file (&signature_buffer, filename, 1);
assert_no_gpg_error (gpg_error, filename); assert_no_gpg_error (gpg_error, filename);
}
else
{
/* Read all the specified files into the signature buffer */
gpg_error = gpgme_data_new (&signature_buffer);
assert_no_gpg_error (gpg_error, NULL);
for (const char * const *name = sig_files; *name != NULL; name++)
{
g_autofree char *path = g_build_filename (homedir, *name, NULL);
g_autoptr(GFile) sig_file = g_file_new_for_path (path);
g_autofree char *contents = NULL;
gsize len;
g_assert_true (g_file_load_contents (sig_file, NULL, &contents,
&len, NULL, &local_error));
g_assert_no_error (local_error);
char *cur = contents;
while (len > 0)
{
ssize_t written = gpgme_data_write (signature_buffer, cur, len);
if (written == -1)
assert_no_gpg_error (gpgme_error_from_syserror (), path);
cur += written;
len -= written;
}
}
gpgme_data_seek (signature_buffer, 0, SEEK_SET);
}
gpg_error = gpgme_op_verify (result->context, gpg_error = gpgme_op_verify (result->context,
signature_buffer, data_buffer, NULL); signature_buffer, data_buffer, NULL);
@ -115,7 +159,7 @@ test_check_counts (TestFixture *fixture,
count_valid = ostree_gpg_verify_result_count_valid (fixture->result); count_valid = ostree_gpg_verify_result_count_valid (fixture->result);
g_assert_cmpint (count_all, ==, 5); g_assert_cmpint (count_all, ==, 5);
g_assert_cmpint (count_valid, ==, 2); g_assert_cmpint (count_valid, ==, 1);
} }
static void static void
@ -123,7 +167,7 @@ test_signature_lookup (TestFixture *fixture,
gconstpointer user_data) gconstpointer user_data)
{ {
/* Checking the signature with the revoked key for this case. */ /* Checking the signature with the revoked key for this case. */
guint expected_signature_index = GPOINTER_TO_UINT (user_data); guint expected_signature_index = 2;
/* Lowercase letters to ensure OstreeGpgVerifyResult handles it. */ /* Lowercase letters to ensure OstreeGpgVerifyResult handles it. */
const char *fingerprint = "68dcc2db4bec5811c2573590bd9d2a44b7f541a6"; const char *fingerprint = "68dcc2db4bec5811c2573590bd9d2a44b7f541a6";
@ -215,7 +259,7 @@ static void
test_valid_signature (TestFixture *fixture, test_valid_signature (TestFixture *fixture,
gconstpointer user_data) gconstpointer user_data)
{ {
guint signature_index = GPOINTER_TO_UINT (user_data); guint signature_index = 0;
g_autoptr(GVariant) tuple = NULL; g_autoptr(GVariant) tuple = NULL;
gboolean valid; gboolean valid;
gboolean sig_expired; gboolean sig_expired;
@ -249,7 +293,7 @@ static void
test_expired_key (TestFixture *fixture, test_expired_key (TestFixture *fixture,
gconstpointer user_data) gconstpointer user_data)
{ {
guint signature_index = GPOINTER_TO_UINT (user_data); guint signature_index = 1;
g_autoptr(GVariant) tuple = NULL; g_autoptr(GVariant) tuple = NULL;
gboolean valid; gboolean valid;
gboolean sig_expired; gboolean sig_expired;
@ -283,7 +327,7 @@ static void
test_revoked_key (TestFixture *fixture, test_revoked_key (TestFixture *fixture,
gconstpointer user_data) gconstpointer user_data)
{ {
guint signature_index = GPOINTER_TO_UINT (user_data); guint signature_index = 2;
g_autoptr(GVariant) tuple = NULL; g_autoptr(GVariant) tuple = NULL;
gboolean valid; gboolean valid;
gboolean sig_expired; gboolean sig_expired;
@ -317,7 +361,7 @@ static void
test_missing_key (TestFixture *fixture, test_missing_key (TestFixture *fixture,
gconstpointer user_data) gconstpointer user_data)
{ {
guint signature_index = GPOINTER_TO_UINT (user_data); guint signature_index = 3;
g_autoptr(GVariant) tuple = NULL; g_autoptr(GVariant) tuple = NULL;
gboolean valid; gboolean valid;
gboolean sig_expired; gboolean sig_expired;
@ -351,7 +395,7 @@ static void
test_expired_signature (TestFixture *fixture, test_expired_signature (TestFixture *fixture,
gconstpointer user_data) gconstpointer user_data)
{ {
guint signature_index = GPOINTER_TO_UINT (user_data); guint signature_index = 4;
g_autoptr(GVariant) tuple = NULL; g_autoptr(GVariant) tuple = NULL;
gboolean valid; gboolean valid;
gboolean sig_expired; gboolean sig_expired;
@ -373,7 +417,7 @@ test_expired_signature (TestFixture *fixture,
&key_missing, &key_missing,
&key_exp_timestamp); &key_exp_timestamp);
g_assert_true (valid); g_assert_false (valid);
g_assert_true (sig_expired); g_assert_true (sig_expired);
g_assert_false (key_expired); g_assert_false (key_expired);
g_assert_false (key_revoked); g_assert_false (key_revoked);
@ -381,6 +425,83 @@ test_expired_signature (TestFixture *fixture,
g_assert_cmpint (key_exp_timestamp, ==, 0); g_assert_cmpint (key_exp_timestamp, ==, 0);
} }
static void
test_require_valid_signature (TestFixture *fixture,
gconstpointer user_data)
{
GError *error = NULL;
gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result,
&error);
g_assert_true (res);
g_assert_no_error (error);
}
static void
test_require_valid_signature_expired_key (TestFixture *fixture,
gconstpointer user_data)
{
GError *error = NULL;
gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result,
&error);
g_assert_false (res);
g_assert_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_EXPIRED_KEY);
assert_str_contains (error->message, "Key expired");
}
static void
test_require_valid_signature_revoked_key (TestFixture *fixture,
gconstpointer user_data)
{
GError *error = NULL;
gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result,
&error);
g_assert_false (res);
g_assert_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_REVOKED_KEY);
assert_str_contains (error->message, "Key revoked");
}
static void
test_require_valid_signature_missing_key (TestFixture *fixture,
gconstpointer user_data)
{
GError *error = NULL;
gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result,
&error);
g_assert_false (res);
g_assert_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_MISSING_KEY);
assert_str_contains (error->message, "public key not found");
}
static void
test_require_valid_signature_expired_signature (TestFixture *fixture,
gconstpointer user_data)
{
GError *error = NULL;
gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result,
&error);
g_assert_false (res);
g_assert_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_EXPIRED_SIGNATURE);
assert_str_contains (error->message, "Signature expired");
}
static void
test_require_valid_signature_expired_missing_key (TestFixture *fixture,
gconstpointer user_data)
{
GError *error = NULL;
gboolean res = ostree_gpg_verify_result_require_valid_signature (fixture->result,
&error);
g_assert_false (res);
/*
* The error will be for the last signature, which is for a missing key, but
* the message should show both issues.
*/
g_assert_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_MISSING_KEY);
assert_str_contains (error->message, "Key expired");
assert_str_contains (error->message, "public key not found");
}
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
@ -397,7 +518,7 @@ main (int argc, char **argv)
g_test_add ("/gpg-verify-result/signature-lookup", g_test_add ("/gpg-verify-result/signature-lookup",
TestFixture, TestFixture,
GINT_TO_POINTER (2), NULL,
test_fixture_setup, test_fixture_setup,
test_signature_lookup, test_signature_lookup,
test_fixture_teardown); test_fixture_teardown);
@ -411,38 +532,85 @@ main (int argc, char **argv)
g_test_add ("/gpg-verify-result/valid-signature", g_test_add ("/gpg-verify-result/valid-signature",
TestFixture, TestFixture,
GINT_TO_POINTER (0), /* signature index */ NULL,
test_fixture_setup, test_fixture_setup,
test_valid_signature, test_valid_signature,
test_fixture_teardown); test_fixture_teardown);
g_test_add ("/gpg-verify-result/expired-key", g_test_add ("/gpg-verify-result/expired-key",
TestFixture, TestFixture,
GINT_TO_POINTER (1), /* signature index */ NULL,
test_fixture_setup, test_fixture_setup,
test_expired_key, test_expired_key,
test_fixture_teardown); test_fixture_teardown);
g_test_add ("/gpg-verify-result/revoked-key", g_test_add ("/gpg-verify-result/revoked-key",
TestFixture, TestFixture,
GINT_TO_POINTER (2), /* signature index */ NULL,
test_fixture_setup, test_fixture_setup,
test_revoked_key, test_revoked_key,
test_fixture_teardown); test_fixture_teardown);
g_test_add ("/gpg-verify-result/missing-key", g_test_add ("/gpg-verify-result/missing-key",
TestFixture, TestFixture,
GINT_TO_POINTER (3), /* signature index */ NULL,
test_fixture_setup, test_fixture_setup,
test_missing_key, test_missing_key,
test_fixture_teardown); test_fixture_teardown);
g_test_add ("/gpg-verify-result/expired-signature", g_test_add ("/gpg-verify-result/expired-signature",
TestFixture, TestFixture,
GINT_TO_POINTER (4), /* signature index */ NULL,
test_fixture_setup, test_fixture_setup,
test_expired_signature, test_expired_signature,
test_fixture_teardown); test_fixture_teardown);
g_test_add ("/gpg-verify-result/require-valid-signature",
TestFixture,
NULL,
test_fixture_setup,
test_require_valid_signature,
test_fixture_teardown);
const char *expired_key_files[] = { "lgpl2.sig1", NULL };
g_test_add ("/gpg-verify-result/require-valid-signature-expired-key",
TestFixture,
expired_key_files,
test_fixture_setup,
test_require_valid_signature_expired_key,
test_fixture_teardown);
const char *revoked_key_files[] = { "lgpl2.sig2", NULL };
g_test_add ("/gpg-verify-result/require-valid-signature-revoked-key",
TestFixture,
revoked_key_files,
test_fixture_setup,
test_require_valid_signature_revoked_key,
test_fixture_teardown);
const char *missing_key_files[] = { "lgpl2.sig3", NULL };
g_test_add ("/gpg-verify-result/require-valid-signature-missing-key",
TestFixture,
missing_key_files,
test_fixture_setup,
test_require_valid_signature_missing_key,
test_fixture_teardown);
const char *expired_signature_files[] = { "lgpl2.sig4", NULL };
g_test_add ("/gpg-verify-result/require-valid-signature-expired-signature",
TestFixture,
expired_signature_files,
test_fixture_setup,
test_require_valid_signature_expired_signature,
test_fixture_teardown);
const char *expired_missing_key_files[] = { "lgpl2.sig1", "lgpl2.sig3", NULL };
g_test_add ("/gpg-verify-result/require-valid-signature-expired-missing-key",
TestFixture,
expired_missing_key_files,
test_fixture_setup,
test_require_valid_signature_expired_missing_key,
test_fixture_teardown);
return g_test_run (); return g_test_run ();
} }

View File

@ -544,6 +544,12 @@ test_libarchive_selinux (gconstpointer data)
if (skip_if_no_xattr (td)) if (skip_if_no_xattr (td))
goto out; goto out;
if (getenv ("container"))
{
// FIXME dedup this with libtest.sh have_selinux_relabel
g_test_skip ("skip in containers for now");
goto out;
}
if (td->skip_all != NULL) if (td->skip_all != NULL)
{ {

View File

@ -28,7 +28,7 @@ fi
. $(dirname $0)/libtest.sh . $(dirname $0)/libtest.sh
echo "1..17" echo "1..18"
setup_test_repository "bare" setup_test_repository "bare"
@ -234,3 +234,17 @@ for filter in '^usr/bin/,usr/sbin/' '/bin/,/sbin/'; do
assert_file_has_content usr/lib/libfoo.so 'a library' assert_file_has_content usr/lib/libfoo.so 'a library'
echo "ok tar pathname filter modification: ${filter}" echo "ok tar pathname filter modification: ${filter}"
done done
# Test sizes metadata. This needs an archive repo, so a separate repo is used.
cd ${test_tmpdir}
rm -rf repo2
ostree_repo_init repo2 --mode=archive
${CMD_PREFIX} ostree --repo=repo2 commit \
-s "from tar" -b test-tar \
--generate-sizes \
--tree=tar=foo.tar.gz
${CMD_PREFIX} ostree --repo=repo2 show --print-sizes test-tar > sizes.txt
assert_file_has_content sizes.txt 'Compressed size (needed/total): 0[  ]bytes/1.1[  ]kB'
assert_file_has_content sizes.txt 'Unpacked size (needed/total): 0[  ]bytes/900[  ]bytes'
assert_file_has_content sizes.txt 'Number of objects (needed/total): 0/12'
echo "ok tar sizes metadata"

58
tests/test-pull-sizes.sh Executable file
View File

@ -0,0 +1,58 @@
#!/bin/bash
#
# Copyright (C) 2019 Endless Mobile, Inc.
#
# SPDX-License-Identifier: LGPL-2.0+
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
set -euo pipefail
. $(dirname $0)/libtest.sh
setup_fake_remote_repo1 "archive" "--generate-sizes"
echo '1..3'
cd ${test_tmpdir}
mkdir repo
ostree_repo_init repo
${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin $(cat httpd-address)/ostree/gnomerepo
# Pull commit metadata only. All size and objects will be needed.
${CMD_PREFIX} ostree --repo=repo pull --commit-metadata-only origin main
${CMD_PREFIX} ostree --repo=repo show --print-sizes origin:main > show.txt
assert_file_has_content show.txt 'Compressed size (needed/total): 637[  ]bytes/637[  ]bytes'
assert_file_has_content show.txt 'Unpacked size (needed/total): 457[  ]bytes/457[  ]bytes'
assert_file_has_content show.txt 'Number of objects (needed/total): 10/10'
echo "ok sizes commit metadata only"
# Pull the parent commit so we get most of the objects
parent=$(${CMD_PREFIX} ostree --repo=repo rev-parse origin:main^)
${CMD_PREFIX} ostree --repo=repo pull origin ${parent}
${CMD_PREFIX} ostree --repo=repo show --print-sizes origin:main > show.txt
assert_file_has_content show.txt 'Compressed size (needed/total): 501[  ]bytes/637[  ]bytes'
assert_file_has_content show.txt 'Unpacked size (needed/total): 429[  ]bytes/457[  ]bytes'
assert_file_has_content show.txt 'Number of objects (needed/total): 6/10'
echo "ok sizes commit partial"
# Finish pulling the commit and check that no objects needed
${CMD_PREFIX} ostree --repo=repo pull origin main
${CMD_PREFIX} ostree --repo=repo show --print-sizes origin:main > show.txt
assert_file_has_content show.txt 'Compressed size (needed/total): 0[  ]bytes/637[  ]bytes'
assert_file_has_content show.txt 'Unpacked size (needed/total): 0[  ]bytes/457[  ]bytes'
assert_file_has_content show.txt 'Number of objects (needed/total): 0/10'
echo "ok sizes commit full"

View File

@ -189,7 +189,7 @@ cp ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig{.2,}
if ${OSTREE} --repo=repo pull origin main 2>err.txt; then if ${OSTREE} --repo=repo pull origin main 2>err.txt; then
assert_not_reached "Successful pull with old summary" assert_not_reached "Successful pull with old summary"
fi fi
assert_file_has_content err.txt "none are in trusted keyring" assert_file_has_content err.txt "BAD signature"
assert_has_file repo/tmp/cache/summaries/origin assert_has_file repo/tmp/cache/summaries/origin
assert_has_file repo/tmp/cache/summaries/origin.sig assert_has_file repo/tmp/cache/summaries/origin.sig
cmp repo/tmp/cache/summaries/origin ${test_tmpdir}/ostree-srv/gnomerepo/summary.1 >&2 cmp repo/tmp/cache/summaries/origin ${test_tmpdir}/ostree-srv/gnomerepo/summary.1 >&2

View File

@ -28,7 +28,12 @@ unset OSTREE_GPG_HOME
setup_fake_remote_repo1 "archive" setup_fake_remote_repo1 "archive"
echo "1..4" # Some tests require an appropriate gpg
num_non_gpg_tests=4
num_gpg_tests=2
num_tests=$((num_non_gpg_tests + num_gpg_tests))
echo "1..${num_tests}"
cd ${test_tmpdir} cd ${test_tmpdir}
mkdir repo mkdir repo
@ -163,7 +168,7 @@ ${OSTREE} remote add --set=gpgkeypath=${test_tmpdir}/gpghome/key1.asc,${test_tmp
if ${OSTREE} pull R8:main 2>err.txt; then if ${OSTREE} pull R8:main 2>err.txt; then
assert_not_reached "Unexpectedly succeeded at pulling with different key" assert_not_reached "Unexpectedly succeeded at pulling with different key"
fi fi
assert_file_has_content err.txt "GPG signatures found, but none are in trusted keyring" assert_file_has_content err.txt "public key not found"
# Test gpgkeypath success with directory containing a valid key # Test gpgkeypath success with directory containing a valid key
${OSTREE} remote add --set=gpgkeypath=${test_tmpdir}/gpghome/ R9 $(cat httpd-address)/ostree/gnomerepo ${OSTREE} remote add --set=gpgkeypath=${test_tmpdir}/gpghome/ R9 $(cat httpd-address)/ostree/gnomerepo
@ -243,7 +248,7 @@ ${OSTREE} remote add --set=gpgkeypath=${test_tmpdir}/gpghome/key2.asc R6 $(cat h
if ${OSTREE} pull R6:main 2>err.txt; then if ${OSTREE} pull R6:main 2>err.txt; then
assert_not_reached "Unexpectedly succeeded at pulling with different key" assert_not_reached "Unexpectedly succeeded at pulling with different key"
fi fi
assert_file_has_content err.txt "GPG signatures found, but none are in trusted keyring" assert_file_has_content err.txt "public key not found"
echo "ok" echo "ok"
@ -269,7 +274,7 @@ newrev=$(${CMD_PREFIX} ostree --repo=${test_tmpdir}/ostree-srv/gnomerepo rev-par
if ${OSTREE} pull --require-static-deltas R1:main 2>err.txt; then if ${OSTREE} pull --require-static-deltas R1:main 2>err.txt; then
assert_not_reached "Unexpectedly succeeded at pulling commit signed with untrusted key" assert_not_reached "Unexpectedly succeeded at pulling commit signed with untrusted key"
fi fi
assert_file_has_content err.txt "GPG signatures found, but none are in trusted keyring" assert_file_has_content err.txt "public key not found"
echo "ok gpg untrusted signed commit for delta upgrades" echo "ok gpg untrusted signed commit for delta upgrades"
@ -280,3 +285,57 @@ ${CMD_PREFIX} ostree --repo=${test_tmpdir}/ostree-srv/gnomerepo summary -u --gpg
${OSTREE} pull --require-static-deltas R1:main ${OSTREE} pull --require-static-deltas R1:main
echo "ok gpg trusted signed commit for delta upgrades" echo "ok gpg trusted signed commit for delta upgrades"
# Run some more tests if an appropriate gpg is available
GPG=$(which_gpg)
if [ -z "${GPG}" ]; then
# Print a skip message per skipped test
for (( i = 0; i < num_gpg_tests; i++ )); do
echo "ok # SKIP this test requires gpg"
done
else
# Create a commit signed with keyid 1
echo $(date) > workdir/testfile-for-key-mangling
${CMD_PREFIX} ostree --repo=${test_tmpdir}/ostree-srv/gnomerepo commit -b main --gpg-sign ${TEST_GPG_KEYID_1} --gpg-homedir ${test_tmpdir}/gpghome workdir
# Re-add the remote
${OSTREE} remote delete R1
${OSTREE} remote add --gpg-import ${test_tmpdir}/gpghome/key1.asc R1 $(cat httpd-address)/ostree/gnomerepo | grep -o 'Imported [[:digit:]] GPG key' > result
assert_file_has_content result 'Imported 1 GPG key'
# Expire key 1, wait for it to be expired and import the expired key. Only
# new keys are reported.
${GPG} --homedir=${test_tmpdir}/gpghome --quick-set-expire ${TEST_GPG_KEYFPR_1} seconds=1
sleep 2
${GPG} --homedir=${test_tmpdir}/gpghome --armor --export ${TEST_GPG_KEYID_1} > ${test_tmpdir}/key1expired.asc
${OSTREE} remote gpg-import --keyring ${test_tmpdir}/key1expired.asc R1 | grep -o 'Imported [[:digit:]] GPG key' > result
assert_file_has_content result 'Imported 0 GPG key'
# Pulling should fail since the key is expired
rm repo/refs/remotes/* -rf
${OSTREE} prune --refs-only
if ${OSTREE} pull R1:main 2>err.txt; then
assert_not_reached "Unexpectedly succeeded at pulling commit signed with expired key"
fi
assert_file_has_content err.txt "Key expired"
echo "ok imported expired key"
# Unexpire keyid 1 and revoke it. Revoking is done by importing the
# pre-generated revocation certificate.
${GPG} --homedir=${test_tmpdir}/gpghome --quick-set-expire ${TEST_GPG_KEYFPR_1} seconds=0
${GPG} --homedir=${TEST_GPG_KEYHOME} --import ${TEST_GPG_KEYHOME}/revocations/key1.rev
${GPG} --homedir=${test_tmpdir}/gpghome --armor --export ${TEST_GPG_KEYID_1} > ${test_tmpdir}/key1revoked.asc
${OSTREE} remote gpg-import --keyring ${test_tmpdir}/key1revoked.asc R1 | grep -o 'Imported [[:digit:]] GPG key' > result
assert_file_has_content result 'Imported 0 GPG key'
# Pulling should fail since the key is revoked
rm repo/refs/remotes/* -rf
${OSTREE} prune --refs-only
if ${OSTREE} pull R1:main 2>err.txt; then
assert_not_reached "Unexpectedly succeeded at pulling commit signed with revoked key"
fi
assert_file_has_content err.txt "Key revoked"
echo "ok imported revoked key"
fi

View File

@ -28,11 +28,110 @@ function assertEquals(a, b) {
throw new Error("assertion failed " + JSON.stringify(a) + " == " + JSON.stringify(b)); throw new Error("assertion failed " + JSON.stringify(a) + " == " + JSON.stringify(b));
} }
print('1..1') function assertGreater(a, b) {
if (a <= b)
throw new Error("assertion failed " + JSON.stringify(a) + " > " + JSON.stringify(b));
}
function assertGreaterEquals(a, b) {
if (a < b)
throw new Error("assertion failed " + JSON.stringify(a) + " >= " + JSON.stringify(b));
}
// Adapted from _ostree_read_varuint64()
function readVarint(buffer) {
let result = 0;
let count = 0;
let len = buffer.length;
let cur;
do {
assertGreater(len, 0);
cur = buffer[count];
result = result | ((cur & 0x7F) << (7 * count));
count++;
len--;
} while (cur & 0x80);
return [result, count];
}
// There have been various bugs with byte array unpacking in GJS, so
// just do it manually.
function unpackByteArray(variant) {
let array = [];
let nBytes = variant.n_children();
for (let i = 0; i < nBytes; i++) {
array.push(variant.get_child_value(i).get_byte());
}
return array;
}
function validateSizes(repo, commit, expectedObjects) {
let [,commitVariant] = repo.load_variant(OSTree.ObjectType.COMMIT, commit);
let metadata = commitVariant.get_child_value(0);
let sizes = metadata.lookup_value('ostree.sizes', GLib.VariantType.new('aay'));
let nObjects = sizes.n_children();
let expectedNObjects = Object.keys(expectedObjects).length
assertEquals(nObjects, expectedNObjects);
for (let i = 0; i < nObjects; i++) {
let sizeEntry = sizes.get_child_value(i);
assertGreaterEquals(sizeEntry.n_children(), 34);
let entryBytes = unpackByteArray(sizeEntry);
let checksumBytes = entryBytes.slice(0, 32);
let checksumString = OSTree.checksum_from_bytes(checksumBytes);
print("checksum = " + checksumString);
// Read the sizes from the next 2 varints
let remainingBytes = entryBytes.slice(32);
assertGreaterEquals(remainingBytes.length, 2);
let varintRead;
let compressedSize;
let uncompressedSize;
[compressedSize, varintRead] = readVarint(remainingBytes);
remainingBytes = remainingBytes.slice(varintRead);
assertGreaterEquals(remainingBytes.length, 1);
[uncompressedSize, varintRead] = readVarint(remainingBytes);
remainingBytes = remainingBytes.slice(varintRead);
assertEquals(remainingBytes.length, 1);
let objectType = remainingBytes[0];
let objectTypeString = OSTree.object_type_to_string(objectType);
print("compressed = " + compressedSize);
print("uncompressed = " + uncompressedSize);
print("objtype = " + objectTypeString + " (" + objectType + ")");
let objectName = OSTree.object_to_string(checksumString, objectType);
print("object = " + objectName);
if (!(objectName in expectedObjects)) {
throw new Error("Object " + objectName + " not in " +
JSON.stringify(expectedObjects));
}
let expectedSizes = expectedObjects[objectName];
let expectedCompressedSize = expectedSizes[0];
let expectedUncompressedSize = expectedSizes[1];
if (compressedSize != expectedCompressedSize) {
throw new Error("Compressed size " + compressedSize +
" for checksum " + checksumString +
" does not match expected " + expectedCompressedSize);
}
if (uncompressedSize != expectedUncompressedSize) {
throw new Error("Uncompressed size " + uncompressedSize +
" for checksum " + checksumString +
" does not match expected " + expectedUncompressedSize);
}
}
}
print('1..3')
let testDataDir = Gio.File.new_for_path('test-data'); let testDataDir = Gio.File.new_for_path('test-data');
testDataDir.make_directory(null); testDataDir.make_directory(null);
testDataDir.get_child('some-file').replace_contents("hello world!", null, false, 0, null); testDataDir.get_child('some-file').replace_contents("hello world!", null, false, 0, null);
testDataDir.get_child('some-file').copy(testDataDir.get_child('duplicate-file'),
Gio.FileCopyFlags.OVERWRITE,
null, null);
testDataDir.get_child('link-file').make_symbolic_link('some-file', null);
testDataDir.get_child('another-file').replace_contents("hello world again!", null, false, 0, null); testDataDir.get_child('another-file').replace_contents("hello world again!", null, false, 0, null);
let repoPath = Gio.File.new_for_path('repo'); let repoPath = Gio.File.new_for_path('repo');
@ -41,7 +140,10 @@ repo.create(OSTree.RepoMode.ARCHIVE_Z2, null);
repo.open(null); repo.open(null);
let commitModifier = OSTree.RepoCommitModifier.new(OSTree.RepoCommitModifierFlags.GENERATE_SIZES, null); let commitModifierFlags = (OSTree.RepoCommitModifierFlags.GENERATE_SIZES |
OSTree.RepoCommitModifierFlags.SKIP_XATTRS |
OSTree.RepoCommitModifierFlags.CANONICAL_PERMISSIONS);
let commitModifier = OSTree.RepoCommitModifier.new(commitModifierFlags, null);
assertEquals(repo.get_mode(), OSTree.RepoMode.ARCHIVE_Z2); assertEquals(repo.get_mode(), OSTree.RepoMode.ARCHIVE_Z2);
@ -55,32 +157,61 @@ print("commit => " + commit);
repo.commit_transaction(null); repo.commit_transaction(null);
// Test the sizes metadata // Test the sizes metadata. The key is the object and the value is an
let [,commitVariant] = repo.load_variant(OSTree.ObjectType.COMMIT, commit); // array of compressed size and uncompressed size.
let metadata = commitVariant.get_child_value(0); let expectedObjects = {
let sizes = metadata.lookup_value('ostree.sizes', GLib.VariantType.new('aay')); 'f5ee222a21e2c96edbd6f2543c4bc8a039f827be3823d04777c9ee187778f1ad.file': [
let nSizes = sizes.n_children(); 54, 18
assertEquals(nSizes, 2); ],
let expectedUncompressedSizes = [12, 18]; 'd35bfc50864fca777dbeead3ba3689115b76674a093210316589b1fe5cc3ff4b.file': [
let foundExpectedUncompressedSizes = 0; 48, 12
for (let i = 0; i < nSizes; i++) { ],
let sizeEntry = sizes.get_child_value(i); '8322876a078e79d8c960b8b4658fe77e7b2f878f8a6cf89dbb87c6becc8128a0.file': [
assertEquals(sizeEntry.n_children(), 34); 43, 9
let compressedSize = sizeEntry.get_child_value(32).get_byte(); ],
let uncompressedSize = sizeEntry.get_child_value(33).get_byte(); '1c77033ca06eae77ed99cb26472969964314ffd5b4e4c0fd3ff6ec4265c86e51.dirtree': [
print("compressed = " + compressedSize); 185, 185
print("uncompressed = " + uncompressedSize); ],
for (let j = 0; j < expectedUncompressedSizes.length; j++) { '446a0ef11b7cc167f3b603e585c7eeeeb675faa412d5ec73f62988eb0b6c5488.dirmeta': [
let expected = expectedUncompressedSizes[j]; 12, 12
if (expected == uncompressedSize) { ],
print("Matched expected uncompressed size " + expected); };
expectedUncompressedSizes.splice(j, 1); validateSizes(repo, commit, expectedObjects);
break;
}
}
}
if (expectedUncompressedSizes.length > 0) {
throw new Error("Failed to match expectedUncompressedSizes: " + JSON.stringify(expectedUncompressedSizes));
}
print("ok test-sizes"); print("ok test-sizes");
// Remove a file to make sure that metadata is not reused from the
// previous commit. Remove that file from the expected metadata and
// replace the dirtree object.
testDataDir.get_child('another-file').delete(null);
delete expectedObjects['f5ee222a21e2c96edbd6f2543c4bc8a039f827be3823d04777c9ee187778f1ad.file'];
delete expectedObjects['1c77033ca06eae77ed99cb26472969964314ffd5b4e4c0fd3ff6ec4265c86e51.dirtree'];
expectedObjects['a384660cc18ffdb60296961dde9a2d6f78f4fec095165652cb53aa81f6dc7539.dirtree'] = [
138, 138
];
repo.prepare_transaction(null);
mtree = OSTree.MutableTree.new();
repo.write_directory_to_mtree(testDataDir, mtree, commitModifier, null);
[,dirTree] = repo.write_mtree(mtree, null);
[,commit] = repo.write_commit(null, 'Some subject', 'Some body', null, dirTree, null);
print("commit => " + commit);
repo.commit_transaction(null);
validateSizes(repo, commit, expectedObjects);
print("ok test-sizes file deleted");
// Repeat the commit now that all the objects are cached and ensure the
// metadata is still correct
repo.prepare_transaction(null);
mtree = OSTree.MutableTree.new();
repo.write_directory_to_mtree(testDataDir, mtree, commitModifier, null);
[,dirTree] = repo.write_mtree(mtree, null);
[,commit] = repo.write_commit(null, 'Another subject', 'Another body', null, dirTree, null);
print("commit => " + commit);
repo.commit_transaction(null);
validateSizes(repo, commit, expectedObjects);
print("ok test-sizes repeated");

View File

@ -2,6 +2,16 @@
this_script="${BASH_SOURCE:-$(readlink -f "$0")}" this_script="${BASH_SOURCE:-$(readlink -f "$0")}"
OSTREE_PREPARE_ROOT=$(dirname "${this_script}")/../ostree-prepare-root
if [ ! -x "${OSTREE_PREPARE_ROOT}" ]; then
# ostree-prepare-root is in $libdir by default, assume we can find it
# based on our test directory, if not we'll have to skip this test.
OSTREE_PREPARE_ROOT=$(dirname "${this_script}")/../../../lib/ostree/ostree-prepare-root
if [ ! -x "${OSTREE_PREPARE_ROOT}" ]; then
OSTREE_PREPARE_ROOT=""
fi
fi
setup_bootfs() { setup_bootfs() {
mkdir -p "$1/proc" "$1/bin" mkdir -p "$1/proc" "$1/bin"
@ -13,7 +23,7 @@ setup_bootfs() {
mount --bind "$1/override_cmdline" "$1/proc/cmdline" mount --bind "$1/override_cmdline" "$1/proc/cmdline"
touch "$1/this_is_bootfs" touch "$1/this_is_bootfs"
cp "$(dirname "$this_script")/../ostree-prepare-root" "$1/bin" cp "${OSTREE_PREPARE_ROOT}" "$1/bin"
} }
setup_rootfs() { setup_rootfs() {
@ -56,7 +66,7 @@ find_in_env() {
"$1" "$tmpdir" "$1" "$tmpdir"
enter_fs "$tmpdir" enter_fs "$tmpdir"
ostree-prepare-root /sysroot ostree-prepare-root /sysroot
find / find / \( -path /proc -o -path /sysroot/proc \) -prune -o -print
touch /usr/usr_writable 2>/null \ touch /usr/usr_writable 2>/null \
&& echo "/usr is writable" \ && echo "/usr is writable" \
|| echo "/usr is not writable" || echo "/usr is not writable"
@ -82,7 +92,9 @@ test_that_prepare_root_sets_sysroot_up_correctly_with_initrd() {
grep -qx "/this_is_bootfs" files grep -qx "/this_is_bootfs" files
grep -qx "/sysroot/this_is_ostree_root" files grep -qx "/sysroot/this_is_ostree_root" files
grep -qx "/sysroot/sysroot/this_is_real_root" files grep -qx "/sysroot/sysroot/this_is_real_root" files
if ! have_systemd_and_libmount; then
grep -qx "/sysroot/var/this_is_ostree_var" files grep -qx "/sysroot/var/this_is_ostree_var" files
fi
grep -qx "/sysroot/usr/this_is_ostree_usr" files grep -qx "/sysroot/usr/this_is_ostree_usr" files
grep -qx "/sysroot/usr is not writable" files grep -qx "/sysroot/usr is not writable" files
@ -101,7 +113,9 @@ test_that_prepare_root_sets_root_up_correctly_with_no_initrd() {
grep -qx "/this_is_ostree_root" files grep -qx "/this_is_ostree_root" files
grep -qx "/sysroot/this_is_bootfs" files grep -qx "/sysroot/this_is_bootfs" files
grep -qx "/sysroot/this_is_real_root" files grep -qx "/sysroot/this_is_real_root" files
if ! have_systemd_and_libmount; then
grep -qx "/var/this_is_ostree_var" files grep -qx "/var/this_is_ostree_var" files
fi
grep -qx "/usr/this_is_ostree_usr" files grep -qx "/usr/this_is_ostree_usr" files
grep -qx "/usr is not writable" files grep -qx "/usr is not writable" files
@ -130,6 +144,9 @@ if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
[ -f /bin/busybox ] || \ [ -f /bin/busybox ] || \
skip "this test needs busybox" skip "this test needs busybox"
[ -n "${OSTREE_PREPARE_ROOT}" ] || \
skip "this test needs ostree-prepare-root"
echo "1..3" echo "1..3"
test_that_prepare_root_sets_sysroot_up_correctly_with_initrd test_that_prepare_root_sets_sysroot_up_correctly_with_initrd
test_that_prepare_root_sets_root_up_correctly_with_no_initrd test_that_prepare_root_sets_root_up_correctly_with_no_initrd

View File

@ -54,7 +54,7 @@ echo 'ok documented symbols'
# ONLY update this checksum in release commits! # ONLY update this checksum in release commits!
cat > released-sha256.txt <<EOF cat > released-sha256.txt <<EOF
cba152efd13b9e80c35edfccde26ecd7f9555968239c5a275c9e411ad27e5183 ${released_syms} dd16acf1370f9b4ecd77d4eb7c4b45548b249f33f629d3147ddc9d264bd32e41 ${released_syms}
EOF EOF
sha256sum -c released-sha256.txt sha256sum -c released-sha256.txt