New upstream version 2017.10

This commit is contained in:
Simon McVittie 2017-08-29 15:42:08 +01:00
commit 592e798794
140 changed files with 4813 additions and 1216 deletions

21
Makefile-bash.am Normal file
View File

@ -0,0 +1,21 @@
# Makefile for bash/
#
# Copyright (C) 2017 Red Hat Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
completionsdir = @BASH_COMPLETIONSDIR@
dist_completions_DATA = bash/ostree

View File

@ -36,8 +36,6 @@ libotutil_la_SOURCES = \
src/libotutil/ot-variant-utils.h \ src/libotutil/ot-variant-utils.h \
src/libotutil/ot-gio-utils.c \ src/libotutil/ot-gio-utils.c \
src/libotutil/ot-gio-utils.h \ src/libotutil/ot-gio-utils.h \
src/libotutil/ot-log-utils.c \
src/libotutil/ot-log-utils.h \
src/libotutil/ot-gpg-utils.c \ src/libotutil/ot-gpg-utils.c \
src/libotutil/ot-gpg-utils.h \ src/libotutil/ot-gpg-utils.h \
src/libotutil/otutil.c \ src/libotutil/otutil.c \

View File

@ -111,6 +111,7 @@ endif
include Makefile-tests.am include Makefile-tests.am
include Makefile-boot.am include Makefile-boot.am
include Makefile-man.am include Makefile-man.am
include Makefile-bash.am
release-tag: release-tag:
cd $(srcdir) && git $(srcdir) tag -m "Release $(VERSION)" v$(VERSION) cd $(srcdir) && git $(srcdir) tag -m "Release $(VERSION)" v$(VERSION)

View File

@ -259,6 +259,25 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA. # Boston, MA 02111-1307, USA.
# Makefile for bash/
#
# Copyright (C) 2017 Red Hat Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
@ -528,7 +547,8 @@ am__aclocal_m4_deps = $(top_srcdir)/buildutil/attributes.m4 \
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4) $(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
$(am__configure_deps) $(am__dist_gpginsttest_DATA_DIST) \ $(am__configure_deps) $(dist_completions_DATA) \
$(am__dist_gpginsttest_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__libostreeinclude_HEADERS_DIST) $(am__DIST_COMMON) $(am__libostreeinclude_HEADERS_DIST) $(am__DIST_COMMON)
@ -576,7 +596,7 @@ am__installdirs = "$(DESTDIR)$(installed_testdir)" \
"$(DESTDIR)$(mkinitcpioinstalldir)" \ "$(DESTDIR)$(mkinitcpioinstalldir)" \
"$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" \ "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" \
"$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" \ "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" \
"$(DESTDIR)$(gpginsttestdir)" \ "$(DESTDIR)$(completionsdir)" "$(DESTDIR)$(gpginsttestdir)" \
"$(DESTDIR)$(gpginsttest_trusteddir)" \ "$(DESTDIR)$(gpginsttest_trusteddir)" \
"$(DESTDIR)$(gpgvinsttestdir)" "$(DESTDIR)$(dracutconfdir)" \ "$(DESTDIR)$(gpgvinsttestdir)" "$(DESTDIR)$(dracutconfdir)" \
"$(DESTDIR)$(girdir)" "$(DESTDIR)$(gpgreadmedir)" \ "$(DESTDIR)$(girdir)" "$(DESTDIR)$(gpgreadmedir)" \
@ -846,7 +866,6 @@ am_libotutil_la_OBJECTS = \
src/libotutil/libotutil_la-ot-unix-utils.lo \ src/libotutil/libotutil_la-ot-unix-utils.lo \
src/libotutil/libotutil_la-ot-variant-utils.lo \ src/libotutil/libotutil_la-ot-variant-utils.lo \
src/libotutil/libotutil_la-ot-gio-utils.lo \ src/libotutil/libotutil_la-ot-gio-utils.lo \
src/libotutil/libotutil_la-ot-log-utils.lo \
src/libotutil/libotutil_la-ot-gpg-utils.lo \ src/libotutil/libotutil_la-ot-gpg-utils.lo \
src/libotutil/libotutil_la-otutil.lo \ src/libotutil/libotutil_la-otutil.lo \
src/libotutil/libotutil_la-ot-tool-util.lo $(am__objects_1) src/libotutil/libotutil_la-ot-tool-util.lo $(am__objects_1)
@ -1396,12 +1415,13 @@ 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 pubring.gpg secring.gpg trustdb.gpg)
DATA = $(dist_gpginsttest_DATA) $(dist_gpginsttest_trusted_DATA) \ DATA = $(dist_completions_DATA) $(dist_gpginsttest_DATA) \
$(dist_gpgvinsttest_DATA) $(dracutconf_DATA) $(gir_DATA) \ $(dist_gpginsttest_trusted_DATA) $(dist_gpgvinsttest_DATA) \
$(gpgreadme_DATA) $(installed_test_DATA) \ $(dracutconf_DATA) $(gir_DATA) $(gpgreadme_DATA) \
$(installed_test_meta_DATA) $(mkinitcpioconf_DATA) \ $(installed_test_DATA) $(installed_test_meta_DATA) \
$(nobase_installed_test_DATA) $(noinst_DATA) $(pkgconfig_DATA) \ $(mkinitcpioconf_DATA) $(nobase_installed_test_DATA) \
$(systemdsystemunit_DATA) $(typelib_DATA) $(noinst_DATA) $(pkgconfig_DATA) $(systemdsystemunit_DATA) \
$(typelib_DATA)
am__libostreeinclude_HEADERS_DIST = src/libostree/ostree.h \ am__libostreeinclude_HEADERS_DIST = src/libostree/ostree.h \
src/libostree/ostree-async-progress.h \ src/libostree/ostree-async-progress.h \
src/libostree/ostree-autocleanups.h \ src/libostree/ostree-autocleanups.h \
@ -1679,8 +1699,8 @@ TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
$(TEST_LOG_FLAGS) $(TEST_LOG_FLAGS)
DIST_SUBDIRS = . apidoc DIST_SUBDIRS = . apidoc
am__DIST_COMMON = $(srcdir)/Makefile-boot.am \ am__DIST_COMMON = $(srcdir)/Makefile-bash.am \
$(srcdir)/Makefile-decls.am \ $(srcdir)/Makefile-boot.am $(srcdir)/Makefile-decls.am \
$(srcdir)/Makefile-libostree-defines.am \ $(srcdir)/Makefile-libostree-defines.am \
$(srcdir)/Makefile-libostree.am $(srcdir)/Makefile-man.am \ $(srcdir)/Makefile-libostree.am $(srcdir)/Makefile-man.am \
$(srcdir)/Makefile-ostree.am $(srcdir)/Makefile-otutil.am \ $(srcdir)/Makefile-ostree.am $(srcdir)/Makefile-otutil.am \
@ -1753,6 +1773,7 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@ AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@ AUTOMAKE = @AUTOMAKE@
AWK = @AWK@ AWK = @AWK@
BASH_COMPLETIONSDIR = @BASH_COMPLETIONSDIR@
BUILDOPT_FUSE_CFLAGS = @BUILDOPT_FUSE_CFLAGS@ BUILDOPT_FUSE_CFLAGS = @BUILDOPT_FUSE_CFLAGS@
BUILDOPT_FUSE_LIBS = @BUILDOPT_FUSE_LIBS@ BUILDOPT_FUSE_LIBS = @BUILDOPT_FUSE_LIBS@
CC = @CC@ CC = @CC@
@ -2152,8 +2173,6 @@ libotutil_la_SOURCES = \
src/libotutil/ot-variant-utils.h \ src/libotutil/ot-variant-utils.h \
src/libotutil/ot-gio-utils.c \ src/libotutil/ot-gio-utils.c \
src/libotutil/ot-gio-utils.h \ src/libotutil/ot-gio-utils.h \
src/libotutil/ot-log-utils.c \
src/libotutil/ot-log-utils.h \
src/libotutil/ot-gpg-utils.c \ src/libotutil/ot-gpg-utils.c \
src/libotutil/ot-gpg-utils.h \ src/libotutil/ot-gpg-utils.h \
src/libotutil/otutil.c \ src/libotutil/otutil.c \
@ -2643,6 +2662,8 @@ tests_test_gpg_verify_result_LDADD = $(TESTS_LDADD) $(OT_INTERNAL_GPGME_LIBS)
@ENABLE_MAN_TRUE@ --stringparam man.copyright.section.enabled 0 @ENABLE_MAN_TRUE@ --stringparam man.copyright.section.enabled 0
@ENABLE_MAN_TRUE@XSLTPROC_MAN = $(XSLTPROC) $(XSLTPROC_FLAGS) @ENABLE_MAN_TRUE@XSLTPROC_MAN = $(XSLTPROC) $(XSLTPROC_FLAGS)
completionsdir = @BASH_COMPLETIONSDIR@
dist_completions_DATA = bash/ostree
embed_dependency = tar -C $(srcdir) --append --exclude='.git/*' --transform="s,^embedded-dependencies/,ostree-embeddeps-$${GITVERSION}/embedded-dependencies/," --file=$${TARFILE_TMP} embed_dependency = tar -C $(srcdir) --append --exclude='.git/*' --transform="s,^embedded-dependencies/,ostree-embeddeps-$${GITVERSION}/embedded-dependencies/," --file=$${TARFILE_TMP}
git_version_rpm = $$(cd $(srcdir) && git describe | sed -e 's,-,\.,g' -e 's,^v,,') git_version_rpm = $$(cd $(srcdir) && git describe | sed -e 's,-,\.,g' -e 's,^v,,')
all: $(BUILT_SOURCES) config.h all: $(BUILT_SOURCES) config.h
@ -2652,7 +2673,7 @@ all: $(BUILT_SOURCES) config.h
.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
am--refresh: Makefile am--refresh: Makefile
@: @:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makefile-decls.am $(top_srcdir)/buildutil/glib-tap.mk $(srcdir)/libglnx/Makefile-libglnx.am.inc $(srcdir)/bsdiff/Makefile-bsdiff.am.inc $(srcdir)/Makefile-otutil.am $(srcdir)/Makefile-libostree.am $(srcdir)/Makefile-libostree-defines.am $(srcdir)/Makefile-ostree.am $(srcdir)/Makefile-switchroot.am $(srcdir)/src/rofiles-fuse/Makefile-inc.am $(srcdir)/Makefile-tests.am $(srcdir)/Makefile-boot.am $(srcdir)/Makefile-man.am $(am__configure_deps) $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makefile-decls.am $(top_srcdir)/buildutil/glib-tap.mk $(srcdir)/libglnx/Makefile-libglnx.am.inc $(srcdir)/bsdiff/Makefile-bsdiff.am.inc $(srcdir)/Makefile-otutil.am $(srcdir)/Makefile-libostree.am $(srcdir)/Makefile-libostree-defines.am $(srcdir)/Makefile-ostree.am $(srcdir)/Makefile-switchroot.am $(srcdir)/src/rofiles-fuse/Makefile-inc.am $(srcdir)/Makefile-tests.am $(srcdir)/Makefile-boot.am $(srcdir)/Makefile-man.am $(srcdir)/Makefile-bash.am $(am__configure_deps)
@for dep in $?; do \ @for dep in $?; do \
case '$(am__configure_deps)' in \ case '$(am__configure_deps)' in \
*$$dep*) \ *$$dep*) \
@ -2674,7 +2695,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac; esac;
$(srcdir)/Makefile-decls.am $(top_srcdir)/buildutil/glib-tap.mk $(srcdir)/libglnx/Makefile-libglnx.am.inc $(srcdir)/bsdiff/Makefile-bsdiff.am.inc $(srcdir)/Makefile-otutil.am $(srcdir)/Makefile-libostree.am $(srcdir)/Makefile-libostree-defines.am $(srcdir)/Makefile-ostree.am $(srcdir)/Makefile-switchroot.am $(srcdir)/src/rofiles-fuse/Makefile-inc.am $(srcdir)/Makefile-tests.am $(srcdir)/Makefile-boot.am $(srcdir)/Makefile-man.am $(am__empty): $(srcdir)/Makefile-decls.am $(top_srcdir)/buildutil/glib-tap.mk $(srcdir)/libglnx/Makefile-libglnx.am.inc $(srcdir)/bsdiff/Makefile-bsdiff.am.inc $(srcdir)/Makefile-otutil.am $(srcdir)/Makefile-libostree.am $(srcdir)/Makefile-libostree-defines.am $(srcdir)/Makefile-ostree.am $(srcdir)/Makefile-switchroot.am $(srcdir)/src/rofiles-fuse/Makefile-inc.am $(srcdir)/Makefile-tests.am $(srcdir)/Makefile-boot.am $(srcdir)/Makefile-man.am $(srcdir)/Makefile-bash.am $(am__empty):
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck $(SHELL) ./config.status --recheck
@ -3113,9 +3134,6 @@ src/libotutil/libotutil_la-ot-variant-utils.lo: \
src/libotutil/libotutil_la-ot-gio-utils.lo: \ src/libotutil/libotutil_la-ot-gio-utils.lo: \
src/libotutil/$(am__dirstamp) \ src/libotutil/$(am__dirstamp) \
src/libotutil/$(DEPDIR)/$(am__dirstamp) src/libotutil/$(DEPDIR)/$(am__dirstamp)
src/libotutil/libotutil_la-ot-log-utils.lo: \
src/libotutil/$(am__dirstamp) \
src/libotutil/$(DEPDIR)/$(am__dirstamp)
src/libotutil/libotutil_la-ot-gpg-utils.lo: \ src/libotutil/libotutil_la-ot-gpg-utils.lo: \
src/libotutil/$(am__dirstamp) \ src/libotutil/$(am__dirstamp) \
src/libotutil/$(DEPDIR)/$(am__dirstamp) src/libotutil/$(DEPDIR)/$(am__dirstamp)
@ -4220,7 +4238,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/libotutil/$(DEPDIR)/libotutil_la-ot-gio-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/libotutil/$(DEPDIR)/libotutil_la-ot-gio-utils.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/libotutil/$(DEPDIR)/libotutil_la-ot-gpg-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/libotutil/$(DEPDIR)/libotutil_la-ot-gpg-utils.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/libotutil/$(DEPDIR)/libotutil_la-ot-keyfile-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/libotutil/$(DEPDIR)/libotutil_la-ot-keyfile-utils.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/libotutil/$(DEPDIR)/libotutil_la-ot-log-utils.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/libotutil/$(DEPDIR)/libotutil_la-ot-opt-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/libotutil/$(DEPDIR)/libotutil_la-ot-opt-utils.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/libotutil/$(DEPDIR)/libotutil_la-ot-tool-util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/libotutil/$(DEPDIR)/libotutil_la-ot-tool-util.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/libotutil/$(DEPDIR)/libotutil_la-ot-unix-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/libotutil/$(DEPDIR)/libotutil_la-ot-unix-utils.Plo@am__quote@
@ -4910,13 +4927,6 @@ src/libotutil/libotutil_la-ot-gio-utils.lo: src/libotutil/ot-gio-utils.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@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libotutil_la_CFLAGS) $(CFLAGS) -c -o src/libotutil/libotutil_la-ot-gio-utils.lo `test -f 'src/libotutil/ot-gio-utils.c' || echo '$(srcdir)/'`src/libotutil/ot-gio-utils.c @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libotutil_la_CFLAGS) $(CFLAGS) -c -o src/libotutil/libotutil_la-ot-gio-utils.lo `test -f 'src/libotutil/ot-gio-utils.c' || echo '$(srcdir)/'`src/libotutil/ot-gio-utils.c
src/libotutil/libotutil_la-ot-log-utils.lo: src/libotutil/ot-log-utils.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libotutil_la_CFLAGS) $(CFLAGS) -MT src/libotutil/libotutil_la-ot-log-utils.lo -MD -MP -MF src/libotutil/$(DEPDIR)/libotutil_la-ot-log-utils.Tpo -c -o src/libotutil/libotutil_la-ot-log-utils.lo `test -f 'src/libotutil/ot-log-utils.c' || echo '$(srcdir)/'`src/libotutil/ot-log-utils.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libotutil/$(DEPDIR)/libotutil_la-ot-log-utils.Tpo src/libotutil/$(DEPDIR)/libotutil_la-ot-log-utils.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libotutil/ot-log-utils.c' object='src/libotutil/libotutil_la-ot-log-utils.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libotutil_la_CFLAGS) $(CFLAGS) -c -o src/libotutil/libotutil_la-ot-log-utils.lo `test -f 'src/libotutil/ot-log-utils.c' || echo '$(srcdir)/'`src/libotutil/ot-log-utils.c
src/libotutil/libotutil_la-ot-gpg-utils.lo: src/libotutil/ot-gpg-utils.c src/libotutil/libotutil_la-ot-gpg-utils.lo: src/libotutil/ot-gpg-utils.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libotutil_la_CFLAGS) $(CFLAGS) -MT src/libotutil/libotutil_la-ot-gpg-utils.lo -MD -MP -MF src/libotutil/$(DEPDIR)/libotutil_la-ot-gpg-utils.Tpo -c -o src/libotutil/libotutil_la-ot-gpg-utils.lo `test -f 'src/libotutil/ot-gpg-utils.c' || echo '$(srcdir)/'`src/libotutil/ot-gpg-utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libotutil_la_CFLAGS) $(CFLAGS) -MT src/libotutil/libotutil_la-ot-gpg-utils.lo -MD -MP -MF src/libotutil/$(DEPDIR)/libotutil_la-ot-gpg-utils.Tpo -c -o src/libotutil/libotutil_la-ot-gpg-utils.lo `test -f 'src/libotutil/ot-gpg-utils.c' || echo '$(srcdir)/'`src/libotutil/ot-gpg-utils.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libotutil/$(DEPDIR)/libotutil_la-ot-gpg-utils.Tpo src/libotutil/$(DEPDIR)/libotutil_la-ot-gpg-utils.Plo @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libotutil/$(DEPDIR)/libotutil_la-ot-gpg-utils.Tpo src/libotutil/$(DEPDIR)/libotutil_la-ot-gpg-utils.Plo
@ -6370,6 +6380,27 @@ uninstall-man5:
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir) dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
install-dist_completionsDATA: $(dist_completions_DATA)
@$(NORMAL_INSTALL)
@list='$(dist_completions_DATA)'; test -n "$(completionsdir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(completionsdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(completionsdir)" || 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)$(completionsdir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(completionsdir)" || exit $$?; \
done
uninstall-dist_completionsDATA:
@$(NORMAL_UNINSTALL)
@list='$(dist_completions_DATA)'; test -n "$(completionsdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(completionsdir)'; $(am__uninstall_files_from_dir)
install-dist_gpginsttestDATA: $(dist_gpginsttest_DATA) install-dist_gpginsttestDATA: $(dist_gpginsttest_DATA)
@$(NORMAL_INSTALL) @$(NORMAL_INSTALL)
@list='$(dist_gpginsttest_DATA)'; test -n "$(gpginsttestdir)" || list=; \ @list='$(dist_gpginsttest_DATA)'; test -n "$(gpginsttestdir)" || list=; \
@ -7827,7 +7858,7 @@ install-binPROGRAMS: install-libLTLIBRARIES
installdirs: installdirs-recursive installdirs: installdirs-recursive
installdirs-am: installdirs-am:
for dir in "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(privlibdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(systemdsystemgeneratordir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(dracutmoddir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(mkinitcpioinstalldir)" "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(gpginsttestdir)" "$(DESTDIR)$(gpginsttest_trusteddir)" "$(DESTDIR)$(gpgvinsttestdir)" "$(DESTDIR)$(dracutconfdir)" "$(DESTDIR)$(girdir)" "$(DESTDIR)$(gpgreadmedir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(installed_test_metadir)" "$(DESTDIR)$(mkinitcpioconfdir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(systemdsystemunitdir)" "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(libostreeincludedir)"; do \ for dir in "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(privlibdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(systemdsystemgeneratordir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(dracutmoddir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(mkinitcpioinstalldir)" "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(completionsdir)" "$(DESTDIR)$(gpginsttestdir)" "$(DESTDIR)$(gpginsttest_trusteddir)" "$(DESTDIR)$(gpgvinsttestdir)" "$(DESTDIR)$(dracutconfdir)" "$(DESTDIR)$(girdir)" "$(DESTDIR)$(gpgreadmedir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(installed_test_metadir)" "$(DESTDIR)$(mkinitcpioconfdir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(systemdsystemunitdir)" "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(libostreeincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done done
install: $(BUILT_SOURCES) install: $(BUILT_SOURCES)
@ -7915,7 +7946,8 @@ info: info-recursive
info-am: info-am:
install-data-am: install-dist_gpginsttestDATA \ install-data-am: install-dist_completionsDATA \
install-dist_gpginsttestDATA \
install-dist_gpginsttest_trustedDATA \ install-dist_gpginsttest_trustedDATA \
install-dist_gpgvinsttestDATA install-dracutconfDATA \ install-dist_gpgvinsttestDATA install-dracutconfDATA \
install-dracutmodSCRIPTS install-girDATA install-gpgreadmeDATA \ install-dracutmodSCRIPTS install-girDATA install-gpgreadmeDATA \
@ -7981,7 +8013,7 @@ ps: ps-recursive
ps-am: ps-am:
uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \ uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
uninstall-dist_gpginsttestDATA \ uninstall-dist_completionsDATA uninstall-dist_gpginsttestDATA \
uninstall-dist_gpginsttest_trustedDATA \ uninstall-dist_gpginsttest_trustedDATA \
uninstall-dist_gpgvinsttestDATA uninstall-dracutconfDATA \ uninstall-dist_gpgvinsttestDATA uninstall-dracutconfDATA \
uninstall-dracutmodSCRIPTS uninstall-girDATA \ uninstall-dracutmodSCRIPTS uninstall-girDATA \
@ -8023,7 +8055,7 @@ uninstall-man: uninstall-man1 uninstall-man5
distuninstallcheck dvi dvi-am html html-am info info-am \ distuninstallcheck dvi dvi-am html html-am info info-am \
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_gpginsttestDATA \ install-dist_completionsDATA install-dist_gpginsttestDATA \
install-dist_gpginsttest_trustedDATA \ install-dist_gpginsttest_trustedDATA \
install-dist_gpgvinsttestDATA install-dracutconfDATA \ install-dist_gpgvinsttestDATA install-dracutconfDATA \
install-dracutmodSCRIPTS install-dvi install-dvi-am \ install-dracutmodSCRIPTS install-dvi install-dvi-am \
@ -8048,7 +8080,7 @@ uninstall-man: uninstall-man1 uninstall-man5
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
recheck tags tags-am uninstall uninstall-am \ recheck tags tags-am uninstall uninstall-am \
uninstall-binPROGRAMS uninstall-binSCRIPTS \ uninstall-binPROGRAMS uninstall-binSCRIPTS \
uninstall-dist_gpginsttestDATA \ uninstall-dist_completionsDATA uninstall-dist_gpginsttestDATA \
uninstall-dist_gpginsttest_trustedDATA \ uninstall-dist_gpginsttest_trustedDATA \
uninstall-dist_gpgvinsttestDATA uninstall-dracutconfDATA \ uninstall-dist_gpgvinsttestDATA uninstall-dracutconfDATA \
uninstall-dracutmodSCRIPTS uninstall-girDATA \ uninstall-dracutmodSCRIPTS uninstall-girDATA \

View File

@ -98,9 +98,6 @@ More documentation
New! See the docs online at [Read The Docs (OSTree)](https://ostree.readthedocs.org/en/latest/ ) New! See the docs online at [Read The Docs (OSTree)](https://ostree.readthedocs.org/en/latest/ )
Some more information is available on the old wiki page:
<https://wiki.gnome.org/Projects/OSTree>
Contributing Contributing
------------ ------------

View File

@ -189,6 +189,7 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@ AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@ AUTOMAKE = @AUTOMAKE@
AWK = @AWK@ AWK = @AWK@
BASH_COMPLETIONSDIR = @BASH_COMPLETIONSDIR@
BUILDOPT_FUSE_CFLAGS = @BUILDOPT_FUSE_CFLAGS@ BUILDOPT_FUSE_CFLAGS = @BUILDOPT_FUSE_CFLAGS@
BUILDOPT_FUSE_LIBS = @BUILDOPT_FUSE_LIBS@ BUILDOPT_FUSE_LIBS = @BUILDOPT_FUSE_LIBS@
CC = @CC@ CC = @CC@

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 2017.9</p></div> <div><p class="releaseinfo">for OSTree 2017.10</p></div>
</div> </div>
<hr> <hr>
</div> </div>

View File

@ -52,6 +52,14 @@
<a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepo" title="OstreeRepo"><span class="returnvalue">OstreeRepo</span></a> * <a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepo" title="OstreeRepo"><span class="returnvalue">OstreeRepo</span></a> *
</td> </td>
<td class="function_name"> <td class="function_name">
<a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-open-at" title="ostree_repo_open_at ()">ostree_repo_open_at</a> <span class="c_punctuation">()</span>
</td>
</tr>
<tr>
<td class="function_type">
<a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepo" title="OstreeRepo"><span class="returnvalue">OstreeRepo</span></a> *
</td>
<td class="function_name">
<a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-new" title="ostree_repo_new ()">ostree_repo_new</a> <span class="c_punctuation">()</span> <a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-new" title="ostree_repo_new ()">ostree_repo_new</a> <span class="c_punctuation">()</span>
</td> </td>
</tr> </tr>
@ -113,6 +121,14 @@
</tr> </tr>
<tr> <tr>
<td class="function_type"> <td class="function_type">
<a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepo" title="OstreeRepo"><span class="returnvalue">OstreeRepo</span></a> *
</td>
<td class="function_name">
<a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-create-at" title="ostree_repo_create_at ()">ostree_repo_create_at</a> <span class="c_punctuation">()</span>
</td>
</tr>
<tr>
<td class="function_type">
<span class="returnvalue">gboolean</span> <span class="returnvalue">gboolean</span>
</td> </td>
<td class="function_name"> <td class="function_name">
@ -348,6 +364,14 @@
<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-Content-addressed-object-store.html#ostree-repo-set-alias-ref-immediate" title="ostree_repo_set_alias_ref_immediate ()">ostree_repo_set_alias_ref_immediate</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-Content-addressed-object-store.html#ostree-repo-set-cache-dir" title="ostree_repo_set_cache_dir ()">ostree_repo_set_cache_dir</a> <span class="c_punctuation">()</span> <a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-set-cache-dir" title="ostree_repo_set_cache_dir ()">ostree_repo_set_cache_dir</a> <span class="c_punctuation">()</span>
</td> </td>
</tr> </tr>
@ -1158,6 +1182,47 @@ ostree_repo_mode_from_string (<em class="parameter"><code>const <span class="typ
</div> </div>
<hr> <hr>
<div class="refsect2"> <div class="refsect2">
<a name="ostree-repo-open-at"></a><h3>ostree_repo_open_at ()</h3>
<pre class="programlisting"><a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepo" title="OstreeRepo"><span class="returnvalue">OstreeRepo</span></a> *
ostree_repo_open_at (<em class="parameter"><code><span class="type">int</span> dfd</code></em>,
<em class="parameter"><code>const <span class="type">char</span> *path</code></em>,
<em class="parameter"><code><span class="type">GCancellable</span> *cancellable</code></em>,
<em class="parameter"><code><span class="type">GError</span> **error</code></em>);</pre>
<p>This combines <a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-new" title="ostree_repo_new ()"><code class="function">ostree_repo_new()</code></a> (but using fd-relative access) with
<a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-open" title="ostree_repo_open ()"><code class="function">ostree_repo_open()</code></a>. Use this when you know you should be operating on an
already extant repository. If you want to create one, use <a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-create-at" title="ostree_repo_create_at ()"><code class="function">ostree_repo_create_at()</code></a>.</p>
<div class="refsect3">
<a name="ostree-repo-open-at.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>dfd</p></td>
<td class="parameter_description"><p>Directory fd</p></td>
<td class="parameter_annotations"> </td>
</tr>
<tr>
<td class="parameter_name"><p>path</p></td>
<td class="parameter_description"><p>Path</p></td>
<td class="parameter_annotations"> </td>
</tr>
</tbody>
</table></div>
</div>
<div class="refsect3">
<a name="ostree-repo-open-at.returns"></a><h4>Returns</h4>
<p> An accessor object for an OSTree repository located at <em class="parameter"><code>dfd</code></em>
+ <em class="parameter"><code>path</code></em>
. </p>
<p><span class="annotation">[<a href="http://foldoc.org/transfer%20full"><span class="acronym">transfer full</span></a>]</span></p>
</div>
</div>
<hr>
<div class="refsect2">
<a name="ostree-repo-new"></a><h3>ostree_repo_new ()</h3> <a name="ostree-repo-new"></a><h3>ostree_repo_new ()</h3>
<pre class="programlisting"><a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepo" title="OstreeRepo"><span class="returnvalue">OstreeRepo</span></a> * <pre class="programlisting"><a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepo" title="OstreeRepo"><span class="returnvalue">OstreeRepo</span></a> *
ostree_repo_new (<em class="parameter"><code><span class="type">GFile</span> *path</code></em>);</pre> ostree_repo_new (<em class="parameter"><code><span class="type">GFile</span> *path</code></em>);</pre>
@ -1366,6 +1431,76 @@ If the repository is not writable, the <em class="parameter"><code>error</code><
</div> </div>
<hr> <hr>
<div class="refsect2"> <div class="refsect2">
<a name="ostree-repo-create-at"></a><h3>ostree_repo_create_at ()</h3>
<pre class="programlisting"><a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepo" title="OstreeRepo"><span class="returnvalue">OstreeRepo</span></a> *
ostree_repo_create_at (<em class="parameter"><code><span class="type">int</span> dfd</code></em>,
<em class="parameter"><code>const <span class="type">char</span> *path</code></em>,
<em class="parameter"><code><a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepoMode" title="enum OstreeRepoMode"><span class="type">OstreeRepoMode</span></a> mode</code></em>,
<em class="parameter"><code><span class="type">GVariant</span> *options</code></em>,
<em class="parameter"><code><span class="type">GCancellable</span> *cancellable</code></em>,
<em class="parameter"><code><span class="type">GError</span> **error</code></em>);</pre>
<p>This is a file-descriptor relative version of <a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-create" title="ostree_repo_create ()"><code class="function">ostree_repo_create()</code></a>.
Create the underlying structure on disk for the repository, and call
<a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-open-at" title="ostree_repo_open_at ()"><code class="function">ostree_repo_open_at()</code></a> on the result, preparing it for use.</p>
<p>If a repository already exists at <em class="parameter"><code>dfd</code></em>
+ <em class="parameter"><code>path</code></em>
(defined by an <code class="literal">objects/</code>
subdirectory existing), then this function will simply call
<a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-open-at" title="ostree_repo_open_at ()"><code class="function">ostree_repo_open_at()</code></a>. In other words, this function cannot be used to change
the mode or configuration (<code class="literal">repo/config</code>) of an existing repo.</p>
<p>The <em class="parameter"><code>options</code></em>
dict may contain:</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>collection-id: s: Set as collection ID in repo/config (Since 2017.9)</p></li></ul></div>
<div class="refsect3">
<a name="ostree-repo-create-at.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>dfd</p></td>
<td class="parameter_description"><p>Directory fd</p></td>
<td class="parameter_annotations"> </td>
</tr>
<tr>
<td class="parameter_name"><p>path</p></td>
<td class="parameter_description"><p>Path</p></td>
<td class="parameter_annotations"> </td>
</tr>
<tr>
<td class="parameter_name"><p>mode</p></td>
<td class="parameter_description"><p>The mode to store the repository in</p></td>
<td class="parameter_annotations"> </td>
</tr>
<tr>
<td class="parameter_name"><p>options</p></td>
<td class="parameter_description"><p>a{sv}: See below for accepted keys</p></td>
<td class="parameter_annotations"> </td>
</tr>
<tr>
<td class="parameter_name"><p>cancellable</p></td>
<td class="parameter_description"><p>Cancellable</p></td>
<td class="parameter_annotations"> </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>
<div class="refsect3">
<a name="ostree-repo-create-at.returns"></a><h4>Returns</h4>
<p> A new OSTree repository reference. </p>
<p><span class="annotation">[<a href="http://foldoc.org/transfer%20full"><span class="acronym">transfer full</span></a>]</span></p>
</div>
</div>
<hr>
<div class="refsect2">
<a name="ostree-repo-create"></a><h3>ostree_repo_create ()</h3> <a name="ostree-repo-create"></a><h3>ostree_repo_create ()</h3>
<pre class="programlisting"><span class="returnvalue">gboolean</span> <pre class="programlisting"><span class="returnvalue">gboolean</span>
ostree_repo_create (<em class="parameter"><code><a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a> *self</code></em>, ostree_repo_create (<em class="parameter"><code><a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a> *self</code></em>,
@ -1379,6 +1514,10 @@ repository, and finish creating any necessary files in a partially
created repository. However, this function cannot change the mode created repository. However, this function cannot change the mode
of an existing repository, and will silently ignore an attempt to of an existing repository, and will silently ignore an attempt to
do so.</p> do so.</p>
<p>Since 2017.9, "existing repository" is defined by the existence of an
<code class="literal">objects</code> subdirectory.</p>
<p>This function predates <a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-create-at" title="ostree_repo_create_at ()"><code class="function">ostree_repo_create_at()</code></a>. It is an error to call
this function on a repository initialized via <a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-open-at" title="ostree_repo_open_at ()"><code class="function">ostree_repo_open_at()</code></a>.</p>
<div class="refsect3"> <div class="refsect3">
<a name="ostree-repo-create.parameters"></a><h4>Parameters</h4> <a name="ostree-repo-create.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">
@ -1417,6 +1556,24 @@ do so.</p>
<a name="ostree-repo-get-path"></a><h3>ostree_repo_get_path ()</h3> <a name="ostree-repo-get-path"></a><h3>ostree_repo_get_path ()</h3>
<pre class="programlisting"><span class="returnvalue">GFile</span> * <pre class="programlisting"><span class="returnvalue">GFile</span> *
ostree_repo_get_path (<em class="parameter"><code><a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a> *self</code></em>);</pre> ostree_repo_get_path (<em class="parameter"><code><a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a> *self</code></em>);</pre>
<p>Note that since the introduction of <a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-open-at" title="ostree_repo_open_at ()"><code class="function">ostree_repo_open_at()</code></a>, this function may
return a process-specific path in <code class="literal">/proc</code> if the repository was created using
that API. In general, you should avoid use of this API.</p>
<div class="refsect3">
<a name="ostree-repo-get-path.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>Repo</p></td>
<td class="parameter_annotations"> </td>
</tr></tbody>
</table></div>
</div>
<div class="refsect3"> <div class="refsect3">
<a name="ostree-repo-get-path.returns"></a><h4>Returns</h4> <a name="ostree-repo-get-path.returns"></a><h4>Returns</h4>
<p> Path to repo. </p> <p> Path to repo. </p>
@ -2662,6 +2819,60 @@ case where we're creating or overwriting an existing ref.</p>
</div> </div>
<hr> <hr>
<div class="refsect2"> <div class="refsect2">
<a name="ostree-repo-set-alias-ref-immediate"></a><h3>ostree_repo_set_alias_ref_immediate ()</h3>
<pre class="programlisting"><span class="returnvalue">gboolean</span>
ostree_repo_set_alias_ref_immediate (<em class="parameter"><code><a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a> *self</code></em>,
<em class="parameter"><code>const <span class="type">char</span> *remote</code></em>,
<em class="parameter"><code>const <span class="type">char</span> *ref</code></em>,
<em class="parameter"><code>const <span class="type">char</span> *target</code></em>,
<em class="parameter"><code><span class="type">GCancellable</span> *cancellable</code></em>,
<em class="parameter"><code><span class="type">GError</span> **error</code></em>);</pre>
<p>Like <a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-set-ref-immediate" title="ostree_repo_set_ref_immediate ()"><code class="function">ostree_repo_set_ref_immediate()</code></a>, but creates an alias.</p>
<div class="refsect3">
<a name="ostree-repo-set-alias-ref-immediate.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>An <a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a></p></td>
<td class="parameter_annotations"> </td>
</tr>
<tr>
<td class="parameter_name"><p>remote</p></td>
<td class="parameter_description"><p> A remote for the ref. </p></td>
<td class="parameter_annotations"><span class="annotation">[<a href="http://foldoc.org/allow-none"><span class="acronym">allow-none</span></a>]</span></td>
</tr>
<tr>
<td class="parameter_name"><p>ref</p></td>
<td class="parameter_description"><p>The ref to write</p></td>
<td class="parameter_annotations"> </td>
</tr>
<tr>
<td class="parameter_name"><p>target</p></td>
<td class="parameter_description"><p> The ref target to point it to, or <code class="literal">NULL</code> to unset. </p></td>
<td class="parameter_annotations"><span class="annotation">[<a href="http://foldoc.org/allow-none"><span class="acronym">allow-none</span></a>]</span></td>
</tr>
<tr>
<td class="parameter_name"><p>cancellable</p></td>
<td class="parameter_description"><p>GCancellable</p></td>
<td class="parameter_annotations"> </td>
</tr>
<tr>
<td class="parameter_name"><p>error</p></td>
<td class="parameter_description"><p>GError</p></td>
<td class="parameter_annotations"> </td>
</tr>
</tbody>
</table></div>
</div>
</div>
<hr>
<div class="refsect2">
<a name="ostree-repo-set-cache-dir"></a><h3>ostree_repo_set_cache_dir ()</h3> <a name="ostree-repo-set-cache-dir"></a><h3>ostree_repo_set_cache_dir ()</h3>
<pre class="programlisting"><span class="returnvalue">gboolean</span> <pre class="programlisting"><span class="returnvalue">gboolean</span>
ostree_repo_set_cache_dir (<em class="parameter"><code><a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a> *self</code></em>, ostree_repo_set_cache_dir (<em class="parameter"><code><a class="link" href="ostree-Content-addressed-object-store.html#OstreeRepo" title="OstreeRepo"><span class="type">OstreeRepo</span></a> *self</code></em>,
@ -7182,13 +7393,22 @@ in bytes, counting only content objects.</p></td>
<col class="enum_members_description"> <col class="enum_members_description">
<col width="200px" class="enum_members_annotations"> <col width="200px" class="enum_members_annotations">
</colgroup> </colgroup>
<tbody><tr> <tbody>
<tr>
<td class="enum_member_name"><p><a name="OSTREE-REPO-LIST-REFS-EXT-NONE:CAPS"></a>OSTREE_REPO_LIST_REFS_EXT_NONE</p></td> <td class="enum_member_name"><p><a name="OSTREE-REPO-LIST-REFS-EXT-NONE:CAPS"></a>OSTREE_REPO_LIST_REFS_EXT_NONE</p></td>
<td class="enum_member_description"> <td class="enum_member_description">
<p>No flags.</p> <p>No flags.</p>
</td> </td>
<td class="enum_member_annotations"> </td> <td class="enum_member_annotations"> </td>
</tr></tbody> </tr>
<tr>
<td class="enum_member_name"><p><a name="OSTREE-REPO-LIST-REFS-EXT-ALIASES:CAPS"></a>OSTREE_REPO_LIST_REFS_EXT_ALIASES</p></td>
<td class="enum_member_description">
<p>Only list aliases. Since: 2017.10</p>
</td>
<td class="enum_member_annotations"> </td>
</tr>
</tbody>
</table></div> </table></div>
</div> </div>
</div> </div>

View File

@ -115,6 +115,10 @@
</colgroup> </colgroup>
<tbody> <tbody>
<tr> <tr>
<td class="datatype_keyword">enum</td>
<td class="function_name"><a class="link" href="ostree-GPG-signature-verification-results.html#OstreeGpgError" title="enum OstreeGpgError">OstreeGpgError</a></td>
</tr>
<tr>
<td class="typedef_keyword">typedef</td> <td class="typedef_keyword">typedef</td>
<td class="function_name"><a class="link" href="ostree-GPG-signature-verification-results.html#OstreeGpgVerifyResult" title="OstreeGpgVerifyResult">OstreeGpgVerifyResult</a></td> <td class="function_name"><a class="link" href="ostree-GPG-signature-verification-results.html#OstreeGpgVerifyResult" title="OstreeGpgVerifyResult">OstreeGpgVerifyResult</a></td>
</tr> </tr>
@ -515,6 +519,46 @@ signature from trusted keyring, otherwise <code class="literal">FALSE</code></p>
<div class="refsect1"> <div class="refsect1">
<a name="ostree-GPG-signature-verification-results.other_details"></a><h2>Types and Values</h2> <a name="ostree-GPG-signature-verification-results.other_details"></a><h2>Types and Values</h2>
<div class="refsect2"> <div class="refsect2">
<a name="OstreeGpgError"></a><h3>enum OstreeGpgError</h3>
<p>Errors returned by signature creation and verification operations in OSTree.
These may be returned by any API which creates or verifies signatures.</p>
<div class="refsect3">
<a name="OstreeGpgError.members"></a><h4>Members</h4>
<div class="informaltable"><table class="informaltable" width="100%" border="0">
<colgroup>
<col width="300px" class="enum_members_name">
<col class="enum_members_description">
<col width="200px" class="enum_members_annotations">
</colgroup>
<tbody>
<tr>
<td class="enum_member_name"><p><a name="OSTREE-GPG-ERROR-NO-SIGNATURE:CAPS"></a>OSTREE_GPG_ERROR_NO_SIGNATURE</p></td>
<td class="enum_member_description">
<p>A signature was expected, but not found.</p>
</td>
<td class="enum_member_annotations"> </td>
</tr>
<tr>
<td class="enum_member_name"><p><a name="OSTREE-GPG-ERROR-INVALID-SIGNATURE:CAPS"></a>OSTREE_GPG_ERROR_INVALID_SIGNATURE</p></td>
<td class="enum_member_description">
<p>A signature was malformed.</p>
</td>
<td class="enum_member_annotations"> </td>
</tr>
<tr>
<td class="enum_member_name"><p><a name="OSTREE-GPG-ERROR-MISSING-KEY:CAPS"></a>OSTREE_GPG_ERROR_MISSING_KEY</p></td>
<td class="enum_member_description">
<p>A signature was found, but was created with a key not in the configured keyrings.</p>
</td>
<td class="enum_member_annotations"> </td>
</tr>
</tbody>
</table></div>
</div>
<p class="since">Since: 2017.10</p>
</div>
<hr>
<div class="refsect2">
<a name="OstreeGpgVerifyResult"></a><h3>OstreeGpgVerifyResult</h3> <a name="OstreeGpgVerifyResult"></a><h3>OstreeGpgVerifyResult</h3>
<pre class="programlisting">typedef struct OstreeGpgVerifyResult OstreeGpgVerifyResult; <pre class="programlisting">typedef struct OstreeGpgVerifyResult OstreeGpgVerifyResult;
</pre> </pre>

View File

@ -82,6 +82,7 @@
<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="function" name="ostree_repo_mode_from_string ()" link="ostree-Content-addressed-object-store.html#ostree-repo-mode-from-string"/> <keyword type="function" name="ostree_repo_mode_from_string ()" link="ostree-Content-addressed-object-store.html#ostree-repo-mode-from-string"/>
<keyword type="function" name="ostree_repo_open_at ()" link="ostree-Content-addressed-object-store.html#ostree-repo-open-at"/>
<keyword type="function" name="ostree_repo_new ()" link="ostree-Content-addressed-object-store.html#ostree-repo-new"/> <keyword type="function" name="ostree_repo_new ()" link="ostree-Content-addressed-object-store.html#ostree-repo-new"/>
<keyword type="function" name="ostree_repo_new_for_sysroot_path ()" link="ostree-Content-addressed-object-store.html#ostree-repo-new-for-sysroot-path"/> <keyword type="function" name="ostree_repo_new_for_sysroot_path ()" link="ostree-Content-addressed-object-store.html#ostree-repo-new-for-sysroot-path"/>
<keyword type="function" name="ostree_repo_new_default ()" link="ostree-Content-addressed-object-store.html#ostree-repo-new-default"/> <keyword type="function" name="ostree_repo_new_default ()" link="ostree-Content-addressed-object-store.html#ostree-repo-new-default"/>
@ -90,6 +91,7 @@
<keyword type="function" name="ostree_repo_get_disable_fsync ()" link="ostree-Content-addressed-object-store.html#ostree-repo-get-disable-fsync"/> <keyword type="function" name="ostree_repo_get_disable_fsync ()" link="ostree-Content-addressed-object-store.html#ostree-repo-get-disable-fsync"/>
<keyword type="function" name="ostree_repo_is_system ()" link="ostree-Content-addressed-object-store.html#ostree-repo-is-system"/> <keyword type="function" name="ostree_repo_is_system ()" link="ostree-Content-addressed-object-store.html#ostree-repo-is-system"/>
<keyword type="function" name="ostree_repo_is_writable ()" link="ostree-Content-addressed-object-store.html#ostree-repo-is-writable"/> <keyword type="function" name="ostree_repo_is_writable ()" link="ostree-Content-addressed-object-store.html#ostree-repo-is-writable"/>
<keyword type="function" name="ostree_repo_create_at ()" link="ostree-Content-addressed-object-store.html#ostree-repo-create-at"/>
<keyword type="function" name="ostree_repo_create ()" link="ostree-Content-addressed-object-store.html#ostree-repo-create"/> <keyword type="function" name="ostree_repo_create ()" link="ostree-Content-addressed-object-store.html#ostree-repo-create"/>
<keyword type="function" name="ostree_repo_get_path ()" link="ostree-Content-addressed-object-store.html#ostree-repo-get-path"/> <keyword type="function" name="ostree_repo_get_path ()" link="ostree-Content-addressed-object-store.html#ostree-repo-get-path"/>
<keyword type="function" name="ostree_repo_get_mode ()" link="ostree-Content-addressed-object-store.html#ostree-repo-get-mode"/> <keyword type="function" name="ostree_repo_get_mode ()" link="ostree-Content-addressed-object-store.html#ostree-repo-get-mode"/>
@ -119,6 +121,7 @@
<keyword type="function" name="ostree_repo_transaction_set_refspec ()" link="ostree-Content-addressed-object-store.html#ostree-repo-transaction-set-refspec"/> <keyword type="function" name="ostree_repo_transaction_set_refspec ()" link="ostree-Content-addressed-object-store.html#ostree-repo-transaction-set-refspec"/>
<keyword type="function" name="ostree_repo_transaction_set_ref ()" link="ostree-Content-addressed-object-store.html#ostree-repo-transaction-set-ref"/> <keyword type="function" name="ostree_repo_transaction_set_ref ()" link="ostree-Content-addressed-object-store.html#ostree-repo-transaction-set-ref"/>
<keyword type="function" name="ostree_repo_set_ref_immediate ()" link="ostree-Content-addressed-object-store.html#ostree-repo-set-ref-immediate"/> <keyword type="function" name="ostree_repo_set_ref_immediate ()" link="ostree-Content-addressed-object-store.html#ostree-repo-set-ref-immediate"/>
<keyword type="function" name="ostree_repo_set_alias_ref_immediate ()" link="ostree-Content-addressed-object-store.html#ostree-repo-set-alias-ref-immediate"/>
<keyword type="function" name="ostree_repo_set_cache_dir ()" link="ostree-Content-addressed-object-store.html#ostree-repo-set-cache-dir"/> <keyword type="function" name="ostree_repo_set_cache_dir ()" link="ostree-Content-addressed-object-store.html#ostree-repo-set-cache-dir"/>
<keyword type="function" name="ostree_repo_sign_delta ()" link="ostree-Content-addressed-object-store.html#ostree-repo-sign-delta"/> <keyword type="function" name="ostree_repo_sign_delta ()" link="ostree-Content-addressed-object-store.html#ostree-repo-sign-delta"/>
<keyword type="function" name="ostree_repo_has_object ()" link="ostree-Content-addressed-object-store.html#ostree-repo-has-object"/> <keyword type="function" name="ostree_repo_has_object ()" link="ostree-Content-addressed-object-store.html#ostree-repo-has-object"/>
@ -320,6 +323,7 @@
<keyword type="function" name="ostree_gpg_verify_result_describe ()" link="ostree-GPG-signature-verification-results.html#ostree-gpg-verify-result-describe"/> <keyword type="function" name="ostree_gpg_verify_result_describe ()" link="ostree-GPG-signature-verification-results.html#ostree-gpg-verify-result-describe"/>
<keyword type="function" name="ostree_gpg_verify_result_describe_variant ()" link="ostree-GPG-signature-verification-results.html#ostree-gpg-verify-result-describe-variant"/> <keyword type="function" name="ostree_gpg_verify_result_describe_variant ()" link="ostree-GPG-signature-verification-results.html#ostree-gpg-verify-result-describe-variant"/>
<keyword type="function" name="ostree_gpg_verify_result_require_valid_signature ()" link="ostree-GPG-signature-verification-results.html#ostree-gpg-verify-result-require-valid-signature"/> <keyword type="function" name="ostree_gpg_verify_result_require_valid_signature ()" link="ostree-GPG-signature-verification-results.html#ostree-gpg-verify-result-require-valid-signature"/>
<keyword type="enum" name="enum OstreeGpgError" link="ostree-GPG-signature-verification-results.html#OstreeGpgError" since="2017.10"/>
<keyword type="typedef" name="OstreeGpgVerifyResult" link="ostree-GPG-signature-verification-results.html#OstreeGpgVerifyResult"/> <keyword type="typedef" name="OstreeGpgVerifyResult" link="ostree-GPG-signature-verification-results.html#OstreeGpgVerifyResult"/>
<keyword type="enum" name="enum OstreeGpgSignatureAttr" link="ostree-GPG-signature-verification-results.html#OstreeGpgSignatureAttr"/> <keyword type="enum" name="enum OstreeGpgSignatureAttr" link="ostree-GPG-signature-verification-results.html#OstreeGpgSignatureAttr"/>
<keyword type="enum" name="enum OstreeGpgSignatureFormatFlags" link="ostree-GPG-signature-verification-results.html#OstreeGpgSignatureFormatFlags"/> <keyword type="enum" name="enum OstreeGpgSignatureFormatFlags" link="ostree-GPG-signature-verification-results.html#OstreeGpgSignatureFormatFlags"/>
@ -392,6 +396,7 @@
<keyword type="constant" name="OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS" link="ostree-Content-addressed-object-store.html#OSTREE-REPO-REMOTE-CHANGE-DELETE-IF-EXISTS:CAPS"/> <keyword type="constant" name="OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS" link="ostree-Content-addressed-object-store.html#OSTREE-REPO-REMOTE-CHANGE-DELETE-IF-EXISTS:CAPS"/>
<keyword type="constant" name="OSTREE_REPO_RESOLVE_REV_EXT_NONE" link="ostree-Content-addressed-object-store.html#OSTREE-REPO-RESOLVE-REV-EXT-NONE:CAPS"/> <keyword type="constant" name="OSTREE_REPO_RESOLVE_REV_EXT_NONE" link="ostree-Content-addressed-object-store.html#OSTREE-REPO-RESOLVE-REV-EXT-NONE:CAPS"/>
<keyword type="constant" name="OSTREE_REPO_LIST_REFS_EXT_NONE" link="ostree-Content-addressed-object-store.html#OSTREE-REPO-LIST-REFS-EXT-NONE:CAPS"/> <keyword type="constant" name="OSTREE_REPO_LIST_REFS_EXT_NONE" link="ostree-Content-addressed-object-store.html#OSTREE-REPO-LIST-REFS-EXT-NONE:CAPS"/>
<keyword type="constant" name="OSTREE_REPO_LIST_REFS_EXT_ALIASES" link="ostree-Content-addressed-object-store.html#OSTREE-REPO-LIST-REFS-EXT-ALIASES:CAPS"/>
<keyword type="constant" name="OSTREE_REPO_COMMIT_STATE_PARTIAL" link="ostree-Content-addressed-object-store.html#OSTREE-REPO-COMMIT-STATE-PARTIAL:CAPS"/> <keyword type="constant" name="OSTREE_REPO_COMMIT_STATE_PARTIAL" link="ostree-Content-addressed-object-store.html#OSTREE-REPO-COMMIT-STATE-PARTIAL:CAPS"/>
<keyword type="constant" name="OSTREE_REPO_COMMIT_FILTER_ALLOW" link="ostree-Content-addressed-object-store.html#OSTREE-REPO-COMMIT-FILTER-ALLOW:CAPS"/> <keyword type="constant" name="OSTREE_REPO_COMMIT_FILTER_ALLOW" link="ostree-Content-addressed-object-store.html#OSTREE-REPO-COMMIT-FILTER-ALLOW:CAPS"/>
<keyword type="constant" name="OSTREE_REPO_COMMIT_FILTER_SKIP" link="ostree-Content-addressed-object-store.html#OSTREE-REPO-COMMIT-FILTER-SKIP:CAPS"/> <keyword type="constant" name="OSTREE_REPO_COMMIT_FILTER_SKIP" link="ostree-Content-addressed-object-store.html#OSTREE-REPO-COMMIT-FILTER-SKIP:CAPS"/>
@ -436,6 +441,9 @@
<keyword type="constant" name="OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_NONE" link="ostree-Simple-upgrade-class.html#OSTREE-SYSROOT-UPGRADER-PULL-FLAGS-NONE:CAPS"/> <keyword type="constant" name="OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_NONE" link="ostree-Simple-upgrade-class.html#OSTREE-SYSROOT-UPGRADER-PULL-FLAGS-NONE:CAPS"/>
<keyword type="constant" name="OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_ALLOW_OLDER" link="ostree-Simple-upgrade-class.html#OSTREE-SYSROOT-UPGRADER-PULL-FLAGS-ALLOW-OLDER:CAPS"/> <keyword type="constant" name="OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_ALLOW_OLDER" link="ostree-Simple-upgrade-class.html#OSTREE-SYSROOT-UPGRADER-PULL-FLAGS-ALLOW-OLDER:CAPS"/>
<keyword type="constant" name="OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_SYNTHETIC" link="ostree-Simple-upgrade-class.html#OSTREE-SYSROOT-UPGRADER-PULL-FLAGS-SYNTHETIC:CAPS"/> <keyword type="constant" name="OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_SYNTHETIC" link="ostree-Simple-upgrade-class.html#OSTREE-SYSROOT-UPGRADER-PULL-FLAGS-SYNTHETIC: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_MISSING_KEY" link="ostree-GPG-signature-verification-results.html#OSTREE-GPG-ERROR-MISSING-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"/>

View File

@ -417,6 +417,10 @@ OSTREE_CHECK_VERSION, macro in ostree-version
<dd></dd> <dd></dd>
<a name="idxG"></a><h3 class="title">G</h3> <a name="idxG"></a><h3 class="title">G</h3>
<dt> <dt>
<a class="link" href="ostree-GPG-signature-verification-results.html#OstreeGpgError" title="enum OstreeGpgError">OstreeGpgError</a>, enum in <a class="link" href="ostree-GPG-signature-verification-results.html" title="GPG signature verification results">GPG signature verification results</a>
</dt>
<dd></dd>
<dt>
<a class="link" href="ostree-GPG-signature-verification-results.html#OstreeGpgSignatureAttr" title="enum OstreeGpgSignatureAttr">OstreeGpgSignatureAttr</a>, enum in <a class="link" href="ostree-GPG-signature-verification-results.html" title="GPG signature verification results">GPG signature verification results</a> <a class="link" href="ostree-GPG-signature-verification-results.html#OstreeGpgSignatureAttr" title="enum OstreeGpgSignatureAttr">OstreeGpgSignatureAttr</a>, enum in <a class="link" href="ostree-GPG-signature-verification-results.html" title="GPG signature verification results">GPG signature verification results</a>
</dt> </dt>
<dd></dd> <dd></dd>
@ -762,6 +766,10 @@ OSTREE_RELEASE_VERSION, macro in ostree-version
</dt> </dt>
<dd></dd> <dd></dd>
<dt> <dt>
<a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-create-at" title="ostree_repo_create_at ()">ostree_repo_create_at</a>, function in <a class="link" href="ostree-Content-addressed-object-store.html" title="Content-addressed object store">Content-addressed object store</a>
</dt>
<dd></dd>
<dt>
<a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-delete-object" title="ostree_repo_delete_object ()">ostree_repo_delete_object</a>, function in <a class="link" href="ostree-Content-addressed-object-store.html" title="Content-addressed object store">Content-addressed object store</a> <a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-delete-object" title="ostree_repo_delete_object ()">ostree_repo_delete_object</a>, function in <a class="link" href="ostree-Content-addressed-object-store.html" title="Content-addressed object store">Content-addressed object store</a>
</dt> </dt>
<dd></dd> <dd></dd>
@ -962,6 +970,10 @@ OSTREE_RELEASE_VERSION, macro in ostree-version
</dt> </dt>
<dd></dd> <dd></dd>
<dt> <dt>
<a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-open-at" title="ostree_repo_open_at ()">ostree_repo_open_at</a>, function in <a class="link" href="ostree-Content-addressed-object-store.html" title="Content-addressed object store">Content-addressed object store</a>
</dt>
<dd></dd>
<dt>
<a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-prepare-transaction" title="ostree_repo_prepare_transaction ()">ostree_repo_prepare_transaction</a>, function in <a class="link" href="ostree-Content-addressed-object-store.html" title="Content-addressed object store">Content-addressed object store</a> <a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-prepare-transaction" title="ostree_repo_prepare_transaction ()">ostree_repo_prepare_transaction</a>, function in <a class="link" href="ostree-Content-addressed-object-store.html" title="Content-addressed object store">Content-addressed object store</a>
</dt> </dt>
<dd></dd> <dd></dd>
@ -1070,6 +1082,10 @@ OSTREE_RELEASE_VERSION, macro in ostree-version
</dt> </dt>
<dd></dd> <dd></dd>
<dt> <dt>
<a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-set-alias-ref-immediate" title="ostree_repo_set_alias_ref_immediate ()">ostree_repo_set_alias_ref_immediate</a>, function in <a class="link" href="ostree-Content-addressed-object-store.html" title="Content-addressed object store">Content-addressed object store</a>
</dt>
<dd></dd>
<dt>
<a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-set-cache-dir" title="ostree_repo_set_cache_dir ()">ostree_repo_set_cache_dir</a>, function in <a class="link" href="ostree-Content-addressed-object-store.html" title="Content-addressed object store">Content-addressed object store</a> <a class="link" href="ostree-Content-addressed-object-store.html#ostree-repo-set-cache-dir" title="ostree_repo_set_cache_dir ()">ostree_repo_set_cache_dir</a>, function in <a class="link" href="ostree-Content-addressed-object-store.html" title="Content-addressed object store">Content-addressed object store</a>
</dt> </dt>
<dd></dd> <dd></dd>

View File

@ -82,6 +82,7 @@ ostree_repo_get_collection_id
ostree_repo_set_collection_id ostree_repo_set_collection_id
ostree_validate_collection_id ostree_validate_collection_id
ostree_repo_list_collection_refs ostree_repo_list_collection_refs
ostree_repo_remote_list_collection_refs
ostree_repo_set_collection_ref_immediate ostree_repo_set_collection_ref_immediate
ostree_repo_transaction_set_collection_ref ostree_repo_transaction_set_collection_ref
</SECTION> </SECTION>

View File

@ -194,6 +194,7 @@ ostree_diff_item_get_type
<SECTION> <SECTION>
<FILE>ostree-gpg-verify-result</FILE> <FILE>ostree-gpg-verify-result</FILE>
OstreeGpgError
OstreeGpgVerifyResult OstreeGpgVerifyResult
OstreeGpgSignatureAttr OstreeGpgSignatureAttr
ostree_gpg_verify_result_count_all ostree_gpg_verify_result_count_all
@ -210,6 +211,8 @@ OSTREE_GPG_VERIFY_RESULT
OSTREE_IS_GPG_VERIFY_RESULT OSTREE_IS_GPG_VERIFY_RESULT
OSTREE_TYPE_GPG_VERIFY_RESULT OSTREE_TYPE_GPG_VERIFY_RESULT
ostree_gpg_verify_result_get_type ostree_gpg_verify_result_get_type
OSTREE_GPG_ERROR
ostree_gpg_error_quark
</SECTION> </SECTION>
<FILE>ostree-lzma-compressor</FILE> <FILE>ostree-lzma-compressor</FILE>
@ -268,6 +271,7 @@ ostree_mutable_tree_get_type
OstreeRepo OstreeRepo
OstreeRepoMode OstreeRepoMode
ostree_repo_mode_from_string ostree_repo_mode_from_string
ostree_repo_open_at
ostree_repo_new ostree_repo_new
ostree_repo_new_for_sysroot_path ostree_repo_new_for_sysroot_path
ostree_repo_new_default ostree_repo_new_default
@ -276,6 +280,7 @@ ostree_repo_set_disable_fsync
ostree_repo_get_disable_fsync ostree_repo_get_disable_fsync
ostree_repo_is_system ostree_repo_is_system
ostree_repo_is_writable ostree_repo_is_writable
ostree_repo_create_at
ostree_repo_create ostree_repo_create
ostree_repo_get_path ostree_repo_get_path
ostree_repo_get_mode ostree_repo_get_mode
@ -307,6 +312,7 @@ ostree_repo_abort_transaction
ostree_repo_transaction_set_refspec ostree_repo_transaction_set_refspec
ostree_repo_transaction_set_ref ostree_repo_transaction_set_ref
ostree_repo_set_ref_immediate ostree_repo_set_ref_immediate
ostree_repo_set_alias_ref_immediate
ostree_repo_set_cache_dir ostree_repo_set_cache_dir
ostree_repo_sign_delta ostree_repo_sign_delta
ostree_repo_has_object ostree_repo_has_object

View File

@ -1 +1 @@
2017.9 2017.10

View File

@ -28,7 +28,6 @@ else
gtkdocize gtkdocize
fi fi
cd $olddir
if ! test -f libglnx/README.md || ! test -f bsdiff/README.md; then if ! test -f libglnx/README.md || ! test -f bsdiff/README.md; then
git submodule update --init git submodule update --init
fi fi
@ -41,4 +40,5 @@ ln -sf ../libglnx/libglnx.m4 buildutil/libglnx.m4
autoreconf --force --install --verbose autoreconf --force --install --verbose
cd $olddir
test -n "$NOCONFIGURE" || "$srcdir/configure" "$@" test -n "$NOCONFIGURE" || "$srcdir/configure" "$@"

2148
bash/ostree Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,8 @@
/* config.h.in. Generated from configure.ac by autoheader. */ /* config.h.in. Generated from configure.ac by autoheader. */
/* Define if we are building with -fsanitize=address */
#undef BUILDOPT_ASAN
/* Define if we are enabling ostree trivial-httpd entrypoint */ /* Define if we are enabling ostree trivial-httpd entrypoint */
#undef BUILDOPT_ENABLE_TRIVIAL_HTTPD_CMDLINE #undef BUILDOPT_ENABLE_TRIVIAL_HTTPD_CMDLINE
@ -9,6 +12,9 @@
/* Define if systemd and libmount */ /* Define if systemd and libmount */
#undef BUILDOPT_LIBSYSTEMD_AND_LIBMOUNT #undef BUILDOPT_LIBSYSTEMD_AND_LIBMOUNT
/* Define if we are building with -fsanitize=thread */
#undef BUILDOPT_TSAN
/* Define if we should avoid using O_TMPFILE */ /* Define if we should avoid using O_TMPFILE */
#undef DISABLE_OTMPFILE #undef DISABLE_OTMPFILE

92
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 2017.9. # Generated by GNU Autoconf 2.69 for libostree 2017.10.
# #
# 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='2017.9' PACKAGE_VERSION='2017.10'
PACKAGE_STRING='libostree 2017.9' PACKAGE_STRING='libostree 2017.10'
PACKAGE_BUGREPORT='walters@verbum.org' PACKAGE_BUGREPORT='walters@verbum.org'
PACKAGE_URL='' PACKAGE_URL=''
@ -764,6 +764,7 @@ GOBJECT_QUERY
GLIB_GENMARSHAL GLIB_GENMARSHAL
GLIB_LIBS GLIB_LIBS
GLIB_CFLAGS GLIB_CFLAGS
BASH_COMPLETIONSDIR
PKG_CONFIG_LIBDIR PKG_CONFIG_LIBDIR
PKG_CONFIG_PATH PKG_CONFIG_PATH
PKG_CONFIG PKG_CONFIG
@ -804,6 +805,8 @@ build_vendor
build_cpu build_cpu
build build
LIBTOOL LIBTOOL
BUILDOPT_TSAN_FALSE
BUILDOPT_TSAN_TRUE
BUILDOPT_ASAN_FALSE BUILDOPT_ASAN_FALSE
BUILDOPT_ASAN_TRUE BUILDOPT_ASAN_TRUE
WARN_CFLAGS WARN_CFLAGS
@ -963,6 +966,7 @@ LT_SYS_LIBRARY_PATH
PKG_CONFIG PKG_CONFIG
PKG_CONFIG_PATH PKG_CONFIG_PATH
PKG_CONFIG_LIBDIR PKG_CONFIG_LIBDIR
BASH_COMPLETIONSDIR
OT_DEP_GIO_UNIX_CFLAGS OT_DEP_GIO_UNIX_CFLAGS
OT_DEP_GIO_UNIX_LIBS OT_DEP_GIO_UNIX_LIBS
OT_DEP_LZMA_CFLAGS OT_DEP_LZMA_CFLAGS
@ -1533,7 +1537,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 2017.9 to adapt to many kinds of systems. \`configure' configures libostree 2017.10 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1603,7 +1607,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 2017.9:";; short | recursive ) echo "Configuration of libostree 2017.10:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1712,6 +1716,9 @@ Some influential environment variables:
directories to add to pkg-config's search path directories to add to pkg-config's search path
PKG_CONFIG_LIBDIR PKG_CONFIG_LIBDIR
path overriding pkg-config's built-in search path path overriding pkg-config's built-in search path
BASH_COMPLETIONSDIR
value of completionsdir for bash-completion, overriding
pkg-config
OT_DEP_GIO_UNIX_CFLAGS OT_DEP_GIO_UNIX_CFLAGS
C compiler flags for OT_DEP_GIO_UNIX, overriding pkg-config C compiler flags for OT_DEP_GIO_UNIX, overriding pkg-config
OT_DEP_GIO_UNIX_LIBS OT_DEP_GIO_UNIX_LIBS
@ -1839,7 +1846,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 2017.9 libostree configure 2017.10
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.
@ -2254,7 +2261,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 2017.9, which was It was created by libostree $as_me 2017.10, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@ -3122,7 +3129,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='libostree' PACKAGE='libostree'
VERSION='2017.9' VERSION='2017.10'
# Some tools Automake needs. # Some tools Automake needs.
@ -5856,9 +5863,9 @@ test -n "$YACC" || YACC="yacc"
YEAR_VERSION=2017 YEAR_VERSION=2017
RELEASE_VERSION=9 RELEASE_VERSION=10
PACKAGE_VERSION=2017.9 PACKAGE_VERSION=2017.10
if echo "$CFLAGS" | grep -q -E -e '-Werror($| )'; then : if echo "$CFLAGS" | grep -q -E -e '-Werror($| )'; then :
@ -5937,6 +5944,35 @@ else
BUILDOPT_ASAN_FALSE= BUILDOPT_ASAN_FALSE=
fi fi
if test -z "$BUILDOPT_ASAN_TRUE"; then :
$as_echo "#define BUILDOPT_ASAN 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fsanitize=thread in CFLAGS" >&5
$as_echo_n "checking for -fsanitize=thread in CFLAGS... " >&6; }
if echo $CFLAGS | grep -q -e -fsanitize=thread; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
using_tsan=yes
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test x$using_tsan = xyes; then
BUILDOPT_TSAN_TRUE=
BUILDOPT_TSAN_FALSE='#'
else
BUILDOPT_TSAN_TRUE='#'
BUILDOPT_TSAN_FALSE=
fi
if test -z "$BUILDOPT_TSAN_TRUE"; then :
$as_echo "#define BUILDOPT_TSAN 1" >>confdefs.h
fi
# Initialize libtool # Initialize libtool
@ -13878,6 +13914,34 @@ $as_echo "no" >&6; }
fi fi
fi fi
# PKG_CHECK_VAR added to pkg-config 0.28
if test -n "$BASH_COMPLETIONSDIR"; then
pkg_cv_BASH_COMPLETIONSDIR="$BASH_COMPLETIONSDIR"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"bash-completion\""; } >&5
($PKG_CONFIG --exists --print-errors "bash-completion") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_BASH_COMPLETIONSDIR=`$PKG_CONFIG --variable="completionsdir" "bash-completion" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
BASH_COMPLETIONSDIR=$pkg_cv_BASH_COMPLETIONSDIR
if test "x$BASH_COMPLETIONSDIR" = x""; then :
BASH_COMPLETIONSDIR="${datadir}/bash-completion/completions"
fi
# Check whether --enable-glibtest was given. # Check whether --enable-glibtest was given.
if test "${enable_glibtest+set}" = set; then : if test "${enable_glibtest+set}" = set; then :
enableval=$enable_glibtest; enableval=$enable_glibtest;
@ -17416,6 +17480,10 @@ if test -z "${BUILDOPT_ASAN_TRUE}" && test -z "${BUILDOPT_ASAN_FALSE}"; then
as_fn_error $? "conditional \"BUILDOPT_ASAN\" was never defined. as_fn_error $? "conditional \"BUILDOPT_ASAN\" 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_TSAN_TRUE}" && test -z "${BUILDOPT_TSAN_FALSE}"; then
as_fn_error $? "conditional \"BUILDOPT_TSAN\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${ENABLE_INSTALLED_TESTS_TRUE}" && test -z "${ENABLE_INSTALLED_TESTS_FALSE}"; then if test -z "${ENABLE_INSTALLED_TESTS_TRUE}" && test -z "${ENABLE_INSTALLED_TESTS_FALSE}"; then
as_fn_error $? "conditional \"ENABLE_INSTALLED_TESTS\" was never defined. as_fn_error $? "conditional \"ENABLE_INSTALLED_TESTS\" 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
@ -17961,7 +18029,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 2017.9, which was This file was extended by libostree $as_me 2017.10, 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
@ -18027,7 +18095,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 2017.9 libostree config.status 2017.10
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\\"

View File

@ -4,7 +4,7 @@ dnl update libostree-released.sym from libostree-devel.sym, and update the check
dnl in test-symbols.sh, and also set is_release_build=yes below. Then make dnl in test-symbols.sh, and also set is_release_build=yes below. Then make
dnl another post-release commit to bump the version, and set is_release_build=no. dnl another post-release commit to bump the version, and set is_release_build=no.
m4_define([year_version], [2017]) m4_define([year_version], [2017])
m4_define([release_version], [9]) m4_define([release_version], [10])
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
@ -58,6 +58,19 @@ else
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
fi fi
AM_CONDITIONAL(BUILDOPT_ASAN, [test x$using_asan = xyes]) AM_CONDITIONAL(BUILDOPT_ASAN, [test x$using_asan = xyes])
AM_COND_IF([BUILDOPT_ASAN],
[AC_DEFINE([BUILDOPT_ASAN], 1, [Define if we are building with -fsanitize=address])])
AC_MSG_CHECKING([for -fsanitize=thread in CFLAGS])
if echo $CFLAGS | grep -q -e -fsanitize=thread; then
AC_MSG_RESULT([yes])
using_tsan=yes
else
AC_MSG_RESULT([no])
fi
AM_CONDITIONAL(BUILDOPT_TSAN, [test x$using_tsan = xyes])
AM_COND_IF([BUILDOPT_TSAN],
[AC_DEFINE([BUILDOPT_TSAN], 1, [Define if we are building with -fsanitize=thread])])
# Initialize libtool # Initialize libtool
LT_PREREQ([2.2.4]) LT_PREREQ([2.2.4])
@ -75,6 +88,17 @@ AS_IF([test "$YACC" != "bison -y"], [AC_MSG_ERROR([bison not found but required]
PKG_PROG_PKG_CONFIG PKG_PROG_PKG_CONFIG
# PKG_CHECK_VAR added to pkg-config 0.28
m4_define_default(
[PKG_CHECK_VAR],
[AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])
AS_IF([test -z "$$1"], [$1=`$PKG_CONFIG --variable="$3" "$2"`])
AS_IF([test -n "$$1"], [$4], [$5])])
PKG_CHECK_VAR(BASH_COMPLETIONSDIR, [bash-completion], [completionsdir], ,
BASH_COMPLETIONSDIR="${datadir}/bash-completion/completions")
AC_SUBST(BASH_COMPLETIONSDIR)
AM_PATH_GLIB_2_0(,,AC_MSG_ERROR([GLib not found])) AM_PATH_GLIB_2_0(,,AC_MSG_ERROR([GLib not found]))
dnl When bumping the gio-unix-2.0 dependency (or glib-2.0 in general), dnl When bumping the gio-unix-2.0 dependency (or glib-2.0 in general),

View File

@ -187,11 +187,12 @@ text_percent_internal (const char *text,
const guint n_spaces = sizeof (spaces) - 1; const guint n_spaces = sizeof (spaces) - 1;
const guint ncolumns = glnx_console_columns (); const guint ncolumns = glnx_console_columns ();
const guint bar_min = 10; const guint bar_min = 10;
const guint input_textlen = text ? strlen (text) : 0;
if (text && !*text) if (text && !*text)
text = NULL; text = NULL;
const guint input_textlen = text ? strlen (text) : 0;
if (percentage == current_percent if (percentage == current_percent
&& g_strcmp0 (text, current_text) == 0) && g_strcmp0 (text, current_text) == 0)
return; return;
@ -221,6 +222,7 @@ text_percent_internal (const char *text,
if (percentage == -1) if (percentage == -1)
{ {
if (text != NULL)
fwrite (text, 1, input_textlen, stdout); fwrite (text, 1, input_textlen, stdout);
/* Overwrite remaining space, if any */ /* Overwrite remaining space, if any */
@ -273,7 +275,7 @@ void
glnx_console_progress_text_percent (const char *text, glnx_console_progress_text_percent (const char *text,
guint percentage) guint percentage)
{ {
g_return_if_fail (percentage >= 0 && percentage <= 100); g_return_if_fail (percentage <= 100);
text_percent_internal (text, percentage); text_percent_internal (text, percentage);
} }

View File

@ -83,7 +83,7 @@ typedef struct GLnxRealDirfdIterator GLnxRealDirfdIterator;
/** /**
* glnx_dirfd_iterator_init_at: * glnx_dirfd_iterator_init_at:
* @dfd: File descriptor, may be AT_FDCWD or -1 * @dfd: File descriptor, may be AT_FDCWD or -1
* @path: Path, may be relative to @df * @path: Path, may be relative to @dfd
* @follow: If %TRUE and the last component of @path is a symlink, follow it * @follow: If %TRUE and the last component of @path is a symlink, follow it
* @out_dfd_iter: (out caller-allocates): A directory iterator, will be initialized * @out_dfd_iter: (out caller-allocates): A directory iterator, will be initialized
* @error: Error * @error: Error

View File

@ -31,9 +31,6 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/sendfile.h> #include <sys/sendfile.h>
#include <errno.h> #include <errno.h>
/* See linux.git/fs/btrfs/ioctl.h */
#define BTRFS_IOCTL_MAGIC 0x94
#define BTRFS_IOC_CLONE _IOW(BTRFS_IOCTL_MAGIC, 9, int)
#include <glnx-fdio.h> #include <glnx-fdio.h>
#include <glnx-dirfd.h> #include <glnx-dirfd.h>
@ -43,6 +40,11 @@
#include <glnx-local-alloc.h> #include <glnx-local-alloc.h>
#include <glnx-missing.h> #include <glnx-missing.h>
/* The standardized version of BTRFS_IOC_CLONE */
#ifndef FICLONE
#define FICLONE _IOW(0x94, 9, int)
#endif
/* Returns the number of chars needed to format variables of the /* Returns the number of chars needed to format variables of the
* specified type as a decimal string. Adds in extra space for a * specified type as a decimal string. Adds in extra space for a
* negative '-' prefix (hence works correctly on signed * negative '-' prefix (hence works correctly on signed
@ -654,13 +656,6 @@ copy_symlink_at (int src_dfd,
* conveniently fit in with the rest of libglnx. * conveniently fit in with the rest of libglnx.
*/ */
static int btrfs_reflink(int infd, int outfd) {
g_return_val_if_fail(infd >= 0, -1);
g_return_val_if_fail(outfd >= 0, -1);
return ioctl (outfd, BTRFS_IOC_CLONE, infd);
}
/* Like write(), but loop until @nbytes are written, or an error /* Like write(), but loop until @nbytes are written, or an error
* occurs. * occurs.
* *
@ -703,8 +698,10 @@ glnx_loop_write(int fd, const void *buf, size_t nbytes)
return 0; return 0;
} }
/* Read from @fdf until EOF, writing to @fdt. If @try_reflink is %TRUE, /* Read from @fdf until EOF, writing to @fdt. If max_bytes is -1, a full-file
* attempt to use any "reflink" functionality; see e.g. https://lwn.net/Articles/331808/ * clone will be attempted. Otherwise Linux copy_file_range(), sendfile()
* syscall will be attempted. If none of those work, this function will do a
* plain read()/write() loop.
* *
* The file descriptor @fdf must refer to a regular file. * The file descriptor @fdf must refer to a regular file.
* *
@ -712,58 +709,123 @@ glnx_loop_write(int fd, const void *buf, size_t nbytes)
* On error, this function returns `-1` and @errno will be set. * On error, this function returns `-1` and @errno will be set.
*/ */
int int
glnx_regfile_copy_bytes (int fdf, int fdt, off_t max_bytes, gboolean try_reflink) glnx_regfile_copy_bytes (int fdf, int fdt, off_t max_bytes)
{ {
bool try_sendfile = true; /* Last updates from systemd as of commit 6bda23dd6aaba50cf8e3e6024248cf736cc443ca */
int r; static int have_cfr = -1; /* -1 means unknown */
bool try_cfr = have_cfr != 0;
static int have_sendfile = -1; /* -1 means unknown */
bool try_sendfile = have_sendfile != 0;
g_return_val_if_fail (fdf >= 0, -1); g_return_val_if_fail (fdf >= 0, -1);
g_return_val_if_fail (fdt >= 0, -1); g_return_val_if_fail (fdt >= 0, -1);
g_return_val_if_fail (max_bytes >= -1, -1); g_return_val_if_fail (max_bytes >= -1, -1);
/* Try btrfs reflinks first. */ /* If we've requested to copy the whole range, try a full-file clone first.
if (try_reflink && max_bytes == (off_t) -1) */
if (max_bytes == (off_t) -1)
{ {
r = btrfs_reflink(fdf, fdt); if (ioctl (fdt, FICLONE, fdf) == 0)
if (r >= 0)
return 0; return 0;
/* Fall through */ /* Fall through */
struct stat stbuf;
/* Gather the size so we can provide the whole thing at once to
* copy_file_range() or sendfile().
*/
if (fstat (fdf, &stbuf) < 0)
return -1;
max_bytes = stbuf.st_size;
} }
while (TRUE) while (TRUE)
{ {
size_t m = COPY_BUFFER_SIZE;
ssize_t n; ssize_t n;
if (max_bytes != (off_t) -1) /* First, try copy_file_range(). Note this is an inlined version of
* try_copy_file_range() from systemd upstream, which works better since
* we use POSIX errno style.
*/
if (try_cfr)
{ {
if ((off_t) m > max_bytes) n = copy_file_range (fdf, NULL, fdt, NULL, max_bytes, 0u);
m = (size_t) max_bytes;
}
/* First try sendfile(), unless we already tried */
if (try_sendfile)
{
n = sendfile (fdt, fdf, NULL, m);
if (n < 0) if (n < 0)
{ {
if (errno != EINVAL && errno != ENOSYS) if (errno == ENOSYS)
return -1; {
/* No cfr in kernel, mark as permanently unavailable
try_sendfile = false; * and fall through to sendfile().
/* use fallback below */ */
have_cfr = 0;
try_cfr = false;
} }
else if (n == 0) /* EOF */ else if (errno == EXDEV)
/* We won't try cfr again for this run, but let's be
* conservative and not mark it as available/unavailable until
* we know for sure.
*/
try_cfr = false;
else
return -1;
}
else
{
/* cfr worked, mark it as available */
if (have_cfr == -1)
have_cfr = 1;
if (n == 0) /* EOF */
break;
else
/* Success! */
goto next;
}
}
/* Next try sendfile(); this version is also changed from systemd upstream
* to match the same logic we have for copy_file_range().
*/
if (try_sendfile)
{
n = sendfile (fdt, fdf, NULL, max_bytes);
if (n < 0)
{
if (G_IN_SET (errno, EINVAL, ENOSYS))
{
/* No sendfile(), or it doesn't work on regular files.
* Mark it as permanently unavailable, and fall through
* to plain read()/write().
*/
have_sendfile = 0;
try_sendfile = false;
}
else
return -1;
}
else
{
/* sendfile() worked, mark it as available */
if (have_sendfile == -1)
have_sendfile = 1;
if (n == 0) /* EOF */
break; break;
else if (n > 0) else if (n > 0)
/* Succcess! */ /* Succcess! */
goto next; goto next;
} }
}
/* As a fallback just copy bits by hand */ /* As a fallback just copy bits by hand */
{ char buf[m]; { size_t m = COPY_BUFFER_SIZE;
if (max_bytes != (off_t) -1)
{
if ((off_t) m > max_bytes)
m = (size_t) max_bytes;
}
char buf[m];
n = read (fdf, buf, m); n = TEMP_FAILURE_RETRY (read (fdf, buf, m));
if (n < 0) if (n < 0)
return -1; return -1;
if (n == 0) /* EOF */ if (n == 0) /* EOF */
@ -776,7 +838,7 @@ glnx_regfile_copy_bytes (int fdf, int fdt, off_t max_bytes, gboolean try_reflink
next: next:
if (max_bytes != (off_t) -1) if (max_bytes != (off_t) -1)
{ {
g_assert(max_bytes >= n); g_assert_cmpint (max_bytes, >=, n);
max_bytes -= n; max_bytes -= n;
if (max_bytes == 0) if (max_bytes == 0)
break; break;
@ -867,7 +929,7 @@ glnx_file_copy_at (int src_dfd,
goto out; goto out;
} }
r = glnx_regfile_copy_bytes (src_fd, dest_fd, (off_t) -1, TRUE); r = glnx_regfile_copy_bytes (src_fd, dest_fd, (off_t) -1);
if (r < 0) if (r < 0)
{ {
glnx_set_error_from_errno (error); glnx_set_error_from_errno (error);

View File

@ -170,7 +170,7 @@ int
glnx_loop_write (int fd, const void *buf, size_t nbytes); glnx_loop_write (int fd, const void *buf, size_t nbytes);
int int
glnx_regfile_copy_bytes (int fdf, int fdt, off_t max_bytes, gboolean try_reflink); glnx_regfile_copy_bytes (int fdf, int fdt, off_t max_bytes);
typedef enum { typedef enum {
GLNX_FILE_COPY_OVERWRITE = (1 << 0), GLNX_FILE_COPY_OVERWRITE = (1 << 0),

View File

@ -25,30 +25,6 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define GLNX_DEFINE_CLEANUP_FUNCTION(Type, name, func) \
static inline void name (void *v) \
{ \
func (*(Type*)v); \
}
#define GLNX_DEFINE_CLEANUP_FUNCTION0(Type, name, func) \
static inline void name (void *v) \
{ \
if (*(Type*)v) \
func (*(Type*)v); \
}
/**
* glnx_free:
*
* Call g_free() on a variable location when it goes out of scope.
*/
#define glnx_free __attribute__ ((cleanup(glnx_local_free)))
#ifdef GLNX_GSYSTEM_COMPAT
#define gs_free __attribute__ ((cleanup(glnx_local_free)))
#endif
GLNX_DEFINE_CLEANUP_FUNCTION(void*, glnx_local_free, g_free)
/** /**
* glnx_unref_object: * glnx_unref_object:
* *
@ -57,141 +33,14 @@ GLNX_DEFINE_CLEANUP_FUNCTION(void*, glnx_local_free, g_free)
* %NULL. * %NULL.
*/ */
#define glnx_unref_object __attribute__ ((cleanup(glnx_local_obj_unref))) #define glnx_unref_object __attribute__ ((cleanup(glnx_local_obj_unref)))
#ifdef GLNX_GSYSTEM_COMPAT static inline void
#define gs_unref_object __attribute__ ((cleanup(glnx_local_obj_unref))) glnx_local_obj_unref (void *v)
#endif {
GLNX_DEFINE_CLEANUP_FUNCTION0(GObject*, glnx_local_obj_unref, g_object_unref) GObject *o = *(GObject **)v;
if (o)
/** g_object_unref (o);
* glnx_unref_variant: }
* #define glnx_unref_object __attribute__ ((cleanup(glnx_local_obj_unref)))
* Call g_variant_unref() on a variable location when it goes out of
* scope. Note that unlike g_variant_unref(), the variable may be
* %NULL.
*/
#define glnx_unref_variant __attribute__ ((cleanup(glnx_local_variant_unref)))
#ifdef GLNX_GSYSTEM_COMPAT
#define gs_unref_variant __attribute__ ((cleanup(glnx_local_variant_unref)))
#endif
GLNX_DEFINE_CLEANUP_FUNCTION0(GVariant*, glnx_local_variant_unref, g_variant_unref)
/**
* glnx_free_variant_iter:
*
* Call g_variant_iter_free() on a variable location when it goes out of
* scope.
*/
#define glnx_free_variant_iter __attribute__ ((cleanup(glnx_local_variant_iter_free)))
GLNX_DEFINE_CLEANUP_FUNCTION0(GVariantIter*, glnx_local_variant_iter_free, g_variant_iter_free)
/**
* glnx_free_variant_builder:
*
* Call g_variant_builder_unref() on a variable location when it goes out of
* scope.
*/
#define glnx_unref_variant_builder __attribute__ ((cleanup(glnx_local_variant_builder_unref)))
GLNX_DEFINE_CLEANUP_FUNCTION0(GVariantBuilder*, glnx_local_variant_builder_unref, g_variant_builder_unref)
/**
* glnx_unref_array:
*
* Call g_array_unref() on a variable location when it goes out of
* scope. Note that unlike g_array_unref(), the variable may be
* %NULL.
*/
#define glnx_unref_array __attribute__ ((cleanup(glnx_local_array_unref)))
GLNX_DEFINE_CLEANUP_FUNCTION0(GArray*, glnx_local_array_unref, g_array_unref)
/**
* glnx_unref_ptrarray:
*
* Call g_ptr_array_unref() on a variable location when it goes out of
* scope. Note that unlike g_ptr_array_unref(), the variable may be
* %NULL.
*/
#define glnx_unref_ptrarray __attribute__ ((cleanup(glnx_local_ptrarray_unref)))
#ifdef GLNX_GSYSTEM_COMPAT
#define gs_unref_ptrarray __attribute__ ((cleanup(glnx_local_ptrarray_unref)))
#endif
GLNX_DEFINE_CLEANUP_FUNCTION0(GPtrArray*, glnx_local_ptrarray_unref, g_ptr_array_unref)
/**
* glnx_unref_hashtable:
*
* Call g_hash_table_unref() on a variable location when it goes out
* of scope. Note that unlike g_hash_table_unref(), the variable may
* be %NULL.
*/
#define glnx_unref_hashtable __attribute__ ((cleanup(glnx_local_hashtable_unref)))
#ifdef GLNX_GSYSTEM_COMPAT
#define gs_unref_hashtable __attribute__ ((cleanup(glnx_local_hashtable_unref)))
#endif
GLNX_DEFINE_CLEANUP_FUNCTION0(GHashTable*, glnx_local_hashtable_unref, g_hash_table_unref)
/**
* glnx_free_list:
*
* Call g_list_free() on a variable location when it goes out
* of scope.
*/
#define glnx_free_list __attribute__ ((cleanup(glnx_local_free_list)))
GLNX_DEFINE_CLEANUP_FUNCTION(GList*, glnx_local_free_list, g_list_free)
/**
* glnx_free_slist:
*
* Call g_slist_free() on a variable location when it goes out
* of scope.
*/
#define glnx_free_slist __attribute__ ((cleanup(glnx_local_free_slist)))
GLNX_DEFINE_CLEANUP_FUNCTION(GSList*, glnx_local_free_slist, g_slist_free)
/**
* glnx_free_checksum:
*
* Call g_checksum_free() on a variable location when it goes out
* of scope. Note that unlike g_checksum_free(), the variable may
* be %NULL.
*/
#define glnx_free_checksum __attribute__ ((cleanup(glnx_local_checksum_free)))
GLNX_DEFINE_CLEANUP_FUNCTION0(GChecksum*, glnx_local_checksum_free, g_checksum_free)
/**
* glnx_unref_bytes:
*
* Call g_bytes_unref() on a variable location when it goes out
* of scope. Note that unlike g_bytes_unref(), the variable may
* be %NULL.
*/
#define glnx_unref_bytes __attribute__ ((cleanup(glnx_local_bytes_unref)))
GLNX_DEFINE_CLEANUP_FUNCTION0(GBytes*, glnx_local_bytes_unref, g_bytes_unref)
/**
* glnx_strfreev:
*
* Call g_strfreev() on a variable location when it goes out of scope.
*/
#define glnx_strfreev __attribute__ ((cleanup(glnx_local_strfreev)))
GLNX_DEFINE_CLEANUP_FUNCTION(char**, glnx_local_strfreev, g_strfreev)
/**
* glnx_free_error:
*
* Call g_error_free() on a variable location when it goes out of scope.
*/
#define glnx_free_error __attribute__ ((cleanup(glnx_local_free_error)))
GLNX_DEFINE_CLEANUP_FUNCTION0(GError*, glnx_local_free_error, g_error_free)
/**
* glnx_unref_keyfile:
*
* Call g_key_file_unref() on a variable location when it goes out of scope.
*/
#define glnx_unref_keyfile __attribute__ ((cleanup(glnx_local_keyfile_unref)))
GLNX_DEFINE_CLEANUP_FUNCTION0(GKeyFile*, glnx_local_keyfile_unref, g_key_file_unref)
static inline void static inline void
glnx_cleanup_close_fdp (int *fdp) glnx_cleanup_close_fdp (int *fdp)
@ -204,7 +53,8 @@ glnx_cleanup_close_fdp (int *fdp)
if (fd >= 0) if (fd >= 0)
{ {
errsv = errno; errsv = errno;
(void) close (fd); if (close (fd) < 0)
g_assert (errno != EBADF);
errno = errsv; errno = errsv;
} }
} }

View File

@ -52,3 +52,44 @@ static inline int renameat2(int oldfd, const char *oldname, int newfd, const cha
# endif # endif
} }
#endif #endif
/* Copied from systemd git:
commit 6bda23dd6aaba50cf8e3e6024248cf736cc443ca
Author: Yu Watanabe <watanabe.yu+github@gmail.com>
AuthorDate: Thu Jul 27 20:22:54 2017 +0900
Commit: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
CommitDate: Thu Jul 27 07:22:54 2017 -0400
*/
#if !HAVE_DECL_COPY_FILE_RANGE
# ifndef __NR_copy_file_range
# if defined(__x86_64__)
# define __NR_copy_file_range 326
# elif defined(__i386__)
# define __NR_copy_file_range 377
# elif defined __s390__
# define __NR_copy_file_range 375
# elif defined __arm__
# define __NR_copy_file_range 391
# elif defined __aarch64__
# define __NR_copy_file_range 285
# elif defined __powerpc__
# define __NR_copy_file_range 379
# elif defined __arc__
# define __NR_copy_file_range 285
# else
# warning "__NR_copy_file_range not defined for your architecture"
# endif
# endif
static inline ssize_t copy_file_range(int fd_in, loff_t *off_in,
int fd_out, loff_t *off_out,
size_t len,
unsigned int flags) {
# ifdef __NR_copy_file_range
return syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags);
# else
errno = ENOSYS;
return -1;
# endif
}
#endif

View File

@ -145,8 +145,8 @@ get_xattrs_impl (const char *path,
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
ssize_t bytes_read, real_size; ssize_t bytes_read, real_size;
glnx_free char *xattr_names = NULL; g_autofree char *xattr_names = NULL;
glnx_free char *xattr_names_canonical = NULL; g_autofree char *xattr_names_canonical = NULL;
GVariantBuilder builder; GVariantBuilder builder;
gboolean builder_initialized = FALSE; gboolean builder_initialized = FALSE;
g_autoptr(GVariant) ret_xattrs = NULL; g_autoptr(GVariant) ret_xattrs = NULL;

View File

@ -78,7 +78,7 @@ Boston, MA 02111-1307, USA.
<listitem><para> <listitem><para>
Like git's <literal>clone --reference</literal>. Reuse the provided Like git's <literal>clone --reference</literal>. Reuse the provided
OSTree repo as a local object cache of objects when doing HTTP fetches. OSTree repo as a local object cache when doing HTTP fetches.
May be specified multiple times. May be specified multiple times.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
@ -132,12 +132,15 @@ Boston, MA 02111-1307, USA.
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
repository. If no <literal>BRANCH</literal> is specified, repository. If no <literal>BRANCH</literal> is specified,
all branches are retrieved. all configured branches are retrieved.
</para> </para>
<para> <para>
A special syntax in the <literal>@</literal> character allows A special syntax in the <literal>@</literal> character allows
specifying a specific commit to retrieve from a branch. This specifying a specific commit to retrieve from a branch. The
use cases for this are somewhat similar to pulling a specific
git tag; one could e.g. script a system upgrade to a known-good
version, rather than the latest from the content provider.
</para> </para>
</refsect1> </refsect1>

View File

@ -51,13 +51,17 @@ Boston, MA 02111-1307, USA.
<cmdsynopsis> <cmdsynopsis>
<command>ostree refs</command> <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt">PREFIX</arg> <command>ostree refs</command> <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt">PREFIX</arg>
</cmdsynopsis> </cmdsynopsis>
<cmdsynopsis>
<command>ostree refs</command> <arg choice="req">EXISTING</arg> <arg choice="req">--create=NEWREF</arg>
</cmdsynopsis>
</refsynopsisdiv> </refsynopsisdiv>
<!-- Could this be more specific? What defines a "ref"? etc --> <!-- Could this be more specific? What defines a "ref"? etc -->
<refsect1> <refsect1>
<title>Description</title> <title>Description</title>
<para> <para>
Lists all refs available on the host. If specified, PREFIX assigns the refspec prefix; default prefix is null, which lists all refs. Lists all refs available on the host. If specified, PREFIX assigns the refspec prefix; default
prefix is null, which lists all refs. This command can also be used to create or delete refs.
</para> </para>
</refsect1> </refsect1>
@ -75,6 +79,16 @@ Boston, MA 02111-1307, USA.
printed in full, rather than printed in full, rather than
truncated. </para></listitem> truncated. </para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--create</option>=NEWREF</term>
<listitem><para>
Create a ref pointing to the commit EXISTING. NEWREF must not already exist, and EXISTING
must be an existing commit. More than one ref can point to the same commit.
</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>--delete</option></term> <term><option>--delete</option></term>
@ -85,7 +99,15 @@ Boston, MA 02111-1307, USA.
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>--collections</option></term> <term><option>--alias</option>, <option>-A</option></term>
<listitem><para>
If used with <option>--create</option>, create an alias. Otherwise just list aliases.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--collections</option>, <option>-c</option></term>
<listitem><para> <listitem><para>
Enable interactions with refs using the combination of their Enable interactions with refs using the combination of their
@ -99,8 +121,7 @@ Boston, MA 02111-1307, USA.
is created. (This is an abuse of the refspec syntax.)</para> is created. (This is an abuse of the refspec syntax.)</para>
<para>When deleting refs, all refs whose collection ID equals <para>When deleting refs, all refs whose collection ID equals
the value of the <option>--delete</option> argument are PREFIX are deleted.
deleted.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>

View File

@ -96,6 +96,13 @@ Boston, MA 02111-1307, USA.
<para> <para>
Changes remote repository configurations. The NAME refers to the name of the remote. Changes remote repository configurations. The NAME refers to the name of the remote.
</para> </para>
<para>
The <literal>BRANCH</literal> arguments to the
<command>add</command> subcommand specifies the configured branches
for the remote. See the <literal>branches</literal> section in
<citerefentry><refentrytitle>ostree.repo-config</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for more information.
</para>
<para> <para>
The <command>gpg-import</command> subcommand can associate GPG keys to a specific remote repository for use when pulling signed commits from that repository (if GPG verification is enabled). The <command>gpg-import</command> subcommand can associate GPG keys to a specific remote repository for use when pulling signed commits from that repository (if GPG verification is enabled).
</para> </para>

View File

@ -90,6 +90,8 @@ Boston, MA 02111-1307, USA.
<listitem><para> <listitem><para>
Create delta to revision REV. (This option is required.) Create delta to revision REV. (This option is required.)
The delta is from the parent of REV, unless specified otherwise by <option>--from</option>
or <option>--empty</option>.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>

View File

@ -114,6 +114,14 @@ Boston, MA 02111-1307, USA.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>min-free-space-percent</varname></term>
<listitem><para>Integer percentage value (0-99) that specifies a minimum
percentage of total space (in blocks) in the underlying filesystem to
keep free. The default value is 3.</para></listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
@ -139,6 +147,13 @@ Boston, MA 02111-1307, USA.
metadata: summary, static delta "superblocks".</para></listitem> metadata: summary, static delta "superblocks".</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>branches</varname></term>
<listitem><para>A list of strings. Represents the default configured
branches to fetch from the remote when no specific branches are
requested during a pull operation.</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>proxy</varname></term> <term><varname>proxy</varname></term>
<listitem><para>A string value, if given should be a URL for a <listitem><para>A string value, if given should be a URL for a
@ -191,13 +206,6 @@ Boston, MA 02111-1307, USA.
<listitem><para>If set, pulls from this remote will fail with the configured text. This is intended for OS vendors which have a subscription process to access content.</para></listitem> <listitem><para>If set, pulls from this remote will fail with the configured text. This is intended for OS vendors which have a subscription process to access content.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>min-free-space-percent</varname></term>
<listitem><para>Integer percentage value (0-99) that specifies a minimum
percentage of total space (in blocks) in the underlying filesystem to
keep free. The default value is 3.</para></listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>

View File

@ -18,8 +18,6 @@
***/ ***/
/* 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_2017.10 {
};
/* 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 last number. This is just a copy/paste * edit this other than to update the last number. This is just a copy/paste

View File

@ -70,6 +70,7 @@ global:
ostree_repo_list_collection_refs; ostree_repo_list_collection_refs;
ostree_repo_pull_from_remotes_async; ostree_repo_pull_from_remotes_async;
ostree_repo_pull_from_remotes_finish; ostree_repo_pull_from_remotes_finish;
ostree_repo_remote_list_collection_refs;
ostree_repo_resolve_keyring_for_collection; ostree_repo_resolve_keyring_for_collection;
ostree_repo_set_collection_id; ostree_repo_set_collection_id;
ostree_repo_set_collection_ref_immediate; ostree_repo_set_collection_ref_immediate;

View File

@ -416,6 +416,17 @@ global:
LIBOSTREE_2017.9 { LIBOSTREE_2017.9 {
}; };
LIBOSTREE_2017.10 {
ostree_gpg_error_quark;
ostree_repo_set_alias_ref_immediate;
ostree_repo_open_at;
ostree_repo_create_at;
/* Inherit from .8 since .9 is empty and is also broken
* in that it doesn't have a parent currently;
* <https://github.com/ostreedev/ostree/issues/1087>
*/
} LIBOSTREE_2017.8;
/* 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

@ -38,9 +38,19 @@
* among others. * among others.
*/ */
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
#define GRUB2_USES_16 1 #define GRUB2_SUFFIX "16"
#else #else
#define GRUB2_USES_16 0 #define GRUB2_SUFFIX ""
#endif
/* https://github.com/projectatomic/rpm-ostree-toolbox/issues/102#issuecomment-316483554
* https://github.com/rhboot/grubby/blob/34b1436ccbd56eab8024314cab48f2fc880eef08/grubby.c#L63
*
* This is true at least on Fedora/Red Hat Enterprise Linux for aarch64.
*/
#if defined(__aarch64__)
#define GRUB2_EFI_SUFFIX ""
#else
#define GRUB2_EFI_SUFFIX "efi"
#endif #endif
struct _OstreeBootloaderGrub2 struct _OstreeBootloaderGrub2
@ -214,16 +224,12 @@ _ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot
"No \"linux\" key in bootloader config"); "No \"linux\" key in bootloader config");
goto out; goto out;
} }
g_string_append (output, "linux");
if (is_efi) if (is_efi)
g_string_append (output, "linuxefi "); g_string_append (output, GRUB2_EFI_SUFFIX);
else else
{ g_string_append (output, GRUB2_SUFFIX);
#if GRUB2_USES_16 g_string_append_c (output, ' ');
g_string_append (output, "linux16 ");
#else
g_string_append (output, "linux ");
#endif
}
g_string_append (output, kernel); g_string_append (output, kernel);
options = ostree_bootconfig_parser_get (config, "options"); options = ostree_bootconfig_parser_get (config, "options");
@ -237,16 +243,12 @@ _ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot
initrd = ostree_bootconfig_parser_get (config, "initrd"); initrd = ostree_bootconfig_parser_get (config, "initrd");
if (initrd) if (initrd)
{ {
g_string_append (output, "initrd");
if (is_efi) if (is_efi)
g_string_append (output, "initrdefi "); g_string_append (output, GRUB2_EFI_SUFFIX);
else else
{ g_string_append (output, GRUB2_SUFFIX);
#if GRUB2_USES_16 g_string_append_c (output, ' ');
g_string_append (output, "initrd16 ");
#else
g_string_append (output, "initrd ");
#endif
}
g_string_append (output, initrd); g_string_append (output, initrd);
g_string_append_c (output, '\n'); g_string_append_c (output, '\n');
} }

View File

@ -21,6 +21,7 @@
#pragma once #pragma once
#include <gio/gio.h> #include <gio/gio.h>
#include "otutil.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -48,6 +49,7 @@ struct _OstreeBootloaderInterface
GError **error); GError **error);
gboolean (* is_atomic) (OstreeBootloader *self); gboolean (* is_atomic) (OstreeBootloader *self);
}; };
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeBootloader, g_object_unref)
GType _ostree_bootloader_get_type (void) G_GNUC_CONST; GType _ostree_bootloader_get_type (void) G_GNUC_CONST;

View File

@ -20,8 +20,9 @@
#include "config.h" #include "config.h"
#include "otutil.h"
#include "ostree.h"
#include "ostree-deployment-private.h" #include "ostree-deployment-private.h"
#include "libglnx.h"
typedef GObjectClass OstreeDeploymentClass; typedef GObjectClass OstreeDeploymentClass;
@ -138,7 +139,7 @@ _ostree_deployment_set_bootcsum (OstreeDeployment *self,
OstreeDeployment * OstreeDeployment *
ostree_deployment_clone (OstreeDeployment *self) ostree_deployment_clone (OstreeDeployment *self)
{ {
glnx_unref_object OstreeBootconfigParser *new_bootconfig = NULL; g_autoptr(OstreeBootconfigParser) new_bootconfig = NULL;
OstreeDeployment *ret = ostree_deployment_new (self->index, self->osname, self->csum, OstreeDeployment *ret = ostree_deployment_new (self->index, self->osname, self->csum,
self->deployserial, self->deployserial,
self->bootcsum, self->bootserial); self->bootcsum, self->bootserial);
@ -187,7 +188,7 @@ ostree_deployment_equal (gconstpointer ap, gconstpointer bp)
OstreeDeployment *a = (OstreeDeployment*)ap; OstreeDeployment *a = (OstreeDeployment*)ap;
OstreeDeployment *b = (OstreeDeployment*)bp; OstreeDeployment *b = (OstreeDeployment*)bp;
if (a == NULL && b == NULL) if (a == b)
return TRUE; return TRUE;
else if (a != NULL && b != NULL) else if (a != NULL && b != NULL)
return g_str_equal (ostree_deployment_get_osname (a), return g_str_equal (ostree_deployment_get_osname (a),

View File

@ -425,11 +425,9 @@ static gboolean
timer_cb (gpointer data) timer_cb (gpointer data)
{ {
OstreeFetcher *fetcher = data; OstreeFetcher *fetcher = data;
CURLMcode rc;
GSource *orig_src = fetcher->timer_event; GSource *orig_src = fetcher->timer_event;
rc = curl_multi_socket_action (fetcher->multi, CURL_SOCKET_TIMEOUT, 0, &fetcher->curl_running); (void)curl_multi_socket_action (fetcher->multi, CURL_SOCKET_TIMEOUT, 0, &fetcher->curl_running);
g_assert (rc == CURLM_OK);
check_multi_info (fetcher); check_multi_info (fetcher);
if (fetcher->timer_event == orig_src) if (fetcher->timer_event == orig_src)
fetcher->timer_event = NULL; fetcher->timer_event = NULL;
@ -460,15 +458,12 @@ static gboolean
event_cb (int fd, GIOCondition condition, gpointer data) event_cb (int fd, GIOCondition condition, gpointer data)
{ {
OstreeFetcher *fetcher = data; OstreeFetcher *fetcher = data;
CURLMcode rc;
int action = int action =
(condition & G_IO_IN ? CURL_CSELECT_IN : 0) | (condition & G_IO_IN ? CURL_CSELECT_IN : 0) |
(condition & G_IO_OUT ? CURL_CSELECT_OUT : 0); (condition & G_IO_OUT ? CURL_CSELECT_OUT : 0);
rc = curl_multi_socket_action (fetcher->multi, fd, action, &fetcher->curl_running); (void)curl_multi_socket_action (fetcher->multi, fd, action, &fetcher->curl_running);
g_assert (rc == CURLM_OK);
check_multi_info (fetcher); check_multi_info (fetcher);
if (fetcher->curl_running > 0) if (fetcher->curl_running > 0)
{ {

View File

@ -350,7 +350,7 @@ session_thread_set_tls_interaction_cb (ThreadClosure *thread_closure,
const char *cert_and_key_path = data; /* str\0str\0 in one malloc buf */ const char *cert_and_key_path = data; /* str\0str\0 in one malloc buf */
const char *cert_path = cert_and_key_path; const char *cert_path = cert_and_key_path;
const char *key_path = cert_and_key_path + strlen (cert_and_key_path) + 1; const char *key_path = cert_and_key_path + strlen (cert_and_key_path) + 1;
glnx_unref_object OstreeTlsCertInteraction *interaction = NULL; g_autoptr(OstreeTlsCertInteraction) interaction = NULL;
/* The GTlsInteraction instance must be created in the /* The GTlsInteraction instance must be created in the
* session thread so it uses the correct GMainContext. */ * session thread so it uses the correct GMainContext. */

View File

@ -40,6 +40,7 @@ struct OstreeGpgVerifier {
GObject parent; GObject parent;
GList *keyrings; GList *keyrings;
GPtrArray *keyring_data;
GPtrArray *key_ascii_files; GPtrArray *key_ascii_files;
}; };
@ -53,6 +54,7 @@ ostree_gpg_verifier_finalize (GObject *object)
g_list_free_full (self->keyrings, g_object_unref); g_list_free_full (self->keyrings, g_object_unref);
if (self->key_ascii_files) if (self->key_ascii_files)
g_ptr_array_unref (self->key_ascii_files); g_ptr_array_unref (self->key_ascii_files);
g_clear_pointer (&self->keyring_data, (GDestroyNotify)g_ptr_array_unref);
G_OBJECT_CLASS (_ostree_gpg_verifier_parent_class)->finalize (object); G_OBJECT_CLASS (_ostree_gpg_verifier_parent_class)->finalize (object);
} }
@ -71,6 +73,7 @@ _ostree_gpg_verifier_class_init (OstreeGpgVerifierClass *klass)
static void static void
_ostree_gpg_verifier_init (OstreeGpgVerifier *self) _ostree_gpg_verifier_init (OstreeGpgVerifier *self)
{ {
self->keyring_data = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref);
} }
static void static void
@ -95,8 +98,8 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
{ {
GLNX_AUTO_PREFIX_ERROR("GPG", error); GLNX_AUTO_PREFIX_ERROR("GPG", error);
gpgme_error_t gpg_error = 0; gpgme_error_t gpg_error = 0;
ot_auto_gpgme_data gpgme_data_t data_buffer = NULL; g_auto(gpgme_data_t) data_buffer = NULL;
ot_auto_gpgme_data gpgme_data_t signature_buffer = NULL; g_auto(gpgme_data_t) signature_buffer = NULL;
g_autofree char *tmp_dir = NULL; g_autofree char *tmp_dir = NULL;
g_autoptr(GOutputStream) target_stream = NULL; g_autoptr(GOutputStream) target_stream = NULL;
OstreeGpgVerifyResult *result = NULL; OstreeGpgVerifyResult *result = NULL;
@ -151,6 +154,17 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
goto out; goto out;
} }
for (guint i = 0; i < self->keyring_data->len; i++)
{
GBytes *keyringd = self->keyring_data->pdata[i];
gsize len;
gsize bytes_written;
const guint8 *buf = g_bytes_get_data (keyringd, &len);
if (!g_output_stream_write_all (target_stream, buf, len, &bytes_written,
cancellable, error))
goto out;
}
if (!g_output_stream_close (target_stream, cancellable, error)) if (!g_output_stream_close (target_stream, cancellable, error))
goto out; goto out;
@ -165,7 +179,7 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
{ {
const char *path = self->key_ascii_files->pdata[i]; const char *path = self->key_ascii_files->pdata[i];
glnx_fd_close int fd = -1; glnx_fd_close int fd = -1;
ot_auto_gpgme_data gpgme_data_t kdata = NULL; g_auto(gpgme_data_t) kdata = NULL;
if (!glnx_openat_rdonly (AT_FDCWD, path, TRUE, &fd, error)) if (!glnx_openat_rdonly (AT_FDCWD, path, TRUE, &fd, error))
goto out; goto out;
@ -253,8 +267,11 @@ out:
return result; return result;
} }
/* Given @path which should contain a GPG keyring file, add it
* to the list of trusted keys.
*/
void void
_ostree_gpg_verifier_add_keyring (OstreeGpgVerifier *self, _ostree_gpg_verifier_add_keyring_file (OstreeGpgVerifier *self,
GFile *path) GFile *path)
{ {
g_return_if_fail (G_IS_FILE (path)); g_return_if_fail (G_IS_FILE (path));
@ -262,6 +279,16 @@ _ostree_gpg_verifier_add_keyring (OstreeGpgVerifier *self,
self->keyrings = g_list_append (self->keyrings, g_object_ref (path)); self->keyrings = g_list_append (self->keyrings, g_object_ref (path));
} }
/* Given @keyring which should be the contents of a GPG keyring file, add it to
* the list of trusted keys.
*/
void
_ostree_gpg_verifier_add_keyring_data (OstreeGpgVerifier *self,
GBytes *keyring)
{
g_ptr_array_add (self->keyring_data, g_bytes_ref (keyring));
}
void void
_ostree_gpg_verifier_add_key_ascii_file (OstreeGpgVerifier *self, _ostree_gpg_verifier_add_key_ascii_file (OstreeGpgVerifier *self,
const char *path) const char *path)
@ -276,32 +303,39 @@ _ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self,
GFile *path, GFile *path,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{
gboolean ret = FALSE;
g_autoptr(GFileEnumerator) enumerator = NULL;
enumerator = g_file_enumerate_children (path, OSTREE_GIO_FAST_QUERYINFO, {
G_FILE_QUERY_INFO_NONE, return _ostree_gpg_verifier_add_keyring_dir_at (self, AT_FDCWD,
gs_file_get_path_cached (path),
cancellable, error); cancellable, error);
if (!enumerator) }
goto out;
gboolean
_ostree_gpg_verifier_add_keyring_dir_at (OstreeGpgVerifier *self,
int dfd,
const char *path,
GCancellable *cancellable,
GError **error)
{
g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
if (!glnx_dirfd_iterator_init_at (dfd, path, FALSE,
&dfd_iter, error))
return FALSE;
while (TRUE) while (TRUE)
{ {
GFileInfo *file_info; struct dirent *dent;
GFile *path;
const char *name;
if (!g_file_enumerator_iterate (enumerator, &file_info, &path, if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
cancellable, error)) return FALSE;
goto out; if (dent == NULL)
if (file_info == NULL)
break; break;
if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_REGULAR) if (dent->d_type != DT_REG)
continue; continue;
name = g_file_info_get_name (file_info); const char *name = dent->d_name;
/* Files with a .gpg suffix are typically keyrings except /* Files with a .gpg suffix are typically keyrings except
* for trustdb.gpg, which is the GPG trust database. */ * for trustdb.gpg, which is the GPG trust database. */
@ -315,12 +349,18 @@ _ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self,
if (g_str_equal (name, "secring.gpg")) if (g_str_equal (name, "secring.gpg"))
continue; continue;
self->keyrings = g_list_append (self->keyrings, g_object_ref (path)); glnx_fd_close int fd = -1;
if (!glnx_openat_rdonly (dfd_iter.fd, dent->d_name, TRUE, &fd, error))
return FALSE;
g_autoptr(GBytes) data = glnx_fd_readall_bytes (fd, cancellable, error);
if (!data)
return FALSE;
g_ptr_array_add (self->keyring_data, g_steal_pointer (&data));
} }
ret = TRUE; return TRUE;
out:
return ret;
} }
gboolean gboolean

View File

@ -55,11 +55,19 @@ gboolean _ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
gboolean _ostree_gpg_verifier_add_keyring_dir_at (OstreeGpgVerifier *self,
int dfd,
const char *path,
GCancellable *cancellable,
GError **error);
gboolean _ostree_gpg_verifier_add_global_keyring_dir (OstreeGpgVerifier *self, gboolean _ostree_gpg_verifier_add_global_keyring_dir (OstreeGpgVerifier *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
void _ostree_gpg_verifier_add_keyring (OstreeGpgVerifier *self, void _ostree_gpg_verifier_add_keyring_data (OstreeGpgVerifier *self,
GBytes *data);
void _ostree_gpg_verifier_add_keyring_file (OstreeGpgVerifier *self,
GFile *path); GFile *path);
void _ostree_gpg_verifier_add_key_ascii_file (OstreeGpgVerifier *self, void _ostree_gpg_verifier_add_key_ascii_file (OstreeGpgVerifier *self,

View File

@ -237,34 +237,49 @@ ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result,
const gchar *key_id, const gchar *key_id,
guint *out_signature_index) guint *out_signature_index)
{ {
g_autofree char *key_id_upper = NULL; g_auto(gpgme_key_t) lookup_key = NULL;
gpgme_signature_t signature; gpgme_signature_t signature;
guint signature_index; guint signature_index;
gboolean ret = FALSE;
g_return_val_if_fail (OSTREE_IS_GPG_VERIFY_RESULT (result), FALSE); g_return_val_if_fail (OSTREE_IS_GPG_VERIFY_RESULT (result), FALSE);
g_return_val_if_fail (key_id != NULL, FALSE); g_return_val_if_fail (key_id != NULL, FALSE);
/* signature->fpr is always upper-case. */ /* fetch requested key_id from keyring to canonicalise ID */
key_id_upper = g_ascii_strup (key_id, -1); (void) gpgme_get_key (result->context, key_id, &lookup_key, 0);
if (lookup_key == NULL)
{
g_debug ("Could not find key ID %s to lookup signature.", key_id);
return FALSE;
}
for (signature = result->details->signatures, signature_index = 0; for (signature = result->details->signatures, signature_index = 0;
signature != NULL; signature != NULL;
signature = signature->next, signature_index++) signature = signature->next, signature_index++)
{ {
if (signature->fpr == NULL) g_auto(gpgme_key_t) signature_key = NULL;
continue;
if (g_str_has_suffix (signature->fpr, key_id_upper)) (void) gpgme_get_key (result->context, signature->fpr, &signature_key, 0);
if (signature_key == NULL)
{
g_debug ("Could not find key when looking up signature from %s.", signature->fpr);
continue;
}
/* the first subkey in the list is the primary key */
if (!g_strcmp0 (lookup_key->subkeys->fpr,
signature_key->subkeys->fpr))
{ {
if (out_signature_index != NULL) if (out_signature_index != NULL)
*out_signature_index = signature_index; *out_signature_index = signature_index;
ret = TRUE; /* Note early return */
break; return TRUE;
}
} }
return ret; }
return FALSE;
} }
/** /**
@ -291,7 +306,7 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result,
guint n_attrs) guint n_attrs)
{ {
GVariantBuilder builder; GVariantBuilder builder;
gpgme_key_t key = NULL; g_auto(gpgme_key_t) key = NULL;
gpgme_signature_t signature; gpgme_signature_t signature;
guint ii; guint ii;
@ -313,7 +328,8 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result,
* (OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING). */ * (OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING). */
for (ii = 0; ii < n_attrs; ii++) for (ii = 0; ii < n_attrs; ii++)
{ {
if (attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_USER_NAME || if (attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT ||
attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_USER_NAME ||
attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL) attrs[ii] == OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL)
{ {
(void) gpgme_get_key (result->context, signature->fpr, &key, 0); (void) gpgme_get_key (result->context, signature->fpr, &key, 0);
@ -357,7 +373,11 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result,
break; break;
case OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT: case OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT:
child = g_variant_new_string (signature->fpr); if (key != NULL && key->subkeys != NULL)
v_string = key->subkeys->fpr;
else
v_string = signature->fpr;
child = g_variant_new_string (v_string);
break; break;
case OSTREE_GPG_SIGNATURE_ATTR_TIMESTAMP: case OSTREE_GPG_SIGNATURE_ATTR_TIMESTAMP:
@ -407,9 +427,6 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result,
g_variant_builder_add_value (&builder, child); g_variant_builder_add_value (&builder, child);
} }
if (key != NULL)
gpgme_key_unref (key);
return g_variant_builder_end (&builder); return g_variant_builder_end (&builder);
} }
@ -665,9 +682,12 @@ 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)
{ {
return glnx_throw (error, "%s", g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_MISSING_KEY,
"GPG signatures found, but none are in trusted keyring"); "GPG signatures found, but none are in trusted keyring");
return FALSE;
} }
return TRUE; return TRUE;
} }
G_DEFINE_QUARK (OstreeGpgError, ostree_gpg_error)

View File

@ -137,4 +137,25 @@ _OSTREE_PUBLIC
gboolean ostree_gpg_verify_result_require_valid_signature (OstreeGpgVerifyResult *result, gboolean ostree_gpg_verify_result_require_valid_signature (OstreeGpgVerifyResult *result,
GError **error); GError **error);
/**
* OstreeGpgError:
* @OSTREE_GPG_ERROR_NO_SIGNATURE: A signature was expected, but not found.
* @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.
*
* Errors returned by signature creation and verification operations in OSTree.
* These may be returned by any API which creates or verifies signatures.
*
* Since: 2017.10
*/
typedef enum {
OSTREE_GPG_ERROR_NO_SIGNATURE = 0,
OSTREE_GPG_ERROR_INVALID_SIGNATURE,
OSTREE_GPG_ERROR_MISSING_KEY,
} OstreeGpgError;
_OSTREE_PUBLIC
GQuark ostree_gpg_error_quark (void);
#define OSTREE_GPG_ERROR (ostree_gpg_error_quark ())
G_END_DECLS G_END_DECLS

View File

@ -36,7 +36,7 @@
#ifdef HAVE_LIBMOUNT #ifdef HAVE_LIBMOUNT
typedef FILE OtLibMountFile; typedef FILE OtLibMountFile;
G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtLibMountFile, endmntent); G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtLibMountFile, endmntent)
/* Taken from systemd path-util.c */ /* Taken from systemd path-util.c */
static bool static bool

View File

@ -22,8 +22,10 @@
#pragma once #pragma once
#include "config.h"
#include <gio/gio.h> #include <gio/gio.h>
#include "libglnx.h" #include "otutil.h"
#ifdef HAVE_LIBARCHIVE #ifdef HAVE_LIBARCHIVE
#include <archive.h> #include <archive.h>
#include <archive_entry.h> #include <archive_entry.h>
@ -32,14 +34,10 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#ifdef HAVE_LIBARCHIVE #ifdef HAVE_LIBARCHIVE
GLNX_DEFINE_CLEANUP_FUNCTION (void *, flatpak_local_free_write_archive, archive_write_free) typedef struct archive OtAutoArchiveWrite;
#define ot_cleanup_write_archive __attribute__((cleanup (flatpak_local_free_write_archive))) G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtAutoArchiveWrite, archive_write_free)
typedef struct archive OtAutoArchiveRead;
GLNX_DEFINE_CLEANUP_FUNCTION (void *, flatpak_local_free_read_archive, archive_read_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC(OtAutoArchiveRead, archive_read_free)
#define ot_cleanup_read_archive __attribute__((cleanup (flatpak_local_free_read_archive)))
#else
#define ot_cleanup_write_archive
#define ot_cleanup_read_archive
#endif #endif
G_END_DECLS G_END_DECLS

View File

@ -40,6 +40,7 @@ struct OstreeMetalinkClass
{ {
GObjectClass parent_class; GObjectClass parent_class;
}; };
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeMetalink, g_object_unref)
GType _ostree_metalink_get_type (void) G_GNUC_CONST; GType _ostree_metalink_get_type (void) G_GNUC_CONST;

View File

@ -22,9 +22,8 @@
#include "config.h" #include "config.h"
#include "ostree-mutable-tree.h"
#include "otutil.h" #include "otutil.h"
#include "ostree-core.h" #include "ostree.h"
/** /**
* SECTION:ostree-mutable-tree * SECTION:ostree-mutable-tree
@ -183,7 +182,7 @@ ostree_mutable_tree_ensure_dir (OstreeMutableTree *self,
GError **error) GError **error)
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
glnx_unref_object OstreeMutableTree *ret_dir = NULL; g_autoptr(OstreeMutableTree) ret_dir = NULL;
g_return_val_if_fail (name != NULL, FALSE); g_return_val_if_fail (name != NULL, FALSE);
@ -219,7 +218,7 @@ ostree_mutable_tree_lookup (OstreeMutableTree *self,
GError **error) GError **error)
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
glnx_unref_object OstreeMutableTree *ret_subdir = NULL; g_autoptr(OstreeMutableTree) ret_subdir = NULL;
g_autofree char *ret_file_checksum = NULL; g_autofree char *ret_file_checksum = NULL;
ret_subdir = ot_gobject_refz (g_hash_table_lookup (self->subdirs, name)); ret_subdir = ot_gobject_refz (g_hash_table_lookup (self->subdirs, name));
@ -261,7 +260,7 @@ ostree_mutable_tree_ensure_parent_dirs (OstreeMutableTree *self,
gboolean ret = FALSE; gboolean ret = FALSE;
int i; int i;
OstreeMutableTree *subdir = self; /* nofree */ OstreeMutableTree *subdir = self; /* nofree */
glnx_unref_object OstreeMutableTree *ret_parent = NULL; g_autoptr(OstreeMutableTree) ret_parent = NULL;
g_assert (metadata_checksum != NULL); g_assert (metadata_checksum != NULL);

View File

@ -46,7 +46,7 @@ checkout_state_clear (CheckoutState *state)
if (state->selabel_path_buf) if (state->selabel_path_buf)
g_string_free (state->selabel_path_buf, TRUE); g_string_free (state->selabel_path_buf, TRUE);
} }
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(CheckoutState, checkout_state_clear); G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(CheckoutState, checkout_state_clear)
static gboolean static gboolean
checkout_object_for_uncompressed_cache (OstreeRepo *self, checkout_object_for_uncompressed_cache (OstreeRepo *self,
@ -122,7 +122,7 @@ write_regular_file_content (OstreeRepo *self,
int infd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*) input); int infd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*) input);
guint64 len = g_file_info_get_size (file_info); guint64 len = g_file_info_get_size (file_info);
if (glnx_regfile_copy_bytes (infd, outfd, (off_t)len, TRUE) < 0) if (glnx_regfile_copy_bytes (infd, outfd, (off_t)len) < 0)
return glnx_throw_errno_prefix (error, "regfile copy"); return glnx_throw_errno_prefix (error, "regfile copy");
} }
else else

View File

@ -27,16 +27,16 @@
#include <gio/gfiledescriptorbased.h> #include <gio/gfiledescriptorbased.h>
#include <gio/gunixinputstream.h> #include <gio/gunixinputstream.h>
#include <gio/gunixoutputstream.h> #include <gio/gunixoutputstream.h>
#include "otutil.h" #include <sys/xattr.h>
#include <glib/gprintf.h>
#include "otutil.h"
#include "ostree.h"
#include "ostree-core-private.h" #include "ostree-core-private.h"
#include "ostree-repo-private.h" #include "ostree-repo-private.h"
#include "ostree-repo-file-enumerator.h" #include "ostree-repo-file-enumerator.h"
#include "ostree-checksum-input-stream.h" #include "ostree-checksum-input-stream.h"
#include "ostree-mutable-tree.h"
#include "ostree-varint.h" #include "ostree-varint.h"
#include <sys/xattr.h>
#include <glib/gprintf.h>
gboolean gboolean
_ostree_repo_ensure_loose_objdir_at (int dfd, _ostree_repo_ensure_loose_objdir_at (int dfd,
@ -467,7 +467,7 @@ create_regular_tmpfile_linkable_with_content (OstreeRepo *self,
if (G_IS_FILE_DESCRIPTOR_BASED (input)) if (G_IS_FILE_DESCRIPTOR_BASED (input))
{ {
int infd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*) input); int infd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*) input);
if (glnx_regfile_copy_bytes (infd, tmpf.fd, (off_t)length, TRUE) < 0) if (glnx_regfile_copy_bytes (infd, tmpf.fd, (off_t)length) < 0)
return glnx_throw_errno_prefix (error, "regfile copy"); return glnx_throw_errno_prefix (error, "regfile copy");
} }
else else
@ -485,10 +485,8 @@ create_regular_tmpfile_linkable_with_content (OstreeRepo *self,
g_input_stream_read (input, buf, MIN (remaining, sizeof (buf)), cancellable, error); g_input_stream_read (input, buf, MIN (remaining, sizeof (buf)), cancellable, error);
if (bytes_read < 0) if (bytes_read < 0)
return FALSE; return FALSE;
else if (G_UNLIKELY (bytes_read == 0 && remaining > 0))
return glnx_throw (error, "Unexpected EOF with %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " bytes remaining", remaining, length);
else if (bytes_read == 0) else if (bytes_read == 0)
break; return glnx_throw (error, "Unexpected EOF with %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " bytes remaining", remaining, length);
if (glnx_loop_write (tmpf.fd, buf, bytes_read) < 0) if (glnx_loop_write (tmpf.fd, buf, bytes_read) < 0)
return glnx_throw_errno_prefix (error, "write"); return glnx_throw_errno_prefix (error, "write");
remaining -= bytes_read; remaining -= bytes_read;
@ -1448,7 +1446,31 @@ ostree_repo_set_ref_immediate (OstreeRepo *self,
GError **error) GError **error)
{ {
const OstreeCollectionRef _ref = { NULL, (gchar *) ref }; const OstreeCollectionRef _ref = { NULL, (gchar *) ref };
return _ostree_repo_write_ref (self, remote, &_ref, checksum, return _ostree_repo_write_ref (self, remote, &_ref, checksum, NULL,
cancellable, error);
}
/**
* ostree_repo_set_alias_ref_immediate:
* @self: An #OstreeRepo
* @remote: (allow-none): A remote for the ref
* @ref: The ref to write
* @target: (allow-none): The ref target to point it to, or %NULL to unset
* @cancellable: GCancellable
* @error: GError
*
* Like ostree_repo_set_ref_immediate(), but creates an alias.
*/
gboolean
ostree_repo_set_alias_ref_immediate (OstreeRepo *self,
const char *remote,
const char *ref,
const char *target,
GCancellable *cancellable,
GError **error)
{
const OstreeCollectionRef _ref = { NULL, (gchar *) ref };
return _ostree_repo_write_ref (self, remote, &_ref, NULL, target,
cancellable, error); cancellable, error);
} }
@ -1480,7 +1502,7 @@ ostree_repo_set_collection_ref_immediate (OstreeRepo *self,
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
return _ostree_repo_write_ref (self, NULL, ref, checksum, return _ostree_repo_write_ref (self, NULL, ref, checksum, NULL,
cancellable, error); cancellable, error);
} }
@ -2528,7 +2550,7 @@ write_directory_content_to_mtree_internal (OstreeRepo *self,
{ {
g_autoptr(GFile) child = NULL; g_autoptr(GFile) child = NULL;
g_autoptr(GFileInfo) modified_info = NULL; g_autoptr(GFileInfo) modified_info = NULL;
glnx_unref_object OstreeMutableTree *child_mtree = NULL; g_autoptr(OstreeMutableTree) child_mtree = NULL;
g_autofree char *child_relpath = NULL; g_autofree char *child_relpath = NULL;
const char *name; const char *name;
GFileType file_type; GFileType file_type;

View File

@ -556,7 +556,8 @@ get_refs_and_checksums_from_summary (GBytes *summary_bytes,
} }
/* Download the summary file from @remote, and return the bytes of the file in /* Download the summary file from @remote, and return the bytes of the file in
* @out_summary_bytes. */ * @out_summary_bytes. This will return %TRUE and set @out_summary_bytes to %NULL
* if the summary file does not exist. */
static gboolean static gboolean
fetch_summary_from_remote (OstreeRepo *repo, fetch_summary_from_remote (OstreeRepo *repo,
OstreeRemote *remote, OstreeRemote *remote,
@ -648,6 +649,13 @@ get_checksums (OstreeRepoFinderAvahi *finder,
error)) error))
return FALSE; return FALSE;
if (summary_bytes == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"No summary file found on server");
return FALSE;
}
return get_refs_and_checksums_from_summary (summary_bytes, supported_ref_to_checksum, error); return get_refs_and_checksums_from_summary (summary_bytes, supported_ref_to_checksum, error);
} }
@ -816,9 +824,10 @@ ostree_avahi_service_build_repo_finder_result (OstreeAvahiService
g_clear_pointer (&remote->keyring, g_free); g_clear_pointer (&remote->keyring, g_free);
remote->keyring = g_strdup (repo->keyring); remote->keyring = g_strdup (repo->keyring);
/* gpg-verify-summary is false since we use the unsigned summary file support. */
g_key_file_set_string (remote->options, remote->group, "url", repo->uri); g_key_file_set_string (remote->options, remote->group, "url", repo->uri);
g_key_file_set_boolean (remote->options, remote->group, "gpg-verify", TRUE); g_key_file_set_boolean (remote->options, remote->group, "gpg-verify", TRUE);
g_key_file_set_boolean (remote->options, remote->group, "gpg-verify-summary", TRUE); g_key_file_set_boolean (remote->options, remote->group, "gpg-verify-summary", FALSE);
get_checksums (finder, parent_repo, remote, supported_ref_to_checksum, &error); get_checksums (finder, parent_repo, remote, supported_ref_to_checksum, &error);
if (error != NULL) if (error != NULL)
@ -830,7 +839,7 @@ ostree_avahi_service_build_repo_finder_result (OstreeAvahiService
g_ptr_array_add (results, ostree_repo_finder_result_new (remote, OSTREE_REPO_FINDER (finder), g_ptr_array_add (results, ostree_repo_finder_result_new (remote, OSTREE_REPO_FINDER (finder),
priority, supported_ref_to_checksum, priority, supported_ref_to_checksum,
(summary_timestamp != NULL) ? GUINT64_FROM_BE (g_variant_get_uint64 (summary_timestamp)) : 0)); GUINT64_FROM_BE (g_variant_get_uint64 (summary_timestamp))));
} }
} }

View File

@ -111,9 +111,10 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find
for (i = 0; i < n_remotes; i++) for (i = 0; i < n_remotes; i++)
{ {
g_autoptr(GError) local_error = NULL; g_autoptr(GError) local_error = NULL;
g_autoptr(GHashTable) remote_refs = NULL; /* (element-type utf8 utf8) */ g_autoptr(GHashTable) remote_refs = NULL; /* (element-type OstreeCollectionRef utf8) */
const gchar *checksum; const gchar *checksum;
g_autofree gchar *remote_collection_id = NULL; g_autofree gchar *remote_collection_id = NULL;
gboolean resolved_a_ref = FALSE;
remote_name = remotes[i]; remote_name = remotes[i];
@ -127,8 +128,9 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find
continue; continue;
} }
if (!ostree_repo_remote_list_refs (parent_repo, remote_name, &remote_refs, if (!ostree_repo_remote_list_collection_refs (parent_repo, remote_name,
cancellable, &local_error)) &remote_refs, cancellable,
&local_error))
{ {
g_debug ("Ignoring remote %s due to error loading its refs: %s", g_debug ("Ignoring remote %s due to error loading its refs: %s",
remote_name, local_error->message); remote_name, local_error->message);
@ -139,13 +141,14 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find
for (j = 0; refs[j] != NULL; j++) for (j = 0; refs[j] != NULL; j++)
{ {
if (g_strcmp0 (refs[j]->collection_id, remote_collection_id) == 0 && if (g_strcmp0 (refs[j]->collection_id, remote_collection_id) == 0 &&
g_hash_table_lookup_extended (remote_refs, refs[j]->ref_name, NULL, (gpointer *) &checksum)) g_hash_table_lookup_extended (remote_refs, refs[j], NULL, (gpointer *) &checksum))
{ {
/* The requested ref is listed in the refs for this remote. Add /* The requested ref is listed in the refs for this remote. Add
* the remote to the results, and the ref to its * the remote to the results, and the ref to its
* @supported_ref_to_checksum. */ * @supported_ref_to_checksum. */
g_debug ("Resolved ref (%s, %s) to remote %s.", g_debug ("Resolved ref (%s, %s) to remote %s.",
refs[j]->collection_id, refs[j]->ref_name, remote_name); refs[j]->collection_id, refs[j]->ref_name, remote_name);
resolved_a_ref = TRUE;
supported_ref_to_checksum = g_hash_table_lookup (repo_name_to_refs, remote_name); supported_ref_to_checksum = g_hash_table_lookup (repo_name_to_refs, remote_name);
@ -161,6 +164,9 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find
(gpointer) refs[j], g_strdup (checksum)); (gpointer) refs[j], g_strdup (checksum));
} }
} }
if (!resolved_a_ref)
g_debug ("Ignoring remote %s due to it not advertising any of the requested refs.", remote_name);
} }
/* Aggregate the results. */ /* Aggregate the results. */

View File

@ -31,6 +31,7 @@
#include "ostree-autocleanups.h" #include "ostree-autocleanups.h"
#include "ostree-remote-private.h" #include "ostree-remote-private.h"
#include "ostree-repo-private.h"
#include "ostree-repo-finder.h" #include "ostree-repo-finder.h"
#include "ostree-repo-finder-mount.h" #include "ostree-repo-finder-mount.h"
@ -257,19 +258,16 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde
{ {
struct stat stbuf; struct stat stbuf;
g_autofree gchar *collection_and_ref = NULL; g_autofree gchar *collection_and_ref = NULL;
g_autofree gchar *repo_dir_path = NULL;
g_autofree gchar *resolved_repo_uri = NULL; g_autofree gchar *resolved_repo_uri = NULL;
g_autofree gchar *keyring = NULL; g_autofree gchar *keyring = NULL;
g_autoptr(UriAndKeyring) resolved_repo = NULL; g_autoptr(UriAndKeyring) resolved_repo = NULL;
collection_and_ref = g_build_filename (refs[i]->collection_id, refs[i]->ref_name, NULL); collection_and_ref = g_build_filename (refs[i]->collection_id, refs[i]->ref_name, NULL);
repo_dir_path = g_build_filename (mount_root_path, ".ostree", "repos",
collection_and_ref, NULL);
if (!glnx_fstatat (repos_dfd, collection_and_ref, &stbuf, AT_NO_AUTOMOUNT, &local_error)) if (!glnx_fstatat (repos_dfd, collection_and_ref, &stbuf, AT_NO_AUTOMOUNT, &local_error))
{ {
g_debug ("Ignoring ref (%s, %s) on mount %s as querying info of %s failed: %s", g_debug ("Ignoring ref (%s, %s) on mount %s as querying info of %s failed: %s",
refs[i]->collection_id, refs[i]->ref_name, mount_name, repo_dir_path, local_error->message); refs[i]->collection_id, refs[i]->ref_name, mount_name, collection_and_ref, local_error->message);
g_clear_error (&local_error); g_clear_error (&local_error);
continue; continue;
} }
@ -277,7 +275,7 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde
if ((stbuf.st_mode & S_IFMT) != S_IFDIR) if ((stbuf.st_mode & S_IFMT) != S_IFDIR)
{ {
g_debug ("Ignoring ref (%s, %s) on mount %s as %s is of type %u, not a directory.", g_debug ("Ignoring ref (%s, %s) on mount %s as %s is of type %u, not a directory.",
refs[i]->collection_id, refs[i]->ref_name, mount_name, repo_dir_path, (stbuf.st_mode & S_IFMT)); refs[i]->collection_id, refs[i]->ref_name, mount_name, collection_and_ref, (stbuf.st_mode & S_IFMT));
g_clear_error (&local_error); g_clear_error (&local_error);
continue; continue;
} }
@ -294,27 +292,19 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde
} }
/* Exclude repositories which resolve to @parent_repo. */ /* Exclude repositories which resolve to @parent_repo. */
g_autofree char *canonical_repo_dir_path = realpath (repo_dir_path, NULL); if (stbuf.st_dev == parent_repo->device &&
g_autofree gchar *parent_repo_path = g_file_get_path (ostree_repo_get_path (parent_repo)); stbuf.st_ino == parent_repo->inode)
g_autofree char *canonical_parent_repo_path = realpath (parent_repo_path, NULL);
if (g_strcmp0 (canonical_repo_dir_path, canonical_parent_repo_path) == 0)
{ {
g_debug ("Ignoring ref (%s, %s) on mount %s as its repository was the one we are resolving for: %s", g_debug ("Ignoring ref (%s, %s) on mount %s as it is the same as the one we are resolving",
refs[i]->collection_id, refs[i]->ref_name, mount_name, canonical_parent_repo_path); refs[i]->collection_id, refs[i]->ref_name, mount_name);
g_clear_error (&local_error); g_clear_error (&local_error);
continue; continue;
} }
/* Grab the given ref and a checksum for it from the repo. /* Grab the given ref and a checksum for it from the repo, if it appears to be a valid repo */
* FIXME: Ideally, there would be some ostree_repo_open_at() which we g_autoptr(OstreeRepo) repo = ostree_repo_open_at (repos_dfd, collection_and_ref,
* could use to keep the openat() chain going. See cancellable, &local_error);
* https://github.com/ostreedev/ostree/pull/820. */ if (!repo)
g_autoptr(OstreeRepo) repo = NULL;
g_autoptr(GFile) repo_dir_file = g_file_new_for_path (repo_dir_path);
repo = ostree_repo_new (repo_dir_file);
if (!ostree_repo_open (repo, cancellable, &local_error))
{ {
g_debug ("Ignoring ref (%s, %s) on mount %s as its repository could not be opened: %s", g_debug ("Ignoring ref (%s, %s) on mount %s as its repository could not be opened: %s",
refs[i]->collection_id, refs[i]->ref_name, mount_name, local_error->message); refs[i]->collection_id, refs[i]->ref_name, mount_name, local_error->message);
@ -358,6 +348,11 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde
* $mount_root/.ostree/repos/$refs[i]->collection_id/$refs[i]->ref_name. * $mount_root/.ostree/repos/$refs[i]->collection_id/$refs[i]->ref_name.
* Add it to the results, keyed by the canonicalised repository URI * Add it to the results, keyed by the canonicalised repository URI
* to deduplicate the results. */ * to deduplicate the results. */
g_autofree char *repo_abspath = g_build_filename (mount_root_path, ".ostree/repos",
collection_and_ref, NULL);
/* FIXME - why are we using realpath here? */
g_autofree char *canonical_repo_dir_path = realpath (repo_abspath, NULL);
resolved_repo_uri = g_strconcat ("file://", canonical_repo_dir_path, NULL); resolved_repo_uri = g_strconcat ("file://", canonical_repo_dir_path, NULL);
g_debug ("Resolved ref (%s, %s) on mount %s to repo URI %s with keyring %s.", g_debug ("Resolved ref (%s, %s) on mount %s to repo URI %s with keyring %s.",
refs[i]->collection_id, refs[i]->ref_name, mount_name, resolved_repo_uri, keyring); refs[i]->collection_id, refs[i]->ref_name, mount_name, resolved_repo_uri, keyring);
@ -392,9 +387,10 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde
g_clear_pointer (&remote->keyring, g_free); g_clear_pointer (&remote->keyring, g_free);
remote->keyring = g_strdup (repo->keyring); remote->keyring = g_strdup (repo->keyring);
/* gpg-verify-summary is false since we use the unsigned summary file support. */
g_key_file_set_string (remote->options, remote->group, "url", repo->uri); g_key_file_set_string (remote->options, remote->group, "url", repo->uri);
g_key_file_set_boolean (remote->options, remote->group, "gpg-verify", TRUE); g_key_file_set_boolean (remote->options, remote->group, "gpg-verify", TRUE);
g_key_file_set_boolean (remote->options, remote->group, "gpg-verify-summary", TRUE); g_key_file_set_boolean (remote->options, remote->group, "gpg-verify-summary", FALSE);
/* Set the timestamp in the #OstreeRepoFinderResult to 0 because /* Set the timestamp in the #OstreeRepoFinderResult to 0 because
* the code in ostree_repo_pull_from_remotes_async() will be able to * the code in ostree_repo_pull_from_remotes_async() will be able to

View File

@ -550,7 +550,9 @@ ostree_repo_finder_result_free (OstreeRepoFinderResult *result)
{ {
g_return_if_fail (result != NULL); g_return_if_fail (result != NULL);
g_hash_table_unref (result->ref_to_checksum); /* This may be NULL iff the result is freed half-way through find_remotes_cb()
* in ostree-repo-pull.c, and at no other time. */
g_clear_pointer (&result->ref_to_checksum, g_hash_table_unref);
g_object_unref (result->finder); g_object_unref (result->finder);
ostree_remote_unref (result->remote); ostree_remote_unref (result->remote);
g_free (result); g_free (result);

View File

@ -22,10 +22,10 @@
#include "config.h" #include "config.h"
#include "otutil.h"
#include "ostree.h"
#include "ostree-core-private.h" #include "ostree-core-private.h"
#include "ostree-repo-private.h" #include "ostree-repo-private.h"
#include "ostree-repo-file.h"
#include "ostree-mutable-tree.h"
#ifdef HAVE_LIBARCHIVE #ifdef HAVE_LIBARCHIVE
#include <archive.h> #include <archive.h>
@ -185,7 +185,7 @@ mtree_ensure_dir_with_meta (OstreeRepo *repo,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
glnx_unref_object OstreeMutableTree *dir = NULL; g_autoptr(OstreeMutableTree) dir = NULL;
g_autofree guchar *csum_raw = NULL; g_autofree guchar *csum_raw = NULL;
g_autofree char *csum = NULL; g_autofree char *csum = NULL;
@ -374,7 +374,7 @@ aic_create_parent_dirs (OstreeRepoArchiveImportContext *ctx,
GError **error) GError **error)
{ {
g_autofree char *fullpath = NULL; g_autofree char *fullpath = NULL;
glnx_unref_object OstreeMutableTree *dir = NULL; g_autoptr(OstreeMutableTree) dir = NULL;
/* start with the root itself */ /* start with the root itself */
if (!aic_ensure_parent_dir (ctx, ctx->root, "/", &dir, cancellable, error)) if (!aic_ensure_parent_dir (ctx, ctx->root, "/", &dir, cancellable, error))
@ -643,7 +643,7 @@ aic_import_entry (OstreeRepoArchiveImportContext *ctx,
GError **error) GError **error)
{ {
g_autoptr(GFileInfo) fi = NULL; g_autoptr(GFileInfo) fi = NULL;
glnx_unref_object OstreeMutableTree *parent = NULL; g_autoptr(OstreeMutableTree) parent = NULL;
g_autofree char *path = aic_get_final_entry_pathname (ctx, error); g_autofree char *path = aic_get_final_entry_pathname (ctx, error);
if (path == NULL) if (path == NULL)
@ -669,7 +669,7 @@ aic_import_from_hardlink (OstreeRepoArchiveImportContext *ctx,
const char *name = glnx_basename (target); const char *name = glnx_basename (target);
const char *name_dh = glnx_basename (dh->path); const char *name_dh = glnx_basename (dh->path);
g_autoptr(GPtrArray) components = NULL; g_autoptr(GPtrArray) components = NULL;
glnx_unref_object OstreeMutableTree *parent = NULL; g_autoptr(OstreeMutableTree) parent = NULL;
if (!ostree_mutable_tree_lookup (dh->parent, name_dh, &csum, NULL, error)) if (!ostree_mutable_tree_lookup (dh->parent, name_dh, &csum, NULL, error))
return FALSE; return FALSE;
@ -696,8 +696,8 @@ aic_lookup_file_csum (OstreeRepoArchiveImportContext *ctx,
{ {
g_autofree char *csum = NULL; g_autofree char *csum = NULL;
const char *name = glnx_basename (target); const char *name = glnx_basename (target);
glnx_unref_object OstreeMutableTree *parent = NULL; g_autoptr(OstreeMutableTree) parent = NULL;
glnx_unref_object OstreeMutableTree *subdir = NULL; g_autoptr(OstreeMutableTree) subdir = NULL;
g_autoptr(GPtrArray) components = NULL; g_autoptr(GPtrArray) components = NULL;
if (!ot_util_path_split_validate (target, &components, error)) if (!ot_util_path_split_validate (target, &components, error))
@ -900,7 +900,7 @@ ostree_repo_write_archive_to_mtree (OstreeRepo *self,
{ {
#ifdef HAVE_LIBARCHIVE #ifdef HAVE_LIBARCHIVE
gboolean ret = FALSE; gboolean ret = FALSE;
ot_cleanup_read_archive struct archive *a = archive_read_new (); g_autoptr(OtAutoArchiveRead) a = archive_read_new ();
OstreeRepoImportArchiveOptions opts = { 0, }; OstreeRepoImportArchiveOptions opts = { 0, };
#ifdef HAVE_ARCHIVE_READ_SUPPORT_FILTER_ALL #ifdef HAVE_ARCHIVE_READ_SUPPORT_FILTER_ALL

View File

@ -21,10 +21,10 @@
#pragma once #pragma once
#include <sys/statvfs.h> #include <sys/statvfs.h>
#include "otutil.h"
#include "ostree-ref.h" #include "ostree-ref.h"
#include "ostree-repo.h" #include "ostree-repo.h"
#include "ostree-remote-private.h" #include "ostree-remote-private.h"
#include "otutil.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -96,7 +96,11 @@ struct OstreeRepo {
char *commit_stagedir_name; char *commit_stagedir_name;
GLnxLockFile commit_stagedir_lock; GLnxLockFile commit_stagedir_lock;
GFile *repodir; /* A cached fd-relative version, distinct from the case where we may have a
* user-provided absolute path.
*/
GFile *repodir_fdrel;
GFile *repodir; /* May be %NULL if we were opened via ostree_repo_open_at() */
int repo_dir_fd; int repo_dir_fd;
int tmp_dir_fd; int tmp_dir_fd;
int cache_dir_fd; int cache_dir_fd;
@ -132,10 +136,13 @@ struct OstreeRepo {
GHashTable *updated_uncompressed_dirs; GHashTable *updated_uncompressed_dirs;
GHashTable *object_sizes; GHashTable *object_sizes;
uid_t owner_uid; /* Cache the repo's device/inode to use for comparisons elsewhere */
uid_t target_owner_uid; dev_t device;
ino_t inode;
uid_t owner_uid; /* Cache of repo's owner uid */
uid_t target_owner_uid; /* Ensure files are chowned to this uid/gid */
gid_t target_owner_gid; gid_t target_owner_gid;
guint min_free_space_percent; guint min_free_space_percent; /* See the min-free-space-percent config option */
guint test_error_flags; /* OstreeRepoTestErrorFlags */ guint test_error_flags; /* OstreeRepoTestErrorFlags */
@ -173,7 +180,7 @@ _ostree_repo_memory_cache_ref_init (OstreeRepoMemoryCacheRef *state,
void void
_ostree_repo_memory_cache_ref_destroy (OstreeRepoMemoryCacheRef *state); _ostree_repo_memory_cache_ref_destroy (OstreeRepoMemoryCacheRef *state);
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(OstreeRepoMemoryCacheRef, _ostree_repo_memory_cache_ref_destroy); G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(OstreeRepoMemoryCacheRef, _ostree_repo_memory_cache_ref_destroy)
#define OSTREE_REPO_TMPDIR_STAGING "staging-" #define OSTREE_REPO_TMPDIR_STAGING "staging-"
#define OSTREE_REPO_TMPDIR_FETCHER "fetcher-" #define OSTREE_REPO_TMPDIR_FETCHER "fetcher-"
@ -265,6 +272,7 @@ _ostree_repo_write_ref (OstreeRepo *self,
const char *remote, const char *remote,
const OstreeCollectionRef *ref, const OstreeCollectionRef *ref,
const char *rev, const char *rev,
const char *alias,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);

View File

@ -50,10 +50,21 @@
#include <gio/gunixinputstream.h> #include <gio/gunixinputstream.h>
#include <sys/statvfs.h> #include <sys/statvfs.h>
#ifdef HAVE_LIBSYSTEMD
#include <systemd/sd-journal.h>
#endif
#define OSTREE_MESSAGE_FETCH_COMPLETE_ID SD_ID128_MAKE(75,ba,3d,eb,0a,f0,41,a9,a4,62,72,ff,85,d9,e7,3e)
#define OSTREE_REPO_PULL_CONTENT_PRIORITY (OSTREE_FETCHER_DEFAULT_PRIORITY) #define OSTREE_REPO_PULL_CONTENT_PRIORITY (OSTREE_FETCHER_DEFAULT_PRIORITY)
#define OSTREE_REPO_PULL_METADATA_PRIORITY (OSTREE_REPO_PULL_CONTENT_PRIORITY - 100) #define OSTREE_REPO_PULL_METADATA_PRIORITY (OSTREE_REPO_PULL_CONTENT_PRIORITY - 100)
typedef enum {
OSTREE_FETCHER_SECURITY_STATE_CA_PINNED,
OSTREE_FETCHER_SECURITY_STATE_TLS,
OSTREE_FETCHER_SECURITY_STATE_INSECURE,
} OstreeFetcherSecurityState;
typedef struct { typedef struct {
OstreeRepo *repo; OstreeRepo *repo;
int tmpdir_dfd; int tmpdir_dfd;
@ -61,6 +72,8 @@ typedef struct {
char *remote_name; char *remote_name;
OstreeRepoMode remote_mode; OstreeRepoMode remote_mode;
OstreeFetcher *fetcher; OstreeFetcher *fetcher;
OstreeFetcherSecurityState fetcher_security_state;
GPtrArray *meta_mirrorlist; /* List of base URIs for fetching metadata */ GPtrArray *meta_mirrorlist; /* List of base URIs for fetching metadata */
GPtrArray *content_mirrorlist; /* List of base URIs for fetching content */ GPtrArray *content_mirrorlist; /* List of base URIs for fetching content */
OstreeRepo *remote_repo_local; OstreeRepo *remote_repo_local;
@ -1405,12 +1418,12 @@ gpg_verify_unwritten_commit (OtPullData *pull_data,
{ {
if (pull_data->gpg_verify) if (pull_data->gpg_verify)
{ {
glnx_unref_object OstreeGpgVerifyResult *result = NULL; g_autoptr(OstreeGpgVerifyResult) result = NULL;
g_autoptr(GBytes) signed_data = g_variant_get_data_as_bytes (commit); g_autoptr(GBytes) signed_data = g_variant_get_data_as_bytes (commit);
if (!detached_metadata) if (!detached_metadata)
{ {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE,
"Commit %s: no detached metadata found for GPG verification", "Commit %s: no detached metadata found for GPG verification",
checksum); checksum);
return FALSE; return FALSE;
@ -1611,7 +1624,7 @@ scan_commit_object (OtPullData *pull_data,
if (pull_data->gpg_verify) if (pull_data->gpg_verify)
{ {
glnx_unref_object OstreeGpgVerifyResult *result = NULL; g_autoptr(OstreeGpgVerifyResult) result = NULL;
result = ostree_repo_verify_commit_for_remote (pull_data->repo, result = ostree_repo_verify_commit_for_remote (pull_data->repo,
checksum, checksum,
@ -1777,6 +1790,7 @@ scan_one_metadata_object_c (OtPullData *pull_data,
{ {
if (objtype == OSTREE_OBJECT_TYPE_COMMIT) if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
{ {
/* mark as partial to ensure we scan the commit below */
if (!write_commitpartial_for (pull_data, tmp_checksum, error)) if (!write_commitpartial_for (pull_data, tmp_checksum, error))
return FALSE; return FALSE;
} }
@ -1806,6 +1820,12 @@ scan_one_metadata_object_c (OtPullData *pull_data,
return FALSE; return FALSE;
if (!localcache_repo_has_obj) if (!localcache_repo_has_obj)
continue; continue;
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
{
/* mark as partial to ensure we scan the commit below */
if (!write_commitpartial_for (pull_data, tmp_checksum, error))
return FALSE;
}
if (!ostree_repo_import_object_from_with_trust (pull_data->repo, refd_repo, if (!ostree_repo_import_object_from_with_trust (pull_data->repo, refd_repo,
objtype, tmp_checksum, objtype, tmp_checksum,
!pull_data->is_untrusted, !pull_data->is_untrusted,
@ -2450,7 +2470,7 @@ on_superblock_fetched (GObject *src,
*/ */
if (pull_data->gpg_verify_summary && !summary_csum) if (pull_data->gpg_verify_summary && !summary_csum)
{ {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE,
"GPG verification enabled, but no summary signatures found (use gpg-verify-summary=false in remote config to disable)"); "GPG verification enabled, but no summary signatures found (use gpg-verify-summary=false in remote config to disable)");
goto out; goto out;
} }
@ -2612,11 +2632,13 @@ static OstreeFetcher *
_ostree_repo_remote_new_fetcher (OstreeRepo *self, _ostree_repo_remote_new_fetcher (OstreeRepo *self,
const char *remote_name, const char *remote_name,
gboolean gzip, gboolean gzip,
OstreeFetcherSecurityState *out_state,
GError **error) GError **error)
{ {
OstreeFetcher *fetcher = NULL; OstreeFetcher *fetcher = NULL;
OstreeFetcherConfigFlags fetcher_flags = 0; OstreeFetcherConfigFlags fetcher_flags = 0;
gboolean tls_permissive = FALSE; gboolean tls_permissive = FALSE;
OstreeFetcherSecurityState ret_state = OSTREE_FETCHER_SECURITY_STATE_TLS;
gboolean success = FALSE; gboolean success = FALSE;
g_return_val_if_fail (OSTREE_IS_REPO (self), NULL); g_return_val_if_fail (OSTREE_IS_REPO (self), NULL);
@ -2628,7 +2650,10 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self,
goto out; goto out;
if (tls_permissive) if (tls_permissive)
{
fetcher_flags |= OSTREE_FETCHER_FLAGS_TLS_PERMISSIVE; fetcher_flags |= OSTREE_FETCHER_FLAGS_TLS_PERMISSIVE;
ret_state = OSTREE_FETCHER_SECURITY_STATE_INSECURE;
}
if (gzip) if (gzip)
fetcher_flags |= OSTREE_FETCHER_FLAGS_TRANSFER_GZIP; fetcher_flags |= OSTREE_FETCHER_FLAGS_TRANSFER_GZIP;
@ -2673,6 +2698,10 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self,
if (tls_ca_path != NULL) if (tls_ca_path != NULL)
{ {
_ostree_fetcher_set_tls_database (fetcher, tls_ca_path); _ostree_fetcher_set_tls_database (fetcher, tls_ca_path);
/* Don't change if it's already _INSECURE */
if (ret_state == OSTREE_FETCHER_SECURITY_STATE_TLS)
ret_state = OSTREE_FETCHER_SECURITY_STATE_CA_PINNED;
} }
} }
@ -2706,6 +2735,8 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self,
out: out:
if (!success) if (!success)
g_clear_object (&fetcher); g_clear_object (&fetcher);
if (out_state)
*out_state = ret_state;
return fetcher; return fetcher;
} }
@ -2724,7 +2755,7 @@ _ostree_preload_metadata_file (OstreeRepo *self,
if (is_metalink) if (is_metalink)
{ {
glnx_unref_object OstreeMetalink *metalink = NULL; g_autoptr(OstreeMetalink) metalink = NULL;
GError *local_error = NULL; GError *local_error = NULL;
/* the metalink uri is buried in the mirrorlist as the first (and only) /* the metalink uri is buried in the mirrorlist as the first (and only)
@ -2874,7 +2905,7 @@ repo_remote_fetch_summary (OstreeRepo *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
glnx_unref_object OstreeFetcher *fetcher = NULL; g_autoptr(OstreeFetcher) fetcher = NULL;
g_autoptr(GMainContext) mainctx = NULL; g_autoptr(GMainContext) mainctx = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
gboolean from_cache = FALSE; gboolean from_cache = FALSE;
@ -2891,7 +2922,7 @@ repo_remote_fetch_summary (OstreeRepo *self,
mainctx = g_main_context_new (); mainctx = g_main_context_new ();
g_main_context_push_thread_default (mainctx); g_main_context_push_thread_default (mainctx);
fetcher = _ostree_repo_remote_new_fetcher (self, name, TRUE, error); fetcher = _ostree_repo_remote_new_fetcher (self, name, TRUE, NULL, error);
if (fetcher == NULL) if (fetcher == NULL)
goto out; goto out;
@ -3001,10 +3032,13 @@ repo_remote_fetch_summary (OstreeRepo *self,
* any options specific to this pull (such as extra headers). * any options specific to this pull (such as extra headers).
*/ */
static gboolean static gboolean
reinitialize_fetcher (OtPullData *pull_data, const char *remote_name, GError **error) reinitialize_fetcher (OtPullData *pull_data, const char *remote_name,
GError **error)
{ {
g_clear_object (&pull_data->fetcher); g_clear_object (&pull_data->fetcher);
pull_data->fetcher = _ostree_repo_remote_new_fetcher (pull_data->repo, remote_name, FALSE, error); pull_data->fetcher = _ostree_repo_remote_new_fetcher (pull_data->repo, remote_name, FALSE,
&pull_data->fetcher_security_state,
error);
if (pull_data->fetcher == NULL) if (pull_data->fetcher == NULL)
return FALSE; return FALSE;
@ -3186,7 +3220,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
g_autoptr(GHashTable) requested_refs_to_fetch = NULL; /* (element-type OstreeCollectionRef utf8) */ g_autoptr(GHashTable) requested_refs_to_fetch = NULL; /* (element-type OstreeCollectionRef utf8) */
g_autoptr(GHashTable) commits_to_fetch = NULL; g_autoptr(GHashTable) commits_to_fetch = NULL;
g_autofree char *remote_mode_str = NULL; g_autofree char *remote_mode_str = NULL;
glnx_unref_object OstreeMetalink *metalink = NULL; g_autoptr(OstreeMetalink) metalink = NULL;
OtPullData pull_data_real = { 0, }; OtPullData pull_data_real = { 0, };
OtPullData *pull_data = &pull_data_real; OtPullData *pull_data = &pull_data_real;
GKeyFile *remote_config = NULL; GKeyFile *remote_config = NULL;
@ -3210,6 +3244,10 @@ ostree_repo_pull_with_options (OstreeRepo *self,
g_autoptr(GHashTable) updated_requested_refs_to_fetch = NULL; /* (element-type OstreeCollectionRef utf8) */ g_autoptr(GHashTable) updated_requested_refs_to_fetch = NULL; /* (element-type OstreeCollectionRef utf8) */
int i; int i;
g_autofree char **opt_localcache_repos = NULL; g_autofree char **opt_localcache_repos = NULL;
/* If refs or collection-refs has exactly one value, this will point to that
* value, otherwise NULL. Used for logging.
*/
const char *the_ref_to_fetch = NULL;
if (options) if (options)
{ {
@ -3239,6 +3277,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
(void) g_variant_lookup (options, "localcache-repos", "^a&s", &opt_localcache_repos); (void) g_variant_lookup (options, "localcache-repos", "^a&s", &opt_localcache_repos);
} }
g_return_val_if_fail (OSTREE_IS_REPO (self), FALSE);
g_return_val_if_fail (pull_data->maxdepth >= -1, FALSE); g_return_val_if_fail (pull_data->maxdepth >= -1, FALSE);
g_return_val_if_fail (!opt_collection_refs_set || g_return_val_if_fail (!opt_collection_refs_set ||
(refs_to_fetch == NULL && override_commit_ids == NULL), FALSE); (refs_to_fetch == NULL && override_commit_ids == NULL), FALSE);
@ -3621,21 +3660,21 @@ ostree_repo_pull_with_options (OstreeRepo *self,
if (!bytes_summary && pull_data->gpg_verify_summary) if (!bytes_summary && pull_data->gpg_verify_summary)
{ {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"GPG verification enabled, but no summary found (use gpg-verify-summary=false in remote config to disable)"); "GPG verification enabled, but no summary found (use gpg-verify-summary=false in remote config to disable)");
goto out; goto out;
} }
if (!bytes_summary && pull_data->require_static_deltas) if (!bytes_summary && pull_data->require_static_deltas)
{ {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"Fetch configured to require static deltas, but no summary found"); "Fetch configured to require static deltas, but no summary found");
goto out; goto out;
} }
if (!bytes_sig && pull_data->gpg_verify_summary) if (!bytes_sig && pull_data->gpg_verify_summary)
{ {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE,
"GPG verification enabled, but no summary.sig found (use gpg-verify-summary=false in remote config to disable)"); "GPG verification enabled, but no summary.sig found (use gpg-verify-summary=false in remote config to disable)");
goto out; goto out;
} }
@ -3892,6 +3931,15 @@ ostree_repo_pull_with_options (OstreeRepo *self,
g_hash_table_unref (requested_refs_to_fetch); g_hash_table_unref (requested_refs_to_fetch);
requested_refs_to_fetch = g_steal_pointer (&updated_requested_refs_to_fetch); requested_refs_to_fetch = g_steal_pointer (&updated_requested_refs_to_fetch);
if (g_hash_table_size (requested_refs_to_fetch) == 1)
{
GLNX_HASH_TABLE_FOREACH (requested_refs_to_fetch,
const OstreeCollectionRef *, ref)
{
the_ref_to_fetch = ref->ref_name;
break;
}
}
/* Create the state directory here - it's new with the commitpartial code, /* Create the state directory here - it's new with the commitpartial code,
* and may not exist in older repositories. * and may not exist in older repositories.
@ -4060,6 +4108,69 @@ ostree_repo_pull_with_options (OstreeRepo *self,
ostree_async_progress_set_status (pull_data->progress, buf->str); ostree_async_progress_set_status (pull_data->progress, buf->str);
} }
#ifdef HAVE_LIBSYSTEMD
if (bytes_transferred > 0 && pull_data->remote_name)
{
g_autoptr(GString) msg = g_string_new ("");
if (the_ref_to_fetch)
g_string_append_printf (msg, "libostree pull from '%s' for %s complete",
pull_data->remote_name, the_ref_to_fetch);
else
g_string_append_printf (msg, "libostree pull from '%s' for %u refs complete",
pull_data->remote_name, g_hash_table_size (requested_refs_to_fetch));
const char *gpg_verify_state;
if (pull_data->gpg_verify_summary)
{
if (pull_data->gpg_verify)
gpg_verify_state = "summary+commit";
else
gpg_verify_state = "summary-only";
}
else
gpg_verify_state = (pull_data->gpg_verify ? "commit" : "disabled");
g_string_append_printf (msg, "\nsecurity: GPG: %s ", gpg_verify_state);
OstreeFetcherURI *first_uri = pull_data->meta_mirrorlist->pdata[0];
g_autofree char *first_scheme = _ostree_fetcher_uri_get_scheme (first_uri);
if (g_str_has_prefix (first_scheme, "http"))
{
g_string_append (msg, "http: ");
switch (pull_data->fetcher_security_state)
{
case OSTREE_FETCHER_SECURITY_STATE_CA_PINNED:
g_string_append (msg, "CA-pinned");
break;
case OSTREE_FETCHER_SECURITY_STATE_TLS:
g_string_append (msg, "TLS");
break;
case OSTREE_FETCHER_SECURITY_STATE_INSECURE:
g_string_append (msg, "insecure");
break;
}
}
g_string_append (msg, "\n");
if (pull_data->n_fetched_deltaparts > 0)
g_string_append_printf (msg, "delta: parts: %u loose: %u",
pull_data->n_fetched_deltaparts,
pull_data->n_fetched_metadata + pull_data->n_fetched_content);
else
g_string_append_printf (msg, "non-delta: meta: %u content: %u",
pull_data->n_fetched_metadata, pull_data->n_fetched_content);
const guint n_seconds = (guint) ((end_time - pull_data->start_time) / G_USEC_PER_SEC);
g_autofree char *formatted_xferred = g_format_size (bytes_transferred);
g_string_append_printf (msg, "\ntransfer: secs: %u size: %s", n_seconds, formatted_xferred);
sd_journal_send ("MESSAGE=%s", msg->str,
"MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_MESSAGE_FETCH_COMPLETE_ID),
"OSTREE_REMOTE=%s", pull_data->remote_name,
"OSTREE_GPG=%s", gpg_verify_state,
"OSTREE_SECONDS=%u", n_seconds,
"OSTREE_XFER_SIZE=%s", formatted_xferred,
NULL);
}
#endif
/* iterate over commits fetched and delete any commitpartial files */ /* iterate over commits fetched and delete any commitpartial files */
if (pull_data->dirs == NULL && !pull_data->is_commit_only) if (pull_data->dirs == NULL && !pull_data->is_commit_only)
{ {
@ -4730,6 +4841,14 @@ find_remotes_cb (GObject *obj,
g_clear_error (&error); g_clear_error (&error);
continue; continue;
} }
else if (summary_bytes == NULL)
{
g_debug ("%s: Failed to download summary for result %s. Ignoring. %s",
G_STRFUNC, result->remote->name,
"No summary file exists on server");
g_clear_pointer (&g_ptr_array_index (results, i), (GDestroyNotify) ostree_repo_finder_result_free);
continue;
}
/* Check the metadata in the summary file, especially whether it contains /* Check the metadata in the summary file, especially whether it contains
* all the @refs we are interested in. */ * all the @refs we are interested in. */
@ -4836,7 +4955,7 @@ find_remotes_cb (GObject *obj,
goto error; goto error;
fetcher = _ostree_repo_remote_new_fetcher (self, result->remote->name, fetcher = _ostree_repo_remote_new_fetcher (self, result->remote->name,
TRUE, &error); TRUE, NULL, &error);
if (fetcher == NULL) if (fetcher == NULL)
goto error; goto error;
@ -4857,7 +4976,7 @@ find_remotes_cb (GObject *obj,
&error)) &error))
goto error; goto error;
glnx_unref_object OstreeGpgVerifyResult *verify_result = NULL; g_autoptr(OstreeGpgVerifyResult) verify_result = NULL;
verify_result = ostree_repo_verify_commit_for_remote (self, verify_result = ostree_repo_verify_commit_for_remote (self,
commit_metadata->checksum, commit_metadata->checksum,
@ -4974,7 +5093,7 @@ find_remotes_cb (GObject *obj,
{ {
OstreeRepoFinderResult *result = g_ptr_array_index (results, i); OstreeRepoFinderResult *result = g_ptr_array_index (results, i);
g_autoptr(GHashTable) validated_ref_to_checksum = NULL; /* (element-type utf8 utf8) */ g_autoptr(GHashTable) validated_ref_to_checksum = NULL; /* (element-type utf8 utf8) */
gsize j; gsize j, n_latest_refs;
/* Previous error processing this result? */ /* Previous error processing this result? */
if (result == NULL) if (result == NULL)
@ -4986,6 +5105,7 @@ find_remotes_cb (GObject *obj,
ostree_collection_ref_equal, ostree_collection_ref_equal,
(GDestroyNotify) ostree_collection_ref_free, (GDestroyNotify) ostree_collection_ref_free,
g_free); g_free);
n_latest_refs = 0;
for (j = 0; refs[j] != NULL; j++) for (j = 0; refs[j] != NULL; j++)
{ {
@ -4993,11 +5113,13 @@ find_remotes_cb (GObject *obj,
if (pointer_table_get (refs_and_remotes_table, j, i) != latest_commit_for_ref) if (pointer_table_get (refs_and_remotes_table, j, i) != latest_commit_for_ref)
latest_commit_for_ref = NULL; latest_commit_for_ref = NULL;
if (latest_commit_for_ref != NULL)
n_latest_refs++;
g_hash_table_insert (validated_ref_to_checksum, ostree_collection_ref_dup (refs[j]), g_strdup (latest_commit_for_ref)); g_hash_table_insert (validated_ref_to_checksum, ostree_collection_ref_dup (refs[j]), g_strdup (latest_commit_for_ref));
} }
if (g_hash_table_size (validated_ref_to_checksum) == 0) if (n_latest_refs == 0)
{ {
g_debug ("%s: Omitting remote %s from results as none of its refs are new enough.", g_debug ("%s: Omitting remote %s from results as none of its refs are new enough.",
G_STRFUNC, result->remote->name); G_STRFUNC, result->remote->name);
@ -5229,7 +5351,7 @@ ostree_repo_pull_from_remotes_async (OstreeRepo *self,
g_variant_dict_insert (&local_options_dict, "flags", "i", OSTREE_REPO_PULL_FLAGS_UNTRUSTED | flags); g_variant_dict_insert (&local_options_dict, "flags", "i", OSTREE_REPO_PULL_FLAGS_UNTRUSTED | flags);
g_variant_dict_insert_value (&local_options_dict, "collection-refs", g_variant_builder_end (&refs_to_pull_builder)); g_variant_dict_insert_value (&local_options_dict, "collection-refs", g_variant_builder_end (&refs_to_pull_builder));
g_variant_dict_insert (&local_options_dict, "gpg-verify", "b", TRUE); g_variant_dict_insert (&local_options_dict, "gpg-verify", "b", TRUE);
g_variant_dict_insert (&local_options_dict, "gpg-verify-summary", "b", TRUE); g_variant_dict_insert (&local_options_dict, "gpg-verify-summary", "b", FALSE);
g_variant_dict_insert (&local_options_dict, "inherit-transaction", "b", TRUE); g_variant_dict_insert (&local_options_dict, "inherit-transaction", "b", TRUE);
copy_option (&options_dict, &local_options_dict, "depth", G_VARIANT_TYPE ("i")); copy_option (&options_dict, &local_options_dict, "depth", G_VARIANT_TYPE ("i"));
copy_option (&options_dict, &local_options_dict, "disable-static-deltas", G_VARIANT_TYPE ("b")); copy_option (&options_dict, &local_options_dict, "disable-static-deltas", G_VARIANT_TYPE ("b"));
@ -5497,7 +5619,7 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self,
if (gpg_verify_summary && signatures == NULL) if (gpg_verify_summary && signatures == NULL)
{ {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE,
"GPG verification enabled, but no summary signatures found (use gpg-verify-summary=false in remote config to disable)"); "GPG verification enabled, but no summary signatures found (use gpg-verify-summary=false in remote config to disable)");
goto out; goto out;
} }
@ -5505,7 +5627,7 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self,
/* Verify any summary signatures. */ /* Verify any summary signatures. */
if (gpg_verify_summary && summary != NULL && signatures != NULL) if (gpg_verify_summary && summary != NULL && signatures != NULL)
{ {
glnx_unref_object OstreeGpgVerifyResult *result = NULL; g_autoptr(OstreeGpgVerifyResult) result = NULL;
result = ostree_repo_verify_summary (self, result = ostree_repo_verify_summary (self,
name, name,
@ -5540,7 +5662,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
GError **error) GError **error)
{ {
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"This version of ostree was built without libsoup, and cannot fetch over HTTP"); "This version of ostree was built without libsoup or libcurl, and cannot fetch over HTTP");
return FALSE; return FALSE;
} }
@ -5554,7 +5676,7 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self,
GError **error) GError **error)
{ {
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"This version of ostree was built without libsoup, and cannot fetch over HTTP"); "This version of ostree was built without libsoup or libcurl, and cannot fetch over HTTP");
return FALSE; return FALSE;
} }

View File

@ -472,6 +472,7 @@ ostree_repo_resolve_rev_ext (OstreeRepo *self,
static gboolean static gboolean
enumerate_refs_recurse (OstreeRepo *repo, enumerate_refs_recurse (OstreeRepo *repo,
const char *remote, const char *remote,
OstreeRepoListRefsExtFlags flags,
const char *collection_id, const char *collection_id,
int base_dfd, int base_dfd,
GString *base_path, GString *base_path,
@ -482,6 +483,7 @@ enumerate_refs_recurse (OstreeRepo *repo,
GError **error) GError **error)
{ {
g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
const gboolean aliases_only = (flags & OSTREE_REPO_LIST_REFS_EXT_ALIASES) > 0;
if (!glnx_dirfd_iterator_init_at (child_dfd, path, FALSE, &dfd_iter, error)) if (!glnx_dirfd_iterator_init_at (child_dfd, path, FALSE, &dfd_iter, error))
return FALSE; return FALSE;
@ -502,17 +504,31 @@ enumerate_refs_recurse (OstreeRepo *repo,
{ {
g_string_append_c (base_path, '/'); g_string_append_c (base_path, '/');
if (!enumerate_refs_recurse (repo, remote, collection_id, base_dfd, base_path, if (!enumerate_refs_recurse (repo, remote, flags, collection_id, base_dfd, base_path,
dfd_iter.fd, dent->d_name, dfd_iter.fd, dent->d_name,
refs, cancellable, error)) refs, cancellable, error))
return FALSE; return FALSE;
} }
else if (dent->d_type == DT_REG) else
{
if (aliases_only && dent->d_type == DT_LNK)
{
g_autofree char *target = glnx_readlinkat_malloc (base_dfd, base_path->str,
cancellable, error);
const char *resolved_target = target;
if (!target)
return FALSE;
while (g_str_has_prefix (resolved_target, "../"))
resolved_target += 3;
g_hash_table_insert (refs, g_strdup (base_path->str), g_strdup (resolved_target));
}
else if ((!aliases_only && dent->d_type == DT_REG) || dent->d_type == DT_LNK)
{ {
if (!add_ref_to_set (remote, collection_id, base_dfd, base_path->str, refs, if (!add_ref_to_set (remote, collection_id, base_dfd, base_path->str, refs,
cancellable, error)) cancellable, error))
return FALSE; return FALSE;
} }
}
g_string_truncate (base_path, len); g_string_truncate (base_path, len);
} }
@ -523,6 +539,7 @@ enumerate_refs_recurse (OstreeRepo *repo,
static gboolean static gboolean
_ostree_repo_list_refs_internal (OstreeRepo *self, _ostree_repo_list_refs_internal (OstreeRepo *self,
gboolean cut_prefix, gboolean cut_prefix,
OstreeRepoListRefsExtFlags flags,
const char *refspec_prefix, const char *refspec_prefix,
GHashTable **out_all_refs, GHashTable **out_all_refs,
GCancellable *cancellable, GCancellable *cancellable,
@ -571,7 +588,7 @@ _ostree_repo_list_refs_internal (OstreeRepo *self,
if (!glnx_opendirat (self->repo_dir_fd, cut_prefix ? path : prefix_path, TRUE, &base_fd, error)) if (!glnx_opendirat (self->repo_dir_fd, cut_prefix ? path : prefix_path, TRUE, &base_fd, error))
return FALSE; return FALSE;
if (!enumerate_refs_recurse (self, remote, NULL, base_fd, base_path, if (!enumerate_refs_recurse (self, remote, flags, NULL, base_fd, base_path,
base_fd, cut_prefix ? "." : ref_prefix, base_fd, cut_prefix ? "." : ref_prefix,
ret_all_refs, cancellable, error)) ret_all_refs, cancellable, error))
return FALSE; return FALSE;
@ -598,7 +615,7 @@ _ostree_repo_list_refs_internal (OstreeRepo *self,
if (!glnx_opendirat (self->repo_dir_fd, "refs/heads", TRUE, &refs_heads_dfd, error)) if (!glnx_opendirat (self->repo_dir_fd, "refs/heads", TRUE, &refs_heads_dfd, error))
return FALSE; return FALSE;
if (!enumerate_refs_recurse (self, NULL, NULL, refs_heads_dfd, base_path, if (!enumerate_refs_recurse (self, NULL, flags, NULL, refs_heads_dfd, base_path,
refs_heads_dfd, ".", refs_heads_dfd, ".",
ret_all_refs, cancellable, error)) ret_all_refs, cancellable, error))
return FALSE; return FALSE;
@ -624,7 +641,7 @@ _ostree_repo_list_refs_internal (OstreeRepo *self,
if (!glnx_opendirat (dfd_iter.fd, dent->d_name, TRUE, &remote_dfd, error)) if (!glnx_opendirat (dfd_iter.fd, dent->d_name, TRUE, &remote_dfd, error))
return FALSE; return FALSE;
if (!enumerate_refs_recurse (self, dent->d_name, NULL, remote_dfd, base_path, if (!enumerate_refs_recurse (self, dent->d_name, flags, NULL, remote_dfd, base_path,
remote_dfd, ".", remote_dfd, ".",
ret_all_refs, ret_all_refs,
cancellable, error)) cancellable, error))
@ -655,7 +672,10 @@ ostree_repo_list_refs (OstreeRepo *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
return _ostree_repo_list_refs_internal (self, TRUE, refspec_prefix, out_all_refs, cancellable, error); return _ostree_repo_list_refs_internal (self, TRUE,
OSTREE_REPO_LIST_REFS_EXT_NONE,
refspec_prefix, out_all_refs,
cancellable, error);
} }
/** /**
@ -681,7 +701,9 @@ ostree_repo_list_refs_ext (OstreeRepo *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
return _ostree_repo_list_refs_internal (self, FALSE, refspec_prefix, out_all_refs, cancellable, error); return _ostree_repo_list_refs_internal (self, FALSE, flags,
refspec_prefix, out_all_refs,
cancellable, error);
} }
/** /**
@ -757,17 +779,163 @@ ostree_repo_remote_list_refs (OstreeRepo *self,
return TRUE; return TRUE;
} }
#ifdef OSTREE_ENABLE_EXPERIMENTAL_API
static gboolean
remote_list_collection_refs_process_refs (OstreeRepo *self,
const gchar *remote_name,
const gchar *summary_collection_id,
GVariant *summary_refs,
GHashTable *ret_all_refs,
GError **error)
{
gsize j, n;
for (j = 0, n = g_variant_n_children (summary_refs); j < n; j++)
{
const guchar *csum_bytes;
g_autoptr(GVariant) ref_v = NULL, csum_v = NULL;
gchar tmp_checksum[OSTREE_SHA256_STRING_LEN + 1];
const gchar *ref_name;
/* Check the ref name. */
ref_v = g_variant_get_child_value (summary_refs, j);
g_variant_get_child (ref_v, 0, "&s", &ref_name);
if (!ostree_validate_rev (ref_name, error))
return FALSE;
/* Check the commit checksum. */
g_variant_get_child (ref_v, 1, "(t@ay@a{sv})", NULL, &csum_v, NULL);
csum_bytes = ostree_checksum_bytes_peek_validate (csum_v, error);
if (csum_bytes == NULL)
return FALSE;
ostree_checksum_inplace_from_bytes (csum_bytes, tmp_checksum);
g_hash_table_insert (ret_all_refs,
ostree_collection_ref_new (summary_collection_id, ref_name),
g_strdup (tmp_checksum));
}
return TRUE;
}
/**
* ostree_repo_remote_list_collection_refs:
* @self: Repo
* @remote_name: Name of the remote.
* @out_all_refs: (out) (element-type OstreeCollectionRef utf8): Mapping from collectionref to checksum
* @cancellable: Cancellable
* @error: Error
*
* List refs advertised by @remote_name, including refs which are part of
* collections. If the repository at @remote_name has a collection ID set, its
* refs will be returned with that collection ID; otherwise, they will be returned
* with a %NULL collection ID in each #OstreeCollectionRef key in @out_all_refs.
* Any refs for other collections stored in the repository will also be returned.
* No filtering is performed.
*
* Since: 2017.10
*/
gboolean
ostree_repo_remote_list_collection_refs (OstreeRepo *self,
const char *remote_name,
GHashTable **out_all_refs,
GCancellable *cancellable,
GError **error)
{
g_autoptr(GBytes) summary_bytes = NULL;
g_autoptr(GHashTable) ret_all_refs = NULL; /* (element-type OstreeCollectionRef utf8) */
g_autoptr(GVariant) summary_v = NULL;
g_autoptr(GVariant) additional_metadata_v = NULL;
g_autoptr(GVariant) summary_refs = NULL;
const char *summary_collection_id;
g_autoptr(GVariantIter) summary_collection_map = NULL;
if (!ostree_repo_remote_fetch_summary (self, remote_name,
&summary_bytes, NULL,
cancellable, error))
return FALSE;
if (summary_bytes == NULL)
return glnx_throw (error, "Remote refs not available; server has no summary file");
ret_all_refs = g_hash_table_new_full (ostree_collection_ref_hash,
ostree_collection_ref_equal,
(GDestroyNotify) ostree_collection_ref_free,
g_free);
summary_v = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT,
summary_bytes, FALSE);
additional_metadata_v = g_variant_get_child_value (summary_v, 1);
/* List the refs in the main map. */
if (!g_variant_lookup (additional_metadata_v, OSTREE_SUMMARY_COLLECTION_ID, "&s", &summary_collection_id))
summary_collection_id = NULL;
summary_refs = g_variant_get_child_value (summary_v, 0);
if (!remote_list_collection_refs_process_refs (self, remote_name,
summary_collection_id, summary_refs,
ret_all_refs, error))
return FALSE;
/* List the refs in the collection map. */
if (!g_variant_lookup (additional_metadata_v, OSTREE_SUMMARY_COLLECTION_MAP, "a{sa(s(taya{sv}))}", &summary_collection_map))
summary_collection_map = NULL;
while (summary_collection_map != NULL &&
g_variant_iter_loop (summary_collection_map, "{s@a(s(taya{sv}))}", &summary_collection_id, &summary_refs))
{
if (!remote_list_collection_refs_process_refs (self, remote_name,
summary_collection_id, summary_refs,
ret_all_refs, error))
return FALSE;
}
ot_transfer_out_value (out_all_refs, &ret_all_refs);
return TRUE;
}
#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */
static char *
relative_symlink_to (const char *relpath,
const char *target)
{
g_assert (*relpath);
g_assert (*target && *target != '/');
g_autoptr(GString) buf = g_string_new ("");
while (TRUE)
{
const char *slash = strchr (relpath, '/');
if (!slash)
break;
relpath = slash + 1;
g_string_append (buf, "../");
}
g_string_append (buf, target);
return g_string_free (g_steal_pointer (&buf), FALSE);
}
/* May specify @rev or @alias */
gboolean gboolean
_ostree_repo_write_ref (OstreeRepo *self, _ostree_repo_write_ref (OstreeRepo *self,
const char *remote, const char *remote,
const OstreeCollectionRef *ref, const OstreeCollectionRef *ref,
const char *rev, const char *rev,
const char *alias,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
glnx_fd_close int dfd = -1; glnx_fd_close int dfd = -1;
g_return_val_if_fail (remote == NULL || ref->collection_id == NULL, FALSE); g_return_val_if_fail (remote == NULL || ref->collection_id == NULL, FALSE);
g_return_val_if_fail (!(rev != NULL && alias != NULL), FALSE);
if (remote != NULL && !ostree_validate_remote_name (remote, error)) if (remote != NULL && !ostree_validate_remote_name (remote, error))
return FALSE; return FALSE;
@ -832,7 +1000,7 @@ _ostree_repo_write_ref (OstreeRepo *self,
return glnx_throw_errno_prefix (error, "Opening remotes/ dir %s", remote); return glnx_throw_errno_prefix (error, "Opening remotes/ dir %s", remote);
} }
if (rev == NULL) if (rev == NULL && alias == NULL)
{ {
if (dfd >= 0) if (dfd >= 0)
{ {
@ -843,11 +1011,32 @@ _ostree_repo_write_ref (OstreeRepo *self,
} }
} }
} }
else else if (rev != NULL)
{ {
if (!write_checksum_file_at (self, dfd, ref->ref_name, rev, cancellable, error)) if (!write_checksum_file_at (self, dfd, ref->ref_name, rev, cancellable, error))
return FALSE; return FALSE;
} }
else if (alias != NULL)
{
const char *lastslash = strrchr (ref->ref_name, '/');
if (lastslash)
{
char *parent = strdupa (ref->ref_name);
parent[lastslash - ref->ref_name] = '\0';
if (!glnx_shutil_mkdir_p_at (dfd, parent, 0755, cancellable, error))
return FALSE;
}
g_autofree char *reltarget = relative_symlink_to (ref->ref_name, alias);
g_autofree char *tmplink = NULL;
if (!_ostree_make_temporary_symlink_at (self->tmp_dir_fd, reltarget,
&tmplink, cancellable, error))
return FALSE;
if (!glnx_renameat (self->tmp_dir_fd, tmplink, dfd, ref->ref_name, error))
return FALSE;
}
if (!_ostree_repo_update_mtime (self, error)) if (!_ostree_repo_update_mtime (self, error))
return FALSE; return FALSE;
@ -876,7 +1065,7 @@ _ostree_repo_update_refs (OstreeRepo *self,
return FALSE; return FALSE;
const OstreeCollectionRef ref = { NULL, ref_name }; const OstreeCollectionRef ref = { NULL, ref_name };
if (!_ostree_repo_write_ref (self, remote, &ref, rev, if (!_ostree_repo_write_ref (self, remote, &ref, rev, NULL,
cancellable, error)) cancellable, error))
return FALSE; return FALSE;
} }
@ -899,7 +1088,7 @@ _ostree_repo_update_collection_refs (OstreeRepo *self,
const OstreeCollectionRef *ref = key; const OstreeCollectionRef *ref = key;
const char *rev = value; const char *rev = value;
if (!_ostree_repo_write_ref (self, NULL, ref, rev, if (!_ostree_repo_write_ref (self, NULL, ref, rev, NULL,
cancellable, error)) cancellable, error))
return FALSE; return FALSE;
} }
@ -961,7 +1150,8 @@ ostree_repo_list_collection_refs (OstreeRepo *self,
if (!glnx_opendirat (self->repo_dir_fd, "refs/heads", TRUE, &refs_heads_dfd, error)) if (!glnx_opendirat (self->repo_dir_fd, "refs/heads", TRUE, &refs_heads_dfd, error))
return FALSE; return FALSE;
if (!enumerate_refs_recurse (self, NULL, main_collection_id, refs_heads_dfd, base_path, if (!enumerate_refs_recurse (self, NULL, OSTREE_REPO_LIST_REFS_EXT_NONE,
main_collection_id, refs_heads_dfd, base_path,
refs_heads_dfd, ".", refs_heads_dfd, ".",
ret_all_refs, cancellable, error)) ret_all_refs, cancellable, error))
return FALSE; return FALSE;
@ -993,7 +1183,8 @@ ostree_repo_list_collection_refs (OstreeRepo *self,
if (!glnx_opendirat (dfd_iter.fd, dent->d_name, TRUE, &collection_dfd, error)) if (!glnx_opendirat (dfd_iter.fd, dent->d_name, TRUE, &collection_dfd, error))
return FALSE; return FALSE;
if (!enumerate_refs_recurse (self, NULL, dent->d_name, collection_dfd, base_path, if (!enumerate_refs_recurse (self, NULL, OSTREE_REPO_LIST_REFS_EXT_NONE,
dent->d_name, collection_dfd, base_path,
collection_dfd, ".", collection_dfd, ".",
ret_all_refs, ret_all_refs,
cancellable, error)) cancellable, error))

View File

@ -649,7 +649,7 @@ _ostree_delta_get_endianness (GVariant *superblock,
* deltas, period. Past the gigabyte scale you really want * deltas, period. Past the gigabyte scale you really want
* bittorrent or something. * bittorrent or something.
*/ */
if ((total_size / total_objects) > G_MAXUINT32) if (total_objects > 0 && (total_size / total_objects) > G_MAXUINT32)
{ {
is_byteswapped = TRUE; is_byteswapped = TRUE;
} }

View File

@ -456,6 +456,7 @@ ostree_repo_finalize (GObject *object)
g_clear_object (&self->parent_repo); g_clear_object (&self->parent_repo);
g_free (self->stagedir_prefix); g_free (self->stagedir_prefix);
g_clear_object (&self->repodir_fdrel);
g_clear_object (&self->repodir); g_clear_object (&self->repodir);
if (self->repo_dir_fd != -1) if (self->repo_dir_fd != -1)
(void) close (self->repo_dir_fd); (void) close (self->repo_dir_fd);
@ -546,22 +547,11 @@ ostree_repo_get_property(GObject *object,
} }
} }
static void
ostree_repo_constructed (GObject *object)
{
OstreeRepo *self = OSTREE_REPO (object);
g_assert (self->repodir != NULL);
G_OBJECT_CLASS (ostree_repo_parent_class)->constructed (object);
}
static void static void
ostree_repo_class_init (OstreeRepoClass *klass) ostree_repo_class_init (OstreeRepoClass *klass)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = ostree_repo_constructed;
object_class->get_property = ostree_repo_get_property; object_class->get_property = ostree_repo_get_property;
object_class->set_property = ostree_repo_set_property; object_class->set_property = ostree_repo_set_property;
object_class->finalize = ostree_repo_finalize; object_class->finalize = ostree_repo_finalize;
@ -581,6 +571,7 @@ ostree_repo_class_init (OstreeRepoClass *klass)
"", "",
G_TYPE_FILE, G_TYPE_FILE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class, g_object_class_install_property (object_class,
PROP_REMOTES_CONFIG_DIR, PROP_REMOTES_CONFIG_DIR,
g_param_spec_string ("remotes-config-dir", g_param_spec_string ("remotes-config-dir",
@ -662,6 +653,43 @@ ostree_repo_new (GFile *path)
return g_object_new (OSTREE_TYPE_REPO, "path", path, NULL); return g_object_new (OSTREE_TYPE_REPO, "path", path, NULL);
} }
static OstreeRepo *
repo_open_at_take_fd (int *dfd,
GCancellable *cancellable,
GError **error)
{
g_autoptr(OstreeRepo) repo = g_object_new (OSTREE_TYPE_REPO, NULL);
repo->repo_dir_fd = glnx_steal_fd (dfd);
if (!ostree_repo_open (repo, cancellable, error))
return NULL;
return g_steal_pointer (&repo);
}
/**
* ostree_repo_open_at:
* @dfd: Directory fd
* @path: Path
*
* This combines ostree_repo_new() (but using fd-relative access) with
* ostree_repo_open(). Use this when you know you should be operating on an
* already extant repository. If you want to create one, use ostree_repo_create_at().
*
* Returns: (transfer full): An accessor object for an OSTree repository located at @dfd + @path
*/
OstreeRepo*
ostree_repo_open_at (int dfd,
const char *path,
GCancellable *cancellable,
GError **error)
{
glnx_fd_close int repo_dfd = -1;
if (!glnx_opendirat (dfd, path, TRUE, &repo_dfd, error))
return NULL;
return repo_open_at_take_fd (&repo_dfd, cancellable, error);
}
static GFile * static GFile *
get_default_repo_path (GFile *sysroot_path) get_default_repo_path (GFile *sysroot_path)
{ {
@ -744,8 +772,16 @@ ostree_repo_is_system (OstreeRepo *repo)
if (!repo->sysroot_dir) if (!repo->sysroot_dir)
return FALSE; return FALSE;
/* If we created via ostree_repo_new(), we'll have a repo path. Compare
* it to the sysroot path in that case.
*/
if (repo->repodir)
{
g_autoptr(GFile) default_repo_path = get_default_repo_path (repo->sysroot_dir); g_autoptr(GFile) default_repo_path = get_default_repo_path (repo->sysroot_dir);
return g_file_equal (repo->repodir, default_repo_path); return g_file_equal (repo->repodir, default_repo_path);
}
/* Otherwise, not a system repo */
return FALSE;
} }
/** /**
@ -1331,9 +1367,9 @@ ostree_repo_remote_gpg_import (OstreeRepo *self,
GError **error) GError **error)
{ {
OstreeRemote *remote; OstreeRemote *remote;
ot_auto_gpgme_ctx gpgme_ctx_t source_context = NULL; g_auto(gpgme_ctx_t) source_context = NULL;
ot_auto_gpgme_ctx gpgme_ctx_t target_context = NULL; g_auto(gpgme_ctx_t) target_context = NULL;
ot_auto_gpgme_data gpgme_data_t data_buffer = NULL; g_auto(gpgme_data_t) data_buffer = NULL;
gpgme_import_result_t import_result; gpgme_import_result_t import_result;
gpgme_import_status_t import_status; gpgme_import_status_t import_status;
g_autofree char *source_tmp_dir = NULL; g_autofree char *source_tmp_dir = NULL;
@ -1670,6 +1706,104 @@ ostree_repo_mode_from_string (const char *mode,
#define DEFAULT_CONFIG_CONTENTS ("[core]\n" \ #define DEFAULT_CONFIG_CONTENTS ("[core]\n" \
"repo_version=1\n") "repo_version=1\n")
/* Just write the dirs to disk, return a dfd */
static gboolean
repo_create_at_internal (int dfd,
const char *path,
OstreeRepoMode mode,
GVariant *options,
int *out_dfd,
GCancellable *cancellable,
GError **error)
{
struct stat stbuf;
/* We do objects/ last - if it exists we do nothing and exit successfully */
const char *state_dirs[] = { "tmp", "extensions", "state",
"refs", "refs/heads", "refs/mirrors",
"refs/remotes", "objects" };
/* Early return if we have an existing repo */
{ g_autofree char *objects_path = g_build_filename (path, "objects", NULL);
if (fstatat (dfd, objects_path, &stbuf, 0) == 0)
{
glnx_fd_close int repo_dfd = -1;
if (!glnx_opendirat (dfd, path, TRUE, &repo_dfd, error))
return FALSE;
/* Note early return */
*out_dfd = glnx_steal_fd (&repo_dfd);
return TRUE;
}
else if (errno != ENOENT)
return glnx_throw_errno_prefix (error, "fstatat");
}
if (mkdirat (dfd, path, 0755) != 0)
{
if (G_UNLIKELY (errno != EEXIST))
return glnx_throw_errno_prefix (error, "mkdirat");
}
glnx_fd_close int repo_dfd = -1;
if (!glnx_opendirat (dfd, path, TRUE, &repo_dfd, error))
return FALSE;
if (fstatat (repo_dfd, "config", &stbuf, 0) < 0)
{
if (errno == ENOENT)
{
const char *mode_str = NULL;
g_autoptr(GString) config_data = g_string_new (DEFAULT_CONFIG_CONTENTS);
if (!ostree_repo_mode_to_string (mode, &mode_str, error))
return FALSE;
g_assert (mode_str);
g_string_append_printf (config_data, "mode=%s\n", mode_str);
const char *collection_id = NULL;
if (options)
g_variant_lookup (options, "collection-id", "&s", &collection_id);
if (collection_id != NULL)
g_string_append_printf (config_data, "collection-id=%s\n", collection_id);
if (!glnx_file_replace_contents_at (repo_dfd, "config",
(guint8*)config_data->str, config_data->len,
0, cancellable, error))
return FALSE;
}
else
return glnx_throw_errno_prefix (error, "fstatat");
}
for (guint i = 0; i < G_N_ELEMENTS (state_dirs); i++)
{
const char *elt = state_dirs[i];
if (mkdirat (repo_dfd, elt, 0755) == -1)
{
if (G_UNLIKELY (errno != EEXIST))
return glnx_throw_errno_prefix (error, "mkdirat");
}
}
/* Test that the fs supports user xattrs now, so we get an error early rather
* than during an object write later.
*/
if (mode == OSTREE_REPO_MODE_BARE_USER)
{
g_auto(GLnxTmpfile) tmpf = { 0, };
if (!glnx_open_tmpfile_linkable_at (repo_dfd, ".", O_RDWR|O_CLOEXEC, &tmpf, error))
return FALSE;
if (!_ostree_write_bareuser_metadata (tmpf.fd, 0, 0, 644, NULL, error))
return FALSE;
}
*out_dfd = glnx_steal_fd (&repo_dfd);
return TRUE;
}
/** /**
* ostree_repo_create: * ostree_repo_create:
* @self: An #OstreeRepo * @self: An #OstreeRepo
@ -1686,6 +1820,11 @@ ostree_repo_mode_from_string (const char *mode,
* of an existing repository, and will silently ignore an attempt to * of an existing repository, and will silently ignore an attempt to
* do so. * do so.
* *
* Since 2017.9, "existing repository" is defined by the existence of an
* `objects` subdirectory.
*
* This function predates ostree_repo_create_at(). It is an error to call
* this function on a repository initialized via ostree_repo_open_at().
*/ */
gboolean gboolean
ostree_repo_create (OstreeRepo *self, ostree_repo_create (OstreeRepo *self,
@ -1693,76 +1832,64 @@ ostree_repo_create (OstreeRepo *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
g_return_val_if_fail (self->repodir, FALSE);
const char *repopath = gs_file_get_path_cached (self->repodir); const char *repopath = gs_file_get_path_cached (self->repodir);
glnx_fd_close int dfd = -1; g_autoptr(GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
struct stat stbuf; if (self->collection_id)
const char *state_dirs[] = { "objects", "tmp", "extensions", "state", g_variant_builder_add (builder, "{s@v}", "collection-id",
"refs", "refs/heads", "refs/mirrors", g_variant_new_variant (g_variant_new_string (self->collection_id)));
"refs/remotes" };
if (mkdir (repopath, 0755) != 0) glnx_fd_close int repo_dir_fd = -1;
{ if (!repo_create_at_internal (AT_FDCWD, repopath, mode,
if (G_UNLIKELY (errno != EEXIST)) g_variant_builder_end (builder),
return glnx_throw_errno (error); &repo_dir_fd,
} cancellable, error))
if (!glnx_opendirat (AT_FDCWD, repopath, TRUE, &dfd, error))
return FALSE; return FALSE;
self->repo_dir_fd = glnx_steal_fd (&repo_dir_fd);
if (fstatat (dfd, "config", &stbuf, 0) < 0)
{
if (errno == ENOENT)
{
const char *mode_str = NULL;
g_autoptr(GString) config_data = g_string_new (DEFAULT_CONFIG_CONTENTS);
if (!ostree_repo_mode_to_string (mode, &mode_str, error))
return FALSE;
g_assert (mode_str);
g_string_append_printf (config_data, "mode=%s\n", mode_str);
if (self->collection_id != NULL)
g_string_append_printf (config_data, "collection-id=%s\n", self->collection_id);
if (!glnx_file_replace_contents_at (dfd, "config",
(guint8*)config_data->str, config_data->len,
0, cancellable, error))
return FALSE;
}
else
return glnx_throw_errno (error);
}
for (guint i = 0; i < G_N_ELEMENTS (state_dirs); i++)
{
const char *elt = state_dirs[i];
if (mkdirat (dfd, elt, 0755) == -1)
{
if (G_UNLIKELY (errno != EEXIST))
return glnx_throw_errno (error);
}
}
/* Test that the fs supports user xattrs now, so we get an error early rather
* than during an object write later.
*/
if (mode == OSTREE_REPO_MODE_BARE_USER)
{
g_auto(GLnxTmpfile) tmpf = { 0, };
if (!glnx_open_tmpfile_linkable_at (dfd, ".", O_RDWR|O_CLOEXEC, &tmpf, error))
return FALSE;
if (!_ostree_write_bareuser_metadata (tmpf.fd, 0, 0, 644, NULL, error))
return FALSE;
}
if (!ostree_repo_open (self, cancellable, error)) if (!ostree_repo_open (self, cancellable, error))
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
/**
* ostree_repo_create_at:
* @dfd: Directory fd
* @path: Path
* @mode: The mode to store the repository in
* @options: a{sv}: See below for accepted keys
* @cancellable: Cancellable
* @error: Error
*
* This is a file-descriptor relative version of ostree_repo_create().
* Create the underlying structure on disk for the repository, and call
* ostree_repo_open_at() on the result, preparing it for use.
*
* If a repository already exists at @dfd + @path (defined by an `objects/`
* subdirectory existing), then this function will simply call
* ostree_repo_open_at(). In other words, this function cannot be used to change
* the mode or configuration (`repo/config`) of an existing repo.
*
* The @options dict may contain:
*
* - collection-id: s: Set as collection ID in repo/config (Since 2017.9)
*
* Returns: (transfer full): A new OSTree repository reference
*/
OstreeRepo *
ostree_repo_create_at (int dfd,
const char *path,
OstreeRepoMode mode,
GVariant *options,
GCancellable *cancellable,
GError **error)
{
glnx_fd_close int repo_dfd = -1;
if (!repo_create_at_internal (dfd, path, mode, options, &repo_dfd,
cancellable, error))
return NULL;
return repo_open_at_take_fd (&repo_dfd, cancellable, error);
}
static gboolean static gboolean
enumerate_directory_allow_noent (GFile *dirpath, enumerate_directory_allow_noent (GFile *dirpath,
const char *queryargs, const char *queryargs,
@ -2132,7 +2259,6 @@ ostree_repo_open (OstreeRepo *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
struct stat self_stbuf;
struct stat stbuf; struct stat stbuf;
g_return_val_if_fail (error == NULL || *error == NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@ -2162,22 +2288,25 @@ ostree_repo_open (OstreeRepo *self,
self->stagedir_prefix = g_strconcat (OSTREE_REPO_TMPDIR_STAGING, boot_id, "-", NULL); self->stagedir_prefix = g_strconcat (OSTREE_REPO_TMPDIR_STAGING, boot_id, "-", NULL);
} }
if (self->repo_dir_fd == -1)
{
g_assert (self->repodir);
if (!glnx_opendirat (AT_FDCWD, gs_file_get_path_cached (self->repodir), TRUE, if (!glnx_opendirat (AT_FDCWD, gs_file_get_path_cached (self->repodir), TRUE,
&self->repo_dir_fd, error)) &self->repo_dir_fd, error))
{ {
g_prefix_error (error, "%s: ", gs_file_get_path_cached (self->repodir)); g_prefix_error (error, "%s: ", gs_file_get_path_cached (self->repodir));
return FALSE; return FALSE;
} }
}
if (!glnx_fstat (self->repo_dir_fd, &self_stbuf, error)) if (!glnx_fstat (self->repo_dir_fd, &stbuf, error))
return FALSE; return FALSE;
self->device = stbuf.st_dev;
self->inode = stbuf.st_ino;
if (!glnx_opendirat (self->repo_dir_fd, "objects", TRUE, if (!glnx_opendirat (self->repo_dir_fd, "objects", TRUE,
&self->objects_dir_fd, error)) &self->objects_dir_fd, error))
{
g_prefix_error (error, "Opening objects/ directory: ");
return FALSE; return FALSE;
}
self->writable = faccessat (self->objects_dir_fd, ".", W_OK, 0) == 0; self->writable = faccessat (self->objects_dir_fd, ".", W_OK, 0) == 0;
if (!self->writable) if (!self->writable)
@ -2238,8 +2367,8 @@ ostree_repo_open (OstreeRepo *self,
if (fstatat (AT_FDCWD, "/ostree/repo", &system_stbuf, 0) == 0) if (fstatat (AT_FDCWD, "/ostree/repo", &system_stbuf, 0) == 0)
{ {
/* Are we the same as /ostree/repo? */ /* Are we the same as /ostree/repo? */
if (self_stbuf.st_dev == system_stbuf.st_dev && if (self->device == system_stbuf.st_dev &&
self_stbuf.st_ino == system_stbuf.st_ino) self->inode == system_stbuf.st_ino)
self->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_IS_SYSROOT_OSTREE; self->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_IS_SYSROOT_OSTREE;
else else
self->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_NO; self->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_NO;
@ -2349,14 +2478,24 @@ _ostree_repo_file_replace_contents (OstreeRepo *self,
/** /**
* ostree_repo_get_path: * ostree_repo_get_path:
* @self: * @self: Repo
*
* Note that since the introduction of ostree_repo_open_at(), this function may
* return a process-specific path in `/proc` if the repository was created using
* that API. In general, you should avoid use of this API.
* *
* Returns: (transfer none): Path to repo * Returns: (transfer none): Path to repo
*/ */
GFile * GFile *
ostree_repo_get_path (OstreeRepo *self) ostree_repo_get_path (OstreeRepo *self)
{ {
/* Did we have an abspath? Return it */
if (self->repodir)
return self->repodir; return self->repodir;
/* Lazily create a fd-relative path */
if (!self->repodir_fdrel)
self->repodir_fdrel = ot_fdrel_to_gfile (self->repo_dir_fd, ".");
return self->repodir_fdrel;
} }
/** /**
@ -4082,14 +4221,14 @@ ostree_repo_sign_commit (OstreeRepo *self,
* check if the commit has already been signed with the given key ID. * check if the commit has already been signed with the given key ID.
* We want to avoid storing duplicate signatures in the metadata. */ * We want to avoid storing duplicate signatures in the metadata. */
g_autoptr(GError) local_error = NULL; g_autoptr(GError) local_error = NULL;
glnx_unref_object OstreeGpgVerifyResult *result g_autoptr(OstreeGpgVerifyResult) result
=_ostree_repo_gpg_verify_with_metadata (self, commit_data, old_metadata, =_ostree_repo_gpg_verify_with_metadata (self, commit_data, old_metadata,
NULL, NULL, NULL, NULL, NULL, NULL,
cancellable, &local_error); cancellable, &local_error);
if (!result) if (!result)
{ {
/* "Not found" just means the commit is not yet signed. That's okay. */ /* "Not found" just means the commit is not yet signed. That's okay. */
if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) if (g_error_matches (local_error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE))
{ {
g_clear_error (&local_error); g_clear_error (&local_error);
} }
@ -4202,31 +4341,52 @@ ostree_repo_add_gpg_signature_summary (OstreeRepo *self,
/* Special remote for _ostree_repo_gpg_verify_with_metadata() */ /* Special remote for _ostree_repo_gpg_verify_with_metadata() */
static const char *OSTREE_ALL_REMOTES = "__OSTREE_ALL_REMOTES__"; static const char *OSTREE_ALL_REMOTES = "__OSTREE_ALL_REMOTES__";
static GFile * /* Look for a keyring for @remote in the repo itself, or in
* /etc/ostree/remotes.d.
*/
static gboolean
find_keyring (OstreeRepo *self, find_keyring (OstreeRepo *self,
OstreeRemote *remote, OstreeRemote *remote,
GCancellable *cancellable) GBytes **ret_bytes,
GCancellable *cancellable,
GError **error)
{ {
g_autoptr(GFile) file = g_file_get_child (self->repodir, remote->keyring); glnx_fd_close int fd = -1;
if (!ot_openat_ignore_enoent (self->repo_dir_fd, remote->keyring, &fd, error))
return FALSE;
if (g_file_query_exists (file, cancellable)) if (fd != -1)
{ {
return g_steal_pointer (&file); GBytes *ret = glnx_fd_readall_bytes (fd, cancellable, error);
if (!ret)
return FALSE;
*ret_bytes = ret;
return TRUE;
} }
g_autoptr(GFile) remotes_d = get_remotes_d_dir (self, NULL); g_autoptr(GFile) remotes_d = get_remotes_d_dir (self, NULL);
if (remotes_d) if (remotes_d)
{ {
g_autoptr(GFile) file2 = g_file_get_child (remotes_d, remote->keyring); g_autoptr(GFile) child = g_file_get_child (remotes_d, remote->keyring);
if (g_file_query_exists (file2, cancellable)) if (!ot_openat_ignore_enoent (AT_FDCWD, gs_file_get_path_cached (child), &fd, error))
return g_steal_pointer (&file2); return FALSE;
if (fd != -1)
{
GBytes *ret = glnx_fd_readall_bytes (fd, cancellable, error);
if (!ret)
return FALSE;
*ret_bytes = ret;
return TRUE;
}
} }
if (self->parent_repo) if (self->parent_repo)
return find_keyring (self->parent_repo, remote, cancellable); return find_keyring (self->parent_repo, remote, ret_bytes, cancellable, error);
return NULL; *ret_bytes = NULL;
return TRUE;
} }
static OstreeGpgVerifyResult * static OstreeGpgVerifyResult *
@ -4239,7 +4399,7 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
glnx_unref_object OstreeGpgVerifier *verifier = NULL; g_autoptr(OstreeGpgVerifier) verifier = NULL;
gboolean add_global_keyring_dir = TRUE; gboolean add_global_keyring_dir = TRUE;
verifier = _ostree_gpg_verifier_new (); verifier = _ostree_gpg_verifier_new ();
@ -4248,7 +4408,7 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self,
{ {
/* Add all available remote keyring files. */ /* Add all available remote keyring files. */
if (!_ostree_gpg_verifier_add_keyring_dir (verifier, self->repodir, if (!_ostree_gpg_verifier_add_keyring_dir_at (verifier, self->repo_dir_fd, ".",
cancellable, error)) cancellable, error))
return NULL; return NULL;
} }
@ -4258,17 +4418,18 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self,
/* Add the remote's keyring file if it exists. */ /* Add the remote's keyring file if it exists. */
OstreeRemote *remote; OstreeRemote *remote;
g_autoptr(GFile) file = NULL;
remote = _ostree_repo_get_remote_inherited (self, remote_name, error); remote = _ostree_repo_get_remote_inherited (self, remote_name, error);
if (remote == NULL) if (remote == NULL)
return NULL; return NULL;
file = find_keyring (self, remote, cancellable); g_autoptr(GBytes) keyring_data = NULL;
if (!find_keyring (self, remote, &keyring_data, cancellable, error))
return NULL;
if (file != NULL) if (keyring_data != NULL)
{ {
_ostree_gpg_verifier_add_keyring (verifier, file); _ostree_gpg_verifier_add_keyring_data (verifier, keyring_data);
add_global_keyring_dir = FALSE; add_global_keyring_dir = FALSE;
} }
@ -4297,7 +4458,7 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self,
} }
if (extra_keyring != NULL) if (extra_keyring != NULL)
{ {
_ostree_gpg_verifier_add_keyring (verifier, extra_keyring); _ostree_gpg_verifier_add_keyring_file (verifier, extra_keyring);
} }
return _ostree_gpg_verifier_check_signature (verifier, return _ostree_gpg_verifier_check_signature (verifier,
@ -4329,7 +4490,7 @@ _ostree_repo_gpg_verify_with_metadata (OstreeRepo *self,
_OSTREE_METADATA_GPGSIGS_TYPE); _OSTREE_METADATA_GPGSIGS_TYPE);
if (!signaturedata) if (!signaturedata)
{ {
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, g_set_error_literal (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE,
"GPG verification enabled, but no signatures found (use gpg-verify=false in remote config to disable)"); "GPG verification enabled, but no signatures found (use gpg-verify=false in remote config to disable)");
return NULL; return NULL;
} }
@ -4441,7 +4602,7 @@ ostree_repo_verify_commit (OstreeRepo *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
glnx_unref_object OstreeGpgVerifyResult *result = NULL; g_autoptr(OstreeGpgVerifyResult) result = NULL;
result = ostree_repo_verify_commit_ext (self, commit_checksum, result = ostree_repo_verify_commit_ext (self, commit_checksum,
keyringdir, extra_keyring, keyringdir, extra_keyring,

View File

@ -63,6 +63,13 @@ gboolean ostree_repo_open (OstreeRepo *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
_OSTREE_PUBLIC
OstreeRepo*
ostree_repo_open_at (int dfd,
const char *path,
GCancellable *cancellable,
GError **error);
_OSTREE_PUBLIC _OSTREE_PUBLIC
void ostree_repo_set_disable_fsync (OstreeRepo *self, void ostree_repo_set_disable_fsync (OstreeRepo *self,
gboolean disable_fsync); gboolean disable_fsync);
@ -89,6 +96,13 @@ gboolean ostree_repo_create (OstreeRepo *self,
OstreeRepoMode mode, OstreeRepoMode mode,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
_OSTREE_PUBLIC
OstreeRepo * ostree_repo_create_at (int dfd,
const char *path,
OstreeRepoMode mode,
GVariant *options,
GCancellable *cancellable,
GError **error);
#ifdef OSTREE_ENABLE_EXPERIMENTAL_API #ifdef OSTREE_ENABLE_EXPERIMENTAL_API
@ -327,6 +341,14 @@ gboolean ostree_repo_set_ref_immediate (OstreeRepo *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
_OSTREE_PUBLIC
gboolean ostree_repo_set_alias_ref_immediate (OstreeRepo *self,
const char *remote,
const char *ref,
const char *target,
GCancellable *cancellable,
GError **error);
#ifdef OSTREE_ENABLE_EXPERIMENTAL_API #ifdef OSTREE_ENABLE_EXPERIMENTAL_API
_OSTREE_PUBLIC _OSTREE_PUBLIC
@ -452,9 +474,11 @@ gboolean ostree_repo_list_refs (OstreeRepo *self,
/** /**
* OstreeRepoListRefsExtFlags: * OstreeRepoListRefsExtFlags:
* @OSTREE_REPO_LIST_REFS_EXT_NONE: No flags. * @OSTREE_REPO_LIST_REFS_EXT_NONE: No flags.
* @OSTREE_REPO_LIST_REFS_EXT_ALIASES: Only list aliases. Since: 2017.10
*/ */
typedef enum { typedef enum {
OSTREE_REPO_LIST_REFS_EXT_NONE = 0, OSTREE_REPO_LIST_REFS_EXT_NONE = 0,
OSTREE_REPO_LIST_REFS_EXT_ALIASES = 1,
} OstreeRepoListRefsExtFlags; } OstreeRepoListRefsExtFlags;
_OSTREE_PUBLIC _OSTREE_PUBLIC
@ -472,6 +496,15 @@ gboolean ostree_repo_remote_list_refs (OstreeRepo *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
#ifdef OSTREE_ENABLE_EXPERIMENTAL_API
_OSTREE_PUBLIC
gboolean ostree_repo_remote_list_collection_refs (OstreeRepo *self,
const char *remote_name,
GHashTable **out_all_refs,
GCancellable *cancellable,
GError **error);
#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */
_OSTREE_PUBLIC _OSTREE_PUBLIC
gboolean ostree_repo_load_variant (OstreeRepo *self, gboolean ostree_repo_load_variant (OstreeRepo *self,
OstreeObjectType objtype, OstreeObjectType objtype,

View File

@ -328,7 +328,7 @@ initable_init (GInitable *initable,
g_autoptr(GFile) policy_root = NULL; g_autoptr(GFile) policy_root = NULL;
if (g_file_query_exists (policy_config_path, NULL)) if (g_file_query_exists (policy_config_path, NULL))
{ {
g_autoptr(GFileInputStream) filein = filein = g_file_read (policy_config_path, cancellable, error); g_autoptr(GFileInputStream) filein = g_file_read (policy_config_path, cancellable, error);
if (!filein) if (!filein)
return FALSE; return FALSE;

View File

@ -22,24 +22,36 @@
#include <gio/gunixinputstream.h> #include <gio/gunixinputstream.h>
#include <gio/gunixoutputstream.h> #include <gio/gunixoutputstream.h>
#include <glib-unix.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/statvfs.h> #include <sys/statvfs.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <linux/fs.h>
#include <err.h>
#ifdef HAVE_LIBMOUNT #ifdef HAVE_LIBMOUNT
#include <libmount.h> #include <libmount.h>
#endif #endif
#ifdef HAVE_LIBSYSTEMD
#include <systemd/sd-journal.h>
#endif
#include "otutil.h"
#include "ostree.h"
#include "ostree-sysroot-private.h" #include "ostree-sysroot-private.h"
#include "ostree-sepolicy-private.h" #include "ostree-sepolicy-private.h"
#include "ostree-deployment-private.h" #include "ostree-deployment-private.h"
#include "ostree-core-private.h" #include "ostree-core-private.h"
#include "ostree-linuxfsutil.h" #include "ostree-linuxfsutil.h"
#include "otutil.h"
#include "libglnx.h" #include "libglnx.h"
#define OSTREE_VARRELABEL_ID "da679b08acd34504b789d96f818ea781" #ifdef HAVE_LIBSYSTEMD
#define OSTREE_CONFIGMERGE_ID "d3863baec13e4449ab0384684a8af3a7" #define OSTREE_VARRELABEL_ID SD_ID128_MAKE(da,67,9b,08,ac,d3,45,04,b7,89,d9,6f,81,8e,a7,81)
#define OSTREE_DEPLOYMENT_COMPLETE_ID "dd440e3e549083b63d0efc7dc15255f1" #define OSTREE_CONFIGMERGE_ID SD_ID128_MAKE(d3,86,3b,ae,c1,3e,44,49,ab,03,84,68,4a,8a,f3,a7)
#define OSTREE_DEPLOYMENT_COMPLETE_ID SD_ID128_MAKE(dd,44,0e,3e,54,90,83,b6,3d,0e,fc,7d,c1,52,55,f1)
#endif
/* /*
* Like symlinkat() but overwrites (atomically) an existing * Like symlinkat() but overwrites (atomically) an existing
@ -101,7 +113,7 @@ hardlink_or_copy_at (int src_dfd,
sysroot_flags_to_copy_flags (0, flags), sysroot_flags_to_copy_flags (0, flags),
cancellable, error); cancellable, error);
else else
return glnx_throw_errno_prefix (error, "linkat"); return glnx_throw_errno_prefix (error, "linkat(%s)", dest_subpath);
} }
return TRUE; return TRUE;
@ -417,11 +429,19 @@ merge_configuration_from (OstreeSysroot *sysroot,
cancellable, error)) cancellable, error))
return glnx_prefix_error (error, "While computing configuration diff"); return glnx_prefix_error (error, "While computing configuration diff");
ot_log_structured_print_id_v (OSTREE_CONFIGMERGE_ID, { g_autofree char *msg =
"Copying /etc changes: %u modified, %u removed, %u added", g_strdup_printf ("Copying /etc changes: %u modified, %u removed, %u added",
modified->len, modified->len, removed->len, added->len);
removed->len, #ifdef HAVE_LIBSYSTEMD
added->len); sd_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_CONFIGMERGE_ID),
"MESSAGE=%s", msg,
"ETC_N_MODIFIED=%u", modified->len,
"ETC_N_REMOVED=%u", removed->len,
"ETC_N_ADDED=%u", added->len,
NULL);
#endif
_ostree_sysroot_emit_journal_msg (sysroot, msg);
}
glnx_fd_close int orig_etc_fd = -1; glnx_fd_close int orig_etc_fd = -1;
if (!glnx_opendirat (merge_deployment_dfd, "usr/etc", TRUE, &orig_etc_fd, error)) if (!glnx_opendirat (merge_deployment_dfd, "usr/etc", TRUE, &orig_etc_fd, error))
@ -676,9 +696,15 @@ selinux_relabel_var_if_needed (OstreeSysroot *sysroot,
if (!deployment_var_labeled) if (!deployment_var_labeled)
{ {
ot_log_structured_print_id_v (OSTREE_VARRELABEL_ID, { g_autofree char *msg =
"Relabeling /var (no stamp file '%s' found)", g_strdup_printf ("Relabeling /var (no stamp file '%s' found)", selabeled);
selabeled); #ifdef HAVE_LIBSYSTEMD
sd_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_VARRELABEL_ID),
"MESSAGE=%s", msg,
NULL);
#endif
_ostree_sysroot_emit_journal_msg (sysroot, msg);
}
g_autoptr(GFile) deployment_var_path = ot_fdrel_to_gfile (os_deploy_dfd, "var"); g_autoptr(GFile) deployment_var_path = ot_fdrel_to_gfile (os_deploy_dfd, "var");
if (!selinux_relabel_dir (sysroot, sepolicy, if (!selinux_relabel_dir (sysroot, sepolicy,
@ -717,7 +743,7 @@ merge_configuration (OstreeSysroot *sysroot,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
glnx_unref_object OstreeSePolicy *sepolicy = NULL; g_autoptr(OstreeSePolicy) sepolicy = NULL;
if (previous_deployment) if (previous_deployment)
{ {
@ -856,146 +882,279 @@ ostree_sysroot_write_origin_file (OstreeSysroot *sysroot,
cancellable, error); cancellable, error);
} }
/* Originally OSTree defined kernels to be found underneath /boot
* in the tree. But that means when mounting /boot at runtime
* we end up masking the content underneath, triggering a warning.
*
* For that reason, and also consistency with the "/usr defines the OS" model we
* later switched to defining the in-tree kernels to be found under
* /usr/lib/ostree-boot.
*/
static gboolean static gboolean
get_kernel_from_tree (int deployment_dfd, get_kernel_from_tree (int deployment_dfd,
int *out_boot_dfd, int *out_boot_dfd,
char **out_kernel_name, char **out_kernel_srcpath,
char **out_initramfs_name, char **out_kernel_namever,
char **out_initramfs_srcpath,
char **out_initramfs_namever,
char **out_bootcsum,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
gboolean ret = FALSE; g_autofree char *ret_kernel_srcpath = NULL;
glnx_fd_close int ret_boot_dfd = -1; g_autofree char *ret_kernel_namever = NULL;
g_auto(GLnxDirFdIterator) dfditer = { 0, }; g_autofree char *ret_initramfs_srcpath = NULL;
g_autofree char *ret_kernel_name = NULL; g_autofree char *ret_initramfs_namever = NULL;
g_autofree char *ret_initramfs_name = NULL;
g_autofree char *kernel_checksum = NULL; g_autofree char *kernel_checksum = NULL;
g_autofree char *initramfs_checksum = NULL; g_autofree char *initramfs_checksum = NULL;
ret_boot_dfd = glnx_opendirat_with_errno (deployment_dfd, "usr/lib/ostree-boot", TRUE); glnx_fd_close int ret_boot_dfd = glnx_opendirat_with_errno (deployment_dfd, "usr/lib/ostree-boot", TRUE);
if (ret_boot_dfd == -1) if (ret_boot_dfd == -1)
{ {
if (errno != ENOENT) if (errno != ENOENT)
{ return glnx_throw_errno_prefix (error, "%s", "openat(usr/lib/ostree-boot)");
glnx_set_prefix_error_from_errno (error, "%s", "openat");
goto out;
}
else else
{ {
if (!glnx_opendirat (deployment_dfd, "boot", TRUE, &ret_boot_dfd, error)) if (!glnx_opendirat (deployment_dfd, "boot", TRUE, &ret_boot_dfd, error))
goto out; return FALSE;
} }
} }
g_auto(GLnxDirFdIterator) dfditer = { 0, };
if (!glnx_dirfd_iterator_init_at (ret_boot_dfd, ".", FALSE, &dfditer, error)) if (!glnx_dirfd_iterator_init_at (ret_boot_dfd, ".", FALSE, &dfditer, error))
goto out; return FALSE;
while (TRUE) while (TRUE)
{ {
struct dirent *dent; struct dirent *dent;
if (!glnx_dirfd_iterator_next_dent (&dfditer, &dent, cancellable, error)) if (!glnx_dirfd_iterator_next_dent (&dfditer, &dent, cancellable, error))
goto out; return FALSE;
if (dent == NULL) if (dent == NULL)
break; break;
if (ret_kernel_name == NULL && g_str_has_prefix (dent->d_name, "vmlinuz-")) const char *name = dent->d_name;
if (ret_kernel_srcpath == NULL && g_str_has_prefix (name, "vmlinuz-"))
{ {
const char *dash = strrchr (dent->d_name, '-'); const char *dash = strrchr (name, '-');
g_assert (dash); g_assert (dash);
if (ostree_validate_structureof_checksum_string (dash + 1, NULL)) if (ostree_validate_structureof_checksum_string (dash + 1, NULL))
{ {
kernel_checksum = g_strdup (dash + 1); kernel_checksum = g_strdup (dash + 1);
ret_kernel_name = g_strdup (dent->d_name); ret_kernel_srcpath = g_strdup (name);
ret_kernel_namever = g_strndup (name, dash - name);
} }
} }
else if (ret_initramfs_name == NULL && g_str_has_prefix (dent->d_name, "initramfs-")) else if (ret_initramfs_srcpath == NULL && g_str_has_prefix (name, "initramfs-"))
{ {
const char *dash = strrchr (dent->d_name, '-'); const char *dash = strrchr (name, '-');
g_assert (dash); g_assert (dash);
if (ostree_validate_structureof_checksum_string (dash + 1, NULL)) if (ostree_validate_structureof_checksum_string (dash + 1, NULL))
{ {
initramfs_checksum = g_strdup (dash + 1); initramfs_checksum = g_strdup (dash + 1);
ret_initramfs_name = g_strdup (dent->d_name); ret_initramfs_srcpath = g_strdup (name);
ret_initramfs_namever = g_strndup (name, dash - name);
} }
} }
if (ret_kernel_name != NULL && ret_initramfs_name != NULL) if (ret_kernel_srcpath != NULL && ret_initramfs_srcpath != NULL)
break; break;
} }
if (ret_kernel_name == NULL) if (ret_kernel_srcpath == NULL)
{ {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"Failed to find boot/vmlinuz-<CHECKSUM> in tree"); "Failed to find kernel in /usr/lib/ostree-boot or /boot");
goto out; return FALSE;
} }
if (ret_initramfs_name != NULL) if (ret_initramfs_srcpath != NULL)
{ {
if (strcmp (kernel_checksum, initramfs_checksum) != 0) if (strcmp (kernel_checksum, initramfs_checksum) != 0)
{ {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"Mismatched kernel checksum vs initrd in tree"); "Mismatched kernel checksum vs initrd");
goto out; return FALSE;
} }
} }
*out_boot_dfd = ret_boot_dfd; *out_boot_dfd = glnx_steal_fd (&ret_boot_dfd);
ret_boot_dfd = -1; *out_kernel_srcpath = g_steal_pointer (&ret_kernel_srcpath);
*out_kernel_name = g_steal_pointer (&ret_kernel_name); *out_kernel_namever = g_steal_pointer (&ret_kernel_namever);
*out_initramfs_name = g_steal_pointer (&ret_initramfs_name); *out_initramfs_srcpath = g_steal_pointer (&ret_initramfs_srcpath);
ret = TRUE; *out_initramfs_namever = g_steal_pointer (&ret_initramfs_namever);
out: *out_bootcsum = g_steal_pointer (&kernel_checksum);
return ret;
}
static gboolean
checksum_from_kernel_src (const char *name,
char **out_checksum,
GError **error)
{
const char *last_dash = strrchr (name, '-');
if (!last_dash)
{
return glnx_throw (error,
"Malformed kernel/initramfs name '%s', missing '-'",
name);
}
*out_checksum = g_strdup (last_dash + 1);
return TRUE; return TRUE;
} }
/* We used to syncfs(), but that doesn't flush the journal on XFS,
* and since GRUB2 can't read the XFS journal, the system
* could fail to boot.
*
* http://marc.info/?l=linux-fsdevel&m=149520244919284&w=2
* https://github.com/ostreedev/ostree/pull/1049
*/
static gboolean static gboolean
syncfs_dir_at (int dfd, fsfreeze_thaw_cycle (OstreeSysroot *self,
const char *path, int rootfs_dfd,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
glnx_fd_close int child_dfd = -1; GLNX_AUTO_PREFIX_ERROR ("During fsfreeze-thaw", error);
if (!glnx_opendirat (dfd, path, TRUE, &child_dfd, error))
return FALSE;
if (syncfs (child_dfd) != 0)
return glnx_throw_errno (error);
int sockpair[2];
if (socketpair (AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sockpair) < 0)
return glnx_throw_errno_prefix (error, "socketpair");
glnx_fd_close int sock_parent = sockpair[0];
glnx_fd_close int sock_watchdog = sockpair[1];
pid_t pid = fork ();
if (pid < 0)
return glnx_throw_errno_prefix (error, "fork");
const gboolean debug_fifreeze = (self->debug_flags & OSTREE_SYSROOT_DEBUG_TEST_FIFREEZE)>0;
char c = '!';
if (pid == 0) /* Child watchdog/unfreezer process. */
{
(void) close (glnx_steal_fd (&sock_parent));
/* Daemonize, and mask SIGINT/SIGTERM, so we're likely to survive e.g.
* someone doing a `systemctl restart rpm-ostreed` or a Ctrl-C of
* `ostree admin upgrade`. We don't daemonize though if testing so
* that we can waitpid().
*/
if (!debug_fifreeze)
{
if (daemon (0, 0) < 0)
err (1, "daemon");
}
int sigs[] = { SIGINT, SIGTERM };
for (guint i = 0; i < G_N_ELEMENTS (sigs); i++)
{
if (signal (sigs[i], SIG_IGN) == SIG_ERR)
err (1, "signal");
}
/* Tell the parent we're ready */
if (write (sock_watchdog, &c, sizeof (c)) != 1)
err (1, "write");
/* Wait for the parent to say it's going to freeze. */
ssize_t bytes_read = TEMP_FAILURE_RETRY (read (sock_watchdog, &c, sizeof (c)));
if (bytes_read < 0)
err (1, "read");
if (bytes_read != 1)
errx (1, "failed to read from parent");
/* Now we wait for the second message from the parent saying the freeze is
* complete. We have a 30 second timeout; if somehow the parent hasn't
* signaled completion, go ahead and unfreeze. But for debugging, just 1
* second to avoid exessively lengthining the test suite.
*/
const int timeout_ms = debug_fifreeze ? 1000 : 30000;
struct pollfd pfds[1];
pfds[0].fd = sock_watchdog;
pfds[0].events = POLLIN | POLLHUP;
int r = TEMP_FAILURE_RETRY (poll (pfds, 1, timeout_ms));
/* Do a thaw if we hit an error, or if the poll timed out */
if (r <= 0)
{
/* Ignore errors:
* EINVAL: Not frozen
* EPERM: For running the test suite as non-root
* EOPNOTSUPP: If the filesystem doesn't support it
*/
int saved_errno = errno;
(void) TEMP_FAILURE_RETRY (ioctl (rootfs_dfd, FITHAW, 0));
errno = saved_errno;
/* But if we got an error from poll, let's log it */
if (r < 0)
err (1, "poll");
}
if (debug_fifreeze)
g_printerr ("fifreeze watchdog was run\n");
exit (EXIT_SUCCESS);
}
else /* Parent process. */
{
(void) close (glnx_steal_fd (&sock_watchdog));
/* Wait for the watchdog to say it's set up; mainly that it's
* masked SIGTERM successfully.
*/
ssize_t bytes_read = TEMP_FAILURE_RETRY (read (sock_parent, &c, sizeof (c)));
if (bytes_read < 0)
return glnx_throw_errno_prefix (error, "read(watchdog init)");
if (bytes_read != 1)
return glnx_throw (error, "read(watchdog init)");
/* And tell the watchdog that we're ready to start */
if (write (sock_parent, &c, sizeof (c)) != sizeof (c))
return glnx_throw_errno_prefix (error, "write(watchdog start)");
/* Testing infrastructure */
if (debug_fifreeze)
{
int wstatus;
/* Ensure the child has written its data */
if (TEMP_FAILURE_RETRY (waitpid (pid, &wstatus, 0)) < 0)
return glnx_throw_errno_prefix (error, "waitpid(test-fifreeze)");
if (!g_spawn_check_exit_status (wstatus, error))
return glnx_prefix_error (error, "test-fifreeze: ");
return glnx_throw (error, "aborting due to test-fifreeze");
}
/* Do a freeze/thaw cycle; TODO add a FIFREEZETHAW ioctl */
if (ioctl (rootfs_dfd, FIFREEZE, 0) != 0)
{
/* Not supported, or we're running in the unit tests (as non-root)?
* OK, let's just do a syncfs.
*/
if (G_IN_SET (errno, EOPNOTSUPP, EPERM))
{
if (TEMP_FAILURE_RETRY (syncfs (rootfs_dfd)) != 0)
return glnx_throw_errno_prefix (error, "syncfs");
/* Write the completion, and return */
if (write (sock_parent, &c, sizeof (c)) != sizeof (c))
return glnx_throw_errno_prefix (error, "write(watchdog syncfs complete)");
return TRUE;
}
else
return glnx_throw_errno_prefix (error, "ioctl(FIFREEZE)");
}
/* And finally thaw, then signal our completion to the watchdog */
if (TEMP_FAILURE_RETRY (ioctl (rootfs_dfd, FITHAW, 0)) != 0)
return glnx_throw_errno_prefix (error, "ioctl(FITHAW)");
if (write (sock_parent, &c, sizeof (c)) != sizeof (c))
return glnx_throw_errno_prefix (error, "write(watchdog FITHAW complete)");
}
return TRUE; return TRUE;
} }
typedef struct {
guint64 root_syncfs_msec;
guint64 boot_syncfs_msec;
guint64 extra_syncfs_msec;
} SyncStats;
/* First, sync the root directory as well as /var and /boot which may /* First, sync the root directory as well as /var and /boot which may
* be separate mount points. Then *in addition*, do a global * be separate mount points. Then *in addition*, do a global
* `sync()`. * `sync()`.
*/ */
static gboolean static gboolean
full_system_sync (OstreeSysroot *self, full_system_sync (OstreeSysroot *self,
SyncStats *out_stats,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
guint64 start_msec = g_get_monotonic_time () / 1000;
if (syncfs (self->sysroot_fd) != 0) if (syncfs (self->sysroot_fd) != 0)
return glnx_throw_errno (error); return glnx_throw_errno_prefix (error, "syncfs(sysroot)");
guint64 end_msec = g_get_monotonic_time () / 1000;
if (!syncfs_dir_at (self->sysroot_fd, "boot", cancellable, error)) out_stats->root_syncfs_msec = (end_msec - start_msec);
start_msec = g_get_monotonic_time () / 1000;
glnx_fd_close int boot_dfd = -1;
if (!glnx_opendirat (self->sysroot_fd, "boot", TRUE, &boot_dfd, error))
return FALSE; return FALSE;
if (!fsfreeze_thaw_cycle (self, boot_dfd, cancellable, error))
return FALSE;
end_msec = g_get_monotonic_time () / 1000;
out_stats->boot_syncfs_msec = (end_msec - start_msec);
/* And now out of an excess of conservativism, we still invoke /* And now out of an excess of conservativism, we still invoke
* sync(). The advantage of still using `syncfs()` above is that we * sync(). The advantage of still using `syncfs()` above is that we
@ -1003,7 +1162,10 @@ full_system_sync (OstreeSysroot *self,
* delineate what we actually want to sync in the future when this * delineate what we actually want to sync in the future when this
* global sync call is removed. * global sync call is removed.
*/ */
start_msec = g_get_monotonic_time () / 1000;
sync (); sync ();
end_msec = g_get_monotonic_time () / 1000;
out_stats->extra_syncfs_msec = (end_msec - start_msec);
return TRUE; return TRUE;
} }
@ -1099,15 +1261,6 @@ swap_bootlinks (OstreeSysroot *self,
return TRUE; return TRUE;
} }
static char *
remove_checksum_from_kernel_name (const char *name,
const char *csum)
{
const char *p = strrchr (name, '-');
g_assert_cmpstr (p+1, ==, csum);
return g_strndup (name, p-name);
}
static GHashTable * static GHashTable *
parse_os_release (const char *contents, parse_os_release (const char *contents,
const char *split) const char *split)
@ -1161,11 +1314,19 @@ install_deployment_kernel (OstreeSysroot *sysroot,
&deployment_dfd, error)) &deployment_dfd, error))
return FALSE; return FALSE;
/* Find the kernel/initramfs in the tree */
glnx_fd_close int tree_boot_dfd = -1; glnx_fd_close int tree_boot_dfd = -1;
g_autofree char *tree_kernel_name = NULL; g_autofree char *tree_kernel_srcpath = NULL;
g_autofree char *tree_initramfs_name = NULL; g_autofree char *tree_kernel_namever = NULL;
g_autofree char *tree_initramfs_srcpath = NULL;
g_autofree char *tree_initramfs_namever = NULL;
g_autofree char *tree_bootcsum = NULL;
if (!get_kernel_from_tree (deployment_dfd, &tree_boot_dfd, if (!get_kernel_from_tree (deployment_dfd, &tree_boot_dfd,
&tree_kernel_name, &tree_initramfs_name, &tree_kernel_srcpath,
&tree_kernel_namever,
&tree_initramfs_srcpath,
&tree_initramfs_namever,
&tree_bootcsum,
cancellable, error)) cancellable, error))
return FALSE; return FALSE;
@ -1175,6 +1336,7 @@ install_deployment_kernel (OstreeSysroot *sysroot,
const char *osname = ostree_deployment_get_osname (deployment); const char *osname = ostree_deployment_get_osname (deployment);
const char *bootcsum = ostree_deployment_get_bootcsum (deployment); const char *bootcsum = ostree_deployment_get_bootcsum (deployment);
g_assert_cmpstr (bootcsum, ==, tree_bootcsum);
g_autofree char *bootcsumdir = g_strdup_printf ("ostree/%s-%s", osname, bootcsum); g_autofree char *bootcsumdir = g_strdup_printf ("ostree/%s-%s", osname, bootcsum);
g_autofree char *bootconfdir = g_strdup_printf ("loader.%d/entries", new_bootversion); g_autofree char *bootconfdir = g_strdup_printf ("loader.%d/entries", new_bootversion);
g_autofree char *bootconf_name = g_strdup_printf ("ostree-%s-%d.conf", osname, g_autofree char *bootconf_name = g_strdup_printf ("ostree-%s-%d.conf", osname,
@ -1189,30 +1351,33 @@ install_deployment_kernel (OstreeSysroot *sysroot,
if (!glnx_shutil_mkdir_p_at (boot_dfd, bootconfdir, 0775, cancellable, error)) if (!glnx_shutil_mkdir_p_at (boot_dfd, bootconfdir, 0775, cancellable, error))
return FALSE; return FALSE;
g_autofree char *dest_kernel_name = remove_checksum_from_kernel_name (tree_kernel_name, bootcsum); /* Install (hardlink/copy) the kernel into /boot/ostree/osname-${bootcsum} if
* it doesn't exist already.
*/
struct stat stbuf; struct stat stbuf;
if (fstatat (bootcsum_dfd, dest_kernel_name, &stbuf, 0) != 0) if (fstatat (bootcsum_dfd, tree_kernel_namever, &stbuf, 0) != 0)
{ {
if (errno != ENOENT) if (errno != ENOENT)
return glnx_throw_errno_prefix (error, "fstat %s", dest_kernel_name); return glnx_throw_errno_prefix (error, "fstat %s", tree_kernel_namever);
if (!hardlink_or_copy_at (tree_boot_dfd, tree_kernel_name, if (!hardlink_or_copy_at (tree_boot_dfd, tree_kernel_srcpath,
bootcsum_dfd, dest_kernel_name, bootcsum_dfd, tree_kernel_namever,
sysroot->debug_flags, sysroot->debug_flags,
cancellable, error)) cancellable, error))
return FALSE; return FALSE;
} }
g_autofree char *dest_initramfs_name = NULL; /* If we have an initramfs, then install it into
if (tree_initramfs_name) * /boot/ostree/osname-${bootcsum} if it doesn't exist already.
*/
if (tree_initramfs_srcpath)
{ {
dest_initramfs_name = remove_checksum_from_kernel_name (tree_initramfs_name, bootcsum); g_assert (tree_initramfs_namever);
if (fstatat (bootcsum_dfd, tree_initramfs_namever, &stbuf, 0) != 0)
if (fstatat (bootcsum_dfd, dest_initramfs_name, &stbuf, 0) != 0)
{ {
if (errno != ENOENT) if (errno != ENOENT)
return glnx_throw_errno_prefix (error, "fstat %s", dest_initramfs_name); return glnx_throw_errno_prefix (error, "fstat %s", tree_initramfs_namever);
if (!hardlink_or_copy_at (tree_boot_dfd, tree_initramfs_name, if (!hardlink_or_copy_at (tree_boot_dfd, tree_initramfs_srcpath,
bootcsum_dfd, dest_initramfs_name, bootcsum_dfd, tree_initramfs_namever,
sysroot->debug_flags, sysroot->debug_flags,
cancellable, error)) cancellable, error))
return FALSE; return FALSE;
@ -1293,12 +1458,12 @@ install_deployment_kernel (OstreeSysroot *sysroot,
g_autofree char *version_key = g_strdup_printf ("%d", n_deployments - ostree_deployment_get_index (deployment)); g_autofree char *version_key = g_strdup_printf ("%d", n_deployments - ostree_deployment_get_index (deployment));
ostree_bootconfig_parser_set (bootconfig, OSTREE_COMMIT_META_KEY_VERSION, version_key); ostree_bootconfig_parser_set (bootconfig, OSTREE_COMMIT_META_KEY_VERSION, version_key);
g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", dest_kernel_name, NULL); g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", tree_kernel_namever, NULL);
ostree_bootconfig_parser_set (bootconfig, "linux", boot_relpath); ostree_bootconfig_parser_set (bootconfig, "linux", boot_relpath);
if (dest_initramfs_name) if (tree_initramfs_namever)
{ {
g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", dest_initramfs_name, NULL); g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", tree_initramfs_namever, NULL);
ostree_bootconfig_parser_set (bootconfig, "initrd", boot_relpath); ostree_bootconfig_parser_set (bootconfig, "initrd", boot_relpath);
} }
@ -1379,7 +1544,7 @@ swap_bootloader (OstreeSysroot *sysroot,
* admin by going back to the previous session. * admin by going back to the previous session.
*/ */
if (fsync (boot_dfd) != 0) if (fsync (boot_dfd) != 0)
return glnx_throw_errno (error); return glnx_throw_errno_prefix (error, "fsync(boot)");
return TRUE; return TRUE;
} }
@ -1452,10 +1617,9 @@ cleanup_legacy_current_symlinks (OstreeSysroot *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
guint i;
g_autoptr(GString) buf = g_string_new (""); g_autoptr(GString) buf = g_string_new ("");
for (i = 0; i < self->deployments->len; i++) for (guint i = 0; i < self->deployments->len; i++)
{ {
OstreeDeployment *deployment = self->deployments->pdata[i]; OstreeDeployment *deployment = self->deployments->pdata[i];
const char *osname = ostree_deployment_get_osname (deployment); const char *osname = ostree_deployment_get_osname (deployment);
@ -1463,11 +1627,8 @@ cleanup_legacy_current_symlinks (OstreeSysroot *self,
g_string_truncate (buf, 0); g_string_truncate (buf, 0);
g_string_append_printf (buf, "ostree/deploy/%s/current", osname); g_string_append_printf (buf, "ostree/deploy/%s/current", osname);
if (unlinkat (self->sysroot_fd, buf->str, 0) < 0) if (!ot_ensure_unlinked_at (self->sysroot_fd, buf->str, error))
{ return FALSE;
if (errno != ENOENT)
return glnx_throw_errno (error);
}
} }
return TRUE; return TRUE;
@ -1568,6 +1729,8 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self,
gboolean found_booted_deployment = FALSE; gboolean found_booted_deployment = FALSE;
gboolean bootloader_is_atomic = FALSE; gboolean bootloader_is_atomic = FALSE;
gboolean boot_was_ro_mount = FALSE; gboolean boot_was_ro_mount = FALSE;
SyncStats syncstats = { 0, };
g_autoptr(OstreeBootloader) bootloader = NULL;
g_assert (self->loaded); g_assert (self->loaded);
@ -1631,7 +1794,7 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self,
goto out; goto out;
} }
if (!full_system_sync (self, cancellable, error)) if (!full_system_sync (self, &syncstats, cancellable, error))
{ {
g_prefix_error (error, "Full sync: "); g_prefix_error (error, "Full sync: ");
goto out; goto out;
@ -1650,9 +1813,8 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self,
else else
{ {
int new_bootversion = self->bootversion ? 0 : 1; int new_bootversion = self->bootversion ? 0 : 1;
glnx_unref_object OstreeBootloader *bootloader = NULL;
g_autofree char* new_loader_entries_dir = NULL; g_autofree char* new_loader_entries_dir = NULL;
glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(OstreeRepo) repo = NULL;
gboolean show_osname = FALSE; gboolean show_osname = FALSE;
if (self->booted_deployment) if (self->booted_deployment)
@ -1751,7 +1913,7 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self,
goto out; goto out;
} }
if (!full_system_sync (self, cancellable, error)) if (!full_system_sync (self, &syncstats, cancellable, error))
{ {
g_prefix_error (error, "Full sync: "); g_prefix_error (error, "Full sync: ");
goto out; goto out;
@ -1765,11 +1927,25 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self,
} }
} }
ot_log_structured_print_id_v (OSTREE_DEPLOYMENT_COMPLETE_ID, { g_autofree char *msg =
"%s; bootconfig swap: %s deployment count change: %i", g_strdup_printf ("%s; bootconfig swap: %s deployment count change: %i",
(bootloader_is_atomic ? "Transaction complete" : "Bootloader updated"), (bootloader_is_atomic ? "Transaction complete" : "Bootloader updated"),
requires_new_bootversion ? "yes" : "no", requires_new_bootversion ? "yes" : "no",
new_deployments->len - self->deployments->len); new_deployments->len - self->deployments->len);
#ifdef HAVE_LIBSYSTEMD
sd_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_DEPLOYMENT_COMPLETE_ID),
"MESSAGE=%s", msg,
"OSTREE_BOOTLOADER=%s", bootloader ? _ostree_bootloader_get_name (bootloader) : "none",
"OSTREE_BOOTLOADER_ATOMIC=%s", bootloader_is_atomic ? "yes" : "no",
"OSTREE_DID_BOOTSWAP=%s", requires_new_bootversion ? "yes" : "no",
"OSTREE_N_DEPLOYMENTS=%u", new_deployments->len,
"OSTREE_SYNCFS_ROOT_MSEC=%" G_GUINT64_FORMAT, syncstats.root_syncfs_msec,
"OSTREE_SYNCFS_BOOT_MSEC=%" G_GUINT64_FORMAT, syncstats.boot_syncfs_msec,
"OSTREE_SYNCFS_EXTRA_MSEC=%" G_GUINT64_FORMAT, syncstats.extra_syncfs_msec,
NULL);
#endif
_ostree_sysroot_emit_journal_msg (self, msg);
}
if (!_ostree_sysroot_bump_mtime (self, error)) if (!_ostree_sysroot_bump_mtime (self, error))
goto out; goto out;
@ -1884,7 +2060,7 @@ ostree_sysroot_deploy_tree (OstreeSysroot *self,
return FALSE; return FALSE;
OstreeRepo *repo = ostree_sysroot_repo (self); OstreeRepo *repo = ostree_sysroot_repo (self);
glnx_unref_object OstreeDeployment *merge_deployment = NULL; g_autoptr(OstreeDeployment) merge_deployment = NULL;
if (provided_merge_deployment != NULL) if (provided_merge_deployment != NULL)
merge_deployment = g_object_ref (provided_merge_deployment); merge_deployment = g_object_ref (provided_merge_deployment);
@ -1894,7 +2070,7 @@ ostree_sysroot_deploy_tree (OstreeSysroot *self,
return FALSE; return FALSE;
g_autofree char *new_bootcsum = NULL; g_autofree char *new_bootcsum = NULL;
glnx_unref_object OstreeDeployment *new_deployment = g_autoptr(OstreeDeployment) new_deployment =
ostree_deployment_new (0, osname, revision, new_deployserial, ostree_deployment_new (0, osname, revision, new_deployserial,
new_bootcsum, -1); new_bootcsum, -1);
ostree_deployment_set_origin (new_deployment, origin); ostree_deployment_set_origin (new_deployment, origin);
@ -1909,33 +2085,29 @@ ostree_sysroot_deploy_tree (OstreeSysroot *self,
} }
glnx_fd_close int tree_boot_dfd = -1; glnx_fd_close int tree_boot_dfd = -1;
g_autofree char *tree_kernel_path = NULL; g_autofree char *tree_kernel_srcpath = NULL;
g_autofree char *tree_initramfs_path = NULL; g_autofree char *tree_kernel_namever = NULL;
g_autofree char *tree_initramfs_srcpath = NULL;
g_autofree char *tree_initramfs_namever = NULL;
g_autofree char *tree_bootcsum = NULL;
if (!get_kernel_from_tree (deployment_dfd, &tree_boot_dfd, if (!get_kernel_from_tree (deployment_dfd, &tree_boot_dfd,
&tree_kernel_path, &tree_initramfs_path, &tree_kernel_srcpath,
&tree_kernel_namever,
&tree_initramfs_srcpath,
&tree_initramfs_namever,
&new_bootcsum,
cancellable, error)) cancellable, error))
return FALSE; return FALSE;
if (tree_initramfs_path != NULL)
{
if (!checksum_from_kernel_src (tree_initramfs_path, &new_bootcsum, error))
return FALSE;
}
else
{
if (!checksum_from_kernel_src (tree_kernel_path, &new_bootcsum, error))
return FALSE;
}
_ostree_deployment_set_bootcsum (new_deployment, new_bootcsum); _ostree_deployment_set_bootcsum (new_deployment, new_bootcsum);
/* Create an empty boot configuration; we will merge things into /* Create an empty boot configuration; we will merge things into
* it as we go. * it as we go.
*/ */
glnx_unref_object OstreeBootconfigParser *bootconfig = ostree_bootconfig_parser_new (); g_autoptr(OstreeBootconfigParser) bootconfig = ostree_bootconfig_parser_new ();
ostree_deployment_set_bootconfig (new_deployment, bootconfig); ostree_deployment_set_bootconfig (new_deployment, bootconfig);
glnx_unref_object OstreeSePolicy *sepolicy = NULL; g_autoptr(OstreeSePolicy) sepolicy = NULL;
if (!merge_configuration (self, repo, merge_deployment, new_deployment, if (!merge_configuration (self, repo, merge_deployment, new_deployment,
deployment_dfd, deployment_dfd,
&sepolicy, &sepolicy,
@ -2013,7 +2185,7 @@ ostree_sysroot_deployment_set_kargs (OstreeSysroot *self,
{ {
guint i; guint i;
g_autoptr(GPtrArray) new_deployments = g_ptr_array_new_with_free_func (g_object_unref); g_autoptr(GPtrArray) new_deployments = g_ptr_array_new_with_free_func (g_object_unref);
glnx_unref_object OstreeDeployment *new_deployment = NULL; g_autoptr(OstreeDeployment) new_deployment = NULL;
__attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL; __attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL;
g_autofree char *new_options = NULL; g_autofree char *new_options = NULL;
OstreeBootconfigParser *new_bootconfig; OstreeBootconfigParser *new_bootconfig;

View File

@ -33,7 +33,8 @@ typedef enum {
OSTREE_SYSROOT_DEBUG_MUTABLE_DEPLOYMENTS = 1 << 0, OSTREE_SYSROOT_DEBUG_MUTABLE_DEPLOYMENTS = 1 << 0,
/* See https://github.com/ostreedev/ostree/pull/759 */ /* See https://github.com/ostreedev/ostree/pull/759 */
OSTREE_SYSROOT_DEBUG_NO_XATTRS = 1 << 1, OSTREE_SYSROOT_DEBUG_NO_XATTRS = 1 << 1,
/* https://github.com/ostreedev/ostree/pull/1049 */
OSTREE_SYSROOT_DEBUG_TEST_FIFREEZE = 1 << 2,
} OstreeSysrootDebugFlags; } OstreeSysrootDebugFlags;
/** /**
@ -56,9 +57,8 @@ struct OstreeSysroot {
OstreeDeployment *booted_deployment; OstreeDeployment *booted_deployment;
struct timespec loaded_ts; struct timespec loaded_ts;
/* Only access through ostree_sysroot_get_repo() */ /* Only access through ostree_sysroot_[_get]repo() */
OstreeRepo *repo; OstreeRepo *repo;
gboolean repo_opened;
OstreeSysrootDebugFlags debug_flags; OstreeSysrootDebugFlags debug_flags;
}; };
@ -68,6 +68,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"
void
_ostree_sysroot_emit_journal_msg (OstreeSysroot *self,
const char *msg);
gboolean gboolean
_ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self, _ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self,
int bootversion, int bootversion,

View File

@ -25,6 +25,7 @@
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/wait.h> #include <sys/wait.h>
#include "ostree.h"
#include "ostree-core-private.h" #include "ostree-core-private.h"
#include "ostree-repo-private.h" #include "ostree-repo-private.h"
#include "ostree-sepolicy-private.h" #include "ostree-sepolicy-private.h"
@ -57,8 +58,18 @@ find_booted_deployment (OstreeSysroot *self,
*/ */
typedef struct { typedef struct {
GObjectClass parent_class; GObjectClass parent_class;
/* Signals */
void (*journal_msg) (OstreeSysroot *sysroot,
const char *msg);
} OstreeSysrootClass; } OstreeSysrootClass;
enum {
JOURNAL_MSG_SIGNAL,
LAST_SIGNAL,
};
static guint signals[LAST_SIGNAL] = { 0 };
enum { enum {
PROP_0, PROP_0,
@ -126,18 +137,11 @@ static void
ostree_sysroot_constructed (GObject *object) ostree_sysroot_constructed (GObject *object)
{ {
OstreeSysroot *self = OSTREE_SYSROOT (object); OstreeSysroot *self = OSTREE_SYSROOT (object);
g_autoptr(GFile) repo_path = NULL;
/* Ensure the system root path is set. */ /* Ensure the system root path is set. */
if (self->path == NULL) if (self->path == NULL)
self->path = g_object_ref (_ostree_get_default_sysroot_path ()); self->path = g_object_ref (_ostree_get_default_sysroot_path ());
repo_path = g_file_resolve_relative_path (self->path, "ostree/repo");
self->repo = ostree_repo_new_for_sysroot_path (repo_path, self->path);
self->repo->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_VIA_SYSROOT;
/* Hold a weak ref for the remote-add handling */
g_weak_ref_init (&self->repo->sysroot, object);
G_OBJECT_CLASS (ostree_sysroot_parent_class)->constructed (object); G_OBJECT_CLASS (ostree_sysroot_parent_class)->constructed (object);
} }
@ -158,6 +162,27 @@ ostree_sysroot_class_init (OstreeSysrootClass *klass)
"", "",
G_TYPE_FILE, G_TYPE_FILE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
/**
* OstreeSysroot::journal-msg:
* @self: Self
* @msg: Human-readable string (should not contain newlines)
*
* libostree will log to the journal various events, such as the /etc merge
* status, and transaction completion. Connect to this signal to also
* synchronously receive the text for those messages. This is intended to be
* used by command line tools which link to libostree as a library.
*
* Currently, the structured data is only available via the systemd journal.
*
* Since: 2017.10
*/
signals[JOURNAL_MSG_SIGNAL] =
g_signal_new ("journal-msg",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (OstreeSysrootClass, journal_msg),
NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING);
} }
static void static void
@ -165,6 +190,7 @@ ostree_sysroot_init (OstreeSysroot *self)
{ {
const GDebugKey keys[] = { const GDebugKey keys[] = {
{ "mutable-deployments", OSTREE_SYSROOT_DEBUG_MUTABLE_DEPLOYMENTS }, { "mutable-deployments", OSTREE_SYSROOT_DEBUG_MUTABLE_DEPLOYMENTS },
{ "test-fifreeze", OSTREE_SYSROOT_DEBUG_TEST_FIFREEZE },
{ "no-xattrs", OSTREE_SYSROOT_DEBUG_NO_XATTRS }, { "no-xattrs", OSTREE_SYSROOT_DEBUG_NO_XATTRS },
}; };
@ -299,24 +325,22 @@ ostree_sysroot_ensure_initialized (OstreeSysroot *self,
cancellable, error)) cancellable, error))
return FALSE; return FALSE;
struct stat stbuf; g_autoptr(OstreeRepo) repo =
if (fstatat (self->sysroot_fd, "ostree/repo/objects", &stbuf, 0) != 0) ostree_repo_create_at (self->sysroot_fd, "ostree/repo",
{ OSTREE_REPO_MODE_BARE, NULL,
if (errno != ENOENT) cancellable, error);
return glnx_throw_errno_prefix (error, "stat(ostree/repo/objects)"); if (!repo)
else
{
g_autoptr(GFile) repo_dir = g_file_resolve_relative_path (self->path, "ostree/repo");
glnx_unref_object OstreeRepo *repo = ostree_repo_new (repo_dir);
if (!ostree_repo_create (repo, OSTREE_REPO_MODE_BARE,
cancellable, error))
return FALSE; return FALSE;
}
}
return TRUE; return TRUE;
} }
void
_ostree_sysroot_emit_journal_msg (OstreeSysroot *self,
const char *msg)
{
g_signal_emit (self, signals[JOURNAL_MSG_SIGNAL], 0, msg);
}
gboolean gboolean
_ostree_sysroot_parse_deploy_path_name (const char *name, _ostree_sysroot_parse_deploy_path_name (const char *name,
char **out_csum, char **out_csum,
@ -454,7 +478,7 @@ _ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self,
g_str_has_suffix (dent->d_name, ".conf") && g_str_has_suffix (dent->d_name, ".conf") &&
S_ISREG (stbuf.st_mode)) S_ISREG (stbuf.st_mode))
{ {
glnx_unref_object OstreeBootconfigParser *config = ostree_bootconfig_parser_new (); g_autoptr(OstreeBootconfigParser) config = ostree_bootconfig_parser_new ();
if (!ostree_bootconfig_parser_parse_at (config, dfd_iter.fd, dent->d_name, cancellable, error)) if (!ostree_bootconfig_parser_parse_at (config, dfd_iter.fd, dent->d_name, cancellable, error))
return glnx_prefix_error (error, "Parsing %s", dent->d_name); return glnx_prefix_error (error, "Parsing %s", dent->d_name);
@ -624,7 +648,7 @@ parse_deployment (OstreeSysroot *self,
cancellable, error)) cancellable, error))
return FALSE; return FALSE;
glnx_unref_object OstreeDeployment *ret_deployment g_autoptr(OstreeDeployment) ret_deployment
= ostree_deployment_new (-1, osname, treecsum, deployserial, = ostree_deployment_new (-1, osname, treecsum, deployserial,
bootcsum, treebootserial); bootcsum, treebootserial);
if (origin) if (origin)
@ -691,7 +715,7 @@ list_deployments_process_one_boot_entry (OstreeSysroot *self,
if (ostree_arg == NULL) if (ostree_arg == NULL)
return glnx_throw (error, "No ostree= kernel argument found"); return glnx_throw (error, "No ostree= kernel argument found");
glnx_unref_object OstreeDeployment *deployment = NULL; g_autoptr(OstreeDeployment) deployment = NULL;
if (!parse_deployment (self, ostree_arg, &deployment, if (!parse_deployment (self, ostree_arg, &deployment,
cancellable, error)) cancellable, error))
return FALSE; return FALSE;
@ -732,14 +756,22 @@ ostree_sysroot_load (OstreeSysroot *self,
} }
static gboolean static gboolean
ensure_repo_opened (OstreeSysroot *self, ensure_repo (OstreeSysroot *self,
GError **error) GError **error)
{ {
if (self->repo_opened) if (self->repo != NULL)
return TRUE; return TRUE;
if (!ostree_repo_open (self->repo, NULL, error)) if (!ensure_sysroot_fd (self, error))
return FALSE; return FALSE;
self->repo_opened = TRUE; self->repo = ostree_repo_open_at (self->sysroot_fd, "ostree/repo", NULL, error);
if (!self->repo)
return FALSE;
/* Flag it as having been created via ostree_sysroot_get_repo(), and hold a
* weak ref for the remote-add handling.
*/
g_weak_ref_init (&self->repo->sysroot, self);
self->repo->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_VIA_SYSROOT;
return TRUE; return TRUE;
} }
@ -756,7 +788,7 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self,
* previous to v2017.6, but we do now to support the error-free * previous to v2017.6, but we do now to support the error-free
* ostree_sysroot_repo() API. * ostree_sysroot_repo() API.
*/ */
if (!ensure_repo_opened (self, error)) if (!ensure_repo (self, error))
return FALSE; return FALSE;
int bootversion = 0; int bootversion = 0;
@ -959,9 +991,8 @@ ostree_sysroot_get_repo (OstreeSysroot *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
if (!ensure_repo_opened (self, error)) if (!ensure_repo (self, error))
return FALSE; return FALSE;
if (out_repo != NULL) if (out_repo != NULL)
*out_repo = g_object_ref (self->repo); *out_repo = g_object_ref (self->repo);
return TRUE; return TRUE;
@ -999,7 +1030,7 @@ _ostree_sysroot_query_bootloader (OstreeSysroot *sysroot,
GError **error) GError **error)
{ {
gboolean is_active; gboolean is_active;
glnx_unref_object OstreeBootloader *ret_loader = g_autoptr(OstreeBootloader) ret_loader =
(OstreeBootloader*)_ostree_bootloader_syslinux_new (sysroot); (OstreeBootloader*)_ostree_bootloader_syslinux_new (sysroot);
if (!_ostree_bootloader_query (ret_loader, &is_active, if (!_ostree_bootloader_query (ret_loader, &is_active,
cancellable, error)) cancellable, error))
@ -1078,7 +1109,7 @@ find_booted_deployment (OstreeSysroot *self,
{ {
struct stat root_stbuf; struct stat root_stbuf;
struct stat self_stbuf; struct stat self_stbuf;
glnx_unref_object OstreeDeployment *ret_deployment = NULL; g_autoptr(OstreeDeployment) ret_deployment = NULL;
if (stat ("/", &root_stbuf) != 0) if (stat ("/", &root_stbuf) != 0)
return glnx_throw_errno_prefix (error, "stat /"); return glnx_throw_errno_prefix (error, "stat /");
@ -1540,6 +1571,7 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot,
return ret; return ret;
} }
/* Deploy a copy of @target_deployment */
static gboolean static gboolean
clone_deployment (OstreeSysroot *sysroot, clone_deployment (OstreeSysroot *sysroot,
OstreeDeployment *target_deployment, OstreeDeployment *target_deployment,
@ -1547,38 +1579,26 @@ clone_deployment (OstreeSysroot *sysroot,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
gboolean ret = FALSE;
__attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL;
glnx_unref_object OstreeDeployment *new_deployment = NULL;
/* Ensure we have a clean slate */ /* Ensure we have a clean slate */
if (!ostree_sysroot_prepare_cleanup (sysroot, cancellable, error)) if (!ostree_sysroot_prepare_cleanup (sysroot, cancellable, error))
{ return glnx_prefix_error (error, "Performing initial cleanup");
g_prefix_error (error, "Performing initial cleanup: ");
goto out;
}
kargs = _ostree_kernel_args_new (); /* Copy the bootloader config options */
OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (merge_deployment);
{ OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (merge_deployment);
g_auto(GStrv) previous_args = g_strsplit (ostree_bootconfig_parser_get (bootconfig, "options"), " ", -1); g_auto(GStrv) previous_args = g_strsplit (ostree_bootconfig_parser_get (bootconfig, "options"), " ", -1);
__attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = _ostree_kernel_args_new ();
_ostree_kernel_args_append_argv (kargs, previous_args); _ostree_kernel_args_append_argv (kargs, previous_args);
}
{ /* Deploy the copy */
g_autoptr(OstreeDeployment) new_deployment = NULL;
g_auto(GStrv) kargs_strv = _ostree_kernel_args_to_strv (kargs); g_auto(GStrv) kargs_strv = _ostree_kernel_args_to_strv (kargs);
if (!ostree_sysroot_deploy_tree (sysroot, if (!ostree_sysroot_deploy_tree (sysroot,
ostree_deployment_get_osname (target_deployment), ostree_deployment_get_osname (target_deployment),
ostree_deployment_get_csum (target_deployment), ostree_deployment_get_csum (target_deployment),
ostree_deployment_get_origin (target_deployment), ostree_deployment_get_origin (target_deployment),
merge_deployment, merge_deployment, kargs_strv, &new_deployment,
kargs_strv,
&new_deployment,
cancellable, error)) cancellable, error))
goto out; return FALSE;
}
/* Hotfixes push the deployment as rollback target, so it shouldn't /* Hotfixes push the deployment as rollback target, so it shouldn't
* be the default. * be the default.
@ -1587,11 +1607,9 @@ clone_deployment (OstreeSysroot *sysroot,
new_deployment, merge_deployment, new_deployment, merge_deployment,
OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT, OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT,
cancellable, error)) cancellable, error))
goto out; return FALSE;
ret = TRUE; return TRUE;
out:
return ret;
} }
/** /**
@ -1616,59 +1634,41 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
gboolean ret = FALSE;
glnx_unref_object OstreeSePolicy *sepolicy = NULL;
OstreeDeploymentUnlockedState current_unlocked =
ostree_deployment_get_unlocked (deployment);
glnx_unref_object OstreeDeployment *deployment_clone =
ostree_deployment_clone (deployment);
glnx_unref_object OstreeDeployment *merge_deployment = NULL;
GKeyFile *origin_clone = ostree_deployment_get_origin (deployment_clone);
const char hotfix_ovl_options[] = "lowerdir=usr,upperdir=.usr-ovl-upper,workdir=.usr-ovl-work";
const char *ovl_options = NULL;
g_autofree char *deployment_path = NULL;
glnx_fd_close int deployment_dfd = -1;
pid_t mount_child;
/* This function cannot re-lock */ /* This function cannot re-lock */
g_return_val_if_fail (unlocked_state != OSTREE_DEPLOYMENT_UNLOCKED_NONE, FALSE); g_return_val_if_fail (unlocked_state != OSTREE_DEPLOYMENT_UNLOCKED_NONE, FALSE);
OstreeDeploymentUnlockedState current_unlocked = ostree_deployment_get_unlocked (deployment);
if (current_unlocked != OSTREE_DEPLOYMENT_UNLOCKED_NONE) if (current_unlocked != OSTREE_DEPLOYMENT_UNLOCKED_NONE)
{ return glnx_throw (error, "Deployment is already in unlocked state: %s",
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Deployment is already in unlocked state: %s",
ostree_deployment_unlocked_state_to_string (current_unlocked)); ostree_deployment_unlocked_state_to_string (current_unlocked));
goto out;
}
merge_deployment = ostree_sysroot_get_merge_deployment (self, ostree_deployment_get_osname (deployment)); g_autoptr(OstreeDeployment) merge_deployment =
ostree_sysroot_get_merge_deployment (self, ostree_deployment_get_osname (deployment));
if (!merge_deployment) if (!merge_deployment)
{ return glnx_throw (error, "No previous deployment to duplicate");
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No previous deployment to duplicate");
goto out;
}
/* For hotfixes, we push a rollback target */ /* For hotfixes, we push a rollback target */
if (unlocked_state == OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX) if (unlocked_state == OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX)
{ {
if (!clone_deployment (self, deployment, merge_deployment, cancellable, error)) if (!clone_deployment (self, deployment, merge_deployment, cancellable, error))
goto out; return FALSE;
} }
/* Crack it open */ /* Crack it open */
if (!ostree_sysroot_deployment_set_mutable (self, deployment, TRUE, if (!ostree_sysroot_deployment_set_mutable (self, deployment, TRUE,
cancellable, error)) cancellable, error))
goto out; return FALSE;
deployment_path = ostree_sysroot_get_deployment_dirpath (self, deployment);
g_autofree char *deployment_path = ostree_sysroot_get_deployment_dirpath (self, deployment);
glnx_fd_close int deployment_dfd = -1;
if (!glnx_opendirat (self->sysroot_fd, deployment_path, TRUE, &deployment_dfd, error)) if (!glnx_opendirat (self->sysroot_fd, deployment_path, TRUE, &deployment_dfd, error))
goto out; return FALSE;
sepolicy = ostree_sepolicy_new_at (deployment_dfd, cancellable, error); g_autoptr(OstreeSePolicy) sepolicy = ostree_sepolicy_new_at (deployment_dfd, cancellable, error);
if (!sepolicy) if (!sepolicy)
goto out; return FALSE;
const char *ovl_options = NULL;
switch (unlocked_state) switch (unlocked_state)
{ {
case OSTREE_DEPLOYMENT_UNLOCKED_NONE: case OSTREE_DEPLOYMENT_UNLOCKED_NONE:
@ -1676,14 +1676,15 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
break; break;
case OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX: case OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX:
{ {
const char hotfix_ovl_options[] = "lowerdir=usr,upperdir=.usr-ovl-upper,workdir=.usr-ovl-work";
/* Create the overlayfs directories in the deployment root /* Create the overlayfs directories in the deployment root
* directly for hotfixes. The ostree-prepare-root.c helper * directly for hotfixes. The ostree-prepare-root.c helper
* is also set up to detect and mount these. * is also set up to detect and mount these.
*/ */
if (!glnx_shutil_mkdir_p_at (deployment_dfd, ".usr-ovl-upper", 0755, cancellable, error)) if (!glnx_shutil_mkdir_p_at (deployment_dfd, ".usr-ovl-upper", 0755, cancellable, error))
goto out; return FALSE;
if (!glnx_shutil_mkdir_p_at (deployment_dfd, ".usr-ovl-work", 0755, cancellable, error)) if (!glnx_shutil_mkdir_p_at (deployment_dfd, ".usr-ovl-work", 0755, cancellable, error))
goto out; return FALSE;
ovl_options = hotfix_ovl_options; ovl_options = hotfix_ovl_options;
} }
break; break;
@ -1701,18 +1702,18 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
if (!_ostree_sepolicy_preparefscreatecon (&con, sepolicy, if (!_ostree_sepolicy_preparefscreatecon (&con, sepolicy,
"/usr", 0755, error)) "/usr", 0755, error))
goto out; return FALSE;
if (!glnx_mkdtempat (AT_FDCWD, development_ovldir, 0755, error)) if (!glnx_mkdtempat (AT_FDCWD, development_ovldir, 0755, error))
goto out; return FALSE;
} }
development_ovl_upper = glnx_strjoina (development_ovldir, "/upper"); development_ovl_upper = glnx_strjoina (development_ovldir, "/upper");
if (!glnx_shutil_mkdir_p_at (AT_FDCWD, development_ovl_upper, 0755, cancellable, error)) if (!glnx_shutil_mkdir_p_at (AT_FDCWD, development_ovl_upper, 0755, cancellable, error))
goto out; return FALSE;
development_ovl_work = glnx_strjoina (development_ovldir, "/work"); development_ovl_work = glnx_strjoina (development_ovldir, "/work");
if (!glnx_shutil_mkdir_p_at (AT_FDCWD, development_ovl_work, 0755, cancellable, error)) if (!glnx_shutil_mkdir_p_at (AT_FDCWD, development_ovl_work, 0755, cancellable, error))
goto out; return FALSE;
ovl_options = glnx_strjoina ("lowerdir=usr,upperdir=", development_ovl_upper, ovl_options = glnx_strjoina ("lowerdir=usr,upperdir=", development_ovl_upper,
",workdir=", development_ovl_work); ",workdir=", development_ovl_work);
} }
@ -1728,12 +1729,9 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
* threads, etc. * threads, etc.
*/ */
{ {
mount_child = fork (); pid_t mount_child = fork ();
if (mount_child < 0) if (mount_child < 0)
{ return glnx_throw_errno_prefix (error, "fork");
glnx_set_prefix_error_from_errno (error, "%s", "fork");
goto out;
}
else if (mount_child == 0) else if (mount_child == 0)
{ {
/* Child process. Do NOT use any GLib API here. */ /* Child process. Do NOT use any GLib API here. */
@ -1749,18 +1747,15 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
int estatus; int estatus;
if (TEMP_FAILURE_RETRY (waitpid (mount_child, &estatus, 0)) < 0) if (TEMP_FAILURE_RETRY (waitpid (mount_child, &estatus, 0)) < 0)
{ return glnx_throw_errno_prefix (error, "waitpid() on mount helper");
glnx_set_prefix_error_from_errno (error, "%s", "waitpid() on mount helper");
goto out;
}
if (!g_spawn_check_exit_status (estatus, error)) if (!g_spawn_check_exit_status (estatus, error))
{ return glnx_throw_errno_prefix (error, "overlayfs mount helper");
g_prefix_error (error, "overlayfs mount helper: ");
goto out;
}
} }
} }
g_autoptr(OstreeDeployment) deployment_clone = ostree_deployment_clone (deployment);
GKeyFile *origin_clone = ostree_deployment_get_origin (deployment_clone);
/* Now, write out the flag saying what we did */ /* Now, write out the flag saying what we did */
switch (unlocked_state) switch (unlocked_state)
{ {
@ -1772,7 +1767,7 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
ostree_deployment_unlocked_state_to_string (unlocked_state)); ostree_deployment_unlocked_state_to_string (unlocked_state));
if (!ostree_sysroot_write_origin_file (self, deployment, origin_clone, if (!ostree_sysroot_write_origin_file (self, deployment, origin_clone,
cancellable, error)) cancellable, error))
goto out; return FALSE;
break; break;
case OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT: case OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT:
{ {
@ -1780,10 +1775,10 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
g_autofree char *devpath_parent = dirname (g_strdup (devpath)); g_autofree char *devpath_parent = dirname (g_strdup (devpath));
if (!glnx_shutil_mkdir_p_at (AT_FDCWD, devpath_parent, 0755, cancellable, error)) if (!glnx_shutil_mkdir_p_at (AT_FDCWD, devpath_parent, 0755, cancellable, error))
goto out; return FALSE;
if (!g_file_set_contents (devpath, "", 0, error)) if (!g_file_set_contents (devpath, "", 0, error))
goto out; return FALSE;
} }
} }
@ -1793,9 +1788,7 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
* regardless. * regardless.
*/ */
if (!_ostree_sysroot_bump_mtime (self, error)) if (!_ostree_sysroot_bump_mtime (self, error))
goto out; return FALSE;
ret = TRUE; return TRUE;
out:
return ret;
} }

View File

@ -18,6 +18,7 @@
#pragma once #pragma once
#include "otutil.h"
#include <gio/gio.h> #include <gio/gio.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -31,6 +32,7 @@ G_BEGIN_DECLS
typedef struct _OstreeTlsCertInteraction OstreeTlsCertInteraction; typedef struct _OstreeTlsCertInteraction OstreeTlsCertInteraction;
typedef struct _OstreeTlsCertInteractionClass OstreeTlsCertInteractionClass; typedef struct _OstreeTlsCertInteractionClass OstreeTlsCertInteractionClass;
G_DEFINE_AUTOPTR_CLEANUP_FUNC(OstreeTlsCertInteraction, g_object_unref)
GType _ostree_tls_cert_interaction_get_type (void) G_GNUC_CONST; GType _ostree_tls_cert_interaction_get_type (void) G_GNUC_CONST;

View File

@ -44,7 +44,7 @@
* *
* Since: 2017.4 * Since: 2017.4
*/ */
#define OSTREE_RELEASE_VERSION (9) #define OSTREE_RELEASE_VERSION (10)
/** /**
* OSTREE_VERSION * OSTREE_VERSION
@ -53,7 +53,7 @@
* *
* Since: 2017.4 * Since: 2017.4
*/ */
#define OSTREE_VERSION (2017.9) #define OSTREE_VERSION (2017.10)
/** /**
* OSTREE_VERSION_S: * OSTREE_VERSION_S:
@ -63,7 +63,7 @@
* *
* Since: 2017.4 * Since: 2017.4
*/ */
#define OSTREE_VERSION_S "2017.9" #define OSTREE_VERSION_S "2017.10"
#define OSTREE_ENCODE_VERSION(year,release) \ #define OSTREE_ENCODE_VERSION(year,release) \
((year) << 16 | (release)) ((year) << 16 | (release))

View File

@ -49,7 +49,7 @@ ot_cleanup_unlinkat (OtCleanupUnlinkat *cleanup)
ot_cleanup_unlinkat_clear (cleanup); ot_cleanup_unlinkat_clear (cleanup);
} }
} }
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(OtCleanupUnlinkat, ot_cleanup_unlinkat); G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(OtCleanupUnlinkat, ot_cleanup_unlinkat)
GFile * ot_fdrel_to_gfile (int dfd, const char *path); GFile * ot_fdrel_to_gfile (int dfd, const char *path);

View File

@ -413,7 +413,7 @@ ot_gpgme_new_ctx (const char *homedir,
GError **error) GError **error)
{ {
gpgme_error_t err; gpgme_error_t err;
ot_auto_gpgme_ctx gpgme_ctx_t context = NULL; g_auto(gpgme_ctx_t) context = NULL;
if ((err = gpgme_new (&context)) != GPG_ERR_NO_ERROR) if ((err = gpgme_new (&context)) != GPG_ERR_NO_ERROR)
{ {

View File

@ -26,10 +26,9 @@
G_BEGIN_DECLS G_BEGIN_DECLS
GLNX_DEFINE_CLEANUP_FUNCTION0(gpgme_data_t, ot_cleanup_gpgme_data, gpgme_data_release) G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_data_t, gpgme_data_release, NULL)
#define ot_auto_gpgme_data __attribute__((cleanup(ot_cleanup_gpgme_data))) G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_ctx_t, gpgme_release, NULL)
GLNX_DEFINE_CLEANUP_FUNCTION0(gpgme_ctx_t, ot_cleanup_gpgme_ctx, gpgme_release) G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_key_t, gpgme_key_unref, NULL)
#define ot_auto_gpgme_ctx __attribute__((cleanup(ot_cleanup_gpgme_ctx)))
void ot_gpgme_error_to_gio_error (gpgme_error_t gpg_error, GError **error); void ot_gpgme_error_to_gio_error (gpgme_error_t gpg_error, GError **error);

View File

@ -1,163 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2016 Colin Walters <walters@verbum.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: Colin Walters <walters@verbum.org>
*/
#include "config.h"
#include <gio/gio.h>
#include <string.h>
#include "otutil.h"
#include "libglnx.h"
#ifdef HAVE_LIBSYSTEMD
#define SD_JOURNAL_SUPPRESS_LOCATION
#include <systemd/sd-journal.h>
#endif
#include <glib-unix.h>
/**
* ot_log_structured:
* @message: Text message to send
* @keys: (allow-none) (array zero-terminated=1) (element-type utf8): Optional structured data
*
* Log structured data in an operating-system specific fashion. The
* parameter @opts should be an array of UTF-8 KEY=VALUE strings.
* This function does not support binary data. See
* http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html
* for more information about fields that can be used on a systemd
* system.
*/
static void
ot_log_structured (const char *message,
const char *const *keys)
{
#ifdef HAVE_LIBSYSTEMD
const char *const*iter;
g_autofree char *msgkey = NULL;
guint i, n_opts;
struct iovec *iovs;
for (n_opts = 0, iter = keys; *iter; iter++, n_opts++)
;
n_opts++; /* Add one for MESSAGE= */
iovs = g_alloca (sizeof (struct iovec) * n_opts);
for (i = 0, iter = keys; *iter; iter++, i++) {
iovs[i].iov_base = (char*)keys[i];
iovs[i].iov_len = strlen (keys[i]);
}
g_assert(i == n_opts-1);
msgkey = g_strconcat ("MESSAGE=", message, NULL);
iovs[i].iov_base = msgkey;
iovs[i].iov_len = strlen (msgkey);
// The code location isn't useful since we're wrapping
sd_journal_sendv (iovs, n_opts);
#else
g_print ("%s\n", message);
#endif
}
/**
* ot_stdout_is_journal:
*
* Use this function when you want your code to behave differently
* depeneding on whether your program was started as a systemd unit,
* or e.g. interactively at a terminal.
*
* Returns: %TRUE if stdout is (probably) connnected to the systemd journal
*/
static gboolean
ot_stdout_is_journal (void)
{
static gsize initialized;
static gboolean stdout_is_socket;
if (g_once_init_enter (&initialized))
{
guint64 pid = (guint64) getpid ();
g_autofree char *fdpath = g_strdup_printf ("/proc/%" G_GUINT64_FORMAT "/fd/1", pid);
char buf[1024];
ssize_t bytes_read;
if ((bytes_read = readlink (fdpath, buf, sizeof(buf) - 1)) != -1)
{
buf[bytes_read] = '\0';
stdout_is_socket = g_str_has_prefix (buf, "socket:");
}
else
stdout_is_socket = FALSE;
g_once_init_leave (&initialized, TRUE);
}
return stdout_is_socket;
}
/**
* gs_log_structured_print:
* @message: A message to log
* @keys: (allow-none) (array zero-terminated=1) (element-type utf8): Optional structured data
*
* Like gs_log_structured(), but also print to standard output (if it
* is not already connected to the system log).
*/
static void
ot_log_structured_print (const char *message,
const char *const *keys)
{
ot_log_structured (message, keys);
#ifdef HAVE_LIBSYSTEMD
if (!ot_stdout_is_journal ())
g_print ("%s\n", message);
#endif
}
/**
* ot_log_structured_print_id_v:
* @message_id: A unique MESSAGE_ID
* @format: A format string
*
* The provided @message_id is a unique MESSAGE_ID (see <ulink url="http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html"> for more information).
*
* This function otherwise acts as ot_log_structured_print(), taking
* @format as a format string.
*/
void
ot_log_structured_print_id_v (const char *message_id,
const char *format,
...)
{
const char *key0 = glnx_strjoina ("MESSAGE_ID=", message_id);
const char *keys[] = { key0, NULL };
g_autofree char *msg = NULL;
va_list args;
va_start (args, format);
msg = g_strdup_vprintf (format, args);
va_end (args);
ot_log_structured_print (msg, (const char *const *)keys);
}

View File

@ -1,31 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2016 Colin Walters <walters@verbum.org>.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#pragma once
#include "ot-unix-utils.h"
G_BEGIN_DECLS
void ot_log_structured_print_id_v (const char *message_id,
const char *format,
...) G_GNUC_PRINTF(2, 3);
G_END_DECLS

View File

@ -51,7 +51,6 @@
#include <ot-variant-utils.h> #include <ot-variant-utils.h>
#include <ot-checksum-utils.h> #include <ot-checksum-utils.h>
#include <ot-gpg-utils.h> #include <ot-gpg-utils.h>
#include <ot-log-utils.h>
#include <ot-checksum-instream.h> #include <ot-checksum-instream.h>
void ot_ptrarray_add_many (GPtrArray *a, ...) G_GNUC_NULL_TERMINATED; void ot_ptrarray_add_many (GPtrArray *a, ...) G_GNUC_NULL_TERMINATED;

View File

@ -56,6 +56,11 @@ typedef struct {
GOutputStream *log; GOutputStream *log;
} OtTrivialHttpd; } OtTrivialHttpd;
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-trivial-httpd.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "daemonize", 'd', 0, G_OPTION_ARG_NONE, &opt_daemonize, "Fork into background when ready", NULL }, { "daemonize", 'd', 0, G_OPTION_ARG_NONE, &opt_daemonize, "Fork into background when ready", NULL },
{ "autoexit", 0, 0, G_OPTION_ARG_NONE, &opt_autoexit, "Automatically exit when directory is deleted", NULL }, { "autoexit", 0, 0, G_OPTION_ARG_NONE, &opt_autoexit, "Automatically exit when directory is deleted", NULL },
@ -94,7 +99,7 @@ httpd_log (OtTrivialHttpd *httpd, const gchar *format, ...)
g_string_append_vprintf (str, format, args); g_string_append_vprintf (str, format, args);
va_end (args); va_end (args);
g_output_stream_write_all (httpd->log, str->str, str->len, &written, NULL, NULL); (void)g_output_stream_write_all (httpd->log, str->str, str->len, &written, NULL, NULL);
} }
static int static int

View File

@ -29,6 +29,11 @@
#include <glib/gi18n.h> #include <glib/gi18n.h>
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-admin-cleanup.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ NULL } { NULL }
}; };
@ -37,7 +42,7 @@ gboolean
ot_admin_builtin_cleanup (int argc, char **argv, GCancellable *cancellable, GError **error) ot_admin_builtin_cleanup (int argc, char **argv, GCancellable *cancellable, GError **error)
{ {
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL; g_autoptr(OstreeSysroot) sysroot = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
context = g_option_context_new ("Delete untagged deployments and repository objects"); context = g_option_context_new ("Delete untagged deployments and repository objects");

View File

@ -39,6 +39,11 @@ static gboolean opt_kernel_proc_cmdline;
static char *opt_osname; static char *opt_osname;
static char *opt_origin_path; static char *opt_origin_path;
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-admin-deploy.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" }, { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" },
{ "origin-file", 0, 0, G_OPTION_ARG_FILENAME, &opt_origin_path, "Specify origin file", "FILENAME" }, { "origin-file", 0, 0, G_OPTION_ARG_FILENAME, &opt_origin_path, "Specify origin file", "FILENAME" },
@ -55,11 +60,11 @@ ot_admin_builtin_deploy (int argc, char **argv, GCancellable *cancellable, GErro
gboolean ret = FALSE; gboolean ret = FALSE;
const char *refspec; const char *refspec;
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL; g_autoptr(OstreeSysroot) sysroot = NULL;
g_autoptr(GKeyFile) origin = NULL; g_autoptr(GKeyFile) origin = NULL;
glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(OstreeRepo) repo = NULL;
glnx_unref_object OstreeDeployment *new_deployment = NULL; g_autoptr(OstreeDeployment) new_deployment = NULL;
glnx_unref_object OstreeDeployment *merge_deployment = NULL; g_autoptr(OstreeDeployment) merge_deployment = NULL;
g_autofree char *revision = NULL; g_autofree char *revision = NULL;
__attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL; __attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL;

View File

@ -31,6 +31,11 @@
static char *opt_osname; static char *opt_osname;
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-admin-config-diff.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" }, { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" },
{ NULL } { NULL }
@ -40,9 +45,9 @@ gboolean
ot_admin_builtin_diff (int argc, char **argv, GCancellable *cancellable, GError **error) ot_admin_builtin_diff (int argc, char **argv, GCancellable *cancellable, GError **error)
{ {
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL; g_autoptr(OstreeSysroot) sysroot = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
glnx_unref_object OstreeDeployment *deployment = NULL; g_autoptr(OstreeDeployment) deployment = NULL;
g_autoptr(GFile) deployment_dir = NULL; g_autoptr(GFile) deployment_dir = NULL;
g_autoptr(GPtrArray) modified = NULL; g_autoptr(GPtrArray) modified = NULL;
g_autoptr(GPtrArray) removed = NULL; g_autoptr(GPtrArray) removed = NULL;

View File

@ -29,6 +29,11 @@
#include <glib/gi18n.h> #include <glib/gi18n.h>
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-admin-init-fs.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ NULL } { NULL }
}; };
@ -37,10 +42,10 @@ gboolean
ot_admin_builtin_init_fs (int argc, char **argv, GCancellable *cancellable, GError **error) ot_admin_builtin_init_fs (int argc, char **argv, GCancellable *cancellable, GError **error)
{ {
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL; g_autoptr(OstreeSysroot) sysroot = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
glnx_fd_close int root_dfd = -1; glnx_fd_close int root_dfd = -1;
glnx_unref_object OstreeSysroot *target_sysroot = NULL; g_autoptr(OstreeSysroot) target_sysroot = NULL;
guint i; guint i;
const char *normal_toplevels[] = {"boot", "dev", "home", "proc", "run", "sys"}; const char *normal_toplevels[] = {"boot", "dev", "home", "proc", "run", "sys"};

View File

@ -29,6 +29,11 @@
#include <glib/gi18n.h> #include <glib/gi18n.h>
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-admin-os-init.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ NULL } { NULL }
}; };
@ -37,7 +42,7 @@ gboolean
ot_admin_builtin_os_init (int argc, char **argv, GCancellable *cancellable, GError **error) ot_admin_builtin_os_init (int argc, char **argv, GCancellable *cancellable, GError **error)
{ {
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL; g_autoptr(OstreeSysroot) sysroot = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
const char *osname = NULL; const char *osname = NULL;

View File

@ -34,6 +34,11 @@
static int opt_index = -1; static int opt_index = -1;
static char **opt_set; static char **opt_set;
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-admin-set-origin.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "set", 's', 0, G_OPTION_ARG_STRING_ARRAY, &opt_set, "Set config option KEY=VALUE for remote", "KEY=VALUE" }, { "set", 's', 0, G_OPTION_ARG_STRING_ARRAY, &opt_set, "Set config option KEY=VALUE for remote", "KEY=VALUE" },
{ "index", 0, 0, G_OPTION_ARG_INT, &opt_index, "Operate on the deployment INDEX, starting from zero", "INDEX" }, { "index", 0, 0, G_OPTION_ARG_INT, &opt_index, "Operate on the deployment INDEX, starting from zero", "INDEX" },
@ -48,9 +53,9 @@ ot_admin_builtin_set_origin (int argc, char **argv, GCancellable *cancellable, G
const char *remotename = NULL; const char *remotename = NULL;
const char *url = NULL; const char *url = NULL;
const char *branch = NULL; const char *branch = NULL;
glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(OstreeRepo) repo = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL; g_autoptr(OstreeSysroot) sysroot = NULL;
glnx_unref_object OstreeDeployment *target_deployment = NULL; g_autoptr(OstreeDeployment) target_deployment = NULL;
context = g_option_context_new ("REMOTENAME URL [BRANCH]"); context = g_option_context_new ("REMOTENAME URL [BRANCH]");

View File

@ -29,6 +29,11 @@
#include <glib/gi18n.h> #include <glib/gi18n.h>
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-admin-status.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ NULL } { NULL }
}; };
@ -84,9 +89,9 @@ gboolean
ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GError **error) ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GError **error)
{ {
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL; g_autoptr(OstreeSysroot) sysroot = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(OstreeRepo) repo = NULL;
OstreeDeployment *booted_deployment = NULL; OstreeDeployment *booted_deployment = NULL;
g_autoptr(OstreeDeployment) pending_deployment = NULL; g_autoptr(OstreeDeployment) pending_deployment = NULL;
g_autoptr(OstreeDeployment) rollback_deployment = NULL; g_autoptr(OstreeDeployment) rollback_deployment = NULL;
@ -129,7 +134,7 @@ ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GErro
const char *ref = ostree_deployment_get_csum (deployment); const char *ref = ostree_deployment_get_csum (deployment);
OstreeDeploymentUnlockedState unlocked = ostree_deployment_get_unlocked (deployment); OstreeDeploymentUnlockedState unlocked = ostree_deployment_get_unlocked (deployment);
g_autofree char *version = version_of_commit (repo, ref); g_autofree char *version = version_of_commit (repo, ref);
glnx_unref_object OstreeGpgVerifyResult *result = NULL; g_autoptr(OstreeGpgVerifyResult) result = NULL;
guint jj, n_signatures; guint jj, n_signatures;
GError *local_error = NULL; GError *local_error = NULL;

View File

@ -33,6 +33,11 @@
static gboolean opt_reboot; static gboolean opt_reboot;
static char *opt_osname; static char *opt_osname;
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-admin-switch.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Reboot after switching trees", NULL }, { "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Reboot after switching trees", NULL },
{ "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" }, { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" },
@ -44,9 +49,9 @@ ot_admin_builtin_switch (int argc, char **argv, GCancellable *cancellable, GErro
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL; g_autoptr(OstreeSysroot) sysroot = NULL;
const char *new_provided_refspec = NULL; const char *new_provided_refspec = NULL;
glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(OstreeRepo) repo = NULL;
g_autofree char *origin_refspec = NULL; g_autofree char *origin_refspec = NULL;
g_autofree char *origin_remote = NULL; g_autofree char *origin_remote = NULL;
g_autofree char *origin_ref = NULL; g_autofree char *origin_ref = NULL;
@ -54,8 +59,8 @@ ot_admin_builtin_switch (int argc, char **argv, GCancellable *cancellable, GErro
g_autofree char *new_ref = NULL; g_autofree char *new_ref = NULL;
g_autofree char *new_refspec = NULL; g_autofree char *new_refspec = NULL;
const char* remote; const char* remote;
glnx_unref_object OstreeSysrootUpgrader *upgrader = NULL; g_autoptr(OstreeSysrootUpgrader) upgrader = NULL;
glnx_unref_object OstreeAsyncProgress *progress = NULL; g_autoptr(OstreeAsyncProgress) progress = NULL;
gboolean changed; gboolean changed;
GKeyFile *old_origin; GKeyFile *old_origin;
g_autoptr(GKeyFile) new_origin = NULL; g_autoptr(GKeyFile) new_origin = NULL;

View File

@ -28,6 +28,11 @@
#include "ostree.h" #include "ostree.h"
#include "otutil.h" #include "otutil.h"
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-admin-undeploy.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ NULL } { NULL }
}; };
@ -36,11 +41,11 @@ gboolean
ot_admin_builtin_undeploy (int argc, char **argv, GCancellable *cancellable, GError **error) ot_admin_builtin_undeploy (int argc, char **argv, GCancellable *cancellable, GError **error)
{ {
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL; g_autoptr(OstreeSysroot) sysroot = NULL;
const char *deploy_index_str; const char *deploy_index_str;
int deploy_index; int deploy_index;
g_autoptr(GPtrArray) current_deployments = NULL; g_autoptr(GPtrArray) current_deployments = NULL;
glnx_unref_object OstreeDeployment *target_deployment = NULL; g_autoptr(OstreeDeployment) target_deployment = NULL;
context = g_option_context_new ("INDEX - Delete deployment INDEX"); context = g_option_context_new ("INDEX - Delete deployment INDEX");

View File

@ -33,6 +33,11 @@
static gboolean opt_hotfix; static gboolean opt_hotfix;
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-admin-unlock.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "hotfix", 0, 0, G_OPTION_ARG_NONE, &opt_hotfix, "Retain changes across reboots", NULL }, { "hotfix", 0, 0, G_OPTION_ARG_NONE, &opt_hotfix, "Retain changes across reboots", NULL },
{ NULL } { NULL }
@ -43,7 +48,7 @@ ot_admin_builtin_unlock (int argc, char **argv, GCancellable *cancellable, GErro
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL; g_autoptr(OstreeSysroot) sysroot = NULL;
OstreeDeployment *booted_deployment = NULL; OstreeDeployment *booted_deployment = NULL;
OstreeDeploymentUnlockedState target_state; OstreeDeploymentUnlockedState target_state;

View File

@ -39,6 +39,11 @@ static gboolean opt_deploy_only;
static char *opt_osname; static char *opt_osname;
static char *opt_override_commit; static char *opt_override_commit;
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-admin-upgrade.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" }, { "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" },
{ "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Reboot after a successful upgrade", NULL }, { "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Reboot after a successful upgrade", NULL },
@ -54,10 +59,10 @@ ot_admin_builtin_upgrade (int argc, char **argv, GCancellable *cancellable, GErr
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL; g_autoptr(OstreeSysroot) sysroot = NULL;
glnx_unref_object OstreeSysrootUpgrader *upgrader = NULL; g_autoptr(OstreeSysrootUpgrader) upgrader = NULL;
g_autoptr(GKeyFile) origin = NULL; g_autoptr(GKeyFile) origin = NULL;
glnx_unref_object OstreeAsyncProgress *progress = NULL; g_autoptr(OstreeAsyncProgress) progress = NULL;
gboolean changed; gboolean changed;
OstreeSysrootUpgraderPullFlags upgraderpullflags = 0; OstreeSysrootUpgraderPullFlags upgraderpullflags = 0;

View File

@ -29,6 +29,11 @@
#include "otutil.h" #include "otutil.h"
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-admin-instutil.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ NULL } { NULL }
}; };
@ -39,7 +44,7 @@ ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, GCancellable *c
gboolean ret = FALSE; gboolean ret = FALSE;
guint bootversion; guint bootversion;
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL; g_autoptr(OstreeSysroot) sysroot = NULL;
context = g_option_context_new ("[BOOTVERSION] - generate GRUB2 configuration from given BLS entries"); context = g_option_context_new ("[BOOTVERSION] - generate GRUB2 configuration from given BLS entries");

View File

@ -174,6 +174,11 @@ selinux_relabel_dir (OstreeSePolicy *sepolicy,
return ret; return ret;
} }
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-admin-instutil.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ NULL } { NULL }
}; };
@ -185,11 +190,11 @@ ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, GCancel
const char *policy_name; const char *policy_name;
g_autoptr(GFile) subpath = NULL; g_autoptr(GFile) subpath = NULL;
const char *prefix = NULL; const char *prefix = NULL;
glnx_unref_object OstreeSePolicy *sepolicy = NULL; g_autoptr(OstreeSePolicy) sepolicy = NULL;
g_autoptr(GPtrArray) deployments = NULL; g_autoptr(GPtrArray) deployments = NULL;
OstreeDeployment *first_deployment; OstreeDeployment *first_deployment;
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL; g_autoptr(OstreeSysroot) sysroot = NULL;
g_autoptr(GFile) deployment_path = NULL; g_autoptr(GFile) deployment_path = NULL;
context = g_option_context_new ("[SUBPATH PREFIX] - relabel all or part of a deployment"); context = g_option_context_new ("[SUBPATH PREFIX] - relabel all or part of a deployment");

View File

@ -35,6 +35,11 @@ static gboolean opt_merge;
static char **opt_replace; static char **opt_replace;
static char **opt_append; static char **opt_append;
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-admin-instutil.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "import-proc-cmdline", 0, 0, G_OPTION_ARG_NONE, &opt_proc_cmdline, "Import current /proc/cmdline", NULL }, { "import-proc-cmdline", 0, 0, G_OPTION_ARG_NONE, &opt_proc_cmdline, "Import current /proc/cmdline", NULL },
{ "merge", 0, 0, G_OPTION_ARG_NONE, &opt_merge, "Merge with previous command line", NULL }, { "merge", 0, 0, G_OPTION_ARG_NONE, &opt_merge, "Merge with previous command line", NULL },
@ -51,7 +56,7 @@ ot_admin_instutil_builtin_set_kargs (int argc, char **argv, GCancellable *cancel
g_autoptr(GPtrArray) deployments = NULL; g_autoptr(GPtrArray) deployments = NULL;
OstreeDeployment *first_deployment = NULL; OstreeDeployment *first_deployment = NULL;
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL; g_autoptr(OstreeSysroot) sysroot = NULL;
__attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL; __attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL;
context = g_option_context_new ("ARGS - set new kernel command line arguments"); context = g_option_context_new ("ARGS - set new kernel command line arguments");

View File

@ -29,6 +29,11 @@
#include <gio/gunixoutputstream.h> #include <gio/gunixoutputstream.h>
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-cat.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ NULL }, { NULL },
}; };

View File

@ -61,6 +61,11 @@ parse_fsync_cb (const char *option_name,
return TRUE; return TRUE;
} }
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-checkout.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "user-mode", 'U', 0, G_OPTION_ARG_NONE, &opt_user_mode, "Do not change file ownership or initialize extended attributes", NULL }, { "user-mode", 'U', 0, G_OPTION_ARG_NONE, &opt_user_mode, "Do not change file ownership or initialize extended attributes", NULL },
{ "disable-cache", 0, 0, G_OPTION_ARG_NONE, &opt_disable_cache, "Do not update or use the internal repository uncompressed object cache", NULL }, { "disable-cache", 0, 0, G_OPTION_ARG_NONE, &opt_disable_cache, "Do not update or use the internal repository uncompressed object cache", NULL },
@ -254,7 +259,7 @@ gboolean
ostree_builtin_checkout (int argc, char **argv, GCancellable *cancellable, GError **error) ostree_builtin_checkout (int argc, char **argv, GCancellable *cancellable, GError **error)
{ {
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(OstreeRepo) repo = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
const char *commit; const char *commit;
const char *destination; const char *destination;

View File

@ -28,6 +28,11 @@
#include <string.h> #include <string.h>
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-checksum.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ NULL } { NULL }
}; };

View File

@ -72,6 +72,11 @@ parse_fsync_cb (const char *option_name,
return TRUE; return TRUE;
} }
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-commit.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "parent", 0, 0, G_OPTION_ARG_STRING, &opt_parent, "Parent ref, or \"none\"", "REF" }, { "parent", 0, 0, G_OPTION_ARG_STRING, &opt_parent, "Parent ref, or \"none\"", "REF" },
{ "subject", 's', 0, G_OPTION_ARG_STRING, &opt_subject, "One line subject", "SUBJECT" }, { "subject", 's', 0, G_OPTION_ARG_STRING, &opt_subject, "One line subject", "SUBJECT" },
@ -375,7 +380,7 @@ gboolean
ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError **error) ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError **error)
{ {
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(OstreeRepo) repo = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
gboolean skip_commit = FALSE; gboolean skip_commit = FALSE;
g_autoptr(GFile) object_to_commit = NULL; g_autoptr(GFile) object_to_commit = NULL;
@ -384,7 +389,7 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError
g_autoptr(GFile) root = NULL; g_autoptr(GFile) root = NULL;
g_autoptr(GVariant) metadata = NULL; g_autoptr(GVariant) metadata = NULL;
g_autoptr(GVariant) detached_metadata = NULL; g_autoptr(GVariant) detached_metadata = NULL;
glnx_unref_object OstreeMutableTree *mtree = NULL; g_autoptr(OstreeMutableTree) mtree = NULL;
g_autofree char *tree_type = NULL; g_autofree char *tree_type = NULL;
g_autoptr(GHashTable) mode_adds = NULL; g_autoptr(GHashTable) mode_adds = NULL;
g_autoptr(GHashTable) mode_overrides = NULL; g_autoptr(GHashTable) mode_overrides = NULL;

View File

@ -27,6 +27,11 @@
#include "ostree.h" #include "ostree.h"
#include "otutil.h" #include "otutil.h"
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-config.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ NULL } { NULL }
}; };
@ -55,7 +60,7 @@ gboolean
ostree_builtin_config (int argc, char **argv, GCancellable *cancellable, GError **error) ostree_builtin_config (int argc, char **argv, GCancellable *cancellable, GError **error)
{ {
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(OstreeRepo) repo = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
const char *op; const char *op;
const char *section_key; const char *section_key;

View File

@ -33,6 +33,11 @@ static gboolean opt_no_xattrs;
static gint opt_owner_uid = -1; static gint opt_owner_uid = -1;
static gint opt_owner_gid = -1; static gint opt_owner_gid = -1;
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-diff.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "stats", 0, 0, G_OPTION_ARG_NONE, &opt_stats, "Print various statistics", NULL }, { "stats", 0, 0, G_OPTION_ARG_NONE, &opt_stats, "Print various statistics", NULL },
{ "fs-diff", 0, 0, G_OPTION_ARG_NONE, &opt_fs_diff, "Print filesystem diff", NULL }, { "fs-diff", 0, 0, G_OPTION_ARG_NONE, &opt_fs_diff, "Print filesystem diff", NULL },
@ -126,7 +131,7 @@ ostree_builtin_diff (int argc, char **argv, GCancellable *cancellable, GError **
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(OstreeRepo) repo = NULL;
const char *src; const char *src;
const char *target; const char *target;
g_autofree char *src_prev = NULL; g_autofree char *src_prev = NULL;

View File

@ -20,12 +20,12 @@
#include "config.h" #include "config.h"
#include "otutil.h"
#include "ot-main.h" #include "ot-main.h"
#include "ot-builtins.h" #include "ot-builtins.h"
#include "ostree-libarchive-private.h"
#include "ostree.h" #include "ostree.h"
#include "ostree-repo-file.h" #include "ostree-repo-file.h"
#include "ostree-libarchive-private.h"
#include "otutil.h"
#ifdef HAVE_LIBARCHIVE #ifdef HAVE_LIBARCHIVE
#include <archive.h> #include <archive.h>
@ -37,6 +37,11 @@ static char *opt_subpath;
static char *opt_prefix; static char *opt_prefix;
static gboolean opt_no_xattrs; static gboolean opt_no_xattrs;
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-export.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "no-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_no_xattrs, "Skip output of extended attributes", NULL }, { "no-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_no_xattrs, "Skip output of extended attributes", NULL },
{ "subpath", 0, 0, G_OPTION_ARG_FILENAME, &opt_subpath, "Checkout sub-directory PATH", "PATH" }, { "subpath", 0, 0, G_OPTION_ARG_FILENAME, &opt_subpath, "Checkout sub-directory PATH", "PATH" },
@ -61,14 +66,16 @@ gboolean
ostree_builtin_export (int argc, char **argv, GCancellable *cancellable, GError **error) ostree_builtin_export (int argc, char **argv, GCancellable *cancellable, GError **error)
{ {
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(OstreeRepo) repo = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
const char *rev; const char *rev;
g_autoptr(GFile) root = NULL; g_autoptr(GFile) root = NULL;
g_autoptr(GFile) subtree = NULL; g_autoptr(GFile) subtree = NULL;
g_autofree char *commit = NULL; g_autofree char *commit = NULL;
g_autoptr(GVariant) commit_data = NULL; g_autoptr(GVariant) commit_data = NULL;
ot_cleanup_write_archive struct archive *a = NULL; #ifdef HAVE_LIBARCHIVE
g_autoptr(OtAutoArchiveWrite) a = NULL;
#endif
OstreeRepoExportArchiveOptions opts = { 0, }; OstreeRepoExportArchiveOptions opts = { 0, };
context = g_option_context_new ("COMMIT - Stream COMMIT to stdout in tar format"); context = g_option_context_new ("COMMIT - Stream COMMIT to stdout in tar format");

View File

@ -125,9 +125,9 @@ ostree_builtin_find_remotes (int argc,
GError **error) GError **error)
{ {
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(OstreeRepo) repo = NULL;
g_autoptr(GPtrArray) refs = NULL; /* (element-type OstreeCollectionRef) */ g_autoptr(GPtrArray) refs = NULL; /* (element-type OstreeCollectionRef) */
glnx_unref_object OstreeAsyncProgress *progress = NULL; g_autoptr(OstreeAsyncProgress) progress = NULL;
gsize i; gsize i;
g_autoptr(GAsyncResult) find_result = NULL, pull_result = NULL; g_autoptr(GAsyncResult) find_result = NULL, pull_result = NULL;
g_auto(OstreeRepoFinderResultv) results = NULL; g_auto(OstreeRepoFinderResultv) results = NULL;

View File

@ -32,6 +32,11 @@ static gboolean opt_quiet;
static gboolean opt_delete; static gboolean opt_delete;
static gboolean opt_add_tombstones; static gboolean opt_add_tombstones;
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-fsck.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "add-tombstones", 0, 0, G_OPTION_ARG_NONE, &opt_add_tombstones, "Add tombstones for missing commits", NULL }, { "add-tombstones", 0, 0, G_OPTION_ARG_NONE, &opt_add_tombstones, "Add tombstones for missing commits", NULL },
{ "quiet", 'q', 0, G_OPTION_ARG_NONE, &opt_quiet, "Only print error messages", NULL }, { "quiet", 'q', 0, G_OPTION_ARG_NONE, &opt_quiet, "Only print error messages", NULL },
@ -212,7 +217,7 @@ fsck_reachable_objects_from_commits (OstreeRepo *repo,
gboolean gboolean
ostree_builtin_fsck (int argc, char **argv, GCancellable *cancellable, GError **error) ostree_builtin_fsck (int argc, char **argv, GCancellable *cancellable, GError **error)
{ {
glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(OstreeRepo) repo = NULL;
gboolean found_corruption = FALSE; gboolean found_corruption = FALSE;
g_autoptr(GOptionContext) context = g_option_context_new ("- Check the repository for consistency"); g_autoptr(GOptionContext) context = g_option_context_new ("- Check the repository for consistency");

View File

@ -31,6 +31,11 @@
static gboolean opt_delete; static gboolean opt_delete;
static char *opt_gpg_homedir; static char *opt_gpg_homedir;
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-gpg-sign.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "delete", 'd', 0, G_OPTION_ARG_NONE, &opt_delete, "Delete signatures having any of the GPG KEY-IDs" }, { "delete", 'd', 0, G_OPTION_ARG_NONE, &opt_delete, "Delete signatures having any of the GPG KEY-IDs" },
{ "gpg-homedir", 0, 0, G_OPTION_ARG_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" },
@ -55,7 +60,7 @@ delete_signatures (OstreeRepo *repo,
GError **error) GError **error)
{ {
GVariantDict metadata_dict; GVariantDict metadata_dict;
glnx_unref_object OstreeGpgVerifyResult *result = NULL; g_autoptr(OstreeGpgVerifyResult) result = NULL;
g_autoptr(GVariant) old_metadata = NULL; g_autoptr(GVariant) old_metadata = NULL;
g_autoptr(GVariant) new_metadata = NULL; g_autoptr(GVariant) new_metadata = NULL;
g_autoptr(GVariant) signature_data = NULL; g_autoptr(GVariant) signature_data = NULL;
@ -199,7 +204,7 @@ gboolean
ostree_builtin_gpg_sign (int argc, char **argv, GCancellable *cancellable, GError **error) ostree_builtin_gpg_sign (int argc, char **argv, GCancellable *cancellable, GError **error)
{ {
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(OstreeRepo) repo = NULL;
g_autofree char *resolved_commit = NULL; g_autofree char *resolved_commit = NULL;
const char *commit; const char *commit;
char **key_ids; char **key_ids;

View File

@ -31,6 +31,11 @@ static char *opt_mode = "bare";
static char *opt_collection_id = NULL; static char *opt_collection_id = NULL;
#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */ #endif /* OSTREE_ENABLE_EXPERIMENTAL_API */
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-init.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "mode", 0, 0, G_OPTION_ARG_STRING, &opt_mode, "Initialize repository in given mode (bare, archive-z2)", NULL }, { "mode", 0, 0, G_OPTION_ARG_STRING, &opt_mode, "Initialize repository in given mode (bare, archive-z2)", NULL },
#ifdef OSTREE_ENABLE_EXPERIMENTAL_API #ifdef OSTREE_ENABLE_EXPERIMENTAL_API

View File

@ -30,6 +30,11 @@
static gboolean opt_raw; static gboolean opt_raw;
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-log.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "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" },
{ NULL } { NULL }
@ -82,7 +87,7 @@ ostree_builtin_log (int argc,
GError **error) GError **error)
{ {
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(OstreeRepo) repo = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
const char *rev; const char *rev;
g_autofree char *checksum = NULL; g_autofree char *checksum = NULL;

View File

@ -34,6 +34,11 @@ static gboolean opt_checksum;
static gboolean opt_xattrs; static gboolean opt_xattrs;
static gboolean opt_nul_filenames_only; static gboolean opt_nul_filenames_only;
/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
* man page (man/ostree-ls.xml) when changing the option list.
*/
static GOptionEntry options[] = { static GOptionEntry options[] = {
{ "dironly", 'd', 0, G_OPTION_ARG_NONE, &opt_dironly, "Do not recurse into directory arguments", NULL }, { "dironly", 'd', 0, G_OPTION_ARG_NONE, &opt_dironly, "Do not recurse into directory arguments", NULL },
{ "recursive", 'R', 0, G_OPTION_ARG_NONE, &opt_recursive, "Print directories recursively", NULL }, { "recursive", 'R', 0, G_OPTION_ARG_NONE, &opt_recursive, "Print directories recursively", NULL },
@ -239,7 +244,7 @@ gboolean
ostree_builtin_ls (int argc, char **argv, GCancellable *cancellable, GError **error) ostree_builtin_ls (int argc, char **argv, GCancellable *cancellable, GError **error)
{ {
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(OstreeRepo) repo = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
const char *rev; const char *rev;
int i; int i;

Some files were not shown because too many files have changed in this diff Show More