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-gio-utils.c \
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.h \
src/libotutil/otutil.c \

View File

@ -111,6 +111,7 @@ endif
include Makefile-tests.am
include Makefile-boot.am
include Makefile-man.am
include Makefile-bash.am
release-tag:
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,
# 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) \
$(ACLOCAL_M4)
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_gpgvinsttest_DATA_DIST) \
$(am__libostreeinclude_HEADERS_DIST) $(am__DIST_COMMON)
@ -576,7 +596,7 @@ am__installdirs = "$(DESTDIR)$(installed_testdir)" \
"$(DESTDIR)$(mkinitcpioinstalldir)" \
"$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" \
"$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" \
"$(DESTDIR)$(gpginsttestdir)" \
"$(DESTDIR)$(completionsdir)" "$(DESTDIR)$(gpginsttestdir)" \
"$(DESTDIR)$(gpginsttest_trusteddir)" \
"$(DESTDIR)$(gpgvinsttestdir)" "$(DESTDIR)$(dracutconfdir)" \
"$(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-variant-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-otutil.lo \
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
am__dist_gpgvinsttest_DATA_DIST = $(addprefix tests/gpg-verify-data/, \
gpg.conf lgpl2 lgpl2.sig pubring.gpg secring.gpg trustdb.gpg)
DATA = $(dist_gpginsttest_DATA) $(dist_gpginsttest_trusted_DATA) \
$(dist_gpgvinsttest_DATA) $(dracutconf_DATA) $(gir_DATA) \
$(gpgreadme_DATA) $(installed_test_DATA) \
$(installed_test_meta_DATA) $(mkinitcpioconf_DATA) \
$(nobase_installed_test_DATA) $(noinst_DATA) $(pkgconfig_DATA) \
$(systemdsystemunit_DATA) $(typelib_DATA)
DATA = $(dist_completions_DATA) $(dist_gpginsttest_DATA) \
$(dist_gpginsttest_trusted_DATA) $(dist_gpgvinsttest_DATA) \
$(dracutconf_DATA) $(gir_DATA) $(gpgreadme_DATA) \
$(installed_test_DATA) $(installed_test_meta_DATA) \
$(mkinitcpioconf_DATA) $(nobase_installed_test_DATA) \
$(noinst_DATA) $(pkgconfig_DATA) $(systemdsystemunit_DATA) \
$(typelib_DATA)
am__libostreeinclude_HEADERS_DIST = src/libostree/ostree.h \
src/libostree/ostree-async-progress.h \
src/libostree/ostree-autocleanups.h \
@ -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_FLAGS)
DIST_SUBDIRS = . apidoc
am__DIST_COMMON = $(srcdir)/Makefile-boot.am \
$(srcdir)/Makefile-decls.am \
am__DIST_COMMON = $(srcdir)/Makefile-bash.am \
$(srcdir)/Makefile-boot.am $(srcdir)/Makefile-decls.am \
$(srcdir)/Makefile-libostree-defines.am \
$(srcdir)/Makefile-libostree.am $(srcdir)/Makefile-man.am \
$(srcdir)/Makefile-ostree.am $(srcdir)/Makefile-otutil.am \
@ -1753,6 +1773,7 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BASH_COMPLETIONSDIR = @BASH_COMPLETIONSDIR@
BUILDOPT_FUSE_CFLAGS = @BUILDOPT_FUSE_CFLAGS@
BUILDOPT_FUSE_LIBS = @BUILDOPT_FUSE_LIBS@
CC = @CC@
@ -2152,8 +2173,6 @@ libotutil_la_SOURCES = \
src/libotutil/ot-variant-utils.h \
src/libotutil/ot-gio-utils.c \
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.h \
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@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}
git_version_rpm = $$(cd $(srcdir) && git describe | sed -e 's,-,\.,g' -e 's,^v,,')
all: $(BUILT_SOURCES) config.h
@ -2652,7 +2673,7 @@ all: $(BUILT_SOURCES) config.h
.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
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 \
case '$(am__configure_deps)' in \
*$$dep*) \
@ -2674,7 +2695,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
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)
$(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/$(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/$(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-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-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-tool-util.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@
@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
@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
@ -6370,6 +6380,27 @@ uninstall-man5:
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
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)
@$(NORMAL_INSTALL)
@list='$(dist_gpginsttest_DATA)'; test -n "$(gpginsttestdir)" || list=; \
@ -7827,7 +7858,7 @@ install-binPROGRAMS: install-libLTLIBRARIES
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(privlibdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(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"; \
done
install: $(BUILT_SOURCES)
@ -7915,7 +7946,8 @@ info: info-recursive
info-am:
install-data-am: install-dist_gpginsttestDATA \
install-data-am: install-dist_completionsDATA \
install-dist_gpginsttestDATA \
install-dist_gpginsttest_trustedDATA \
install-dist_gpgvinsttestDATA install-dracutconfDATA \
install-dracutmodSCRIPTS install-girDATA install-gpgreadmeDATA \
@ -7981,7 +8013,7 @@ ps: ps-recursive
ps-am:
uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
uninstall-dist_gpginsttestDATA \
uninstall-dist_completionsDATA uninstall-dist_gpginsttestDATA \
uninstall-dist_gpginsttest_trustedDATA \
uninstall-dist_gpgvinsttestDATA uninstall-dracutconfDATA \
uninstall-dracutmodSCRIPTS uninstall-girDATA \
@ -8023,7 +8055,7 @@ uninstall-man: uninstall-man1 uninstall-man5
distuninstallcheck dvi dvi-am html html-am info info-am \
install install-am install-binPROGRAMS install-binSCRIPTS \
install-data install-data-am install-data-hook \
install-dist_gpginsttestDATA \
install-dist_completionsDATA install-dist_gpginsttestDATA \
install-dist_gpginsttest_trustedDATA \
install-dist_gpgvinsttestDATA install-dracutconfDATA \
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 \
recheck tags tags-am uninstall uninstall-am \
uninstall-binPROGRAMS uninstall-binSCRIPTS \
uninstall-dist_gpginsttestDATA \
uninstall-dist_completionsDATA uninstall-dist_gpginsttestDATA \
uninstall-dist_gpginsttest_trustedDATA \
uninstall-dist_gpgvinsttestDATA uninstall-dracutconfDATA \
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/ )
Some more information is available on the old wiki page:
<https://wiki.gnome.org/Projects/OSTree>
Contributing
------------

View File

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

View File

@ -14,7 +14,7 @@
<div class="titlepage">
<div>
<div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">OSTree API references</p></th></tr></table></div>
<div><p class="releaseinfo">for OSTree 2017.9</p></div>
<div><p class="releaseinfo">for OSTree 2017.10</p></div>
</div>
<hr>
</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> *
</td>
<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>
</td>
</tr>
@ -113,6 +121,14 @@
</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-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>
</td>
<td class="function_name">
@ -348,6 +364,14 @@
<span class="returnvalue">gboolean</span>
</td>
<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>
</td>
</tr>
@ -1158,6 +1182,47 @@ ostree_repo_mode_from_string (<em class="parameter"><code>const <span class="typ
</div>
<hr>
<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>
<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>
@ -1366,6 +1431,76 @@ If the repository is not writable, the <em class="parameter"><code>error</code><
</div>
<hr>
<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>
<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>,
@ -1379,6 +1514,10 @@ repository, and finish creating any necessary files in a partially
created repository. However, this function cannot change the mode
of an existing repository, and will silently ignore an attempt to
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">
<a name="ostree-repo-create.parameters"></a><h4>Parameters</h4>
<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>
<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>
<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">
<a name="ostree-repo-get-path.returns"></a><h4>Returns</h4>
<p> Path to repo. </p>
@ -2662,6 +2819,60 @@ case where we're creating or overwriting an existing ref.</p>
</div>
<hr>
<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>
<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>,
@ -7182,13 +7393,22 @@ in bytes, counting only content objects.</p></td>
<col class="enum_members_description">
<col width="200px" class="enum_members_annotations">
</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_description">
<p>No flags.</p>
</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>
</div>
</div>

View File

@ -115,6 +115,10 @@
</colgroup>
<tbody>
<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="function_name"><a class="link" href="ostree-GPG-signature-verification-results.html#OstreeGpgVerifyResult" title="OstreeGpgVerifyResult">OstreeGpgVerifyResult</a></td>
</tr>
@ -515,6 +519,46 @@ signature from trusted keyring, otherwise <code class="literal">FALSE</code></p>
<div class="refsect1">
<a name="ostree-GPG-signature-verification-results.other_details"></a><h2>Types and Values</h2>
<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>
<pre class="programlisting">typedef struct OstreeGpgVerifyResult OstreeGpgVerifyResult;
</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_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_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_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"/>
@ -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_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_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_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"/>
@ -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_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_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_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"/>
@ -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_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="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="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"/>
@ -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_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_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_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"/>
@ -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_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_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_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"/>

View File

@ -417,6 +417,10 @@ OSTREE_CHECK_VERSION, macro in ostree-version
<dd></dd>
<a name="idxG"></a><h3 class="title">G</h3>
<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>
</dt>
<dd></dd>
@ -762,6 +766,10 @@ OSTREE_RELEASE_VERSION, macro in ostree-version
</dt>
<dd></dd>
<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>
</dt>
<dd></dd>
@ -962,6 +970,10 @@ OSTREE_RELEASE_VERSION, macro in ostree-version
</dt>
<dd></dd>
<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>
</dt>
<dd></dd>
@ -1070,6 +1082,10 @@ OSTREE_RELEASE_VERSION, macro in ostree-version
</dt>
<dd></dd>
<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>
</dt>
<dd></dd>

View File

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

View File

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

View File

@ -1 +1 @@
2017.9
2017.10

View File

@ -28,7 +28,6 @@ else
gtkdocize
fi
cd $olddir
if ! test -f libglnx/README.md || ! test -f bsdiff/README.md; then
git submodule update --init
fi
@ -41,4 +40,5 @@ ln -sf ../libglnx/libglnx.m4 buildutil/libglnx.m4
autoreconf --force --install --verbose
cd $olddir
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. */
/* Define if we are building with -fsanitize=address */
#undef BUILDOPT_ASAN
/* Define if we are enabling ostree trivial-httpd entrypoint */
#undef BUILDOPT_ENABLE_TRIVIAL_HTTPD_CMDLINE
@ -9,6 +12,9 @@
/* Define if systemd 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 */
#undef DISABLE_OTMPFILE

92
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh
# 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>.
#
@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='libostree'
PACKAGE_TARNAME='libostree'
PACKAGE_VERSION='2017.9'
PACKAGE_STRING='libostree 2017.9'
PACKAGE_VERSION='2017.10'
PACKAGE_STRING='libostree 2017.10'
PACKAGE_BUGREPORT='walters@verbum.org'
PACKAGE_URL=''
@ -764,6 +764,7 @@ GOBJECT_QUERY
GLIB_GENMARSHAL
GLIB_LIBS
GLIB_CFLAGS
BASH_COMPLETIONSDIR
PKG_CONFIG_LIBDIR
PKG_CONFIG_PATH
PKG_CONFIG
@ -804,6 +805,8 @@ build_vendor
build_cpu
build
LIBTOOL
BUILDOPT_TSAN_FALSE
BUILDOPT_TSAN_TRUE
BUILDOPT_ASAN_FALSE
BUILDOPT_ASAN_TRUE
WARN_CFLAGS
@ -963,6 +966,7 @@ LT_SYS_LIBRARY_PATH
PKG_CONFIG
PKG_CONFIG_PATH
PKG_CONFIG_LIBDIR
BASH_COMPLETIONSDIR
OT_DEP_GIO_UNIX_CFLAGS
OT_DEP_GIO_UNIX_LIBS
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.
# This message is too long to be a string in the A/UX 3.1 sh.
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]...
@ -1603,7 +1607,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of libostree 2017.9:";;
short | recursive ) echo "Configuration of libostree 2017.10:";;
esac
cat <<\_ACEOF
@ -1712,6 +1716,9 @@ Some influential environment variables:
directories to add to pkg-config's search path
PKG_CONFIG_LIBDIR
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
C compiler flags for OT_DEP_GIO_UNIX, overriding pkg-config
OT_DEP_GIO_UNIX_LIBS
@ -1839,7 +1846,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
libostree configure 2017.9
libostree configure 2017.10
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@ -2254,7 +2261,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by libostree $as_me 2017.9, which was
It was created by libostree $as_me 2017.10, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@ -3122,7 +3129,7 @@ fi
# Define the identity of the package.
PACKAGE='libostree'
VERSION='2017.9'
VERSION='2017.10'
# Some tools Automake needs.
@ -5856,9 +5863,9 @@ test -n "$YACC" || YACC="yacc"
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 :
@ -5937,6 +5944,35 @@ else
BUILDOPT_ASAN_FALSE=
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
@ -13878,6 +13914,34 @@ $as_echo "no" >&6; }
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.
if test "${enable_glibtest+set}" = set; then :
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.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
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
as_fn_error $? "conditional \"ENABLE_INSTALLED_TESTS\" was never defined.
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
# values after options handling.
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
CONFIG_FILES = $CONFIG_FILES
@ -18027,7 +18095,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
libostree config.status 2017.9
libostree config.status 2017.10
configured by $0, generated by GNU Autoconf 2.69,
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 another post-release commit to bump the version, and set is_release_build=no.
m4_define([year_version], [2017])
m4_define([release_version], [9])
m4_define([release_version], [10])
m4_define([package_version], [year_version.release_version])
AC_INIT([libostree], [package_version], [walters@verbum.org])
is_release_build=yes
@ -58,6 +58,19 @@ else
AC_MSG_RESULT([no])
fi
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
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_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]))
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 ncolumns = glnx_console_columns ();
const guint bar_min = 10;
const guint input_textlen = text ? strlen (text) : 0;
if (text && !*text)
text = NULL;
const guint input_textlen = text ? strlen (text) : 0;
if (percentage == current_percent
&& g_strcmp0 (text, current_text) == 0)
return;
@ -221,6 +222,7 @@ text_percent_internal (const char *text,
if (percentage == -1)
{
if (text != NULL)
fwrite (text, 1, input_textlen, stdout);
/* Overwrite remaining space, if any */
@ -273,7 +275,7 @@ void
glnx_console_progress_text_percent (const char *text,
guint percentage)
{
g_return_if_fail (percentage >= 0 && percentage <= 100);
g_return_if_fail (percentage <= 100);
text_percent_internal (text, percentage);
}

View File

@ -83,7 +83,7 @@ typedef struct GLnxRealDirfdIterator GLnxRealDirfdIterator;
/**
* glnx_dirfd_iterator_init_at:
* @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
* @out_dfd_iter: (out caller-allocates): A directory iterator, will be initialized
* @error: Error

View File

@ -31,9 +31,6 @@
#include <sys/ioctl.h>
#include <sys/sendfile.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-dirfd.h>
@ -43,6 +40,11 @@
#include <glnx-local-alloc.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
* specified type as a decimal string. Adds in extra space for a
* 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.
*/
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
* occurs.
*
@ -703,8 +698,10 @@ glnx_loop_write(int fd, const void *buf, size_t nbytes)
return 0;
}
/* Read from @fdf until EOF, writing to @fdt. If @try_reflink is %TRUE,
* attempt to use any "reflink" functionality; see e.g. https://lwn.net/Articles/331808/
/* Read from @fdf until EOF, writing to @fdt. If max_bytes is -1, a full-file
* 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.
*
@ -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.
*/
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;
int r;
/* Last updates from systemd as of commit 6bda23dd6aaba50cf8e3e6024248cf736cc443ca */
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 (fdt >= 0, -1);
g_return_val_if_fail (max_bytes >= -1, -1);
/* Try btrfs reflinks first. */
if (try_reflink && max_bytes == (off_t) -1)
/* If we've requested to copy the whole range, try a full-file clone first.
*/
if (max_bytes == (off_t) -1)
{
r = btrfs_reflink(fdf, fdt);
if (r >= 0)
if (ioctl (fdt, FICLONE, fdf) == 0)
return 0;
/* 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)
{
size_t m = COPY_BUFFER_SIZE;
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)
m = (size_t) max_bytes;
}
/* First try sendfile(), unless we already tried */
if (try_sendfile)
{
n = sendfile (fdt, fdf, NULL, m);
n = copy_file_range (fdf, NULL, fdt, NULL, max_bytes, 0u);
if (n < 0)
{
if (errno != EINVAL && errno != ENOSYS)
return -1;
try_sendfile = false;
/* use fallback below */
if (errno == ENOSYS)
{
/* No cfr in kernel, mark as permanently unavailable
* and fall through to sendfile().
*/
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;
else if (n > 0)
/* Succcess! */
goto next;
}
}
/* 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)
return -1;
if (n == 0) /* EOF */
@ -776,7 +838,7 @@ glnx_regfile_copy_bytes (int fdf, int fdt, off_t max_bytes, gboolean try_reflink
next:
if (max_bytes != (off_t) -1)
{
g_assert(max_bytes >= n);
g_assert_cmpint (max_bytes, >=, n);
max_bytes -= n;
if (max_bytes == 0)
break;
@ -867,7 +929,7 @@ glnx_file_copy_at (int src_dfd,
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)
{
glnx_set_error_from_errno (error);

View File

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

View File

@ -25,30 +25,6 @@
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:
*
@ -57,141 +33,14 @@ GLNX_DEFINE_CLEANUP_FUNCTION(void*, glnx_local_free, g_free)
* %NULL.
*/
#define glnx_unref_object __attribute__ ((cleanup(glnx_local_obj_unref)))
#ifdef GLNX_GSYSTEM_COMPAT
#define gs_unref_object __attribute__ ((cleanup(glnx_local_obj_unref)))
#endif
GLNX_DEFINE_CLEANUP_FUNCTION0(GObject*, glnx_local_obj_unref, g_object_unref)
/**
* glnx_unref_variant:
*
* 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
glnx_local_obj_unref (void *v)
{
GObject *o = *(GObject **)v;
if (o)
g_object_unref (o);
}
#define glnx_unref_object __attribute__ ((cleanup(glnx_local_obj_unref)))
static inline void
glnx_cleanup_close_fdp (int *fdp)
@ -204,7 +53,8 @@ glnx_cleanup_close_fdp (int *fdp)
if (fd >= 0)
{
errsv = errno;
(void) close (fd);
if (close (fd) < 0)
g_assert (errno != EBADF);
errno = errsv;
}
}

View File

@ -52,3 +52,44 @@ static inline int renameat2(int oldfd, const char *oldname, int newfd, const cha
# 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;
ssize_t bytes_read, real_size;
glnx_free char *xattr_names = NULL;
glnx_free char *xattr_names_canonical = NULL;
g_autofree char *xattr_names = NULL;
g_autofree char *xattr_names_canonical = NULL;
GVariantBuilder builder;
gboolean builder_initialized = FALSE;
g_autoptr(GVariant) ret_xattrs = NULL;

View File

@ -78,7 +78,7 @@ Boston, MA 02111-1307, USA.
<listitem><para>
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.
</para></listitem>
</varlistentry>
@ -132,12 +132,15 @@ Boston, MA 02111-1307, USA.
This command can retrieve just a specific commit, or go all
the way to performing a full mirror of the remote
repository. If no <literal>BRANCH</literal> is specified,
all branches are retrieved.
all configured branches are retrieved.
</para>
<para>
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>
</refsect1>

View File

@ -51,13 +51,17 @@ Boston, MA 02111-1307, USA.
<cmdsynopsis>
<command>ostree refs</command> <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt">PREFIX</arg>
</cmdsynopsis>
<cmdsynopsis>
<command>ostree refs</command> <arg choice="req">EXISTING</arg> <arg choice="req">--create=NEWREF</arg>
</cmdsynopsis>
</refsynopsisdiv>
<!-- Could this be more specific? What defines a "ref"? etc -->
<refsect1>
<title>Description</title>
<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>
</refsect1>
@ -75,6 +79,16 @@ Boston, MA 02111-1307, USA.
printed in full, rather than
truncated. </para></listitem>
</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>
<term><option>--delete</option></term>
@ -85,7 +99,15 @@ Boston, MA 02111-1307, USA.
</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>
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>
<para>When deleting refs, all refs whose collection ID equals
the value of the <option>--delete</option> argument are
deleted.
PREFIX are deleted.
</para></listitem>
</varlistentry>
</variablelist>

View File

@ -96,6 +96,13 @@ Boston, MA 02111-1307, USA.
<para>
Changes remote repository configurations. The NAME refers to the name of the remote.
</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>
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>

View File

@ -90,6 +90,8 @@ Boston, MA 02111-1307, USA.
<listitem><para>
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>
</varlistentry>

View File

@ -114,6 +114,14 @@ Boston, MA 02111-1307, USA.
</para>
</listitem>
</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>
</refsect1>
@ -139,6 +147,13 @@ Boston, MA 02111-1307, USA.
metadata: summary, static delta "superblocks".</para></listitem>
</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>
<term><varname>proxy</varname></term>
<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>
</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>
</refsect1>

View File

@ -18,8 +18,6 @@
***/
/* 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
* 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_pull_from_remotes_async;
ostree_repo_pull_from_remotes_finish;
ostree_repo_remote_list_collection_refs;
ostree_repo_resolve_keyring_for_collection;
ostree_repo_set_collection_id;
ostree_repo_set_collection_ref_immediate;

View File

@ -416,6 +416,17 @@ global:
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
* comments at the top of this file.
*/

View File

@ -38,9 +38,19 @@
* among others.
*/
#if defined(__i386__) || defined(__x86_64__)
#define GRUB2_USES_16 1
#define GRUB2_SUFFIX "16"
#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
struct _OstreeBootloaderGrub2
@ -214,16 +224,12 @@ _ostree_bootloader_grub2_generate_config (OstreeSysroot *sysroot
"No \"linux\" key in bootloader config");
goto out;
}
if (is_efi)
g_string_append (output, "linuxefi ");
else
{
#if GRUB2_USES_16
g_string_append (output, "linux16 ");
#else
g_string_append (output, "linux");
#endif
}
if (is_efi)
g_string_append (output, GRUB2_EFI_SUFFIX);
else
g_string_append (output, GRUB2_SUFFIX);
g_string_append_c (output, ' ');
g_string_append (output, kernel);
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");
if (initrd)
{
if (is_efi)
g_string_append (output, "initrdefi ");
else
{
#if GRUB2_USES_16
g_string_append (output, "initrd16 ");
#else
g_string_append (output, "initrd");
#endif
}
if (is_efi)
g_string_append (output, GRUB2_EFI_SUFFIX);
else
g_string_append (output, GRUB2_SUFFIX);
g_string_append_c (output, ' ');
g_string_append (output, initrd);
g_string_append_c (output, '\n');
}

View File

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

View File

@ -20,8 +20,9 @@
#include "config.h"
#include "otutil.h"
#include "ostree.h"
#include "ostree-deployment-private.h"
#include "libglnx.h"
typedef GObjectClass OstreeDeploymentClass;
@ -138,7 +139,7 @@ _ostree_deployment_set_bootcsum (OstreeDeployment *self,
OstreeDeployment *
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,
self->deployserial,
self->bootcsum, self->bootserial);
@ -187,7 +188,7 @@ ostree_deployment_equal (gconstpointer ap, gconstpointer bp)
OstreeDeployment *a = (OstreeDeployment*)ap;
OstreeDeployment *b = (OstreeDeployment*)bp;
if (a == NULL && b == NULL)
if (a == b)
return TRUE;
else if (a != NULL && b != NULL)
return g_str_equal (ostree_deployment_get_osname (a),

View File

@ -425,11 +425,9 @@ static gboolean
timer_cb (gpointer data)
{
OstreeFetcher *fetcher = data;
CURLMcode rc;
GSource *orig_src = fetcher->timer_event;
rc = curl_multi_socket_action (fetcher->multi, CURL_SOCKET_TIMEOUT, 0, &fetcher->curl_running);
g_assert (rc == CURLM_OK);
(void)curl_multi_socket_action (fetcher->multi, CURL_SOCKET_TIMEOUT, 0, &fetcher->curl_running);
check_multi_info (fetcher);
if (fetcher->timer_event == orig_src)
fetcher->timer_event = NULL;
@ -460,15 +458,12 @@ static gboolean
event_cb (int fd, GIOCondition condition, gpointer data)
{
OstreeFetcher *fetcher = data;
CURLMcode rc;
int action =
(condition & G_IO_IN ? CURL_CSELECT_IN : 0) |
(condition & G_IO_OUT ? CURL_CSELECT_OUT : 0);
rc = curl_multi_socket_action (fetcher->multi, fd, action, &fetcher->curl_running);
g_assert (rc == CURLM_OK);
(void)curl_multi_socket_action (fetcher->multi, fd, action, &fetcher->curl_running);
check_multi_info (fetcher);
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_path = cert_and_key_path;
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
* session thread so it uses the correct GMainContext. */

View File

@ -40,6 +40,7 @@ struct OstreeGpgVerifier {
GObject parent;
GList *keyrings;
GPtrArray *keyring_data;
GPtrArray *key_ascii_files;
};
@ -53,6 +54,7 @@ ostree_gpg_verifier_finalize (GObject *object)
g_list_free_full (self->keyrings, g_object_unref);
if (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);
}
@ -71,6 +73,7 @@ _ostree_gpg_verifier_class_init (OstreeGpgVerifierClass *klass)
static void
_ostree_gpg_verifier_init (OstreeGpgVerifier *self)
{
self->keyring_data = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref);
}
static void
@ -95,8 +98,8 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
{
GLNX_AUTO_PREFIX_ERROR("GPG", error);
gpgme_error_t gpg_error = 0;
ot_auto_gpgme_data gpgme_data_t data_buffer = NULL;
ot_auto_gpgme_data gpgme_data_t signature_buffer = NULL;
g_auto(gpgme_data_t) data_buffer = NULL;
g_auto(gpgme_data_t) signature_buffer = NULL;
g_autofree char *tmp_dir = NULL;
g_autoptr(GOutputStream) target_stream = NULL;
OstreeGpgVerifyResult *result = NULL;
@ -151,6 +154,17 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
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))
goto out;
@ -165,7 +179,7 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
{
const char *path = self->key_ascii_files->pdata[i];
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))
goto out;
@ -253,8 +267,11 @@ out:
return result;
}
/* Given @path which should contain a GPG keyring file, add it
* to the list of trusted keys.
*/
void
_ostree_gpg_verifier_add_keyring (OstreeGpgVerifier *self,
_ostree_gpg_verifier_add_keyring_file (OstreeGpgVerifier *self,
GFile *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));
}
/* 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
_ostree_gpg_verifier_add_key_ascii_file (OstreeGpgVerifier *self,
const char *path)
@ -276,32 +303,39 @@ _ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self,
GFile *path,
GCancellable *cancellable,
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);
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)
{
GFileInfo *file_info;
GFile *path;
const char *name;
struct dirent *dent;
if (!g_file_enumerator_iterate (enumerator, &file_info, &path,
cancellable, error))
goto out;
if (file_info == NULL)
if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
return FALSE;
if (dent == NULL)
break;
if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_REGULAR)
if (dent->d_type != DT_REG)
continue;
name = g_file_info_get_name (file_info);
const char *name = dent->d_name;
/* Files with a .gpg suffix are typically keyrings except
* 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"))
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;
out:
return ret;
return TRUE;
}
gboolean

View File

@ -55,11 +55,19 @@ gboolean _ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self,
GCancellable *cancellable,
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,
GCancellable *cancellable,
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);
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,
guint *out_signature_index)
{
g_autofree char *key_id_upper = NULL;
g_auto(gpgme_key_t) lookup_key = NULL;
gpgme_signature_t signature;
guint signature_index;
gboolean ret = FALSE;
g_return_val_if_fail (OSTREE_IS_GPG_VERIFY_RESULT (result), FALSE);
g_return_val_if_fail (key_id != NULL, FALSE);
/* signature->fpr is always upper-case. */
key_id_upper = g_ascii_strup (key_id, -1);
/* fetch requested key_id from keyring to canonicalise ID */
(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;
signature != NULL;
signature = signature->next, signature_index++)
{
if (signature->fpr == NULL)
continue;
g_auto(gpgme_key_t) signature_key = NULL;
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)
*out_signature_index = signature_index;
ret = TRUE;
break;
}
/* Note early return */
return TRUE;
}
return ret;
}
return FALSE;
}
/**
@ -291,7 +306,7 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result,
guint n_attrs)
{
GVariantBuilder builder;
gpgme_key_t key = NULL;
g_auto(gpgme_key_t) key = NULL;
gpgme_signature_t signature;
guint ii;
@ -313,7 +328,8 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result,
* (OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING). */
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)
{
(void) gpgme_get_key (result->context, signature->fpr, &key, 0);
@ -357,7 +373,11 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result,
break;
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;
case OSTREE_GPG_SIGNATURE_ATTR_TIMESTAMP:
@ -407,9 +427,6 @@ ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result,
g_variant_builder_add_value (&builder, child);
}
if (key != NULL)
gpgme_key_unref (key);
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)
{
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");
return FALSE;
}
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,
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

View File

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

View File

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

View File

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

View File

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

View File

@ -46,7 +46,7 @@ checkout_state_clear (CheckoutState *state)
if (state->selabel_path_buf)
g_string_free (state->selabel_path_buf, TRUE);
}
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(CheckoutState, checkout_state_clear);
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(CheckoutState, checkout_state_clear)
static gboolean
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);
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");
}
else

View File

@ -27,16 +27,16 @@
#include <gio/gfiledescriptorbased.h>
#include <gio/gunixinputstream.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-repo-private.h"
#include "ostree-repo-file-enumerator.h"
#include "ostree-checksum-input-stream.h"
#include "ostree-mutable-tree.h"
#include "ostree-varint.h"
#include <sys/xattr.h>
#include <glib/gprintf.h>
gboolean
_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))
{
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");
}
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);
if (bytes_read < 0)
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)
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)
return glnx_throw_errno_prefix (error, "write");
remaining -= bytes_read;
@ -1448,7 +1446,31 @@ ostree_repo_set_ref_immediate (OstreeRepo *self,
GError **error)
{
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);
}
@ -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 (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);
}
@ -2528,7 +2550,7 @@ write_directory_content_to_mtree_internal (OstreeRepo *self,
{
g_autoptr(GFile) child = 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;
const char *name;
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
* @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
fetch_summary_from_remote (OstreeRepo *repo,
OstreeRemote *remote,
@ -648,6 +649,13 @@ get_checksums (OstreeRepoFinderAvahi *finder,
error))
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);
}
@ -816,9 +824,10 @@ ostree_avahi_service_build_repo_finder_result (OstreeAvahiService
g_clear_pointer (&remote->keyring, g_free);
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_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);
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),
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++)
{
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;
g_autofree gchar *remote_collection_id = NULL;
gboolean resolved_a_ref = FALSE;
remote_name = remotes[i];
@ -127,8 +128,9 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find
continue;
}
if (!ostree_repo_remote_list_refs (parent_repo, remote_name, &remote_refs,
cancellable, &local_error))
if (!ostree_repo_remote_list_collection_refs (parent_repo, remote_name,
&remote_refs, cancellable,
&local_error))
{
g_debug ("Ignoring remote %s due to error loading its refs: %s",
remote_name, local_error->message);
@ -139,13 +141,14 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find
for (j = 0; refs[j] != NULL; j++)
{
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 remote to the results, and the ref to its
* @supported_ref_to_checksum. */
g_debug ("Resolved ref (%s, %s) to remote %s.",
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);
@ -161,6 +164,9 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find
(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. */

View File

@ -31,6 +31,7 @@
#include "ostree-autocleanups.h"
#include "ostree-remote-private.h"
#include "ostree-repo-private.h"
#include "ostree-repo-finder.h"
#include "ostree-repo-finder-mount.h"
@ -257,19 +258,16 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde
{
struct stat stbuf;
g_autofree gchar *collection_and_ref = NULL;
g_autofree gchar *repo_dir_path = NULL;
g_autofree gchar *resolved_repo_uri = NULL;
g_autofree gchar *keyring = NULL;
g_autoptr(UriAndKeyring) resolved_repo = 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))
{
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);
continue;
}
@ -277,7 +275,7 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde
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.",
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);
continue;
}
@ -294,27 +292,19 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde
}
/* Exclude repositories which resolve to @parent_repo. */
g_autofree char *canonical_repo_dir_path = realpath (repo_dir_path, NULL);
g_autofree gchar *parent_repo_path = g_file_get_path (ostree_repo_get_path (parent_repo));
g_autofree char *canonical_parent_repo_path = realpath (parent_repo_path, NULL);
if (g_strcmp0 (canonical_repo_dir_path, canonical_parent_repo_path) == 0)
if (stbuf.st_dev == parent_repo->device &&
stbuf.st_ino == parent_repo->inode)
{
g_debug ("Ignoring ref (%s, %s) on mount %s as its repository was the one we are resolving for: %s",
refs[i]->collection_id, refs[i]->ref_name, mount_name, canonical_parent_repo_path);
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);
g_clear_error (&local_error);
continue;
}
/* Grab the given ref and a checksum for it from the repo.
* FIXME: Ideally, there would be some ostree_repo_open_at() which we
* could use to keep the openat() chain going. See
* https://github.com/ostreedev/ostree/pull/820. */
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))
/* Grab the given ref and a checksum for it from the repo, if it appears to be a valid repo */
g_autoptr(OstreeRepo) repo = ostree_repo_open_at (repos_dfd, collection_and_ref,
cancellable, &local_error);
if (!repo)
{
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);
@ -358,6 +348,11 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde
* $mount_root/.ostree/repos/$refs[i]->collection_id/$refs[i]->ref_name.
* Add it to the results, keyed by the canonicalised repository URI
* 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);
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);
@ -392,9 +387,10 @@ ostree_repo_finder_mount_resolve_async (OstreeRepoFinder *finde
g_clear_pointer (&remote->keyring, g_free);
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_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
* 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_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);
ostree_remote_unref (result->remote);
g_free (result);

View File

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

View File

@ -21,10 +21,10 @@
#pragma once
#include <sys/statvfs.h>
#include "otutil.h"
#include "ostree-ref.h"
#include "ostree-repo.h"
#include "ostree-remote-private.h"
#include "otutil.h"
G_BEGIN_DECLS
@ -96,7 +96,11 @@ struct OstreeRepo {
char *commit_stagedir_name;
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 tmp_dir_fd;
int cache_dir_fd;
@ -132,10 +136,13 @@ struct OstreeRepo {
GHashTable *updated_uncompressed_dirs;
GHashTable *object_sizes;
uid_t owner_uid;
uid_t target_owner_uid;
/* Cache the repo's device/inode to use for comparisons elsewhere */
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;
guint min_free_space_percent;
guint min_free_space_percent; /* See the min-free-space-percent config option */
guint test_error_flags; /* OstreeRepoTestErrorFlags */
@ -173,7 +180,7 @@ _ostree_repo_memory_cache_ref_init (OstreeRepoMemoryCacheRef *state,
void
_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_FETCHER "fetcher-"
@ -265,6 +272,7 @@ _ostree_repo_write_ref (OstreeRepo *self,
const char *remote,
const OstreeCollectionRef *ref,
const char *rev,
const char *alias,
GCancellable *cancellable,
GError **error);

View File

@ -50,10 +50,21 @@
#include <gio/gunixinputstream.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_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 {
OstreeRepo *repo;
int tmpdir_dfd;
@ -61,6 +72,8 @@ typedef struct {
char *remote_name;
OstreeRepoMode remote_mode;
OstreeFetcher *fetcher;
OstreeFetcherSecurityState fetcher_security_state;
GPtrArray *meta_mirrorlist; /* List of base URIs for fetching metadata */
GPtrArray *content_mirrorlist; /* List of base URIs for fetching content */
OstreeRepo *remote_repo_local;
@ -1405,12 +1418,12 @@ gpg_verify_unwritten_commit (OtPullData *pull_data,
{
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);
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",
checksum);
return FALSE;
@ -1611,7 +1624,7 @@ scan_commit_object (OtPullData *pull_data,
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,
checksum,
@ -1777,6 +1790,7 @@ scan_one_metadata_object_c (OtPullData *pull_data,
{
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;
}
@ -1806,6 +1820,12 @@ scan_one_metadata_object_c (OtPullData *pull_data,
return FALSE;
if (!localcache_repo_has_obj)
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,
objtype, tmp_checksum,
!pull_data->is_untrusted,
@ -2450,7 +2470,7 @@ on_superblock_fetched (GObject *src,
*/
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)");
goto out;
}
@ -2612,11 +2632,13 @@ static OstreeFetcher *
_ostree_repo_remote_new_fetcher (OstreeRepo *self,
const char *remote_name,
gboolean gzip,
OstreeFetcherSecurityState *out_state,
GError **error)
{
OstreeFetcher *fetcher = NULL;
OstreeFetcherConfigFlags fetcher_flags = 0;
gboolean tls_permissive = FALSE;
OstreeFetcherSecurityState ret_state = OSTREE_FETCHER_SECURITY_STATE_TLS;
gboolean success = FALSE;
g_return_val_if_fail (OSTREE_IS_REPO (self), NULL);
@ -2628,7 +2650,10 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self,
goto out;
if (tls_permissive)
{
fetcher_flags |= OSTREE_FETCHER_FLAGS_TLS_PERMISSIVE;
ret_state = OSTREE_FETCHER_SECURITY_STATE_INSECURE;
}
if (gzip)
fetcher_flags |= OSTREE_FETCHER_FLAGS_TRANSFER_GZIP;
@ -2673,6 +2698,10 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self,
if (tls_ca_path != NULL)
{
_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:
if (!success)
g_clear_object (&fetcher);
if (out_state)
*out_state = ret_state;
return fetcher;
}
@ -2724,7 +2755,7 @@ _ostree_preload_metadata_file (OstreeRepo *self,
if (is_metalink)
{
glnx_unref_object OstreeMetalink *metalink = NULL;
g_autoptr(OstreeMetalink) metalink = NULL;
GError *local_error = NULL;
/* 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,
GError **error)
{
glnx_unref_object OstreeFetcher *fetcher = NULL;
g_autoptr(OstreeFetcher) fetcher = NULL;
g_autoptr(GMainContext) mainctx = NULL;
gboolean ret = FALSE;
gboolean from_cache = FALSE;
@ -2891,7 +2922,7 @@ repo_remote_fetch_summary (OstreeRepo *self,
mainctx = g_main_context_new ();
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)
goto out;
@ -3001,10 +3032,13 @@ repo_remote_fetch_summary (OstreeRepo *self,
* any options specific to this pull (such as extra headers).
*/
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);
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)
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) commits_to_fetch = 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 = &pull_data_real;
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) */
int i;
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)
{
@ -3239,6 +3277,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
(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 (!opt_collection_refs_set ||
(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)
{
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)");
goto out;
}
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");
goto out;
}
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)");
goto out;
}
@ -3892,6 +3931,15 @@ ostree_repo_pull_with_options (OstreeRepo *self,
g_hash_table_unref (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,
* 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);
}
#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 */
if (pull_data->dirs == NULL && !pull_data->is_commit_only)
{
@ -4730,6 +4841,14 @@ find_remotes_cb (GObject *obj,
g_clear_error (&error);
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
* all the @refs we are interested in. */
@ -4836,7 +4955,7 @@ find_remotes_cb (GObject *obj,
goto error;
fetcher = _ostree_repo_remote_new_fetcher (self, result->remote->name,
TRUE, &error);
TRUE, NULL, &error);
if (fetcher == NULL)
goto error;
@ -4857,7 +4976,7 @@ find_remotes_cb (GObject *obj,
&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,
commit_metadata->checksum,
@ -4974,7 +5093,7 @@ find_remotes_cb (GObject *obj,
{
OstreeRepoFinderResult *result = g_ptr_array_index (results, i);
g_autoptr(GHashTable) validated_ref_to_checksum = NULL; /* (element-type utf8 utf8) */
gsize j;
gsize j, n_latest_refs;
/* Previous error processing this result? */
if (result == NULL)
@ -4986,6 +5105,7 @@ find_remotes_cb (GObject *obj,
ostree_collection_ref_equal,
(GDestroyNotify) ostree_collection_ref_free,
g_free);
n_latest_refs = 0;
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)
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));
}
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_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_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-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);
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"));
@ -5497,7 +5619,7 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self,
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)");
goto out;
}
@ -5505,7 +5627,7 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self,
/* Verify any summary signatures. */
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,
name,
@ -5540,7 +5662,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
GError **error)
{
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;
}
@ -5554,7 +5676,7 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self,
GError **error)
{
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;
}

View File

@ -472,6 +472,7 @@ ostree_repo_resolve_rev_ext (OstreeRepo *self,
static gboolean
enumerate_refs_recurse (OstreeRepo *repo,
const char *remote,
OstreeRepoListRefsExtFlags flags,
const char *collection_id,
int base_dfd,
GString *base_path,
@ -482,6 +483,7 @@ enumerate_refs_recurse (OstreeRepo *repo,
GError **error)
{
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))
return FALSE;
@ -502,17 +504,31 @@ enumerate_refs_recurse (OstreeRepo *repo,
{
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,
refs, cancellable, error))
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,
cancellable, error))
return FALSE;
}
}
g_string_truncate (base_path, len);
}
@ -523,6 +539,7 @@ enumerate_refs_recurse (OstreeRepo *repo,
static gboolean
_ostree_repo_list_refs_internal (OstreeRepo *self,
gboolean cut_prefix,
OstreeRepoListRefsExtFlags flags,
const char *refspec_prefix,
GHashTable **out_all_refs,
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))
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,
ret_all_refs, cancellable, error))
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))
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, ".",
ret_all_refs, cancellable, error))
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))
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, ".",
ret_all_refs,
cancellable, error))
@ -655,7 +672,10 @@ ostree_repo_list_refs (OstreeRepo *self,
GCancellable *cancellable,
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,
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;
}
#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
_ostree_repo_write_ref (OstreeRepo *self,
const char *remote,
const OstreeCollectionRef *ref,
const char *rev,
const char *alias,
GCancellable *cancellable,
GError **error)
{
glnx_fd_close int dfd = -1;
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))
return FALSE;
@ -832,7 +1000,7 @@ _ostree_repo_write_ref (OstreeRepo *self,
return glnx_throw_errno_prefix (error, "Opening remotes/ dir %s", remote);
}
if (rev == NULL)
if (rev == NULL && alias == NULL)
{
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))
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))
return FALSE;
@ -876,7 +1065,7 @@ _ostree_repo_update_refs (OstreeRepo *self,
return FALSE;
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))
return FALSE;
}
@ -899,7 +1088,7 @@ _ostree_repo_update_collection_refs (OstreeRepo *self,
const OstreeCollectionRef *ref = key;
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))
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))
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, ".",
ret_all_refs, cancellable, error))
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))
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, ".",
ret_all_refs,
cancellable, error))

View File

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

View File

@ -456,6 +456,7 @@ ostree_repo_finalize (GObject *object)
g_clear_object (&self->parent_repo);
g_free (self->stagedir_prefix);
g_clear_object (&self->repodir_fdrel);
g_clear_object (&self->repodir);
if (self->repo_dir_fd != -1)
(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
ostree_repo_class_init (OstreeRepoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = ostree_repo_constructed;
object_class->get_property = ostree_repo_get_property;
object_class->set_property = ostree_repo_set_property;
object_class->finalize = ostree_repo_finalize;
@ -581,6 +571,7 @@ ostree_repo_class_init (OstreeRepoClass *klass)
"",
G_TYPE_FILE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class,
PROP_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);
}
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 *
get_default_repo_path (GFile *sysroot_path)
{
@ -744,9 +772,17 @@ ostree_repo_is_system (OstreeRepo *repo)
if (!repo->sysroot_dir)
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);
return g_file_equal (repo->repodir, default_repo_path);
}
/* Otherwise, not a system repo */
return FALSE;
}
/**
* ostree_repo_is_writable:
@ -1331,9 +1367,9 @@ ostree_repo_remote_gpg_import (OstreeRepo *self,
GError **error)
{
OstreeRemote *remote;
ot_auto_gpgme_ctx gpgme_ctx_t source_context = NULL;
ot_auto_gpgme_ctx gpgme_ctx_t target_context = NULL;
ot_auto_gpgme_data gpgme_data_t data_buffer = NULL;
g_auto(gpgme_ctx_t) source_context = NULL;
g_auto(gpgme_ctx_t) target_context = NULL;
g_auto(gpgme_data_t) data_buffer = NULL;
gpgme_import_result_t import_result;
gpgme_import_status_t import_status;
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" \
"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:
* @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
* 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
ostree_repo_create (OstreeRepo *self,
@ -1693,76 +1832,64 @@ ostree_repo_create (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
g_return_val_if_fail (self->repodir, FALSE);
const char *repopath = gs_file_get_path_cached (self->repodir);
glnx_fd_close int dfd = -1;
struct stat stbuf;
const char *state_dirs[] = { "objects", "tmp", "extensions", "state",
"refs", "refs/heads", "refs/mirrors",
"refs/remotes" };
g_autoptr(GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
if (self->collection_id)
g_variant_builder_add (builder, "{s@v}", "collection-id",
g_variant_new_variant (g_variant_new_string (self->collection_id)));
if (mkdir (repopath, 0755) != 0)
{
if (G_UNLIKELY (errno != EEXIST))
return glnx_throw_errno (error);
}
if (!glnx_opendirat (AT_FDCWD, repopath, TRUE, &dfd, error))
glnx_fd_close int repo_dir_fd = -1;
if (!repo_create_at_internal (AT_FDCWD, repopath, mode,
g_variant_builder_end (builder),
&repo_dir_fd,
cancellable, error))
return FALSE;
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;
}
self->repo_dir_fd = glnx_steal_fd (&repo_dir_fd);
if (!ostree_repo_open (self, cancellable, error))
return FALSE;
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
enumerate_directory_allow_noent (GFile *dirpath,
const char *queryargs,
@ -2132,7 +2259,6 @@ ostree_repo_open (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
struct stat self_stbuf;
struct stat stbuf;
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);
}
if (self->repo_dir_fd == -1)
{
g_assert (self->repodir);
if (!glnx_opendirat (AT_FDCWD, gs_file_get_path_cached (self->repodir), TRUE,
&self->repo_dir_fd, error))
{
g_prefix_error (error, "%s: ", gs_file_get_path_cached (self->repodir));
return FALSE;
}
}
if (!glnx_fstat (self->repo_dir_fd, &self_stbuf, error))
if (!glnx_fstat (self->repo_dir_fd, &stbuf, error))
return FALSE;
self->device = stbuf.st_dev;
self->inode = stbuf.st_ino;
if (!glnx_opendirat (self->repo_dir_fd, "objects", TRUE,
&self->objects_dir_fd, error))
{
g_prefix_error (error, "Opening objects/ directory: ");
return FALSE;
}
self->writable = faccessat (self->objects_dir_fd, ".", W_OK, 0) == 0;
if (!self->writable)
@ -2238,8 +2367,8 @@ ostree_repo_open (OstreeRepo *self,
if (fstatat (AT_FDCWD, "/ostree/repo", &system_stbuf, 0) == 0)
{
/* Are we the same as /ostree/repo? */
if (self_stbuf.st_dev == system_stbuf.st_dev &&
self_stbuf.st_ino == system_stbuf.st_ino)
if (self->device == system_stbuf.st_dev &&
self->inode == system_stbuf.st_ino)
self->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_IS_SYSROOT_OSTREE;
else
self->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_NO;
@ -2349,14 +2478,24 @@ _ostree_repo_file_replace_contents (OstreeRepo *self,
/**
* 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
*/
GFile *
ostree_repo_get_path (OstreeRepo *self)
{
/* Did we have an abspath? Return it */
if (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.
* We want to avoid storing duplicate signatures in the metadata. */
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,
NULL, NULL, NULL,
cancellable, &local_error);
if (!result)
{
/* "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);
}
@ -4202,31 +4341,52 @@ ostree_repo_add_gpg_signature_summary (OstreeRepo *self,
/* Special remote for _ostree_repo_gpg_verify_with_metadata() */
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,
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);
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))
return g_steal_pointer (&file2);
if (!ot_openat_ignore_enoent (AT_FDCWD, gs_file_get_path_cached (child), &fd, error))
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)
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 *
@ -4239,7 +4399,7 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
glnx_unref_object OstreeGpgVerifier *verifier = NULL;
g_autoptr(OstreeGpgVerifier) verifier = NULL;
gboolean add_global_keyring_dir = TRUE;
verifier = _ostree_gpg_verifier_new ();
@ -4248,7 +4408,7 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self,
{
/* 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))
return NULL;
}
@ -4258,17 +4418,18 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self,
/* Add the remote's keyring file if it exists. */
OstreeRemote *remote;
g_autoptr(GFile) file = NULL;
remote = _ostree_repo_get_remote_inherited (self, remote_name, error);
if (remote == 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;
}
@ -4297,7 +4458,7 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self,
}
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,
@ -4329,7 +4490,7 @@ _ostree_repo_gpg_verify_with_metadata (OstreeRepo *self,
_OSTREE_METADATA_GPGSIGS_TYPE);
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)");
return NULL;
}
@ -4441,7 +4602,7 @@ ostree_repo_verify_commit (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
glnx_unref_object OstreeGpgVerifyResult *result = NULL;
g_autoptr(OstreeGpgVerifyResult) result = NULL;
result = ostree_repo_verify_commit_ext (self, commit_checksum,
keyringdir, extra_keyring,

View File

@ -63,6 +63,13 @@ gboolean ostree_repo_open (OstreeRepo *self,
GCancellable *cancellable,
GError **error);
_OSTREE_PUBLIC
OstreeRepo*
ostree_repo_open_at (int dfd,
const char *path,
GCancellable *cancellable,
GError **error);
_OSTREE_PUBLIC
void ostree_repo_set_disable_fsync (OstreeRepo *self,
gboolean disable_fsync);
@ -89,6 +96,13 @@ gboolean ostree_repo_create (OstreeRepo *self,
OstreeRepoMode mode,
GCancellable *cancellable,
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
@ -327,6 +341,14 @@ gboolean ostree_repo_set_ref_immediate (OstreeRepo *self,
GCancellable *cancellable,
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
_OSTREE_PUBLIC
@ -452,9 +474,11 @@ gboolean ostree_repo_list_refs (OstreeRepo *self,
/**
* OstreeRepoListRefsExtFlags:
* @OSTREE_REPO_LIST_REFS_EXT_NONE: No flags.
* @OSTREE_REPO_LIST_REFS_EXT_ALIASES: Only list aliases. Since: 2017.10
*/
typedef enum {
OSTREE_REPO_LIST_REFS_EXT_NONE = 0,
OSTREE_REPO_LIST_REFS_EXT_ALIASES = 1,
} OstreeRepoListRefsExtFlags;
_OSTREE_PUBLIC
@ -472,6 +496,15 @@ gboolean ostree_repo_remote_list_refs (OstreeRepo *self,
GCancellable *cancellable,
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
gboolean ostree_repo_load_variant (OstreeRepo *self,
OstreeObjectType objtype,

View File

@ -328,7 +328,7 @@ initable_init (GInitable *initable,
g_autoptr(GFile) policy_root = 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)
return FALSE;

View File

@ -22,24 +22,36 @@
#include <gio/gunixinputstream.h>
#include <gio/gunixoutputstream.h>
#include <glib-unix.h>
#include <sys/mount.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
#include <libmount.h>
#endif
#ifdef HAVE_LIBSYSTEMD
#include <systemd/sd-journal.h>
#endif
#include "otutil.h"
#include "ostree.h"
#include "ostree-sysroot-private.h"
#include "ostree-sepolicy-private.h"
#include "ostree-deployment-private.h"
#include "ostree-core-private.h"
#include "ostree-linuxfsutil.h"
#include "otutil.h"
#include "libglnx.h"
#define OSTREE_VARRELABEL_ID "da679b08acd34504b789d96f818ea781"
#define OSTREE_CONFIGMERGE_ID "d3863baec13e4449ab0384684a8af3a7"
#define OSTREE_DEPLOYMENT_COMPLETE_ID "dd440e3e549083b63d0efc7dc15255f1"
#ifdef HAVE_LIBSYSTEMD
#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_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
@ -101,7 +113,7 @@ hardlink_or_copy_at (int src_dfd,
sysroot_flags_to_copy_flags (0, flags),
cancellable, error);
else
return glnx_throw_errno_prefix (error, "linkat");
return glnx_throw_errno_prefix (error, "linkat(%s)", dest_subpath);
}
return TRUE;
@ -417,11 +429,19 @@ merge_configuration_from (OstreeSysroot *sysroot,
cancellable, error))
return glnx_prefix_error (error, "While computing configuration diff");
ot_log_structured_print_id_v (OSTREE_CONFIGMERGE_ID,
"Copying /etc changes: %u modified, %u removed, %u added",
modified->len,
removed->len,
added->len);
{ g_autofree char *msg =
g_strdup_printf ("Copying /etc changes: %u modified, %u removed, %u added",
modified->len, removed->len, added->len);
#ifdef HAVE_LIBSYSTEMD
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;
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)
{
ot_log_structured_print_id_v (OSTREE_VARRELABEL_ID,
"Relabeling /var (no stamp file '%s' found)",
selabeled);
{ g_autofree char *msg =
g_strdup_printf ("Relabeling /var (no stamp file '%s' found)", 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");
if (!selinux_relabel_dir (sysroot, sepolicy,
@ -717,7 +743,7 @@ merge_configuration (OstreeSysroot *sysroot,
GCancellable *cancellable,
GError **error)
{
glnx_unref_object OstreeSePolicy *sepolicy = NULL;
g_autoptr(OstreeSePolicy) sepolicy = NULL;
if (previous_deployment)
{
@ -856,131 +882,253 @@ ostree_sysroot_write_origin_file (OstreeSysroot *sysroot,
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
get_kernel_from_tree (int deployment_dfd,
int *out_boot_dfd,
char **out_kernel_name,
char **out_initramfs_name,
char **out_kernel_srcpath,
char **out_kernel_namever,
char **out_initramfs_srcpath,
char **out_initramfs_namever,
char **out_bootcsum,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
glnx_fd_close int ret_boot_dfd = -1;
g_auto(GLnxDirFdIterator) dfditer = { 0, };
g_autofree char *ret_kernel_name = NULL;
g_autofree char *ret_initramfs_name = NULL;
g_autofree char *ret_kernel_srcpath = NULL;
g_autofree char *ret_kernel_namever = NULL;
g_autofree char *ret_initramfs_srcpath = NULL;
g_autofree char *ret_initramfs_namever = NULL;
g_autofree char *kernel_checksum = NULL;
g_autofree char *initramfs_checksum = NULL;
ret_boot_dfd = glnx_opendirat_with_errno (deployment_dfd, "usr/lib/ostree-boot", TRUE);
glnx_fd_close int ret_boot_dfd = glnx_opendirat_with_errno (deployment_dfd, "usr/lib/ostree-boot", TRUE);
if (ret_boot_dfd == -1)
{
if (errno != ENOENT)
{
glnx_set_prefix_error_from_errno (error, "%s", "openat");
goto out;
}
return glnx_throw_errno_prefix (error, "%s", "openat(usr/lib/ostree-boot)");
else
{
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))
goto out;
return FALSE;
while (TRUE)
{
struct dirent *dent;
if (!glnx_dirfd_iterator_next_dent (&dfditer, &dent, cancellable, error))
goto out;
return FALSE;
if (dent == NULL)
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);
if (ostree_validate_structureof_checksum_string (dash + 1, NULL))
{
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);
if (ostree_validate_structureof_checksum_string (dash + 1, NULL))
{
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;
}
if (ret_kernel_name == NULL)
if (ret_kernel_srcpath == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"Failed to find boot/vmlinuz-<CHECKSUM> in tree");
goto out;
"Failed to find kernel in /usr/lib/ostree-boot or /boot");
return FALSE;
}
if (ret_initramfs_name != NULL)
if (ret_initramfs_srcpath != NULL)
{
if (strcmp (kernel_checksum, initramfs_checksum) != 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"Mismatched kernel checksum vs initrd in tree");
goto out;
"Mismatched kernel checksum vs initrd");
return FALSE;
}
}
*out_boot_dfd = ret_boot_dfd;
ret_boot_dfd = -1;
*out_kernel_name = g_steal_pointer (&ret_kernel_name);
*out_initramfs_name = g_steal_pointer (&ret_initramfs_name);
ret = TRUE;
out:
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);
*out_boot_dfd = glnx_steal_fd (&ret_boot_dfd);
*out_kernel_srcpath = g_steal_pointer (&ret_kernel_srcpath);
*out_kernel_namever = g_steal_pointer (&ret_kernel_namever);
*out_initramfs_srcpath = g_steal_pointer (&ret_initramfs_srcpath);
*out_initramfs_namever = g_steal_pointer (&ret_initramfs_namever);
*out_bootcsum = g_steal_pointer (&kernel_checksum);
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
syncfs_dir_at (int dfd,
const char *path,
fsfreeze_thaw_cycle (OstreeSysroot *self,
int rootfs_dfd,
GCancellable *cancellable,
GError **error)
{
glnx_fd_close int child_dfd = -1;
if (!glnx_opendirat (dfd, path, TRUE, &child_dfd, error))
return FALSE;
if (syncfs (child_dfd) != 0)
return glnx_throw_errno (error);
GLNX_AUTO_PREFIX_ERROR ("During fsfreeze-thaw", 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;
}
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
* be separate mount points. Then *in addition*, do a global
@ -988,14 +1136,25 @@ syncfs_dir_at (int dfd,
*/
static gboolean
full_system_sync (OstreeSysroot *self,
SyncStats *out_stats,
GCancellable *cancellable,
GError **error)
{
guint64 start_msec = g_get_monotonic_time () / 1000;
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;
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
* 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
* global sync call is removed.
*/
start_msec = g_get_monotonic_time () / 1000;
sync ();
end_msec = g_get_monotonic_time () / 1000;
out_stats->extra_syncfs_msec = (end_msec - start_msec);
return TRUE;
}
@ -1099,15 +1261,6 @@ swap_bootlinks (OstreeSysroot *self,
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 *
parse_os_release (const char *contents,
const char *split)
@ -1161,11 +1314,19 @@ install_deployment_kernel (OstreeSysroot *sysroot,
&deployment_dfd, error))
return FALSE;
/* Find the kernel/initramfs in the tree */
glnx_fd_close int tree_boot_dfd = -1;
g_autofree char *tree_kernel_name = NULL;
g_autofree char *tree_initramfs_name = NULL;
g_autofree char *tree_kernel_srcpath = 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,
&tree_kernel_name, &tree_initramfs_name,
&tree_kernel_srcpath,
&tree_kernel_namever,
&tree_initramfs_srcpath,
&tree_initramfs_namever,
&tree_bootcsum,
cancellable, error))
return FALSE;
@ -1175,6 +1336,7 @@ install_deployment_kernel (OstreeSysroot *sysroot,
const char *osname = ostree_deployment_get_osname (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 *bootconfdir = g_strdup_printf ("loader.%d/entries", new_bootversion);
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))
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;
if (fstatat (bootcsum_dfd, dest_kernel_name, &stbuf, 0) != 0)
if (fstatat (bootcsum_dfd, tree_kernel_namever, &stbuf, 0) != 0)
{
if (errno != ENOENT)
return glnx_throw_errno_prefix (error, "fstat %s", dest_kernel_name);
if (!hardlink_or_copy_at (tree_boot_dfd, tree_kernel_name,
bootcsum_dfd, dest_kernel_name,
return glnx_throw_errno_prefix (error, "fstat %s", tree_kernel_namever);
if (!hardlink_or_copy_at (tree_boot_dfd, tree_kernel_srcpath,
bootcsum_dfd, tree_kernel_namever,
sysroot->debug_flags,
cancellable, error))
return FALSE;
}
g_autofree char *dest_initramfs_name = NULL;
if (tree_initramfs_name)
/* If we have an initramfs, then install it into
* /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);
if (fstatat (bootcsum_dfd, dest_initramfs_name, &stbuf, 0) != 0)
g_assert (tree_initramfs_namever);
if (fstatat (bootcsum_dfd, tree_initramfs_namever, &stbuf, 0) != 0)
{
if (errno != ENOENT)
return glnx_throw_errno_prefix (error, "fstat %s", dest_initramfs_name);
if (!hardlink_or_copy_at (tree_boot_dfd, tree_initramfs_name,
bootcsum_dfd, dest_initramfs_name,
return glnx_throw_errno_prefix (error, "fstat %s", tree_initramfs_namever);
if (!hardlink_or_copy_at (tree_boot_dfd, tree_initramfs_srcpath,
bootcsum_dfd, tree_initramfs_namever,
sysroot->debug_flags,
cancellable, error))
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));
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);
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);
}
@ -1379,7 +1544,7 @@ swap_bootloader (OstreeSysroot *sysroot,
* admin by going back to the previous session.
*/
if (fsync (boot_dfd) != 0)
return glnx_throw_errno (error);
return glnx_throw_errno_prefix (error, "fsync(boot)");
return TRUE;
}
@ -1452,10 +1617,9 @@ cleanup_legacy_current_symlinks (OstreeSysroot *self,
GCancellable *cancellable,
GError **error)
{
guint i;
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];
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_append_printf (buf, "ostree/deploy/%s/current", osname);
if (unlinkat (self->sysroot_fd, buf->str, 0) < 0)
{
if (errno != ENOENT)
return glnx_throw_errno (error);
}
if (!ot_ensure_unlinked_at (self->sysroot_fd, buf->str, error))
return FALSE;
}
return TRUE;
@ -1568,6 +1729,8 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self,
gboolean found_booted_deployment = FALSE;
gboolean bootloader_is_atomic = FALSE;
gboolean boot_was_ro_mount = FALSE;
SyncStats syncstats = { 0, };
g_autoptr(OstreeBootloader) bootloader = NULL;
g_assert (self->loaded);
@ -1631,7 +1794,7 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self,
goto out;
}
if (!full_system_sync (self, cancellable, error))
if (!full_system_sync (self, &syncstats, cancellable, error))
{
g_prefix_error (error, "Full sync: ");
goto out;
@ -1650,9 +1813,8 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self,
else
{
int new_bootversion = self->bootversion ? 0 : 1;
glnx_unref_object OstreeBootloader *bootloader = NULL;
g_autofree char* new_loader_entries_dir = NULL;
glnx_unref_object OstreeRepo *repo = NULL;
g_autoptr(OstreeRepo) repo = NULL;
gboolean show_osname = FALSE;
if (self->booted_deployment)
@ -1751,7 +1913,7 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self,
goto out;
}
if (!full_system_sync (self, cancellable, error))
if (!full_system_sync (self, &syncstats, cancellable, error))
{
g_prefix_error (error, "Full sync: ");
goto out;
@ -1765,11 +1927,25 @@ ostree_sysroot_write_deployments_with_options (OstreeSysroot *self,
}
}
ot_log_structured_print_id_v (OSTREE_DEPLOYMENT_COMPLETE_ID,
"%s; bootconfig swap: %s deployment count change: %i",
{ g_autofree char *msg =
g_strdup_printf ("%s; bootconfig swap: %s deployment count change: %i",
(bootloader_is_atomic ? "Transaction complete" : "Bootloader updated"),
requires_new_bootversion ? "yes" : "no",
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))
goto out;
@ -1884,7 +2060,7 @@ ostree_sysroot_deploy_tree (OstreeSysroot *self,
return FALSE;
OstreeRepo *repo = ostree_sysroot_repo (self);
glnx_unref_object OstreeDeployment *merge_deployment = NULL;
g_autoptr(OstreeDeployment) merge_deployment = NULL;
if (provided_merge_deployment != NULL)
merge_deployment = g_object_ref (provided_merge_deployment);
@ -1894,7 +2070,7 @@ ostree_sysroot_deploy_tree (OstreeSysroot *self,
return FALSE;
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,
new_bootcsum, -1);
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;
g_autofree char *tree_kernel_path = NULL;
g_autofree char *tree_initramfs_path = NULL;
g_autofree char *tree_kernel_srcpath = 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,
&tree_kernel_path, &tree_initramfs_path,
&tree_kernel_srcpath,
&tree_kernel_namever,
&tree_initramfs_srcpath,
&tree_initramfs_namever,
&new_bootcsum,
cancellable, error))
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);
/* Create an empty boot configuration; we will merge things into
* 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);
glnx_unref_object OstreeSePolicy *sepolicy = NULL;
g_autoptr(OstreeSePolicy) sepolicy = NULL;
if (!merge_configuration (self, repo, merge_deployment, new_deployment,
deployment_dfd,
&sepolicy,
@ -2013,7 +2185,7 @@ ostree_sysroot_deployment_set_kargs (OstreeSysroot *self,
{
guint i;
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;
g_autofree char *new_options = NULL;
OstreeBootconfigParser *new_bootconfig;

View File

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

View File

@ -25,6 +25,7 @@
#include <sys/mount.h>
#include <sys/wait.h>
#include "ostree.h"
#include "ostree-core-private.h"
#include "ostree-repo-private.h"
#include "ostree-sepolicy-private.h"
@ -57,8 +58,18 @@ find_booted_deployment (OstreeSysroot *self,
*/
typedef struct {
GObjectClass parent_class;
/* Signals */
void (*journal_msg) (OstreeSysroot *sysroot,
const char *msg);
} OstreeSysrootClass;
enum {
JOURNAL_MSG_SIGNAL,
LAST_SIGNAL,
};
static guint signals[LAST_SIGNAL] = { 0 };
enum {
PROP_0,
@ -126,18 +137,11 @@ static void
ostree_sysroot_constructed (GObject *object)
{
OstreeSysroot *self = OSTREE_SYSROOT (object);
g_autoptr(GFile) repo_path = NULL;
/* Ensure the system root path is set. */
if (self->path == NULL)
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);
}
@ -158,6 +162,27 @@ ostree_sysroot_class_init (OstreeSysrootClass *klass)
"",
G_TYPE_FILE,
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
@ -165,6 +190,7 @@ ostree_sysroot_init (OstreeSysroot *self)
{
const GDebugKey keys[] = {
{ "mutable-deployments", OSTREE_SYSROOT_DEBUG_MUTABLE_DEPLOYMENTS },
{ "test-fifreeze", OSTREE_SYSROOT_DEBUG_TEST_FIFREEZE },
{ "no-xattrs", OSTREE_SYSROOT_DEBUG_NO_XATTRS },
};
@ -299,22 +325,20 @@ ostree_sysroot_ensure_initialized (OstreeSysroot *self,
cancellable, error))
return FALSE;
struct stat stbuf;
if (fstatat (self->sysroot_fd, "ostree/repo/objects", &stbuf, 0) != 0)
{
if (errno != ENOENT)
return glnx_throw_errno_prefix (error, "stat(ostree/repo/objects)");
else
{
g_autoptr(GFile) repo_dir = g_file_resolve_relative_path (self->path, "ostree/repo");
glnx_unref_object OstreeRepo *repo = ostree_repo_new (repo_dir);
if (!ostree_repo_create (repo, OSTREE_REPO_MODE_BARE,
cancellable, error))
g_autoptr(OstreeRepo) repo =
ostree_repo_create_at (self->sysroot_fd, "ostree/repo",
OSTREE_REPO_MODE_BARE, NULL,
cancellable, error);
if (!repo)
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
@ -454,7 +478,7 @@ _ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self,
g_str_has_suffix (dent->d_name, ".conf") &&
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))
return glnx_prefix_error (error, "Parsing %s", dent->d_name);
@ -624,7 +648,7 @@ parse_deployment (OstreeSysroot *self,
cancellable, error))
return FALSE;
glnx_unref_object OstreeDeployment *ret_deployment
g_autoptr(OstreeDeployment) ret_deployment
= ostree_deployment_new (-1, osname, treecsum, deployserial,
bootcsum, treebootserial);
if (origin)
@ -691,7 +715,7 @@ list_deployments_process_one_boot_entry (OstreeSysroot *self,
if (ostree_arg == NULL)
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,
cancellable, error))
return FALSE;
@ -732,14 +756,22 @@ ostree_sysroot_load (OstreeSysroot *self,
}
static gboolean
ensure_repo_opened (OstreeSysroot *self,
ensure_repo (OstreeSysroot *self,
GError **error)
{
if (self->repo_opened)
if (self->repo != NULL)
return TRUE;
if (!ostree_repo_open (self->repo, NULL, error))
if (!ensure_sysroot_fd (self, error))
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;
}
@ -756,7 +788,7 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self,
* previous to v2017.6, but we do now to support the error-free
* ostree_sysroot_repo() API.
*/
if (!ensure_repo_opened (self, error))
if (!ensure_repo (self, error))
return FALSE;
int bootversion = 0;
@ -959,9 +991,8 @@ ostree_sysroot_get_repo (OstreeSysroot *self,
GCancellable *cancellable,
GError **error)
{
if (!ensure_repo_opened (self, error))
if (!ensure_repo (self, error))
return FALSE;
if (out_repo != NULL)
*out_repo = g_object_ref (self->repo);
return TRUE;
@ -999,7 +1030,7 @@ _ostree_sysroot_query_bootloader (OstreeSysroot *sysroot,
GError **error)
{
gboolean is_active;
glnx_unref_object OstreeBootloader *ret_loader =
g_autoptr(OstreeBootloader) ret_loader =
(OstreeBootloader*)_ostree_bootloader_syslinux_new (sysroot);
if (!_ostree_bootloader_query (ret_loader, &is_active,
cancellable, error))
@ -1078,7 +1109,7 @@ find_booted_deployment (OstreeSysroot *self,
{
struct stat root_stbuf;
struct stat self_stbuf;
glnx_unref_object OstreeDeployment *ret_deployment = NULL;
g_autoptr(OstreeDeployment) ret_deployment = NULL;
if (stat ("/", &root_stbuf) != 0)
return glnx_throw_errno_prefix (error, "stat /");
@ -1540,6 +1571,7 @@ ostree_sysroot_simple_write_deployment (OstreeSysroot *sysroot,
return ret;
}
/* Deploy a copy of @target_deployment */
static gboolean
clone_deployment (OstreeSysroot *sysroot,
OstreeDeployment *target_deployment,
@ -1547,38 +1579,26 @@ clone_deployment (OstreeSysroot *sysroot,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
__attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL;
glnx_unref_object OstreeDeployment *new_deployment = NULL;
/* Ensure we have a clean slate */
if (!ostree_sysroot_prepare_cleanup (sysroot, cancellable, error))
{
g_prefix_error (error, "Performing initial cleanup: ");
goto out;
}
return glnx_prefix_error (error, "Performing initial cleanup");
kargs = _ostree_kernel_args_new ();
{ OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (merge_deployment);
/* Copy the bootloader config options */
OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (merge_deployment);
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);
}
{
/* Deploy the copy */
g_autoptr(OstreeDeployment) new_deployment = NULL;
g_auto(GStrv) kargs_strv = _ostree_kernel_args_to_strv (kargs);
if (!ostree_sysroot_deploy_tree (sysroot,
ostree_deployment_get_osname (target_deployment),
ostree_deployment_get_csum (target_deployment),
ostree_deployment_get_origin (target_deployment),
merge_deployment,
kargs_strv,
&new_deployment,
merge_deployment, kargs_strv, &new_deployment,
cancellable, error))
goto out;
}
return FALSE;
/* Hotfixes push the deployment as rollback target, so it shouldn't
* be the default.
@ -1587,11 +1607,9 @@ clone_deployment (OstreeSysroot *sysroot,
new_deployment, merge_deployment,
OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT,
cancellable, error))
goto out;
return FALSE;
ret = TRUE;
out:
return ret;
return TRUE;
}
/**
@ -1616,59 +1634,41 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
GCancellable *cancellable,
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 */
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)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Deployment is already in unlocked state: %s",
return glnx_throw (error, "Deployment is already in unlocked state: %s",
ostree_deployment_unlocked_state_to_string (current_unlocked));
goto out;
}
merge_deployment = ostree_sysroot_get_merge_deployment (self, ostree_deployment_get_osname (deployment));
g_autoptr(OstreeDeployment) merge_deployment =
ostree_sysroot_get_merge_deployment (self, ostree_deployment_get_osname (deployment));
if (!merge_deployment)
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No previous deployment to duplicate");
goto out;
}
return glnx_throw (error, "No previous deployment to duplicate");
/* For hotfixes, we push a rollback target */
if (unlocked_state == OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX)
{
if (!clone_deployment (self, deployment, merge_deployment, cancellable, error))
goto out;
return FALSE;
}
/* Crack it open */
if (!ostree_sysroot_deployment_set_mutable (self, deployment, TRUE,
cancellable, error))
goto out;
deployment_path = ostree_sysroot_get_deployment_dirpath (self, deployment);
return FALSE;
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))
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)
goto out;
return FALSE;
const char *ovl_options = NULL;
switch (unlocked_state)
{
case OSTREE_DEPLOYMENT_UNLOCKED_NONE:
@ -1676,14 +1676,15 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
break;
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
* directly for hotfixes. The ostree-prepare-root.c helper
* is also set up to detect and mount these.
*/
if (!glnx_shutil_mkdir_p_at (deployment_dfd, ".usr-ovl-upper", 0755, cancellable, error))
goto out;
return FALSE;
if (!glnx_shutil_mkdir_p_at (deployment_dfd, ".usr-ovl-work", 0755, cancellable, error))
goto out;
return FALSE;
ovl_options = hotfix_ovl_options;
}
break;
@ -1701,18 +1702,18 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
if (!_ostree_sepolicy_preparefscreatecon (&con, sepolicy,
"/usr", 0755, error))
goto out;
return FALSE;
if (!glnx_mkdtempat (AT_FDCWD, development_ovldir, 0755, error))
goto out;
return FALSE;
}
development_ovl_upper = glnx_strjoina (development_ovldir, "/upper");
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");
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,
",workdir=", development_ovl_work);
}
@ -1728,12 +1729,9 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
* threads, etc.
*/
{
mount_child = fork ();
pid_t mount_child = fork ();
if (mount_child < 0)
{
glnx_set_prefix_error_from_errno (error, "%s", "fork");
goto out;
}
return glnx_throw_errno_prefix (error, "fork");
else if (mount_child == 0)
{
/* Child process. Do NOT use any GLib API here. */
@ -1749,18 +1747,15 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
int estatus;
if (TEMP_FAILURE_RETRY (waitpid (mount_child, &estatus, 0)) < 0)
{
glnx_set_prefix_error_from_errno (error, "%s", "waitpid() on mount helper");
goto out;
}
return glnx_throw_errno_prefix (error, "waitpid() on mount helper");
if (!g_spawn_check_exit_status (estatus, error))
{
g_prefix_error (error, "overlayfs mount helper: ");
goto out;
}
return glnx_throw_errno_prefix (error, "overlayfs mount helper");
}
}
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 */
switch (unlocked_state)
{
@ -1772,7 +1767,7 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
ostree_deployment_unlocked_state_to_string (unlocked_state));
if (!ostree_sysroot_write_origin_file (self, deployment, origin_clone,
cancellable, error))
goto out;
return FALSE;
break;
case OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT:
{
@ -1780,10 +1775,10 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
g_autofree char *devpath_parent = dirname (g_strdup (devpath));
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))
goto out;
return FALSE;
}
}
@ -1793,9 +1788,7 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
* regardless.
*/
if (!_ostree_sysroot_bump_mtime (self, error))
goto out;
return FALSE;
ret = TRUE;
out:
return ret;
return TRUE;
}

View File

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

View File

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

View File

@ -49,7 +49,7 @@ ot_cleanup_unlinkat (OtCleanupUnlinkat *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);

View File

@ -413,7 +413,7 @@ ot_gpgme_new_ctx (const char *homedir,
GError **error)
{
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)
{

View File

@ -26,10 +26,9 @@
G_BEGIN_DECLS
GLNX_DEFINE_CLEANUP_FUNCTION0(gpgme_data_t, ot_cleanup_gpgme_data, gpgme_data_release)
#define ot_auto_gpgme_data __attribute__((cleanup(ot_cleanup_gpgme_data)))
GLNX_DEFINE_CLEANUP_FUNCTION0(gpgme_ctx_t, ot_cleanup_gpgme_ctx, gpgme_release)
#define ot_auto_gpgme_ctx __attribute__((cleanup(ot_cleanup_gpgme_ctx)))
G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_data_t, gpgme_data_release, NULL)
G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_ctx_t, gpgme_release, NULL)
G_DEFINE_AUTO_CLEANUP_FREE_FUNC(gpgme_key_t, gpgme_key_unref, NULL)
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-checksum-utils.h>
#include <ot-gpg-utils.h>
#include <ot-log-utils.h>
#include <ot-checksum-instream.h>
void ot_ptrarray_add_many (GPtrArray *a, ...) G_GNUC_NULL_TERMINATED;

View File

@ -56,6 +56,11 @@ typedef struct {
GOutputStream *log;
} 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[] = {
{ "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 },
@ -94,7 +99,7 @@ httpd_log (OtTrivialHttpd *httpd, const gchar *format, ...)
g_string_append_vprintf (str, format, 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

View File

@ -29,6 +29,11 @@
#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[] = {
{ NULL }
};
@ -37,7 +42,7 @@ gboolean
ot_admin_builtin_cleanup (int argc, char **argv, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
g_autoptr(OstreeSysroot) sysroot = NULL;
gboolean ret = FALSE;
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_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[] = {
{ "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" },
@ -55,11 +60,11 @@ ot_admin_builtin_deploy (int argc, char **argv, GCancellable *cancellable, GErro
gboolean ret = FALSE;
const char *refspec;
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
g_autoptr(OstreeSysroot) sysroot = NULL;
g_autoptr(GKeyFile) origin = NULL;
glnx_unref_object OstreeRepo *repo = NULL;
glnx_unref_object OstreeDeployment *new_deployment = NULL;
glnx_unref_object OstreeDeployment *merge_deployment = NULL;
g_autoptr(OstreeRepo) repo = NULL;
g_autoptr(OstreeDeployment) new_deployment = NULL;
g_autoptr(OstreeDeployment) merge_deployment = NULL;
g_autofree char *revision = NULL;
__attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL;

View File

@ -31,6 +31,11 @@
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[] = {
{ "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Use a different operating system root than the current one", "OSNAME" },
{ NULL }
@ -40,9 +45,9 @@ gboolean
ot_admin_builtin_diff (int argc, char **argv, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
g_autoptr(OstreeSysroot) sysroot = NULL;
gboolean ret = FALSE;
glnx_unref_object OstreeDeployment *deployment = NULL;
g_autoptr(OstreeDeployment) deployment = NULL;
g_autoptr(GFile) deployment_dir = NULL;
g_autoptr(GPtrArray) modified = NULL;
g_autoptr(GPtrArray) removed = NULL;

View File

@ -29,6 +29,11 @@
#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[] = {
{ NULL }
};
@ -37,10 +42,10 @@ gboolean
ot_admin_builtin_init_fs (int argc, char **argv, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
g_autoptr(OstreeSysroot) sysroot = NULL;
gboolean ret = FALSE;
glnx_fd_close int root_dfd = -1;
glnx_unref_object OstreeSysroot *target_sysroot = NULL;
g_autoptr(OstreeSysroot) target_sysroot = NULL;
guint i;
const char *normal_toplevels[] = {"boot", "dev", "home", "proc", "run", "sys"};

View File

@ -29,6 +29,11 @@
#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[] = {
{ NULL }
};
@ -37,7 +42,7 @@ gboolean
ot_admin_builtin_os_init (int argc, char **argv, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
g_autoptr(OstreeSysroot) sysroot = NULL;
gboolean ret = FALSE;
const char *osname = NULL;

View File

@ -34,6 +34,11 @@
static int opt_index = -1;
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[] = {
{ "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" },
@ -48,9 +53,9 @@ ot_admin_builtin_set_origin (int argc, char **argv, GCancellable *cancellable, G
const char *remotename = NULL;
const char *url = NULL;
const char *branch = NULL;
glnx_unref_object OstreeRepo *repo = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
glnx_unref_object OstreeDeployment *target_deployment = NULL;
g_autoptr(OstreeRepo) repo = NULL;
g_autoptr(OstreeSysroot) sysroot = NULL;
g_autoptr(OstreeDeployment) target_deployment = NULL;
context = g_option_context_new ("REMOTENAME URL [BRANCH]");

View File

@ -29,6 +29,11 @@
#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[] = {
{ NULL }
};
@ -84,9 +89,9 @@ gboolean
ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
g_autoptr(OstreeSysroot) sysroot = NULL;
gboolean ret = FALSE;
glnx_unref_object OstreeRepo *repo = NULL;
g_autoptr(OstreeRepo) repo = NULL;
OstreeDeployment *booted_deployment = NULL;
g_autoptr(OstreeDeployment) pending_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);
OstreeDeploymentUnlockedState unlocked = ostree_deployment_get_unlocked (deployment);
g_autofree char *version = version_of_commit (repo, ref);
glnx_unref_object OstreeGpgVerifyResult *result = NULL;
g_autoptr(OstreeGpgVerifyResult) result = NULL;
guint jj, n_signatures;
GError *local_error = NULL;

View File

@ -33,6 +33,11 @@
static gboolean opt_reboot;
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[] = {
{ "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" },
@ -44,9 +49,9 @@ ot_admin_builtin_switch (int argc, char **argv, GCancellable *cancellable, GErro
{
gboolean ret = FALSE;
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
g_autoptr(OstreeSysroot) sysroot = 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_remote = 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_refspec = NULL;
const char* remote;
glnx_unref_object OstreeSysrootUpgrader *upgrader = NULL;
glnx_unref_object OstreeAsyncProgress *progress = NULL;
g_autoptr(OstreeSysrootUpgrader) upgrader = NULL;
g_autoptr(OstreeAsyncProgress) progress = NULL;
gboolean changed;
GKeyFile *old_origin;
g_autoptr(GKeyFile) new_origin = NULL;

View File

@ -28,6 +28,11 @@
#include "ostree.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[] = {
{ NULL }
};
@ -36,11 +41,11 @@ gboolean
ot_admin_builtin_undeploy (int argc, char **argv, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
g_autoptr(OstreeSysroot) sysroot = NULL;
const char *deploy_index_str;
int deploy_index;
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");

View File

@ -33,6 +33,11 @@
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[] = {
{ "hotfix", 0, 0, G_OPTION_ARG_NONE, &opt_hotfix, "Retain changes across reboots", NULL },
{ NULL }
@ -43,7 +48,7 @@ ot_admin_builtin_unlock (int argc, char **argv, GCancellable *cancellable, GErro
{
gboolean ret = FALSE;
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
g_autoptr(OstreeSysroot) sysroot = NULL;
OstreeDeployment *booted_deployment = NULL;
OstreeDeploymentUnlockedState target_state;

View File

@ -39,6 +39,11 @@ static gboolean opt_deploy_only;
static char *opt_osname;
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[] = {
{ "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 },
@ -54,10 +59,10 @@ ot_admin_builtin_upgrade (int argc, char **argv, GCancellable *cancellable, GErr
{
gboolean ret = FALSE;
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
glnx_unref_object OstreeSysrootUpgrader *upgrader = NULL;
g_autoptr(OstreeSysroot) sysroot = NULL;
g_autoptr(OstreeSysrootUpgrader) upgrader = NULL;
g_autoptr(GKeyFile) origin = NULL;
glnx_unref_object OstreeAsyncProgress *progress = NULL;
g_autoptr(OstreeAsyncProgress) progress = NULL;
gboolean changed;
OstreeSysrootUpgraderPullFlags upgraderpullflags = 0;

View File

@ -29,6 +29,11 @@
#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[] = {
{ NULL }
};
@ -39,7 +44,7 @@ ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, GCancellable *c
gboolean ret = FALSE;
guint bootversion;
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");

View File

@ -174,6 +174,11 @@ selinux_relabel_dir (OstreeSePolicy *sepolicy,
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[] = {
{ NULL }
};
@ -185,11 +190,11 @@ ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, GCancel
const char *policy_name;
g_autoptr(GFile) subpath = NULL;
const char *prefix = NULL;
glnx_unref_object OstreeSePolicy *sepolicy = NULL;
g_autoptr(OstreeSePolicy) sepolicy = NULL;
g_autoptr(GPtrArray) deployments = NULL;
OstreeDeployment *first_deployment;
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
g_autoptr(OstreeSysroot) sysroot = NULL;
g_autoptr(GFile) deployment_path = NULL;
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_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[] = {
{ "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 },
@ -51,7 +56,7 @@ ot_admin_instutil_builtin_set_kargs (int argc, char **argv, GCancellable *cancel
g_autoptr(GPtrArray) deployments = NULL;
OstreeDeployment *first_deployment = 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;
context = g_option_context_new ("ARGS - set new kernel command line arguments");

View File

@ -29,6 +29,11 @@
#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[] = {
{ NULL },
};

View File

@ -61,6 +61,11 @@ parse_fsync_cb (const char *option_name,
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[] = {
{ "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 },
@ -254,7 +259,7 @@ gboolean
ostree_builtin_checkout (int argc, char **argv, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL;
g_autoptr(OstreeRepo) repo = NULL;
gboolean ret = FALSE;
const char *commit;
const char *destination;

View File

@ -28,6 +28,11 @@
#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[] = {
{ NULL }
};

View File

@ -72,6 +72,11 @@ parse_fsync_cb (const char *option_name,
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[] = {
{ "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" },
@ -375,7 +380,7 @@ gboolean
ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL;
g_autoptr(OstreeRepo) repo = NULL;
gboolean ret = FALSE;
gboolean skip_commit = FALSE;
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(GVariant) 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_autoptr(GHashTable) mode_adds = NULL;
g_autoptr(GHashTable) mode_overrides = NULL;

View File

@ -27,6 +27,11 @@
#include "ostree.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[] = {
{ NULL }
};
@ -55,7 +60,7 @@ gboolean
ostree_builtin_config (int argc, char **argv, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL;
g_autoptr(OstreeRepo) repo = NULL;
gboolean ret = FALSE;
const char *op;
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_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[] = {
{ "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 },
@ -126,7 +131,7 @@ ostree_builtin_diff (int argc, char **argv, GCancellable *cancellable, GError **
{
gboolean ret = FALSE;
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL;
g_autoptr(OstreeRepo) repo = NULL;
const char *src;
const char *target;
g_autofree char *src_prev = NULL;

View File

@ -20,12 +20,12 @@
#include "config.h"
#include "otutil.h"
#include "ot-main.h"
#include "ot-builtins.h"
#include "ostree-libarchive-private.h"
#include "ostree.h"
#include "ostree-repo-file.h"
#include "ostree-libarchive-private.h"
#include "otutil.h"
#ifdef HAVE_LIBARCHIVE
#include <archive.h>
@ -37,6 +37,11 @@ static char *opt_subpath;
static char *opt_prefix;
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[] = {
{ "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" },
@ -61,14 +66,16 @@ gboolean
ostree_builtin_export (int argc, char **argv, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL;
g_autoptr(OstreeRepo) repo = NULL;
gboolean ret = FALSE;
const char *rev;
g_autoptr(GFile) root = NULL;
g_autoptr(GFile) subtree = NULL;
g_autofree char *commit = 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, };
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)
{
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL;
g_autoptr(OstreeRepo) repo = NULL;
g_autoptr(GPtrArray) refs = NULL; /* (element-type OstreeCollectionRef) */
glnx_unref_object OstreeAsyncProgress *progress = NULL;
g_autoptr(OstreeAsyncProgress) progress = NULL;
gsize i;
g_autoptr(GAsyncResult) find_result = NULL, pull_result = NULL;
g_auto(OstreeRepoFinderResultv) results = NULL;

View File

@ -32,6 +32,11 @@ static gboolean opt_quiet;
static gboolean opt_delete;
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[] = {
{ "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 },
@ -212,7 +217,7 @@ fsck_reachable_objects_from_commits (OstreeRepo *repo,
gboolean
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;
g_autoptr(GOptionContext) context = g_option_context_new ("- Check the repository for consistency");

View File

@ -31,6 +31,11 @@
static gboolean opt_delete;
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[] = {
{ "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" },
@ -55,7 +60,7 @@ delete_signatures (OstreeRepo *repo,
GError **error)
{
GVariantDict metadata_dict;
glnx_unref_object OstreeGpgVerifyResult *result = NULL;
g_autoptr(OstreeGpgVerifyResult) result = NULL;
g_autoptr(GVariant) old_metadata = NULL;
g_autoptr(GVariant) new_metadata = NULL;
g_autoptr(GVariant) signature_data = NULL;
@ -199,7 +204,7 @@ gboolean
ostree_builtin_gpg_sign (int argc, char **argv, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL;
g_autoptr(OstreeRepo) repo = NULL;
g_autofree char *resolved_commit = NULL;
const char *commit;
char **key_ids;

View File

@ -31,6 +31,11 @@ static char *opt_mode = "bare";
static char *opt_collection_id = NULL;
#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[] = {
{ "mode", 0, 0, G_OPTION_ARG_STRING, &opt_mode, "Initialize repository in given mode (bare, archive-z2)", NULL },
#ifdef OSTREE_ENABLE_EXPERIMENTAL_API

View File

@ -30,6 +30,11 @@
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[] = {
{ "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "Show raw variant data" },
{ NULL }
@ -82,7 +87,7 @@ ostree_builtin_log (int argc,
GError **error)
{
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL;
g_autoptr(OstreeRepo) repo = NULL;
gboolean ret = FALSE;
const char *rev;
g_autofree char *checksum = NULL;

View File

@ -34,6 +34,11 @@ static gboolean opt_checksum;
static gboolean opt_xattrs;
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[] = {
{ "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 },
@ -239,7 +244,7 @@ gboolean
ostree_builtin_ls (int argc, char **argv, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = NULL;
glnx_unref_object OstreeRepo *repo = NULL;
g_autoptr(OstreeRepo) repo = NULL;
gboolean ret = FALSE;
const char *rev;
int i;

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