diff --git a/Makefile-decls.am b/Makefile-decls.am index e41586d1..06018594 100644 --- a/Makefile-decls.am +++ b/Makefile-decls.am @@ -30,6 +30,7 @@ sbin_PROGRAMS = bin_SCRIPTS = lib_LTLIBRARIES = libexec_PROGRAMS = +pkglibexec_PROGRAMS = pkglibexec_SCRIPTS = noinst_LTLIBRARIES = noinst_PROGRAMS = diff --git a/Makefile-libostree.am b/Makefile-libostree.am index a7d7b11b..88210c75 100644 --- a/Makefile-libostree.am +++ b/Makefile-libostree.am @@ -161,6 +161,8 @@ if USE_LIBSOUP libostree_1_la_SOURCES += \ src/libostree/ostree-fetcher.h \ src/libostree/ostree-fetcher.c \ + src/libostree/ostree-fetcher-util.h \ + src/libostree/ostree-fetcher-util.c \ src/libostree/ostree-metalink.h \ src/libostree/ostree-metalink.c \ $(NULL) diff --git a/Makefile-ostree.am b/Makefile-ostree.am index e6b1eabe..05fec155 100644 --- a/Makefile-ostree.am +++ b/Makefile-ostree.am @@ -102,20 +102,25 @@ src/ostree/parse-datetime.c: src/ostree/parse-datetime.y Makefile EXTRA_DIST += src/ostree/parse-datetime.y CLEANFILES += src/ostree/parse-datetime.c -ostree_bin_shared_cflags = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree -I$(srcdir)/src/ostree \ - $(NULL) -ostree_bin_shared_ldadd = libglnx.la libbsdiff.la libotutil.la libostree-kernel-args.la libostree-1.la +ostree_bin_shared_cflags = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree \ + -I$(srcdir)/src/ostree -I$(srcdir)/libglnx $(OT_INTERNAL_GIO_UNIX_CFLAGS) \ + -DPKGLIBEXECDIR=\"$(pkglibexecdir)\" +ostree_bin_shared_ldadd = $(AM_LDFLAGS) libglnx.la libotutil.la libostree-1.la \ + $(OT_INTERNAL_GIO_UNIX_LIBS) + +ostree_CFLAGS = $(ostree_bin_shared_cflags) +ostree_LDADD = $(ostree_bin_shared_ldadd) libbsdiff.la libostree-kernel-args.la $(LIBSYSTEMD_LIBS) -ostree_CFLAGS = $(ostree_bin_shared_cflags) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -I$(srcdir)/libglnx -ostree_LDADD = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_GIO_UNIX_LIBS) $(LIBSYSTEMD_LIBS) if USE_LIBSOUP -ostree_SOURCES += \ - src/ostree/ot-builtin-pull.c \ - src/ostree/ot-builtin-trivial-httpd.c \ - $(NULL) +ostree_SOURCES += src/ostree/ot-builtin-pull.c src/ostree/ot-builtin-trivial-httpd.c ostree_CFLAGS += $(OT_INTERNAL_SOUP_CFLAGS) ostree_LDADD += $(OT_INTERNAL_SOUP_LIBS) + +pkglibexec_PROGRAMS += ostree-trivial-httpd +ostree_trivial_httpd_SOURCES = src/ostree/ostree-trivial-httpd.c +ostree_trivial_httpd_CFLAGS = $(ostree_bin_shared_cflags) $(OT_INTERNAL_SOUP_CFLAGS) +ostree_trivial_httpd_LDADD = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_SOUP_LIBS) endif if USE_LIBARCHIVE diff --git a/Makefile-tests.am b/Makefile-tests.am index 1f9cad48..a0c05488 100644 --- a/Makefile-tests.am +++ b/Makefile-tests.am @@ -28,6 +28,7 @@ EXTRA_DIST += \ # include the builddir in $PATH so we find our just-built ostree # binary. TESTS_ENVIRONMENT += OT_TESTS_DEBUG=1 \ + OSTREE_UNINSTALLED=$(abs_top_builddir) \ G_DEBUG=fatal-warnings \ GI_TYPELIB_PATH=$$(cd $(top_builddir) && pwd)$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH} \ LD_LIBRARY_PATH=$$(cd $(top_builddir)/.libs && pwd)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}} \ @@ -44,6 +45,7 @@ dist_uninstalled_test_scripts = tests/test-symbols.sh dist_test_scripts = \ tests/test-basic.sh \ + tests/test-basic-user.sh \ tests/test-pull-subpath.sh \ tests/test-archivez.sh \ tests/test-remote-add.sh \ @@ -64,6 +66,7 @@ dist_test_scripts = \ tests/test-pull-resume.sh \ tests/test-pull-repeated.sh \ tests/test-pull-untrusted.sh \ + tests/test-pull-many.sh \ tests/test-pull-override-url.sh \ tests/test-local-pull.sh \ tests/test-local-pull-depth.sh \ @@ -118,16 +121,17 @@ dist_installed_test_data = tests/archive-test.sh \ tests/pull-test.sh \ tests/admin-test.sh \ tests/basic-test.sh \ - tests/test-basic-user.sh \ - tests/corrupt-repo-ref.js \ tests/pre-endian-deltas-repo-big.tar.xz \ tests/pre-endian-deltas-repo-little.tar.xz \ $(NULL) EXTRA_DIST += tests/libtest.sh -dist_test_extra_scripts = tests/bootloader-entries-crosscheck.py \ - tests/ostree-grub-generator +dist_test_extra_scripts = \ + tests/bootloader-entries-crosscheck.py \ + tests/corrupt-repo-ref.js \ + tests/ostree-grub-generator \ + $(NULL) # We can't use nobase_ as we need to strip off the tests/, can't # use plain installed_ as we do need the gpghome/ prefix. diff --git a/Makefile.in b/Makefile.in index b471c3a0..20cc20a6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -340,9 +340,10 @@ host_triplet = @host@ bin_PROGRAMS = ostree$(EXEEXT) $(am__EXEEXT_1) sbin_PROGRAMS = libexec_PROGRAMS = +pkglibexec_PROGRAMS = $(am__EXEEXT_11) noinst_PROGRAMS = $(am__EXEEXT_8) tests/test-rollsum-cli$(EXEEXT) ostree_boot_PROGRAMS = $(am__EXEEXT_9) $(am__EXEEXT_10) -TESTS = $(am__EXEEXT_3) $(am__EXEEXT_12) \ +TESTS = $(am__EXEEXT_3) $(am__EXEEXT_13) \ $(dist_uninstalled_test_scripts) installed_test_PROGRAMS = $(am__EXEEXT_7) check_PROGRAMS = $(am__EXEEXT_5) $(am__EXEEXT_6) @@ -389,6 +390,8 @@ check_PROGRAMS = $(am__EXEEXT_5) $(am__EXEEXT_6) @USE_LIBSOUP_TRUE@am__append_21 = \ @USE_LIBSOUP_TRUE@ src/libostree/ostree-fetcher.h \ @USE_LIBSOUP_TRUE@ src/libostree/ostree-fetcher.c \ +@USE_LIBSOUP_TRUE@ src/libostree/ostree-fetcher-util.h \ +@USE_LIBSOUP_TRUE@ src/libostree/ostree-fetcher-util.c \ @USE_LIBSOUP_TRUE@ src/libostree/ostree-metalink.h \ @USE_LIBSOUP_TRUE@ src/libostree/ostree-metalink.c \ @USE_LIBSOUP_TRUE@ $(NULL) @@ -408,38 +411,38 @@ check_PROGRAMS = $(am__EXEEXT_5) $(am__EXEEXT_6) @USE_LIBSOUP_TRUE@ src/ostree/ot-remote-builtin-delete-cookie.c \ @USE_LIBSOUP_TRUE@ src/ostree/ot-remote-builtin-list-cookies.c \ @USE_LIBSOUP_TRUE@ $(NULL) src/ostree/ot-builtin-pull.c \ -@USE_LIBSOUP_TRUE@ src/ostree/ot-builtin-trivial-httpd.c \ -@USE_LIBSOUP_TRUE@ $(NULL) +@USE_LIBSOUP_TRUE@ src/ostree/ot-builtin-trivial-httpd.c @USE_LIBSOUP_TRUE@am__append_33 = $(OT_INTERNAL_SOUP_CFLAGS) @USE_LIBSOUP_TRUE@am__append_34 = $(OT_INTERNAL_SOUP_LIBS) -@USE_LIBARCHIVE_TRUE@am__append_35 = $(OT_DEP_LIBARCHIVE_CFLAGS) -@USE_LIBARCHIVE_TRUE@am__append_36 = $(OT_DEP_LIBARCHIVE_LIBS) -@BUILDOPT_SYSTEMD_TRUE@am__append_37 = ostree-remount +@USE_LIBSOUP_TRUE@am__append_35 = ostree-trivial-httpd +@USE_LIBARCHIVE_TRUE@am__append_36 = $(OT_DEP_LIBARCHIVE_CFLAGS) +@USE_LIBARCHIVE_TRUE@am__append_37 = $(OT_DEP_LIBARCHIVE_LIBS) +@BUILDOPT_SYSTEMD_TRUE@am__append_38 = ostree-remount # It is built anyway as a side-effect of having the symlink in tests/, # and if we declare it here, it gets cleaned up properly -@BUILDOPT_SYSTEMD_FALSE@am__append_38 = ostree-remount -@BUILDOPT_USE_STATIC_COMPILER_FALSE@am__append_39 = ostree-prepare-root -@BUILDOPT_FUSE_TRUE@am__append_40 = rofiles-fuse -@BUILDOPT_ASAN_TRUE@am__append_41 = OT_SKIP_READDIR_RAND=1 G_SLICE=always-malloc -@BUILDOPT_FUSE_TRUE@am__append_42 = tests/test-rofiles-fuse.sh -@BUILDOPT_FUSE_FALSE@am__append_43 = tests/test-rofiles-fuse.sh -@USE_LIBSOUP_TRUE@am__append_44 = tests/test-remote-cookies.sh -@BUILDOPT_GJS_TRUE@am__append_45 = $(js_tests) -@BUILDOPT_GJS_FALSE@am__append_46 = $(js_tests) -@BUILDOPT_GJS_FALSE@am__append_47 = $(js_installed_tests) -@ENABLE_INSTALLED_TESTS_FALSE@am__append_48 = -rpath $(abs_builddir) -@USE_LIBARCHIVE_TRUE@am__append_49 = tests/test-libarchive-import -@ENABLE_INSTALLED_TESTS_TRUE@am__append_50 = install-installed-tests-extra +@BUILDOPT_SYSTEMD_FALSE@am__append_39 = ostree-remount +@BUILDOPT_USE_STATIC_COMPILER_FALSE@am__append_40 = ostree-prepare-root +@BUILDOPT_FUSE_TRUE@am__append_41 = rofiles-fuse +@BUILDOPT_ASAN_TRUE@am__append_42 = OT_SKIP_READDIR_RAND=1 G_SLICE=always-malloc +@BUILDOPT_FUSE_TRUE@am__append_43 = tests/test-rofiles-fuse.sh +@BUILDOPT_FUSE_FALSE@am__append_44 = tests/test-rofiles-fuse.sh +@USE_LIBSOUP_TRUE@am__append_45 = tests/test-remote-cookies.sh +@BUILDOPT_GJS_TRUE@am__append_46 = $(js_tests) +@BUILDOPT_GJS_FALSE@am__append_47 = $(js_tests) +@BUILDOPT_GJS_FALSE@am__append_48 = $(js_installed_tests) +@ENABLE_INSTALLED_TESTS_FALSE@am__append_49 = -rpath $(abs_builddir) +@USE_LIBARCHIVE_TRUE@am__append_50 = tests/test-libarchive-import +@ENABLE_INSTALLED_TESTS_TRUE@am__append_51 = install-installed-tests-extra # Allow the distcheck install under $prefix test to pass -@BUILDOPT_SYSTEMD_TRUE@am__append_51 = --with-systemdsystemunitdir='$${libdir}/systemd/system' +@BUILDOPT_SYSTEMD_TRUE@am__append_52 = --with-systemdsystemunitdir='$${libdir}/systemd/system' # We're using the system grub2-mkconfig generator -@BUILDOPT_BUILTIN_GRUB2_MKCONFIG_FALSE@am__append_52 = src/boot/grub2/grub2-15_ostree -@BUILDOPT_BUILTIN_GRUB2_MKCONFIG_FALSE@am__append_53 = install-grub2-config-hook -@BUILDOPT_FUSE_TRUE@@ENABLE_MAN_TRUE@am__append_54 = rofiles-fuse.1 -@ENABLE_MAN_TRUE@am__append_55 = $(man1_MANS) $(man5_MANS) $(man1_MANS:.1=.xml) $(man5_MANS:.5=.xml) -@ENABLE_MAN_TRUE@am__append_56 = \ +@BUILDOPT_BUILTIN_GRUB2_MKCONFIG_FALSE@am__append_53 = src/boot/grub2/grub2-15_ostree +@BUILDOPT_BUILTIN_GRUB2_MKCONFIG_FALSE@am__append_54 = install-grub2-config-hook +@BUILDOPT_FUSE_TRUE@@ENABLE_MAN_TRUE@am__append_55 = rofiles-fuse.1 +@ENABLE_MAN_TRUE@am__append_56 = $(man1_MANS) $(man5_MANS) $(man1_MANS:.1=.xml) $(man5_MANS:.5=.xml) +@ENABLE_MAN_TRUE@am__append_57 = \ @ENABLE_MAN_TRUE@ $(man1_MANS) \ @ENABLE_MAN_TRUE@ $(man5_MANS) \ @ENABLE_MAN_TRUE@ $(NULL) @@ -500,8 +503,9 @@ am__installdirs = "$(DESTDIR)$(installed_testdir)" \ "$(DESTDIR)$(libdir)" "$(DESTDIR)$(privlibdir)" \ "$(DESTDIR)$(bindir)" "$(DESTDIR)$(installed_testdir)" \ "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(ostree_bootdir)" \ - "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(bindir)" \ - "$(DESTDIR)$(dracutmoddir)" "$(DESTDIR)$(installed_testdir)" \ + "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(sbindir)" \ + "$(DESTDIR)$(bindir)" "$(DESTDIR)$(dracutmoddir)" \ + "$(DESTDIR)$(installed_testdir)" \ "$(DESTDIR)$(mkinitcpioinstalldir)" \ "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" \ "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" \ @@ -628,6 +632,8 @@ am__libostree_1_la_SOURCES_DIST = src/libostree/ostree-enumtypes.h \ src/libostree/ostree-tls-cert-interaction.c \ src/libostree/ostree-tls-cert-interaction.h \ src/libostree/ostree-fetcher.h src/libostree/ostree-fetcher.c \ + src/libostree/ostree-fetcher-util.h \ + src/libostree/ostree-fetcher-util.c \ src/libostree/ostree-metalink.h \ src/libostree/ostree-metalink.c am__objects_2 = src/libostree/libostree_1_la-ostree-enumtypes.lo \ @@ -637,6 +643,7 @@ am__objects_2 = src/libostree/libostree_1_la-ostree-enumtypes.lo \ @HAVE_LIBSOUP_CLIENT_CERTS_TRUE@am__objects_4 = src/libostree/libostree_1_la-ostree-tls-cert-interaction.lo \ @HAVE_LIBSOUP_CLIENT_CERTS_TRUE@ $(am__objects_1) @USE_LIBSOUP_TRUE@am__objects_5 = src/libostree/libostree_1_la-ostree-fetcher.lo \ +@USE_LIBSOUP_TRUE@ src/libostree/libostree_1_la-ostree-fetcher-util.lo \ @USE_LIBSOUP_TRUE@ src/libostree/libostree_1_la-ostree-metalink.lo \ @USE_LIBSOUP_TRUE@ $(am__objects_1) am_libostree_1_la_OBJECTS = $(am__objects_2) \ @@ -698,8 +705,10 @@ libostree_kernel_args_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libostree_kernel_args_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -am__DEPENDENCIES_9 = $(ostree_bin_shared_ldadd) $(am__DEPENDENCIES_2) -libostreetest_la_DEPENDENCIES = $(am__DEPENDENCIES_9) +am__DEPENDENCIES_9 = libglnx.la libotutil.la libostree-1.la \ + $(am__DEPENDENCIES_2) +am__DEPENDENCIES_10 = $(am__DEPENDENCIES_9) $(am__DEPENDENCIES_2) +libostreetest_la_DEPENDENCIES = $(am__DEPENDENCIES_10) am_libostreetest_la_OBJECTS = tests/libostreetest_la-libostreetest.lo libostreetest_la_OBJECTS = $(am_libostreetest_la_OBJECTS) libostreetest_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ @@ -759,9 +768,10 @@ am__EXEEXT_4 = $(am__EXEEXT_3) @ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__EXEEXT_8 = $(am__EXEEXT_4) @BUILDOPT_SYSTEMD_TRUE@am__EXEEXT_9 = ostree-remount$(EXEEXT) @BUILDOPT_USE_STATIC_COMPILER_FALSE@am__EXEEXT_10 = ostree-prepare-root$(EXEEXT) +@USE_LIBSOUP_TRUE@am__EXEEXT_11 = ostree-trivial-httpd$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) $(installed_test_PROGRAMS) \ $(libexec_PROGRAMS) $(noinst_PROGRAMS) $(ostree_boot_PROGRAMS) \ - $(sbin_PROGRAMS) + $(pkglibexec_PROGRAMS) $(sbin_PROGRAMS) am__ostree_SOURCES_DIST = src/ostree/main.c \ src/ostree/ot-builtin-admin.c src/ostree/ot-builtins.h \ src/ostree/ot-builtin-cat.c src/ostree/ot-builtin-config.c \ @@ -817,8 +827,7 @@ am__ostree_SOURCES_DIST = src/ostree/main.c \ @USE_LIBSOUP_TRUE@ src/ostree/ostree-ot-remote-builtin-list-cookies.$(OBJEXT) \ @USE_LIBSOUP_TRUE@ $(am__objects_1) \ @USE_LIBSOUP_TRUE@ src/ostree/ostree-ot-builtin-pull.$(OBJEXT) \ -@USE_LIBSOUP_TRUE@ src/ostree/ostree-ot-builtin-trivial-httpd.$(OBJEXT) \ -@USE_LIBSOUP_TRUE@ $(am__objects_1) +@USE_LIBSOUP_TRUE@ src/ostree/ostree-ot-builtin-trivial-httpd.$(OBJEXT) am_ostree_OBJECTS = src/ostree/ostree-main.$(OBJEXT) \ src/ostree/ostree-ot-builtin-admin.$(OBJEXT) \ src/ostree/ostree-ot-builtin-cat.$(OBJEXT) \ @@ -872,9 +881,9 @@ am_ostree_OBJECTS = src/ostree/ostree-main.$(OBJEXT) \ src/ostree/ostree-ot-remote-builtin-summary.$(OBJEXT) \ $(am__objects_1) $(am__objects_6) ostree_OBJECTS = $(am_ostree_OBJECTS) -ostree_DEPENDENCIES = $(ostree_bin_shared_ldadd) $(am__DEPENDENCIES_2) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_6) \ - $(am__DEPENDENCIES_4) +ostree_DEPENDENCIES = $(am__DEPENDENCIES_9) libbsdiff.la \ + libostree-kernel-args.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_6) $(am__DEPENDENCIES_4) ostree_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ostree_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ @@ -895,6 +904,16 @@ ostree_remount_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(ostree_remount_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \ $@ +am__ostree_trivial_httpd_SOURCES_DIST = \ + src/ostree/ostree-trivial-httpd.c +@USE_LIBSOUP_TRUE@am_ostree_trivial_httpd_OBJECTS = src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.$(OBJEXT) +ostree_trivial_httpd_OBJECTS = $(am_ostree_trivial_httpd_OBJECTS) +@USE_LIBSOUP_TRUE@ostree_trivial_httpd_DEPENDENCIES = \ +@USE_LIBSOUP_TRUE@ $(am__DEPENDENCIES_9) $(am__DEPENDENCIES_2) +ostree_trivial_httpd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(ostree_trivial_httpd_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ am__rofiles_fuse_SOURCES_DIST = src/rofiles-fuse/main.c @BUILDOPT_FUSE_TRUE@am_rofiles_fuse_OBJECTS = src/rofiles-fuse/rofiles_fuse-main.$(OBJEXT) rofiles_fuse_OBJECTS = $(am_rofiles_fuse_OBJECTS) @@ -907,8 +926,8 @@ rofiles_fuse_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ tests_test_basic_c_SOURCES = tests/test-basic-c.c tests_test_basic_c_OBJECTS = \ tests/tests_test_basic_c-test-basic-c.$(OBJEXT) -am__DEPENDENCIES_10 = $(am__DEPENDENCIES_9) libostreetest.la -tests_test_basic_c_DEPENDENCIES = $(am__DEPENDENCIES_10) +am__DEPENDENCIES_11 = $(am__DEPENDENCIES_10) libostreetest.la +tests_test_basic_c_DEPENDENCIES = $(am__DEPENDENCIES_11) tests_test_basic_c_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_basic_c_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -916,7 +935,7 @@ tests_test_basic_c_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ tests_test_bsdiff_SOURCES = tests/test-bsdiff.c tests_test_bsdiff_OBJECTS = \ tests/tests_test_bsdiff-test-bsdiff.$(OBJEXT) -tests_test_bsdiff_DEPENDENCIES = libbsdiff.la $(am__DEPENDENCIES_10) +tests_test_bsdiff_DEPENDENCIES = libbsdiff.la $(am__DEPENDENCIES_11) tests_test_bsdiff_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_bsdiff_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ @@ -925,7 +944,7 @@ am_tests_test_checksum_OBJECTS = \ src/libostree/tests_test_checksum-ostree-core.$(OBJEXT) \ tests/tests_test_checksum-test-checksum.$(OBJEXT) tests_test_checksum_OBJECTS = $(am_tests_test_checksum_OBJECTS) -tests_test_checksum_DEPENDENCIES = $(am__DEPENDENCIES_10) +tests_test_checksum_DEPENDENCIES = $(am__DEPENDENCIES_11) tests_test_checksum_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_checksum_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -933,7 +952,7 @@ tests_test_checksum_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ am_tests_test_gpg_verify_result_OBJECTS = tests/tests_test_gpg_verify_result-test-gpg-verify-result.$(OBJEXT) tests_test_gpg_verify_result_OBJECTS = \ $(am_tests_test_gpg_verify_result_OBJECTS) -tests_test_gpg_verify_result_DEPENDENCIES = $(am__DEPENDENCIES_10) \ +tests_test_gpg_verify_result_DEPENDENCIES = $(am__DEPENDENCIES_11) \ $(am__DEPENDENCIES_3) tests_test_gpg_verify_result_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ @@ -942,7 +961,7 @@ tests_test_gpg_verify_result_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ tests_test_keyfile_utils_SOURCES = tests/test-keyfile-utils.c tests_test_keyfile_utils_OBJECTS = \ tests/tests_test_keyfile_utils-test-keyfile-utils.$(OBJEXT) -tests_test_keyfile_utils_DEPENDENCIES = $(am__DEPENDENCIES_10) +tests_test_keyfile_utils_DEPENDENCIES = $(am__DEPENDENCIES_11) tests_test_keyfile_utils_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_keyfile_utils_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -950,7 +969,7 @@ tests_test_keyfile_utils_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ am_tests_test_libarchive_import_OBJECTS = tests/tests_test_libarchive_import-test-libarchive-import.$(OBJEXT) tests_test_libarchive_import_OBJECTS = \ $(am_tests_test_libarchive_import_OBJECTS) -tests_test_libarchive_import_DEPENDENCIES = $(am__DEPENDENCIES_10) \ +tests_test_libarchive_import_DEPENDENCIES = $(am__DEPENDENCIES_11) \ $(am__DEPENDENCIES_1) tests_test_libarchive_import_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ @@ -962,7 +981,7 @@ am_tests_test_lzma_OBJECTS = \ src/libostree/tests_test_lzma-ostree-lzma-decompressor.$(OBJEXT) \ tests/tests_test_lzma-test-lzma.$(OBJEXT) tests_test_lzma_OBJECTS = $(am_tests_test_lzma_OBJECTS) -tests_test_lzma_DEPENDENCIES = $(am__DEPENDENCIES_10) \ +tests_test_lzma_DEPENDENCIES = $(am__DEPENDENCIES_11) \ $(am__DEPENDENCIES_1) tests_test_lzma_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ @@ -971,7 +990,7 @@ tests_test_lzma_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ tests_test_mutable_tree_SOURCES = tests/test-mutable-tree.c tests_test_mutable_tree_OBJECTS = \ tests/tests_test_mutable_tree-test-mutable-tree.$(OBJEXT) -tests_test_mutable_tree_DEPENDENCIES = $(am__DEPENDENCIES_10) +tests_test_mutable_tree_DEPENDENCIES = $(am__DEPENDENCIES_11) tests_test_mutable_tree_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_mutable_tree_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -979,7 +998,7 @@ tests_test_mutable_tree_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ tests_test_ot_opt_utils_SOURCES = tests/test-ot-opt-utils.c tests_test_ot_opt_utils_OBJECTS = \ tests/tests_test_ot_opt_utils-test-ot-opt-utils.$(OBJEXT) -tests_test_ot_opt_utils_DEPENDENCIES = $(am__DEPENDENCIES_10) +tests_test_ot_opt_utils_DEPENDENCIES = $(am__DEPENDENCIES_11) tests_test_ot_opt_utils_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_ot_opt_utils_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -987,7 +1006,7 @@ tests_test_ot_opt_utils_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ tests_test_ot_tool_util_SOURCES = tests/test-ot-tool-util.c tests_test_ot_tool_util_OBJECTS = \ tests/tests_test_ot_tool_util-test-ot-tool-util.$(OBJEXT) -tests_test_ot_tool_util_DEPENDENCIES = $(am__DEPENDENCIES_10) +tests_test_ot_tool_util_DEPENDENCIES = $(am__DEPENDENCIES_11) tests_test_ot_tool_util_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_ot_tool_util_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -995,7 +1014,7 @@ tests_test_ot_tool_util_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ tests_test_ot_unix_utils_SOURCES = tests/test-ot-unix-utils.c tests_test_ot_unix_utils_OBJECTS = \ tests/tests_test_ot_unix_utils-test-ot-unix-utils.$(OBJEXT) -tests_test_ot_unix_utils_DEPENDENCIES = $(am__DEPENDENCIES_10) +tests_test_ot_unix_utils_DEPENDENCIES = $(am__DEPENDENCIES_11) tests_test_ot_unix_utils_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_ot_unix_utils_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1003,7 +1022,7 @@ tests_test_ot_unix_utils_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ tests_test_pull_c_SOURCES = tests/test-pull-c.c tests_test_pull_c_OBJECTS = \ tests/tests_test_pull_c-test-pull-c.$(OBJEXT) -tests_test_pull_c_DEPENDENCIES = $(am__DEPENDENCIES_10) +tests_test_pull_c_DEPENDENCIES = $(am__DEPENDENCIES_11) tests_test_pull_c_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_pull_c_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ @@ -1013,7 +1032,7 @@ am_tests_test_rollsum_OBJECTS = \ tests/tests_test_rollsum-test-rollsum.$(OBJEXT) tests_test_rollsum_OBJECTS = $(am_tests_test_rollsum_OBJECTS) tests_test_rollsum_DEPENDENCIES = libbupsplit.la \ - $(am__DEPENDENCIES_10) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_11) $(am__DEPENDENCIES_1) tests_test_rollsum_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_rollsum_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1023,7 +1042,7 @@ am_tests_test_rollsum_cli_OBJECTS = \ tests/tests_test_rollsum_cli-test-rollsum-cli.$(OBJEXT) tests_test_rollsum_cli_OBJECTS = $(am_tests_test_rollsum_cli_OBJECTS) tests_test_rollsum_cli_DEPENDENCIES = libbupsplit.la \ - $(am__DEPENDENCIES_10) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_11) $(am__DEPENDENCIES_1) tests_test_rollsum_cli_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_rollsum_cli_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1031,7 +1050,7 @@ tests_test_rollsum_cli_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ tests_test_sysroot_c_SOURCES = tests/test-sysroot-c.c tests_test_sysroot_c_OBJECTS = \ tests/tests_test_sysroot_c-test-sysroot-c.$(OBJEXT) -tests_test_sysroot_c_DEPENDENCIES = $(am__DEPENDENCIES_10) +tests_test_sysroot_c_DEPENDENCIES = $(am__DEPENDENCIES_11) tests_test_sysroot_c_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_sysroot_c_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ @@ -1040,7 +1059,7 @@ am_tests_test_varint_OBJECTS = \ src/libostree/tests_test_varint-ostree-varint.$(OBJEXT) \ tests/tests_test_varint-test-varint.$(OBJEXT) tests_test_varint_OBJECTS = $(am_tests_test_varint_OBJECTS) -tests_test_varint_DEPENDENCIES = $(am__DEPENDENCIES_10) +tests_test_varint_DEPENDENCIES = $(am__DEPENDENCIES_11) tests_test_varint_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(tests_test_varint_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ @@ -1088,8 +1107,9 @@ SOURCES = $(libbsdiff_la_SOURCES) $(libbupsplit_la_SOURCES) \ $(libostreetest_la_SOURCES) $(libotutil_la_SOURCES) \ $(libreaddir_rand_la_SOURCES) $(ostree_SOURCES) \ $(ostree_prepare_root_SOURCES) $(ostree_remount_SOURCES) \ - $(rofiles_fuse_SOURCES) tests/test-basic-c.c \ - tests/test-bsdiff.c $(tests_test_checksum_SOURCES) \ + $(ostree_trivial_httpd_SOURCES) $(rofiles_fuse_SOURCES) \ + tests/test-basic-c.c tests/test-bsdiff.c \ + $(tests_test_checksum_SOURCES) \ $(tests_test_gpg_verify_result_SOURCES) \ tests/test-keyfile-utils.c \ $(tests_test_libarchive_import_SOURCES) \ @@ -1105,6 +1125,7 @@ DIST_SOURCES = $(libbsdiff_la_SOURCES) $(libbupsplit_la_SOURCES) \ $(libostreetest_la_SOURCES) $(libotutil_la_SOURCES) \ $(libreaddir_rand_la_SOURCES) $(am__ostree_SOURCES_DIST) \ $(ostree_prepare_root_SOURCES) $(ostree_remount_SOURCES) \ + $(am__ostree_trivial_httpd_SOURCES_DIST) \ $(am__rofiles_fuse_SOURCES_DIST) tests/test-basic-c.c \ tests/test-bsdiff.c $(tests_test_checksum_SOURCES) \ $(tests_test_gpg_verify_result_SOURCES) \ @@ -1333,20 +1354,21 @@ am__set_TESTS_bases = \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) -am__EXEEXT_11 = -am__EXEEXT_12 = tests/test-basic.sh tests/test-pull-subpath.sh \ - tests/test-archivez.sh tests/test-remote-add.sh \ - tests/test-remote-headers.sh tests/test-remote-gpg-import.sh \ - tests/test-commit-sign.sh tests/test-export.sh \ - tests/test-help.sh tests/test-libarchive.sh \ - tests/test-parent.sh tests/test-pull-archive-z.sh \ - tests/test-pull-commit-only.sh tests/test-pull-depth.sh \ - tests/test-pull-mirror-summary.sh \ +am__EXEEXT_12 = +am__EXEEXT_13 = tests/test-basic.sh tests/test-basic-user.sh \ + tests/test-pull-subpath.sh tests/test-archivez.sh \ + tests/test-remote-add.sh tests/test-remote-headers.sh \ + tests/test-remote-gpg-import.sh tests/test-commit-sign.sh \ + tests/test-export.sh tests/test-help.sh \ + tests/test-libarchive.sh tests/test-parent.sh \ + tests/test-pull-archive-z.sh tests/test-pull-commit-only.sh \ + tests/test-pull-depth.sh tests/test-pull-mirror-summary.sh \ tests/test-pull-large-metadata.sh tests/test-pull-metalink.sh \ tests/test-pull-summary-sigs.sh tests/test-pull-resume.sh \ tests/test-pull-repeated.sh tests/test-pull-untrusted.sh \ - tests/test-pull-override-url.sh tests/test-local-pull.sh \ - tests/test-local-pull-depth.sh tests/test-gpg-signed-commit.sh \ + tests/test-pull-many.sh tests/test-pull-override-url.sh \ + tests/test-local-pull.sh tests/test-local-pull-depth.sh \ + tests/test-gpg-signed-commit.sh \ tests/test-admin-upgrade-unconfigured.sh \ tests/test-admin-deploy-syslinux.sh \ tests/test-admin-deploy-2.sh tests/test-admin-deploy-karg.sh \ @@ -1365,8 +1387,8 @@ am__EXEEXT_12 = tests/test-basic.sh tests/test-pull-subpath.sh \ tests/test-auto-summary.sh tests/test-prune.sh \ tests/test-refs.sh tests/test-demo-buildsystem.sh \ tests/test-switchroot.sh tests/test-pull-contenturl.sh \ - tests/test-pull-mirrorlist.sh $(am__EXEEXT_11) \ - $(am__append_42) $(am__append_44) $(am__append_45) + tests/test-pull-mirrorlist.sh $(am__EXEEXT_12) \ + $(am__append_43) $(am__append_45) $(am__append_46) TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) @@ -1642,7 +1664,7 @@ AM_CPPFLAGS = -DDATADIR='"$(datadir)"' -DLIBEXECDIR='"$(libexecdir)"' \ -DSOUP_VERSION_MAX_ALLOWED=SOUP_VERSION_2_48 AM_CFLAGS = -std=gnu99 $(WARN_CFLAGS) AM_DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc --enable-man \ - --disable-maintainer-mode $(NULL) $(am__append_51) + --disable-maintainer-mode $(NULL) $(am__append_52) SUBDIRS = . $(am__append_14) NULL = BUILT_SOURCES = $(ENUM_GENERATED) @@ -1654,7 +1676,7 @@ CLEANFILES = $(am__append_13) $(BUILT_SOURCES) $(am__append_31) \ tests/ostree-remount-symlink-stamp \ tests/rofiles-fuse-symlink-stamp tests/ostree \ tests/ostree-prepare-root tests/ostree-remount \ - tests/rofiles-fuse $(am__append_56) + tests/rofiles-fuse $(am__append_57) EXTRA_DIST = $(all_dist_test_scripts) $(all_dist_test_data) autogen.sh \ COPYING README.md libglnx/README.md libglnx/COPYING \ libglnx/libglnx.m4 $(NULL) libglnx/Makefile-libglnx.am \ @@ -1668,17 +1690,17 @@ EXTRA_DIST = $(all_dist_test_scripts) $(all_dist_test_data) autogen.sh \ src/libostree/ostree-repo-deprecated.h \ src/ostree/parse-datetime.y buildutil/tap-driver.sh \ buildutil/tap-test tests/glib.supp tests/ostree.supp $(NULL) \ - $(am__append_43) $(am__append_46) tests/libtest.sh \ - $(am__append_47) tests/libostreetest.h tests/libtest.sh \ + $(am__append_44) $(am__append_47) tests/libtest.sh \ + $(am__append_48) tests/libostreetest.h tests/libtest.sh \ tests/gpg-verify-data/README.md $(NULL) \ src/boot/dracut/module-setup.sh src/boot/dracut/ostree.conf \ src/boot/mkinitcpio/ostree \ src/boot/ostree-prepare-root.service \ src/boot/ostree-remount.service src/boot/grub2/grub2-15_ostree \ - src/boot/grub2/ostree-grub-generator $(NULL) $(am__append_55) + src/boot/grub2/ostree-grub-generator $(NULL) $(am__append_56) bin_SCRIPTS = lib_LTLIBRARIES = libostree-1.la -pkglibexec_SCRIPTS = $(am__append_52) +pkglibexec_SCRIPTS = $(am__append_53) noinst_LTLIBRARIES = $(am__append_1) libglnx.la libbsdiff.la \ libotutil.la libostree-kernel-args.la libbupsplit.la \ libostreetest.la @@ -1701,12 +1723,13 @@ TESTS_ENVIRONMENT = G_TEST_SRCDIR="$(abs_srcdir)" \ G_TEST_BUILDDIR="$(abs_builddir)" UNINSTALLEDTESTS=1 \ G_DEBUG=gc-friendly MALLOC_CHECK_=2 \ MALLOC_PERTURB_=$$(($${RANDOM:-256} % 256)) OT_TESTS_DEBUG=1 \ - G_DEBUG=fatal-warnings GI_TYPELIB_PATH=$$(cd $(top_builddir) \ - && pwd)$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH} \ + OSTREE_UNINSTALLED=$(abs_top_builddir) G_DEBUG=fatal-warnings \ + GI_TYPELIB_PATH=$$(cd $(top_builddir) && \ + pwd)$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH} \ LD_LIBRARY_PATH=$$(cd $(top_builddir)/.libs && \ pwd)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}} PATH=$$(cd \ $(top_builddir)/tests && pwd):$${PATH} $(NULL) \ - $(am__append_41) + $(am__append_42) LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/buildutil/tap-driver.sh LOG_COMPILER = $(top_srcdir)/buildutil/tap-test installed_test_LTLIBRARIES = $(am__append_12) @@ -1746,8 +1769,8 @@ all_test_ltlibs = $(test_ltlibraries) $(uninstalled_test_ltlibraries) $(installe # This initializes some more variables # This is a special facility to chain together hooks easily -INSTALL_DATA_HOOKS = install-mkdir-remotes-d-hook $(am__append_50) \ - $(am__append_53) +INSTALL_DATA_HOOKS = install-mkdir-remotes-d-hook $(am__append_51) \ + $(am__append_54) ALL_LOCAL_RULES = tests/libreaddir-rand.so shortened_sysconfdir = $$(echo "$(sysconfdir)" | sed -e 's|^$(prefix)||' -e 's|^/||') ACLOCAL_AMFLAGS = -I buildutil -I libglnx ${ACLOCAL_FLAGS} @@ -2009,15 +2032,21 @@ ostree_SOURCES = src/ostree/main.c src/ostree/ot-builtin-admin.c \ src/ostree/ot-remote-builtin-refs.c \ src/ostree/ot-remote-builtin-summary.c $(NULL) \ $(am__append_32) -ostree_bin_shared_cflags = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree -I$(srcdir)/src/ostree \ - $(NULL) +ostree_bin_shared_cflags = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree \ + -I$(srcdir)/src/ostree -I$(srcdir)/libglnx $(OT_INTERNAL_GIO_UNIX_CFLAGS) \ + -DPKGLIBEXECDIR=\"$(pkglibexecdir)\" -ostree_bin_shared_ldadd = libglnx.la libbsdiff.la libotutil.la libostree-kernel-args.la libostree-1.la -ostree_CFLAGS = $(ostree_bin_shared_cflags) \ - $(OT_INTERNAL_GIO_UNIX_CFLAGS) -I$(srcdir)/libglnx \ - $(am__append_33) $(am__append_35) -ostree_LDADD = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_GIO_UNIX_LIBS) \ - $(LIBSYSTEMD_LIBS) $(am__append_34) $(am__append_36) +ostree_bin_shared_ldadd = $(AM_LDFLAGS) libglnx.la libotutil.la libostree-1.la \ + $(OT_INTERNAL_GIO_UNIX_LIBS) + +ostree_CFLAGS = $(ostree_bin_shared_cflags) $(am__append_33) \ + $(am__append_36) +ostree_LDADD = $(ostree_bin_shared_ldadd) libbsdiff.la \ + libostree-kernel-args.la $(LIBSYSTEMD_LIBS) $(am__append_34) \ + $(am__append_37) +@USE_LIBSOUP_TRUE@ostree_trivial_httpd_SOURCES = src/ostree/ostree-trivial-httpd.c +@USE_LIBSOUP_TRUE@ostree_trivial_httpd_CFLAGS = $(ostree_bin_shared_cflags) $(OT_INTERNAL_SOUP_CFLAGS) +@USE_LIBSOUP_TRUE@ostree_trivial_httpd_LDADD = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_SOUP_LIBS) ostree_prepare_root_SOURCES = \ src/switchroot/ostree-mount-util.h \ src/switchroot/ostree-prepare-root.c \ @@ -2051,19 +2080,20 @@ uninstalled_test_data = tests/ostree-symlink-stamp tests/ostree-prepare-root-sym tests/ostree-remount-symlink-stamp tests/rofiles-fuse-symlink-stamp dist_uninstalled_test_scripts = tests/test-symbols.sh -dist_test_scripts = tests/test-basic.sh tests/test-pull-subpath.sh \ - tests/test-archivez.sh tests/test-remote-add.sh \ - tests/test-remote-headers.sh tests/test-remote-gpg-import.sh \ - tests/test-commit-sign.sh tests/test-export.sh \ - tests/test-help.sh tests/test-libarchive.sh \ - tests/test-parent.sh tests/test-pull-archive-z.sh \ - tests/test-pull-commit-only.sh tests/test-pull-depth.sh \ - tests/test-pull-mirror-summary.sh \ +dist_test_scripts = tests/test-basic.sh tests/test-basic-user.sh \ + tests/test-pull-subpath.sh tests/test-archivez.sh \ + tests/test-remote-add.sh tests/test-remote-headers.sh \ + tests/test-remote-gpg-import.sh tests/test-commit-sign.sh \ + tests/test-export.sh tests/test-help.sh \ + tests/test-libarchive.sh tests/test-parent.sh \ + tests/test-pull-archive-z.sh tests/test-pull-commit-only.sh \ + tests/test-pull-depth.sh tests/test-pull-mirror-summary.sh \ tests/test-pull-large-metadata.sh tests/test-pull-metalink.sh \ tests/test-pull-summary-sigs.sh tests/test-pull-resume.sh \ tests/test-pull-repeated.sh tests/test-pull-untrusted.sh \ - tests/test-pull-override-url.sh tests/test-local-pull.sh \ - tests/test-local-pull-depth.sh tests/test-gpg-signed-commit.sh \ + tests/test-pull-many.sh tests/test-pull-override-url.sh \ + tests/test-local-pull.sh tests/test-local-pull-depth.sh \ + tests/test-gpg-signed-commit.sh \ tests/test-admin-upgrade-unconfigured.sh \ tests/test-admin-deploy-syslinux.sh \ tests/test-admin-deploy-2.sh tests/test-admin-deploy-karg.sh \ @@ -2082,8 +2112,8 @@ dist_test_scripts = tests/test-basic.sh tests/test-pull-subpath.sh \ tests/test-auto-summary.sh tests/test-prune.sh \ tests/test-refs.sh tests/test-demo-buildsystem.sh \ tests/test-switchroot.sh tests/test-pull-contenturl.sh \ - tests/test-pull-mirrorlist.sh $(NULL) $(am__append_42) \ - $(am__append_44) $(am__append_45) + tests/test-pull-mirrorlist.sh $(NULL) $(am__append_43) \ + $(am__append_45) $(am__append_46) # These call into gjs scripts js_tests = tests/test-corruption.sh tests/test-pull-corruption.sh @@ -2091,14 +2121,15 @@ dist_installed_test_data = tests/archive-test.sh \ tests/pull-test.sh \ tests/admin-test.sh \ tests/basic-test.sh \ - tests/test-basic-user.sh \ - tests/corrupt-repo-ref.js \ tests/pre-endian-deltas-repo-big.tar.xz \ tests/pre-endian-deltas-repo-little.tar.xz \ $(NULL) -dist_test_extra_scripts = tests/bootloader-entries-crosscheck.py \ - tests/ostree-grub-generator +dist_test_extra_scripts = \ + tests/bootloader-entries-crosscheck.py \ + tests/corrupt-repo-ref.js \ + tests/ostree-grub-generator \ + $(NULL) # We can't use nobase_ as we need to strip off the tests/, can't @@ -2133,14 +2164,14 @@ libreaddir_rand_la_LIBADD = \ $(NULL) libreaddir_rand_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version \ - $(am__append_48) + $(am__append_49) test_programs = tests/test-varint tests/test-ot-unix-utils \ tests/test-bsdiff tests/test-mutable-tree \ tests/test-keyfile-utils tests/test-ot-opt-utils \ tests/test-ot-tool-util tests/test-gpg-verify-result \ tests/test-checksum tests/test-lzma tests/test-rollsum \ tests/test-basic-c tests/test-sysroot-c tests/test-pull-c \ - $(am__append_49) + $(am__append_50) common_tests_cflags = $(ostree_bin_shared_cflags) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -I$(srcdir)/libglnx common_tests_ldadd = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_GIO_UNIX_LIBS) libostreetest_la_SOURCES = tests/libostreetest.c @@ -2224,7 +2255,7 @@ tests_test_gpg_verify_result_LDADD = $(TESTS_LDADD) $(OT_INTERNAL_GPGME_LIBS) @ENABLE_MAN_TRUE@ ostree-reset.1 ostree-rev-parse.1 \ @ENABLE_MAN_TRUE@ ostree-show.1 ostree-summary.1 \ @ENABLE_MAN_TRUE@ ostree-static-delta.1 ostree-trivial-httpd.1 \ -@ENABLE_MAN_TRUE@ $(am__append_54) +@ENABLE_MAN_TRUE@ $(am__append_55) @ENABLE_MAN_TRUE@man5_files = ostree.repo.5 ostree.repo-config.5 @ENABLE_MAN_TRUE@man1_MANS = $(addprefix man/,$(man1_files)) @ENABLE_MAN_TRUE@man5_MANS = $(addprefix man/,$(man5_files)) @@ -2609,6 +2640,9 @@ src/libostree/libostree_1_la-ostree-tls-cert-interaction.lo: \ src/libostree/libostree_1_la-ostree-fetcher.lo: \ src/libostree/$(am__dirstamp) \ src/libostree/$(DEPDIR)/$(am__dirstamp) +src/libostree/libostree_1_la-ostree-fetcher-util.lo: \ + src/libostree/$(am__dirstamp) \ + src/libostree/$(DEPDIR)/$(am__dirstamp) src/libostree/libostree_1_la-ostree-metalink.lo: \ src/libostree/$(am__dirstamp) \ src/libostree/$(DEPDIR)/$(am__dirstamp) @@ -2895,6 +2929,55 @@ clean-ostree_bootPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list +install-pkglibexecPROGRAMS: $(pkglibexec_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(pkglibexec_PROGRAMS)'; test -n "$(pkglibexecdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibexecdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibexecdir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(pkglibexecdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(pkglibexecdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-pkglibexecPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(pkglibexec_PROGRAMS)'; test -n "$(pkglibexecdir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(pkglibexecdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pkglibexecdir)" && rm -f $$files + +clean-pkglibexecPROGRAMS: + @list='$(pkglibexec_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ @@ -3134,6 +3217,13 @@ src/switchroot/ostree_remount-ostree-remount.$(OBJEXT): \ ostree-remount$(EXEEXT): $(ostree_remount_OBJECTS) $(ostree_remount_DEPENDENCIES) $(EXTRA_ostree_remount_DEPENDENCIES) @rm -f ostree-remount$(EXEEXT) $(AM_V_CCLD)$(ostree_remount_LINK) $(ostree_remount_OBJECTS) $(ostree_remount_LDADD) $(LIBS) +src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.$(OBJEXT): \ + src/ostree/$(am__dirstamp) \ + src/ostree/$(DEPDIR)/$(am__dirstamp) + +ostree-trivial-httpd$(EXEEXT): $(ostree_trivial_httpd_OBJECTS) $(ostree_trivial_httpd_DEPENDENCIES) $(EXTRA_ostree_trivial_httpd_DEPENDENCIES) + @rm -f ostree-trivial-httpd$(EXEEXT) + $(AM_V_CCLD)$(ostree_trivial_httpd_LINK) $(ostree_trivial_httpd_OBJECTS) $(ostree_trivial_httpd_LDADD) $(LIBS) src/rofiles-fuse/$(am__dirstamp): @$(MKDIR_P) src/rofiles-fuse @: > src/rofiles-fuse/$(am__dirstamp) @@ -3520,6 +3610,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-diff.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-dummy-enumtypes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-enumtypes.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-gpg-verifier.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/libostree/$(DEPDIR)/libostree_1_la-ostree-gpg-verify-result.Plo@am__quote@ @@ -3627,6 +3718,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-remote-builtin-show-url.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-ot-remote-builtin-summary.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree-parse-datetime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/ostree/$(DEPDIR)/ostree_trivial_httpd-ostree-trivial-httpd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/rofiles-fuse/$(DEPDIR)/rofiles_fuse-main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/switchroot/$(DEPDIR)/ostree_prepare_root-ostree-prepare-root.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/switchroot/$(DEPDIR)/ostree_remount-ostree-remount.Po@am__quote@ @@ -4065,6 +4157,13 @@ src/libostree/libostree_1_la-ostree-fetcher.lo: src/libostree/ostree-fetcher.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) $(libostree_1_la_CFLAGS) $(CFLAGS) -c -o src/libostree/libostree_1_la-ostree-fetcher.lo `test -f 'src/libostree/ostree-fetcher.c' || echo '$(srcdir)/'`src/libostree/ostree-fetcher.c +src/libostree/libostree_1_la-ostree-fetcher-util.lo: src/libostree/ostree-fetcher-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -MT src/libostree/libostree_1_la-ostree-fetcher-util.lo -MD -MP -MF src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-util.Tpo -c -o src/libostree/libostree_1_la-ostree-fetcher-util.lo `test -f 'src/libostree/ostree-fetcher-util.c' || echo '$(srcdir)/'`src/libostree/ostree-fetcher-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-util.Tpo src/libostree/$(DEPDIR)/libostree_1_la-ostree-fetcher-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/libostree/ostree-fetcher-util.c' object='src/libostree/libostree_1_la-ostree-fetcher-util.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -c -o src/libostree/libostree_1_la-ostree-fetcher-util.lo `test -f 'src/libostree/ostree-fetcher-util.c' || echo '$(srcdir)/'`src/libostree/ostree-fetcher-util.c + src/libostree/libostree_1_la-ostree-metalink.lo: src/libostree/ostree-metalink.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libostree_1_la_CFLAGS) $(CFLAGS) -MT src/libostree/libostree_1_la-ostree-metalink.lo -MD -MP -MF src/libostree/$(DEPDIR)/libostree_1_la-ostree-metalink.Tpo -c -o src/libostree/libostree_1_la-ostree-metalink.lo `test -f 'src/libostree/ostree-metalink.c' || echo '$(srcdir)/'`src/libostree/ostree-metalink.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/libostree/$(DEPDIR)/libostree_1_la-ostree-metalink.Tpo src/libostree/$(DEPDIR)/libostree_1_la-ostree-metalink.Plo @@ -4975,6 +5074,20 @@ src/switchroot/ostree_remount-ostree-remount.obj: src/switchroot/ostree-remount. @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_remount_CFLAGS) $(CFLAGS) -c -o src/switchroot/ostree_remount-ostree-remount.obj `if test -f 'src/switchroot/ostree-remount.c'; then $(CYGPATH_W) 'src/switchroot/ostree-remount.c'; else $(CYGPATH_W) '$(srcdir)/src/switchroot/ostree-remount.c'; fi` +src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.o: src/ostree/ostree-trivial-httpd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_trivial_httpd_CFLAGS) $(CFLAGS) -MT src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.o -MD -MP -MF src/ostree/$(DEPDIR)/ostree_trivial_httpd-ostree-trivial-httpd.Tpo -c -o src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.o `test -f 'src/ostree/ostree-trivial-httpd.c' || echo '$(srcdir)/'`src/ostree/ostree-trivial-httpd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/ostree/$(DEPDIR)/ostree_trivial_httpd-ostree-trivial-httpd.Tpo src/ostree/$(DEPDIR)/ostree_trivial_httpd-ostree-trivial-httpd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/ostree/ostree-trivial-httpd.c' object='src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_trivial_httpd_CFLAGS) $(CFLAGS) -c -o src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.o `test -f 'src/ostree/ostree-trivial-httpd.c' || echo '$(srcdir)/'`src/ostree/ostree-trivial-httpd.c + +src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.obj: src/ostree/ostree-trivial-httpd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_trivial_httpd_CFLAGS) $(CFLAGS) -MT src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.obj -MD -MP -MF src/ostree/$(DEPDIR)/ostree_trivial_httpd-ostree-trivial-httpd.Tpo -c -o src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.obj `if test -f 'src/ostree/ostree-trivial-httpd.c'; then $(CYGPATH_W) 'src/ostree/ostree-trivial-httpd.c'; else $(CYGPATH_W) '$(srcdir)/src/ostree/ostree-trivial-httpd.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/ostree/$(DEPDIR)/ostree_trivial_httpd-ostree-trivial-httpd.Tpo src/ostree/$(DEPDIR)/ostree_trivial_httpd-ostree-trivial-httpd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/ostree/ostree-trivial-httpd.c' object='src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ostree_trivial_httpd_CFLAGS) $(CFLAGS) -c -o src/ostree/ostree_trivial_httpd-ostree-trivial-httpd.obj `if test -f 'src/ostree/ostree-trivial-httpd.c'; then $(CYGPATH_W) 'src/ostree/ostree-trivial-httpd.c'; else $(CYGPATH_W) '$(srcdir)/src/ostree/ostree-trivial-httpd.c'; fi` + src/rofiles-fuse/rofiles_fuse-main.o: src/rofiles-fuse/main.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rofiles_fuse_CFLAGS) $(CFLAGS) -MT src/rofiles-fuse/rofiles_fuse-main.o -MD -MP -MF src/rofiles-fuse/$(DEPDIR)/rofiles_fuse-main.Tpo -c -o src/rofiles-fuse/rofiles_fuse-main.o `test -f 'src/rofiles-fuse/main.c' || echo '$(srcdir)/'`src/rofiles-fuse/main.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/rofiles-fuse/$(DEPDIR)/rofiles_fuse-main.Tpo src/rofiles-fuse/$(DEPDIR)/rofiles_fuse-main.Po @@ -6063,6 +6176,13 @@ tests/test-basic.sh.log: tests/test-basic.sh --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +tests/test-basic-user.sh.log: tests/test-basic-user.sh + @p='tests/test-basic-user.sh'; \ + b='tests/test-basic-user.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) tests/test-pull-subpath.sh.log: tests/test-pull-subpath.sh @p='tests/test-pull-subpath.sh'; \ b='tests/test-pull-subpath.sh'; \ @@ -6203,6 +6323,13 @@ tests/test-pull-untrusted.sh.log: tests/test-pull-untrusted.sh --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +tests/test-pull-many.sh.log: tests/test-pull-many.sh + @p='tests/test-pull-many.sh'; \ + b='tests/test-pull-many.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) tests/test-pull-override-url.sh.log: tests/test-pull-override-url.sh @p='tests/test-pull-override-url.sh'; \ b='tests/test-pull-override-url.sh'; \ @@ -6662,7 +6789,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)$(sbindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(dracutmoddir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(mkinitcpioinstalldir)" "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(gpginsttestdir)" "$(DESTDIR)$(gpginsttest_trusteddir)" "$(DESTDIR)$(gpgvinsttestdir)" "$(DESTDIR)$(dracutconfdir)" "$(DESTDIR)$(girdir)" "$(DESTDIR)$(gpgreadmedir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(installed_test_metadir)" "$(DESTDIR)$(mkinitcpioconfdir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(systemdsystemunitdir)" "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(libostreeincludedir)"; do \ + for dir in "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(privlibdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(dracutmoddir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(mkinitcpioinstalldir)" "$(DESTDIR)$(ostree_bootdir)" "$(DESTDIR)$(pkglibexecdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(gpginsttestdir)" "$(DESTDIR)$(gpginsttest_trusteddir)" "$(DESTDIR)$(gpgvinsttestdir)" "$(DESTDIR)$(dracutconfdir)" "$(DESTDIR)$(girdir)" "$(DESTDIR)$(gpgreadmedir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(installed_test_metadir)" "$(DESTDIR)$(mkinitcpioconfdir)" "$(DESTDIR)$(installed_testdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(systemdsystemunitdir)" "$(DESTDIR)$(typelibdir)" "$(DESTDIR)$(libostreeincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) @@ -6724,7 +6851,8 @@ clean-am: clean-binPROGRAMS clean-checkLTLIBRARIES clean-checkPROGRAMS \ clean-installed_testPROGRAMS clean-libLTLIBRARIES \ clean-libexecPROGRAMS clean-libtool clean-noinstLTLIBRARIES \ clean-noinstPROGRAMS clean-ostree_bootPROGRAMS \ - clean-privlibLTLIBRARIES clean-sbinPROGRAMS mostlyclean-am + clean-pkglibexecPROGRAMS clean-privlibLTLIBRARIES \ + clean-sbinPROGRAMS mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) @@ -6766,7 +6894,8 @@ install-dvi-am: install-exec-am: install-binPROGRAMS install-binSCRIPTS \ install-libLTLIBRARIES install-libexecPROGRAMS \ - install-pkglibexecSCRIPTS install-sbinPROGRAMS + install-pkglibexecPROGRAMS install-pkglibexecSCRIPTS \ + install-sbinPROGRAMS install-html: install-html-recursive @@ -6823,9 +6952,10 @@ uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \ uninstall-mkinitcpioinstallSCRIPTS \ uninstall-nobase_installed_testDATA \ uninstall-ostree_bootPROGRAMS uninstall-ostree_bootSCRIPTS \ - uninstall-pkgconfigDATA uninstall-pkglibexecSCRIPTS \ - uninstall-privlibLTLIBRARIES uninstall-sbinPROGRAMS \ - uninstall-systemdsystemunitDATA uninstall-typelibDATA + uninstall-pkgconfigDATA uninstall-pkglibexecPROGRAMS \ + uninstall-pkglibexecSCRIPTS uninstall-privlibLTLIBRARIES \ + uninstall-sbinPROGRAMS uninstall-systemdsystemunitDATA \ + uninstall-typelibDATA uninstall-man: uninstall-man1 uninstall-man5 @@ -6839,15 +6969,15 @@ uninstall-man: uninstall-man1 uninstall-man5 clean-installed_testPROGRAMS clean-libLTLIBRARIES \ clean-libexecPROGRAMS clean-libtool clean-noinstLTLIBRARIES \ clean-noinstPROGRAMS clean-ostree_bootPROGRAMS \ - clean-privlibLTLIBRARIES clean-sbinPROGRAMS cscope \ - cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ - dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ - distcheck distclean distclean-compile distclean-generic \ - distclean-hdr distclean-libtool distclean-tags distcleancheck \ - distdir distuninstallcheck dvi dvi-am html html-am info \ - info-am install install-am install-binPROGRAMS \ - install-binSCRIPTS install-data install-data-am \ - install-data-hook install-dist_gpginsttestDATA \ + clean-pkglibexecPROGRAMS clean-privlibLTLIBRARIES \ + clean-sbinPROGRAMS cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-compile \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-binSCRIPTS install-data \ + install-data-am install-data-hook install-dist_gpginsttestDATA \ install-dist_gpginsttest_trustedDATA \ install-dist_gpgvinsttestDATA install-dracutconfDATA \ install-dracutmodSCRIPTS install-dvi install-dvi-am \ @@ -6862,9 +6992,9 @@ uninstall-man: uninstall-man1 uninstall-man5 install-mkinitcpioconfDATA install-mkinitcpioinstallSCRIPTS \ install-nobase_installed_testDATA install-ostree_bootPROGRAMS \ install-ostree_bootSCRIPTS install-pdf install-pdf-am \ - install-pkgconfigDATA install-pkglibexecSCRIPTS \ - install-privlibLTLIBRARIES install-ps install-ps-am \ - install-sbinPROGRAMS install-strip \ + install-pkgconfigDATA install-pkglibexecPROGRAMS \ + install-pkglibexecSCRIPTS install-privlibLTLIBRARIES \ + install-ps install-ps-am install-sbinPROGRAMS install-strip \ install-systemdsystemunitDATA install-typelibDATA installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ @@ -6886,9 +7016,10 @@ uninstall-man: uninstall-man1 uninstall-man5 uninstall-mkinitcpioinstallSCRIPTS \ uninstall-nobase_installed_testDATA \ uninstall-ostree_bootPROGRAMS uninstall-ostree_bootSCRIPTS \ - uninstall-pkgconfigDATA uninstall-pkglibexecSCRIPTS \ - uninstall-privlibLTLIBRARIES uninstall-sbinPROGRAMS \ - uninstall-systemdsystemunitDATA uninstall-typelibDATA + uninstall-pkgconfigDATA uninstall-pkglibexecPROGRAMS \ + uninstall-pkglibexecSCRIPTS uninstall-privlibLTLIBRARIES \ + uninstall-sbinPROGRAMS uninstall-systemdsystemunitDATA \ + uninstall-typelibDATA .PRECIOUS: Makefile diff --git a/apidoc/html/index.html b/apidoc/html/index.html index 2cf1bcc6..0ec9a6bf 100644 --- a/apidoc/html/index.html +++ b/apidoc/html/index.html @@ -14,7 +14,7 @@
-

for OSTree 2016.14

+

for OSTree 2016.15


diff --git a/apidoc/html/ostree-Content-addressed-object-store.html b/apidoc/html/ostree-Content-addressed-object-store.html index 8363a580..32f2a50a 100644 --- a/apidoc/html/ostree-Content-addressed-object-store.html +++ b/apidoc/html/ostree-Content-addressed-object-store.html @@ -900,6 +900,14 @@ gboolean +ostree_repo_prune_from_reachable () + + + + +gboolean + + ostree_repo_pull () @@ -5215,8 +5223,8 @@ to

out_objects

-

Map of serialized object name to variant data.

-[
out] +

Map of serialized object name to variant data.

+[out][transfer container][element-type GVariant GVariant]

cancellable

@@ -5272,8 +5280,8 @@ with start

out_commits

-

Array of GVariants

-  +

Map of serialized commit name to variant data.

+[out][transfer container][element-type GVariant GVariant]

cancellable

@@ -5973,6 +5981,74 @@ non existing commit.


+

ostree_repo_prune_from_reachable ()

+
gboolean
+ostree_repo_prune_from_reachable (OstreeRepo *self,
+                                  OstreeRepoPruneOptions *options,
+                                  gint *out_objects_total,
+                                  gint *out_objects_pruned,
+                                  guint64 *out_pruned_object_size_total,
+                                  GCancellable *cancellable,
+                                  GError **error);
+

Delete content from the repository. This function is the "backend" +half of the higher level ostree_repo_prune(). To use this function, +you determine the root set yourself, and this function finds all other +unreferenced objects and deletes them.

+

Use this API when you want to perform more selective pruning - for example, +retain all commits from a production branch, but just GC some history from +your dev branch.

+

The OSTREE_REPO_PRUNE_FLAGS_NO_PRUNE flag may be specified to just determine +statistics on objects that would be deleted, without actually deleting them.

+
+

Parameters

+
+++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

self

Repo

 

options

Options controlling prune process

 

out_objects_total

Number of objects found.

[out]

out_objects_pruned

Number of objects deleted.

[out]

out_pruned_object_size_total

Storage size in bytes of objects deleted.

[out]

cancellable

Cancellable

 

error

Error

 
+
+
+
+

ostree_repo_pull ()

gboolean
 ostree_repo_pull (OstreeRepo *self,
diff --git a/apidoc/html/ostree.devhelp2 b/apidoc/html/ostree.devhelp2
index 734596e6..08fa2960 100644
--- a/apidoc/html/ostree.devhelp2
+++ b/apidoc/html/ostree.devhelp2
@@ -186,6 +186,7 @@
     
     
     
+    
     
     
     
diff --git a/apidoc/html/reference.html b/apidoc/html/reference.html
index 5643d548..fa2e25d8 100644
--- a/apidoc/html/reference.html
+++ b/apidoc/html/reference.html
@@ -918,6 +918,10 @@
 
 
+ostree_repo_prune_from_reachable, function in Content-addressed object store +
+
+
ostree_repo_prune_static_deltas, function in Content-addressed object store
diff --git a/apidoc/ostree-sections.txt b/apidoc/ostree-sections.txt index 3cda9150..dbd12526 100644 --- a/apidoc/ostree-sections.txt +++ b/apidoc/ostree-sections.txt @@ -368,6 +368,7 @@ ostree_repo_commit_traverse_iter_next OstreeRepoPruneFlags ostree_repo_prune ostree_repo_prune_static_deltas +ostree_repo_prune_from_reachable OstreeRepoPullFlags ostree_repo_pull ostree_repo_pull_one_dir diff --git a/apidoc/version.xml b/apidoc/version.xml index 48bb1233..43e74f0f 100644 --- a/apidoc/version.xml +++ b/apidoc/version.xml @@ -1 +1 @@ -2016.14 \ No newline at end of file +2016.15 \ No newline at end of file diff --git a/configure b/configure index 70e531f3..98101308 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for ostree 2016.15. +# Generated by GNU Autoconf 2.69 for ostree 2017.1. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='ostree' PACKAGE_TARNAME='ostree' -PACKAGE_VERSION='2016.15' -PACKAGE_STRING='ostree 2016.15' +PACKAGE_VERSION='2017.1' +PACKAGE_STRING='ostree 2017.1' PACKAGE_BUGREPORT='walters@verbum.org' PACKAGE_URL='' @@ -1482,7 +1482,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 ostree 2016.15 to adapt to many kinds of systems. +\`configure' configures ostree 2017.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1552,7 +1552,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of ostree 2016.15:";; + short | recursive ) echo "Configuration of ostree 2017.1:";; esac cat <<\_ACEOF @@ -1761,7 +1761,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -ostree configure 2016.15 +ostree configure 2017.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2176,7 +2176,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 ostree $as_me 2016.15, which was +It was created by ostree $as_me 2017.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3043,7 +3043,7 @@ fi # Define the identity of the package. PACKAGE='ostree' - VERSION='2016.15' + VERSION='2017.1' # Some tools Automake needs. @@ -17120,7 +17120,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 ostree $as_me 2016.15, which was +This file was extended by ostree $as_me 2017.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -17186,7 +17186,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="\\ -ostree config.status 2016.15 +ostree config.status 2017.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index c59b3f7b..e3f2d12a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.63]) dnl If incrementing the version here, remember to update libostree.sym too -AC_INIT([ostree], [2016.15], [walters@verbum.org]) +AC_INIT([ostree], [2017.1], [walters@verbum.org]) AC_CONFIG_HEADER([config.h]) AC_CONFIG_MACRO_DIR([buildutil]) AC_CONFIG_AUX_DIR([build-aux]) diff --git a/man/ostree-admin-cleanup.1 b/man/ostree-admin-cleanup.1 index 96eb3ba2..b28dafbe 100644 --- a/man/ostree-admin-cleanup.1 +++ b/man/ostree-admin-cleanup.1 @@ -2,7 +2,7 @@ .\" Title: ostree admin cleanup .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree admin cleanup .\" Source: OSTree .\" Language: English diff --git a/man/ostree-admin-config-diff.1 b/man/ostree-admin-config-diff.1 index a0206616..5f962a32 100644 --- a/man/ostree-admin-config-diff.1 +++ b/man/ostree-admin-config-diff.1 @@ -2,7 +2,7 @@ .\" Title: ostree admin config-diff .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree admin config-diff .\" Source: OSTree .\" Language: English diff --git a/man/ostree-admin-deploy.1 b/man/ostree-admin-deploy.1 index f23147fc..645b94cb 100644 --- a/man/ostree-admin-deploy.1 +++ b/man/ostree-admin-deploy.1 @@ -2,7 +2,7 @@ .\" Title: ostree admin deploy .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree admin deploy .\" Source: OSTree .\" Language: English diff --git a/man/ostree-admin-init-fs.1 b/man/ostree-admin-init-fs.1 index 98234a0a..f3818fab 100644 --- a/man/ostree-admin-init-fs.1 +++ b/man/ostree-admin-init-fs.1 @@ -2,7 +2,7 @@ .\" Title: ostree admin init-fs .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree admin init-fs .\" Source: OSTree .\" Language: English diff --git a/man/ostree-admin-instutil.1 b/man/ostree-admin-instutil.1 index fbfe3a49..b39003ca 100644 --- a/man/ostree-admin-instutil.1 +++ b/man/ostree-admin-instutil.1 @@ -2,7 +2,7 @@ .\" Title: ostree admin instutil .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree admin instutil .\" Source: OSTree .\" Language: English diff --git a/man/ostree-admin-os-init.1 b/man/ostree-admin-os-init.1 index 0b90e24d..55a17713 100644 --- a/man/ostree-admin-os-init.1 +++ b/man/ostree-admin-os-init.1 @@ -2,7 +2,7 @@ .\" Title: ostree admin os-init .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree admin os-init .\" Source: OSTree .\" Language: English diff --git a/man/ostree-admin-set-origin.1 b/man/ostree-admin-set-origin.1 index f45cbe4f..b4682360 100644 --- a/man/ostree-admin-set-origin.1 +++ b/man/ostree-admin-set-origin.1 @@ -2,7 +2,7 @@ .\" Title: ostree admin set-origin .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree admin set-origin .\" Source: OSTree .\" Language: English diff --git a/man/ostree-admin-status.1 b/man/ostree-admin-status.1 index 9f65e332..085fa4e5 100644 --- a/man/ostree-admin-status.1 +++ b/man/ostree-admin-status.1 @@ -2,7 +2,7 @@ .\" Title: ostree admin status .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree admin status .\" Source: OSTree .\" Language: English diff --git a/man/ostree-admin-switch.1 b/man/ostree-admin-switch.1 index 46cc6029..6b7455e9 100644 --- a/man/ostree-admin-switch.1 +++ b/man/ostree-admin-switch.1 @@ -2,7 +2,7 @@ .\" Title: ostree admin switch .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree admin switch .\" Source: OSTree .\" Language: English diff --git a/man/ostree-admin-undeploy.1 b/man/ostree-admin-undeploy.1 index 6f3bbe52..e110c352 100644 --- a/man/ostree-admin-undeploy.1 +++ b/man/ostree-admin-undeploy.1 @@ -2,7 +2,7 @@ .\" Title: ostree admin undeploy .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree admin undeploy .\" Source: OSTree .\" Language: English diff --git a/man/ostree-admin-unlock.1 b/man/ostree-admin-unlock.1 index ec5b79f1..51c529b5 100644 --- a/man/ostree-admin-unlock.1 +++ b/man/ostree-admin-unlock.1 @@ -2,7 +2,7 @@ .\" Title: ostree admin unlock .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree admin unlock .\" Source: OSTree .\" Language: English diff --git a/man/ostree-admin-upgrade.1 b/man/ostree-admin-upgrade.1 index 4a9962ee..e0b8e3d2 100644 --- a/man/ostree-admin-upgrade.1 +++ b/man/ostree-admin-upgrade.1 @@ -2,7 +2,7 @@ .\" Title: ostree admin upgrade .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree admin upgrade .\" Source: OSTree .\" Language: English diff --git a/man/ostree-admin.1 b/man/ostree-admin.1 index 7140a617..e2dd8bc0 100644 --- a/man/ostree-admin.1 +++ b/man/ostree-admin.1 @@ -2,7 +2,7 @@ .\" Title: ostree admin .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree admin .\" Source: OSTree .\" Language: English diff --git a/man/ostree-cat.1 b/man/ostree-cat.1 index fafe526f..c31ca5c5 100644 --- a/man/ostree-cat.1 +++ b/man/ostree-cat.1 @@ -2,7 +2,7 @@ .\" Title: ostree cat .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree cat .\" Source: OSTree .\" Language: English diff --git a/man/ostree-checkout.1 b/man/ostree-checkout.1 index 48cfbf7e..bbd6c576 100644 --- a/man/ostree-checkout.1 +++ b/man/ostree-checkout.1 @@ -2,7 +2,7 @@ .\" Title: ostree checkout .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree checkout .\" Source: OSTree .\" Language: English diff --git a/man/ostree-checksum.1 b/man/ostree-checksum.1 index f63e3ad0..26135ad4 100644 --- a/man/ostree-checksum.1 +++ b/man/ostree-checksum.1 @@ -2,7 +2,7 @@ .\" Title: ostree checksum .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree checksum .\" Source: OSTree .\" Language: English diff --git a/man/ostree-commit.1 b/man/ostree-commit.1 index cf8be860..27b29f30 100644 --- a/man/ostree-commit.1 +++ b/man/ostree-commit.1 @@ -2,7 +2,7 @@ .\" Title: ostree commit .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree commit .\" Source: OSTree .\" Language: English diff --git a/man/ostree-config.1 b/man/ostree-config.1 index fd63ccf4..264acd25 100644 --- a/man/ostree-config.1 +++ b/man/ostree-config.1 @@ -2,7 +2,7 @@ .\" Title: ostree config .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree config .\" Source: OSTree .\" Language: English diff --git a/man/ostree-diff.1 b/man/ostree-diff.1 index d9223f0b..20824f09 100644 --- a/man/ostree-diff.1 +++ b/man/ostree-diff.1 @@ -2,7 +2,7 @@ .\" Title: ostree diff .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree diff .\" Source: OSTree .\" Language: English diff --git a/man/ostree-export.1 b/man/ostree-export.1 index 024c0962..2e9d7c07 100644 --- a/man/ostree-export.1 +++ b/man/ostree-export.1 @@ -2,7 +2,7 @@ .\" Title: ostree export .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree export .\" Source: OSTree .\" Language: English diff --git a/man/ostree-fsck.1 b/man/ostree-fsck.1 index d32e2bba..48587d71 100644 --- a/man/ostree-fsck.1 +++ b/man/ostree-fsck.1 @@ -2,7 +2,7 @@ .\" Title: ostree fsck .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree fsck .\" Source: OSTree .\" Language: English diff --git a/man/ostree-gpg-sign.1 b/man/ostree-gpg-sign.1 index 5de200c9..de331604 100644 --- a/man/ostree-gpg-sign.1 +++ b/man/ostree-gpg-sign.1 @@ -2,7 +2,7 @@ .\" Title: ostree gpg-sign .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree gpg-sign .\" Source: OSTree .\" Language: English diff --git a/man/ostree-init.1 b/man/ostree-init.1 index ceb55490..f663f559 100644 --- a/man/ostree-init.1 +++ b/man/ostree-init.1 @@ -2,7 +2,7 @@ .\" Title: ostree init .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree init .\" Source: OSTree .\" Language: English diff --git a/man/ostree-log.1 b/man/ostree-log.1 index 8ab5c3c2..3027cdb3 100644 --- a/man/ostree-log.1 +++ b/man/ostree-log.1 @@ -2,7 +2,7 @@ .\" Title: ostree log .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree log .\" Source: OSTree .\" Language: English diff --git a/man/ostree-ls.1 b/man/ostree-ls.1 index 379def88..5f42268c 100644 --- a/man/ostree-ls.1 +++ b/man/ostree-ls.1 @@ -2,7 +2,7 @@ .\" Title: ostree ls .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree ls .\" Source: OSTree .\" Language: English diff --git a/man/ostree-prune.1 b/man/ostree-prune.1 index d45e6acf..109b58fe 100644 --- a/man/ostree-prune.1 +++ b/man/ostree-prune.1 @@ -2,7 +2,7 @@ .\" Title: ostree prune .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree prune .\" Source: OSTree .\" Language: English diff --git a/man/ostree-pull-local.1 b/man/ostree-pull-local.1 index 9645a046..8ca7ca71 100644 --- a/man/ostree-pull-local.1 +++ b/man/ostree-pull-local.1 @@ -2,7 +2,7 @@ .\" Title: ostree pull-local .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree pull-local .\" Source: OSTree .\" Language: English diff --git a/man/ostree-pull.1 b/man/ostree-pull.1 index 2078bc26..0965f687 100644 --- a/man/ostree-pull.1 +++ b/man/ostree-pull.1 @@ -2,7 +2,7 @@ .\" Title: ostree pull .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree pull .\" Source: OSTree .\" Language: English diff --git a/man/ostree-refs.1 b/man/ostree-refs.1 index b29a3dae..63e7cfeb 100644 --- a/man/ostree-refs.1 +++ b/man/ostree-refs.1 @@ -2,7 +2,7 @@ .\" Title: ostree refs .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree refs .\" Source: OSTree .\" Language: English diff --git a/man/ostree-remote.1 b/man/ostree-remote.1 index 69072bf4..c1a4a3e7 100644 --- a/man/ostree-remote.1 +++ b/man/ostree-remote.1 @@ -2,7 +2,7 @@ .\" Title: ostree remote .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree remote .\" Source: OSTree .\" Language: English diff --git a/man/ostree-reset.1 b/man/ostree-reset.1 index 5ed1bada..5e4a22f0 100644 --- a/man/ostree-reset.1 +++ b/man/ostree-reset.1 @@ -2,7 +2,7 @@ .\" Title: ostree reset .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree reset .\" Source: OSTree .\" Language: English diff --git a/man/ostree-rev-parse.1 b/man/ostree-rev-parse.1 index f571fd03..6d719b82 100644 --- a/man/ostree-rev-parse.1 +++ b/man/ostree-rev-parse.1 @@ -2,7 +2,7 @@ .\" Title: ostree rev-parse .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree rev-parse .\" Source: OSTree .\" Language: English diff --git a/man/ostree-show.1 b/man/ostree-show.1 index dc5611cb..5e7b8487 100644 --- a/man/ostree-show.1 +++ b/man/ostree-show.1 @@ -2,7 +2,7 @@ .\" Title: ostree show .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree show .\" Source: OSTree .\" Language: English diff --git a/man/ostree-static-delta.1 b/man/ostree-static-delta.1 index b80e73c2..3c2d1139 100644 --- a/man/ostree-static-delta.1 +++ b/man/ostree-static-delta.1 @@ -2,7 +2,7 @@ .\" Title: ostree static-delta .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree static-delta .\" Source: OSTree .\" Language: English diff --git a/man/ostree-summary.1 b/man/ostree-summary.1 index a6091579..ae5d1b55 100644 --- a/man/ostree-summary.1 +++ b/man/ostree-summary.1 @@ -2,7 +2,7 @@ .\" Title: ostree summary .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree summary .\" Source: OSTree .\" Language: English diff --git a/man/ostree-trivial-httpd.1 b/man/ostree-trivial-httpd.1 index 46c0b848..74d885f4 100644 --- a/man/ostree-trivial-httpd.1 +++ b/man/ostree-trivial-httpd.1 @@ -2,7 +2,7 @@ .\" Title: ostree trivial-httpd .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree trivial-httpd .\" Source: OSTree .\" Language: English diff --git a/man/ostree.1 b/man/ostree.1 index 2570e397..2f1cbb33 100644 --- a/man/ostree.1 +++ b/man/ostree.1 @@ -2,7 +2,7 @@ .\" Title: ostree .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree .\" Source: OSTree .\" Language: English diff --git a/man/ostree.repo-config.5 b/man/ostree.repo-config.5 index 5251faa5..b4d954c1 100644 --- a/man/ostree.repo-config.5 +++ b/man/ostree.repo-config.5 @@ -2,7 +2,7 @@ .\" Title: ostree.repo-config .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree.repo-config .\" Source: OSTree .\" Language: English diff --git a/man/ostree.repo.5 b/man/ostree.repo.5 index 7f2d121d..0f6ba486 100644 --- a/man/ostree.repo.5 +++ b/man/ostree.repo.5 @@ -2,7 +2,7 @@ .\" Title: ostree.repo .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: ostree.repo .\" Source: OSTree .\" Language: English diff --git a/man/rofiles-fuse.1 b/man/rofiles-fuse.1 index 4e95d411..56437b15 100644 --- a/man/rofiles-fuse.1 +++ b/man/rofiles-fuse.1 @@ -2,7 +2,7 @@ .\" Title: rofiles-fuse .\" Author: Colin Walters .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 12/12/2016 +.\" Date: 01/19/2017 .\" Manual: rofiles-fuse .\" Source: rofiles-fuse .\" Language: English diff --git a/src/libostree/libostree.sym b/src/libostree/libostree.sym index 0b8410fb..888a99ba 100644 --- a/src/libostree/libostree.sym +++ b/src/libostree/libostree.sym @@ -371,12 +371,10 @@ global: * NOTE NOTE NOTE */ -/* Remove comment when first new symbol is added -LIBOSTREE_2016.XX { +LIBOSTREE_2017.1 { global: - someostree_symbol_deleteme; + ostree_repo_prune_from_reachable; } LIBOSTREE_2016.14; -*/ /* 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 diff --git a/src/libostree/ostree-enumtypes.c b/src/libostree/ostree-enumtypes.c index 12c3a477..ee232af4 100644 --- a/src/libostree/ostree-enumtypes.c +++ b/src/libostree/ostree-enumtypes.c @@ -57,6 +57,30 @@ _ostree_fetcher_config_flags_get_type (void) return the_type__volatile; } +GType +_ostree_fetcher_request_flags_get_type (void) +{ + static volatile gsize the_type__volatile = 0; + + if (g_once_init_enter (&the_type__volatile)) + { + static const GFlagsValue values[] = { + { OSTREE_FETCHER_REQUEST_NUL_TERMINATION, + "OSTREE_FETCHER_REQUEST_NUL_TERMINATION", + "termination" }, + { 0, NULL, NULL } + }; + + GType the_type = g_flags_register_static ( + g_intern_static_string ("OstreeFetcherRequestFlags"), + values); + + g_once_init_leave (&the_type__volatile, the_type); + } + + return the_type__volatile; +} + /* Generated data ends here */ diff --git a/src/libostree/ostree-enumtypes.h b/src/libostree/ostree-enumtypes.h index 46d9b88d..95b516d1 100644 --- a/src/libostree/ostree-enumtypes.h +++ b/src/libostree/ostree-enumtypes.h @@ -31,6 +31,9 @@ G_BEGIN_DECLS #define OSTREE_TYPE_FETCHER_CONFIG_FLAGS (_ostree_fetcher_config_flags_get_type ()) GType _ostree_fetcher_config_flags_get_type (void) G_GNUC_CONST; +#define OSTREE_TYPE_FETCHER_REQUEST_FLAGS (_ostree_fetcher_request_flags_get_type ()) +GType _ostree_fetcher_request_flags_get_type (void) G_GNUC_CONST; + G_END_DECLS diff --git a/src/libostree/ostree-fetcher-util.c b/src/libostree/ostree-fetcher-util.c new file mode 100644 index 00000000..b8af972a --- /dev/null +++ b/src/libostree/ostree-fetcher-util.c @@ -0,0 +1,124 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2017 Colin Walters + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include + +#include "ostree-fetcher-util.h" +#include "otutil.h" + +typedef struct +{ + GBytes *result_buf; + gboolean done; + GError **error; +} + FetchUriSyncData; + +static void +fetch_uri_sync_on_complete (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + FetchUriSyncData *data = user_data; + + (void)_ostree_fetcher_request_to_membuf_finish ((OstreeFetcher*)object, + result, &data->result_buf, + data->error); + data->done = TRUE; +} + +gboolean +_ostree_fetcher_mirrored_request_to_membuf (OstreeFetcher *fetcher, + GPtrArray *mirrorlist, + const char *filename, + gboolean add_nul, + gboolean allow_noent, + GBytes **out_contents, + guint64 max_size, + GCancellable *cancellable, + GError **error) +{ + gboolean ret = FALSE; + g_autoptr(GMainContext) mainctx = NULL; + FetchUriSyncData data; + g_assert (error != NULL); + + memset (&data, 0, sizeof (data)); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + mainctx = g_main_context_new (); + g_main_context_push_thread_default (mainctx); + + data.done = FALSE; + data.error = error; + + _ostree_fetcher_request_to_membuf (fetcher, mirrorlist, filename, + add_nul ? OSTREE_FETCHER_REQUEST_NUL_TERMINATION : 0, + max_size, OSTREE_FETCHER_DEFAULT_PRIORITY, + cancellable, fetch_uri_sync_on_complete, &data); + while (!data.done) + g_main_context_iteration (mainctx, TRUE); + + if (!data.result_buf) + { + if (allow_noent) + { + if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + { + g_clear_error (error); + ret = TRUE; + *out_contents = NULL; + } + } + goto out; + } + + ret = TRUE; + *out_contents = g_steal_pointer (&data.result_buf); + out: + if (mainctx) + g_main_context_pop_thread_default (mainctx); + g_clear_pointer (&data.result_buf, (GDestroyNotify)g_bytes_unref); + return ret; +} + +/* Helper for callers who just want to fetch single one-off URIs */ +gboolean +_ostree_fetcher_request_uri_to_membuf (OstreeFetcher *fetcher, + OstreeFetcherURI *uri, + gboolean add_nul, + gboolean allow_noent, + GBytes **out_contents, + guint64 max_size, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GPtrArray) mirrorlist = g_ptr_array_new (); + g_ptr_array_add (mirrorlist, uri); /* no transfer */ + return _ostree_fetcher_mirrored_request_to_membuf (fetcher, mirrorlist, NULL, + add_nul, allow_noent, + out_contents, max_size, + cancellable, error); +} diff --git a/src/libostree/ostree-fetcher-util.h b/src/libostree/ostree-fetcher-util.h new file mode 100644 index 00000000..0f25dc30 --- /dev/null +++ b/src/libostree/ostree-fetcher-util.h @@ -0,0 +1,49 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2016 Colin Walters + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#pragma once + +#ifndef __GI_SCANNER__ + +#include "ostree-fetcher.h" + +G_BEGIN_DECLS + +gboolean _ostree_fetcher_mirrored_request_to_membuf (OstreeFetcher *fetcher, + GPtrArray *mirrorlist, + const char *filename, + gboolean add_nul, + gboolean allow_noent, + GBytes **out_contents, + guint64 max_size, + GCancellable *cancellable, + GError **error); + +gboolean _ostree_fetcher_request_uri_to_membuf (OstreeFetcher *fetcher, + OstreeFetcherURI *uri, + gboolean add_nul, + gboolean allow_noent, + GBytes **out_contents, + guint64 max_size, + GCancellable *cancellable, + GError **error); +G_END_DECLS + +#endif diff --git a/src/libostree/ostree-fetcher.c b/src/libostree/ostree-fetcher.c index 63942166..a178abfe 100644 --- a/src/libostree/ostree-fetcher.c +++ b/src/libostree/ostree-fetcher.c @@ -22,6 +22,7 @@ #include "config.h" +#include #include #include #define LIBSOUP_USE_UNSTABLE_REQUEST_API @@ -51,6 +52,7 @@ typedef struct { SoupSession *session; /* not referenced */ GMainContext *main_context; volatile gint running; + GError *initialization_error; /* Any failure to load the db */ int tmpdir_dfd; char *tmpdir_name; @@ -90,7 +92,8 @@ typedef struct { SoupRequest *request; - gboolean is_stream; + gboolean is_membuf; + OstreeFetcherRequestFlags flags; GInputStream *request_body; char *out_tmpfile; GOutputStream *out_stream; @@ -355,12 +358,14 @@ static void session_thread_set_tls_interaction_cb (ThreadClosure *thread_closure, gpointer data) { - GTlsCertificate *cert = data; + 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; /* The GTlsInteraction instance must be created in the * session thread so it uses the correct GMainContext. */ - interaction = _ostree_tls_cert_interaction_new (cert); + interaction = _ostree_tls_cert_interaction_new (cert_path, key_path); g_object_set (thread_closure->session, SOUP_SESSION_TLS_INTERACTION, @@ -372,13 +377,19 @@ static void session_thread_set_tls_database_cb (ThreadClosure *thread_closure, gpointer data) { - GTlsDatabase *database = data; + const char *db_path = data; - if (database != NULL) + if (db_path != NULL) { - g_object_set (thread_closure->session, - SOUP_SESSION_TLS_DATABASE, - database, NULL); + glnx_unref_object GTlsDatabase *tlsdb = NULL; + + g_clear_error (&thread_closure->initialization_error); + tlsdb = g_tls_file_database_new (db_path, &thread_closure->initialization_error); + + if (tlsdb) + g_object_set (thread_closure->session, + SOUP_SESSION_TLS_DATABASE, + tlsdb, NULL); } else { @@ -450,6 +461,13 @@ session_thread_request_uri (ThreadClosure *thread_closure, pending = g_task_get_task_data (task); cancellable = g_task_get_cancellable (task); + /* If we caught an error in init, re-throw it for every request */ + if (thread_closure->initialization_error) + { + g_task_return_error (task, g_error_copy (thread_closure->initialization_error)); + return; + } + create_pending_soup_request (pending, &local_error); if (local_error != NULL) { @@ -468,7 +486,7 @@ session_thread_request_uri (ThreadClosure *thread_closure, soup_message_headers_append (msg->request_headers, key, value); } - if (pending->is_stream) + if (pending->is_membuf) { soup_request_send_async (pending->request, cancellable, @@ -795,16 +813,24 @@ _ostree_fetcher_set_cookie_jar (OstreeFetcher *self, void _ostree_fetcher_set_client_cert (OstreeFetcher *self, - GTlsCertificate *cert) + const char *cert_path, + const char *key_path) { + g_autoptr(GString) buf = NULL; g_return_if_fail (OSTREE_IS_FETCHER (self)); - g_return_if_fail (G_IS_TLS_CERTIFICATE (cert)); + + if (cert_path) + { + buf = g_string_new (cert_path); + g_string_append_c (buf, '\0'); + g_string_append (buf, key_path); + } #ifdef HAVE_LIBSOUP_CLIENT_CERTS session_thread_idle_add (self->thread_closure, session_thread_set_tls_interaction_cb, - g_object_ref (cert), - (GDestroyNotify) g_object_unref); + g_string_free (g_steal_pointer (&buf), FALSE), + (GDestroyNotify) g_free); #else g_warning ("This version of OSTree is compiled without client side certificate support"); #endif @@ -812,24 +838,14 @@ _ostree_fetcher_set_client_cert (OstreeFetcher *self, void _ostree_fetcher_set_tls_database (OstreeFetcher *self, - GTlsDatabase *db) + const char *tlsdb_path) { g_return_if_fail (OSTREE_IS_FETCHER (self)); - g_return_if_fail (db == NULL || G_IS_TLS_DATABASE (db)); - if (db != NULL) - { - session_thread_idle_add (self->thread_closure, - session_thread_set_tls_database_cb, - g_object_ref (db), - (GDestroyNotify) g_object_unref); - } - else - { - session_thread_idle_add (self->thread_closure, - session_thread_set_tls_database_cb, - NULL, (GDestroyNotify) NULL); - } + session_thread_idle_add (self->thread_closure, + session_thread_set_tls_database_cb, + g_strdup (tlsdb_path), + (GDestroyNotify) g_free); } void @@ -855,6 +871,16 @@ finish_stream (OstreeFetcherPendingURI *pending, */ if (pending->out_stream) { + if ((pending->flags & OSTREE_FETCHER_REQUEST_NUL_TERMINATION) > 0) + { + const guint8 nulchar = 0; + gsize bytes_written; + + if (!g_output_stream_write_all (pending->out_stream, &nulchar, 1, &bytes_written, + cancellable, error)) + goto out; + } + if (!g_output_stream_close (pending->out_stream, cancellable, error)) goto out; @@ -864,30 +890,37 @@ finish_stream (OstreeFetcherPendingURI *pending, g_mutex_unlock (&pending->thread_closure->output_stream_set_lock); } - pending->state = OSTREE_FETCHER_STATE_COMPLETE; - if (fstatat (pending->thread_closure->tmpdir_dfd, - pending->out_tmpfile, - &stbuf, AT_SYMLINK_NOFOLLOW) != 0) + if (!pending->is_membuf) { - glnx_set_error_from_errno (error); - goto out; + if (fstatat (pending->thread_closure->tmpdir_dfd, + pending->out_tmpfile, + &stbuf, AT_SYMLINK_NOFOLLOW) != 0) + { + glnx_set_error_from_errno (error); + goto out; + } } + pending->state = OSTREE_FETCHER_STATE_COMPLETE; + /* Now that we've finished downloading, continue with other queued * requests. */ session_thread_process_pending_queue (pending->thread_closure); - if (stbuf.st_size < pending->content_length) + if (!pending->is_membuf) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Download incomplete"); - goto out; - } - else - { - g_mutex_lock (&pending->thread_closure->output_stream_set_lock); - pending->thread_closure->total_downloaded += stbuf.st_size; - g_mutex_unlock (&pending->thread_closure->output_stream_set_lock); + if (stbuf.st_size < pending->content_length) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Download incomplete"); + goto out; + } + else + { + g_mutex_lock (&pending->thread_closure->output_stream_set_lock); + pending->thread_closure->total_downloaded += stbuf.st_size; + g_mutex_unlock (&pending->thread_closure->output_stream_set_lock); + } } ret = TRUE; @@ -973,9 +1006,18 @@ on_stream_read (GObject *object, { if (!finish_stream (pending, cancellable, &local_error)) goto out; - g_task_return_pointer (task, - g_strdup (pending->out_tmpfile), - (GDestroyNotify) g_free); + if (pending->is_membuf) + { + g_task_return_pointer (task, + g_memory_output_stream_steal_as_bytes ((GMemoryOutputStream*)pending->out_stream), + (GDestroyNotify) g_bytes_unref); + } + else + { + g_task_return_pointer (task, + g_strdup (pending->out_tmpfile), + (GDestroyNotify) g_free); + } remove_pending_rerun_queue (pending); } else @@ -1045,23 +1087,15 @@ on_request_sent (GObject *object, if (SOUP_IS_REQUEST_HTTP (object)) { msg = soup_request_http_get_message ((SoupRequestHTTP*) object); - if (msg->status_code == SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE) + if (!pending->is_membuf && + msg->status_code == SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE) { // We already have the whole file, so just use it. pending->state = OSTREE_FETCHER_STATE_COMPLETE; (void) g_input_stream_close (pending->request_body, NULL, NULL); - if (pending->is_stream) - { - g_task_return_pointer (task, - g_object_ref (pending->request_body), - (GDestroyNotify) g_object_unref); - } - else - { - g_task_return_pointer (task, - g_strdup (pending->out_tmpfile), - (GDestroyNotify) g_free); - } + g_task_return_pointer (task, + g_strdup (pending->out_tmpfile), + (GDestroyNotify) g_free); remove_pending_rerun_queue (pending); goto out; } @@ -1126,7 +1160,7 @@ on_request_sent (GObject *object, pending->content_length = soup_request_get_content_length (pending->request); - if (!pending->is_stream) + if (!pending->is_membuf) { int oflags = O_CREAT | O_WRONLY | O_CLOEXEC; int fd; @@ -1147,26 +1181,23 @@ on_request_sent (GObject *object, goto out; } pending->out_stream = g_unix_output_stream_new (fd, TRUE); - - g_mutex_lock (&pending->thread_closure->output_stream_set_lock); - g_hash_table_add (pending->thread_closure->output_stream_set, - g_object_ref (pending->out_stream)); - g_mutex_unlock (&pending->thread_closure->output_stream_set_lock); - - g_input_stream_read_bytes_async (pending->request_body, - 8192, G_PRIORITY_DEFAULT, - cancellable, - on_stream_read, - g_object_ref (task)); } else { - g_task_return_pointer (task, - g_object_ref (pending->request_body), - (GDestroyNotify) g_object_unref); - remove_pending_rerun_queue (pending); + pending->out_stream = g_memory_output_stream_new_resizable (); } - + + g_mutex_lock (&pending->thread_closure->output_stream_set_lock); + g_hash_table_add (pending->thread_closure->output_stream_set, + g_object_ref (pending->out_stream)); + g_mutex_unlock (&pending->thread_closure->output_stream_set_lock); + + g_input_stream_read_bytes_async (pending->request_body, + 8192, G_PRIORITY_DEFAULT, + cancellable, + on_stream_read, + g_object_ref (task)); + out: if (local_error) { @@ -1180,16 +1211,16 @@ on_request_sent (GObject *object, } static void -ostree_fetcher_mirrored_request_internal (OstreeFetcher *self, - GPtrArray *mirrorlist, - const char *filename, - gboolean is_stream, - guint64 max_size, - int priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data, - gpointer source_tag) +_ostree_fetcher_request_async (OstreeFetcher *self, + GPtrArray *mirrorlist, + const char *filename, + OstreeFetcherRequestFlags flags, + gboolean is_membuf, + guint64 max_size, + int priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { g_autoptr(GTask) task = NULL; OstreeFetcherPendingURI *pending; @@ -1204,11 +1235,12 @@ ostree_fetcher_mirrored_request_internal (OstreeFetcher *self, pending->thread_closure = thread_closure_ref (self->thread_closure); pending->mirrorlist = g_ptr_array_ref (mirrorlist); pending->filename = g_strdup (filename); + pending->flags = flags; pending->max_size = max_size; - pending->is_stream = is_stream; + pending->is_membuf = is_membuf; task = g_task_new (self, cancellable, callback, user_data); - g_task_set_source_tag (task, source_tag); + g_task_set_source_tag (task, _ostree_fetcher_request_async); g_task_set_task_data (task, pending, (GDestroyNotify) pending_uri_unref); /* We'll use the GTask priority for our own priority queue. */ @@ -1221,61 +1253,91 @@ ostree_fetcher_mirrored_request_internal (OstreeFetcher *self, } void -_ostree_fetcher_mirrored_request_with_partial_async (OstreeFetcher *self, - GPtrArray *mirrorlist, - const char *filename, - guint64 max_size, - int priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +_ostree_fetcher_request_to_tmpfile (OstreeFetcher *self, + GPtrArray *mirrorlist, + const char *filename, + guint64 max_size, + int priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - ostree_fetcher_mirrored_request_internal (self, mirrorlist, filename, FALSE, - max_size, priority, cancellable, - callback, user_data, - _ostree_fetcher_mirrored_request_with_partial_async); + _ostree_fetcher_request_async (self, mirrorlist, filename, 0, FALSE, + max_size, priority, cancellable, + callback, user_data); } -char * -_ostree_fetcher_mirrored_request_with_partial_finish (OstreeFetcher *self, - GAsyncResult *result, - GError **error) +gboolean +_ostree_fetcher_request_to_tmpfile_finish (OstreeFetcher *self, + GAsyncResult *result, + char **out_filename, + GError **error) { - g_return_val_if_fail (g_task_is_valid (result, self), NULL); - g_return_val_if_fail (g_async_result_is_tagged (result, - _ostree_fetcher_mirrored_request_with_partial_async), NULL); + GTask *task; + OstreeFetcherPendingURI *pending; + gpointer ret; - return g_task_propagate_pointer (G_TASK (result), error); + g_return_val_if_fail (g_task_is_valid (result, self), FALSE); + g_return_val_if_fail (g_async_result_is_tagged (result, _ostree_fetcher_request_async), FALSE); + + task = (GTask*)result; + pending = g_task_get_task_data (task); + + ret = g_task_propagate_pointer (task, error); + if (!ret) + return FALSE; + + g_assert (!pending->is_membuf); + g_assert (out_filename); + *out_filename = ret; + + return TRUE; } -static void -ostree_fetcher_stream_mirrored_uri_async (OstreeFetcher *self, - GPtrArray *mirrorlist, - const char *filename, - guint64 max_size, - int priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +void +_ostree_fetcher_request_to_membuf (OstreeFetcher *self, + GPtrArray *mirrorlist, + const char *filename, + OstreeFetcherRequestFlags flags, + guint64 max_size, + int priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - ostree_fetcher_mirrored_request_internal (self, mirrorlist, filename, TRUE, - max_size, priority, cancellable, - callback, user_data, - ostree_fetcher_stream_mirrored_uri_async); + _ostree_fetcher_request_async (self, mirrorlist, filename, flags, TRUE, + max_size, priority, cancellable, + callback, user_data); } -static GInputStream * -ostree_fetcher_stream_mirrored_uri_finish (OstreeFetcher *self, - GAsyncResult *result, - GError **error) +gboolean +_ostree_fetcher_request_to_membuf_finish (OstreeFetcher *self, + GAsyncResult *result, + GBytes **out_buf, + GError **error) { - g_return_val_if_fail (g_task_is_valid (result, self), NULL); - g_return_val_if_fail (g_async_result_is_tagged (result, - ostree_fetcher_stream_mirrored_uri_async), NULL); + GTask *task; + OstreeFetcherPendingURI *pending; + gpointer ret; - return g_task_propagate_pointer (G_TASK (result), error); + g_return_val_if_fail (g_task_is_valid (result, self), FALSE); + g_return_val_if_fail (g_async_result_is_tagged (result, _ostree_fetcher_request_async), FALSE); + + task = (GTask*)result; + pending = g_task_get_task_data (task); + + ret = g_task_propagate_pointer (task, error); + if (!ret) + return FALSE; + + g_assert (pending->is_membuf); + g_assert (out_buf); + *out_buf = ret; + + return TRUE; } + guint64 _ostree_fetcher_bytes_transferred (OstreeFetcher *self) { @@ -1307,118 +1369,6 @@ _ostree_fetcher_bytes_transferred (OstreeFetcher *self) return ret; } -typedef struct -{ - GInputStream *result_stream; - gboolean done; - GError **error; -} -FetchUriSyncData; - -static void -fetch_uri_sync_on_complete (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - FetchUriSyncData *data = user_data; - - data->result_stream = ostree_fetcher_stream_mirrored_uri_finish ((OstreeFetcher*)object, - result, data->error); - data->done = TRUE; -} - -gboolean -_ostree_fetcher_mirrored_request_to_membuf (OstreeFetcher *fetcher, - GPtrArray *mirrorlist, - const char *filename, - gboolean add_nul, - gboolean allow_noent, - GBytes **out_contents, - guint64 max_size, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - const guint8 nulchar = 0; - g_autoptr(GMemoryOutputStream) buf = NULL; - g_autoptr(GMainContext) mainctx = NULL; - FetchUriSyncData data; - g_assert (error != NULL); - - data.result_stream = NULL; - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - return FALSE; - - mainctx = g_main_context_new (); - g_main_context_push_thread_default (mainctx); - - data.done = FALSE; - data.error = error; - - ostree_fetcher_stream_mirrored_uri_async (fetcher, mirrorlist, filename, max_size, - OSTREE_FETCHER_DEFAULT_PRIORITY, cancellable, - fetch_uri_sync_on_complete, &data); - while (!data.done) - g_main_context_iteration (mainctx, TRUE); - - if (!data.result_stream) - { - if (allow_noent) - { - if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) - { - g_clear_error (error); - ret = TRUE; - *out_contents = NULL; - } - } - goto out; - } - - buf = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free); - if (g_output_stream_splice ((GOutputStream*)buf, data.result_stream, - G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE, - cancellable, error) < 0) - goto out; - - if (add_nul) - { - if (!g_output_stream_write ((GOutputStream*)buf, &nulchar, 1, cancellable, error)) - goto out; - } - - if (!g_output_stream_close ((GOutputStream*)buf, cancellable, error)) - goto out; - - ret = TRUE; - *out_contents = g_memory_output_stream_steal_as_bytes (buf); - out: - if (mainctx) - g_main_context_pop_thread_default (mainctx); - g_clear_object (&(data.result_stream)); - return ret; -} - -/* Helper for callers who just want to fetch single one-off URIs */ -gboolean -_ostree_fetcher_request_uri_to_membuf (OstreeFetcher *fetcher, - OstreeFetcherURI *uri, - gboolean add_nul, - gboolean allow_noent, - GBytes **out_contents, - guint64 max_size, - GCancellable *cancellable, - GError **error) -{ - g_autoptr(GPtrArray) mirrorlist = g_ptr_array_new (); - g_ptr_array_add (mirrorlist, uri); /* no transfer */ - return _ostree_fetcher_mirrored_request_to_membuf (fetcher, mirrorlist, NULL, - add_nul, allow_noent, - out_contents, max_size, - cancellable, error); -} - void _ostree_fetcher_uri_free (OstreeFetcherURI *uri) { diff --git a/src/libostree/ostree-fetcher.h b/src/libostree/ostree-fetcher.h index 8e282e24..f19eb73b 100644 --- a/src/libostree/ostree-fetcher.h +++ b/src/libostree/ostree-fetcher.h @@ -93,47 +93,51 @@ void _ostree_fetcher_set_proxy (OstreeFetcher *fetcher, const char *proxy); void _ostree_fetcher_set_client_cert (OstreeFetcher *fetcher, - GTlsCertificate *cert); + const char *cert_path, + const char *key_path); void _ostree_fetcher_set_tls_database (OstreeFetcher *self, - GTlsDatabase *db); + const char *tlsdb_path); void _ostree_fetcher_set_extra_headers (OstreeFetcher *self, GVariant *extra_headers); guint64 _ostree_fetcher_bytes_transferred (OstreeFetcher *self); -void _ostree_fetcher_mirrored_request_with_partial_async (OstreeFetcher *self, - GPtrArray *mirrorlist, - const char *filename, - guint64 max_size, - int priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); +void _ostree_fetcher_request_to_tmpfile (OstreeFetcher *self, + GPtrArray *mirrorlist, + const char *filename, + guint64 max_size, + int priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); -char *_ostree_fetcher_mirrored_request_with_partial_finish (OstreeFetcher *self, - GAsyncResult *result, - GError **error); +gboolean _ostree_fetcher_request_to_tmpfile_finish (OstreeFetcher *self, + GAsyncResult *result, + char **out_filename, + GError **error); + +typedef enum { + OSTREE_FETCHER_REQUEST_NUL_TERMINATION = (1 << 0) +} OstreeFetcherRequestFlags; + +void _ostree_fetcher_request_to_membuf (OstreeFetcher *self, + GPtrArray *mirrorlist, + const char *filename, + OstreeFetcherRequestFlags flags, + guint64 max_size, + int priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean _ostree_fetcher_request_to_membuf_finish (OstreeFetcher *self, + GAsyncResult *result, + GBytes **out_buf, + GError **error); -gboolean _ostree_fetcher_mirrored_request_to_membuf (OstreeFetcher *fetcher, - GPtrArray *mirrorlist, - const char *filename, - gboolean add_nul, - gboolean allow_noent, - GBytes **out_contents, - guint64 max_size, - GCancellable *cancellable, - GError **error); -gboolean _ostree_fetcher_request_uri_to_membuf (OstreeFetcher *fetcher, - OstreeFetcherURI *uri, - gboolean add_nul, - gboolean allow_noent, - GBytes **out_contents, - guint64 max_size, - GCancellable *cancellable, - GError **error); G_END_DECLS #endif diff --git a/src/libostree/ostree-metalink.c b/src/libostree/ostree-metalink.c index ee52e51b..6afae59e 100644 --- a/src/libostree/ostree-metalink.c +++ b/src/libostree/ostree-metalink.c @@ -21,6 +21,7 @@ #include "config.h" #include "ostree-metalink.h" +#include "ostree-fetcher-util.h" #include #include "otutil.h" diff --git a/src/libostree/ostree-repo-prune.c b/src/libostree/ostree-repo-prune.c index 22bff915..1b2a8257 100644 --- a/src/libostree/ostree-repo-prune.c +++ b/src/libostree/ostree-repo-prune.c @@ -254,6 +254,61 @@ ostree_repo_prune_static_deltas (OstreeRepo *self, const char *commit, return ret; } +static gboolean +repo_prune_internal (OstreeRepo *self, + GHashTable *objects, + OstreeRepoPruneOptions *options, + gint *out_objects_total, + gint *out_objects_pruned, + guint64 *out_pruned_object_size_total, + GCancellable *cancellable, + GError **error) +{ + gboolean ret = FALSE; + GHashTableIter hash_iter; + gpointer key, value; + OtPruneData data = { 0, }; + + data.repo = self; + data.reachable = g_hash_table_ref (options->reachable); + + g_hash_table_iter_init (&hash_iter, objects); + while (g_hash_table_iter_next (&hash_iter, &key, &value)) + { + GVariant *serialized_key = key; + GVariant *objdata = value; + const char *checksum; + OstreeObjectType objtype; + gboolean is_loose; + + ostree_object_name_deserialize (serialized_key, &checksum, &objtype); + g_variant_get_child (objdata, 0, "b", &is_loose); + + if (!is_loose) + continue; + + if (!maybe_prune_loose_object (&data, options->flags, checksum, objtype, + cancellable, error)) + goto out; + } + + if (!ostree_repo_prune_static_deltas (self, NULL, cancellable, error)) + goto out; + + if (!_ostree_repo_prune_tmp (self, cancellable, error)) + goto out; + + ret = TRUE; + *out_objects_total = (data.n_reachable_meta + data.n_unreachable_meta + + data.n_reachable_content + data.n_unreachable_content); + *out_objects_pruned = (data.n_unreachable_meta + data.n_unreachable_content); + *out_pruned_object_size_total = data.freed_bytes; + out: + if (data.reachable) + g_hash_table_unref (data.reachable); + return ret; +} + /** * ostree_repo_prune: * @self: Repo @@ -289,39 +344,42 @@ ostree_repo_prune (OstreeRepo *self, GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; GHashTableIter hash_iter; gpointer key, value; g_autoptr(GHashTable) objects = NULL; g_autoptr(GHashTable) all_refs = NULL; - OtPruneData data = { 0, }; + g_autoptr(GHashTable) reachable = NULL; gboolean refs_only = flags & OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY; - data.repo = self; - data.reachable = ostree_repo_traverse_new_reachable (); + reachable = ostree_repo_traverse_new_reachable (); + + /* This original prune API has fixed logic for traversing refs or all commits + * combined with actually deleting content. The newer backend API just does + * the deletion. + */ if (refs_only) { if (!ostree_repo_list_refs (self, NULL, &all_refs, cancellable, error)) - goto out; - + return FALSE; + g_hash_table_iter_init (&hash_iter, all_refs); - + while (g_hash_table_iter_next (&hash_iter, &key, &value)) { const char *checksum = value; g_debug ("Finding objects to keep for commit %s", checksum); - if (!ostree_repo_traverse_commit_union (self, checksum, depth, data.reachable, + if (!ostree_repo_traverse_commit_union (self, checksum, depth, reachable, cancellable, error)) - goto out; + return FALSE; } } if (!ostree_repo_list_objects (self, OSTREE_REPO_LIST_OBJECTS_ALL | OSTREE_REPO_LIST_OBJECTS_NO_PARENTS, &objects, cancellable, error)) - goto out; + return FALSE; if (!refs_only) { @@ -338,45 +396,57 @@ ostree_repo_prune (OstreeRepo *self, continue; g_debug ("Finding objects to keep for commit %s", checksum); - if (!ostree_repo_traverse_commit_union (self, checksum, depth, data.reachable, + if (!ostree_repo_traverse_commit_union (self, checksum, depth, reachable, cancellable, error)) - goto out; + return FALSE; } } - g_hash_table_iter_init (&hash_iter, objects); - while (g_hash_table_iter_next (&hash_iter, &key, &value)) - { - GVariant *serialized_key = key; - GVariant *objdata = value; - const char *checksum; - OstreeObjectType objtype; - gboolean is_loose; - - ostree_object_name_deserialize (serialized_key, &checksum, &objtype); - g_variant_get_child (objdata, 0, "b", &is_loose); - - if (!is_loose) - continue; - - if (!maybe_prune_loose_object (&data, flags, checksum, objtype, - cancellable, error)) - goto out; - } - - if (!ostree_repo_prune_static_deltas (self, NULL, cancellable, error)) - goto out; - - if (!_ostree_repo_prune_tmp (self, cancellable, error)) - goto out; - - ret = TRUE; - *out_objects_total = (data.n_reachable_meta + data.n_unreachable_meta + - data.n_reachable_content + data.n_unreachable_content); - *out_objects_pruned = (data.n_unreachable_meta + data.n_unreachable_content); - *out_pruned_object_size_total = data.freed_bytes; - out: - if (data.reachable) - g_hash_table_unref (data.reachable); - return ret; + { OstreeRepoPruneOptions opts = { flags, reachable }; + return repo_prune_internal (self, objects, &opts, + out_objects_total, out_objects_pruned, + out_pruned_object_size_total, cancellable, error); + } +} + +/** + * ostree_repo_prune_from_reachable: + * @self: Repo + * @options: Options controlling prune process + * @out_objects_total: (out): Number of objects found + * @out_objects_pruned: (out): Number of objects deleted + * @out_pruned_object_size_total: (out): Storage size in bytes of objects deleted + * @cancellable: Cancellable + * @error: Error + * + * Delete content from the repository. This function is the "backend" + * half of the higher level ostree_repo_prune(). To use this function, + * you determine the root set yourself, and this function finds all other + * unreferenced objects and deletes them. + * + * Use this API when you want to perform more selective pruning - for example, + * retain all commits from a production branch, but just GC some history from + * your dev branch. + * + * The %OSTREE_REPO_PRUNE_FLAGS_NO_PRUNE flag may be specified to just determine + * statistics on objects that would be deleted, without actually deleting them. + */ +gboolean +ostree_repo_prune_from_reachable (OstreeRepo *self, + OstreeRepoPruneOptions *options, + gint *out_objects_total, + gint *out_objects_pruned, + guint64 *out_pruned_object_size_total, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GHashTable) objects = NULL; + + if (!ostree_repo_list_objects (self, OSTREE_REPO_LIST_OBJECTS_ALL | OSTREE_REPO_LIST_OBJECTS_NO_PARENTS, + &objects, cancellable, error)) + return FALSE; + + return repo_prune_internal (self, objects, options, out_objects_total, + out_objects_pruned, out_pruned_object_size_total, + cancellable, error); } diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 9c99dc4f..45995a30 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -32,6 +32,7 @@ #include "ostree-repo-private.h" #include "ostree-repo-static-delta-private.h" #include "ostree-metalink.h" +#include "ostree-fetcher-util.h" #include "ot-fs-utils.h" #include @@ -66,6 +67,7 @@ typedef struct { gint n_scanned_metadata; gboolean gpg_verify; + gboolean require_static_deltas; gboolean gpg_verify_summary; gboolean has_tombstone_commits; @@ -78,7 +80,7 @@ typedef struct { GHashTable *commit_to_depth; /* Maps commit checksum maximum depth */ GHashTable *scanned_metadata; /* Maps object name to itself */ GHashTable *requested_metadata; /* Maps object name to itself */ - GHashTable *requested_content; /* Maps object name to itself */ + GHashTable *requested_content; /* Maps checksum to itself */ guint n_outstanding_metadata_fetches; guint n_outstanding_metadata_write_requests; guint n_outstanding_content_fetches; @@ -177,6 +179,10 @@ update_progress (gpointer user_data) if (! pull_data->progress) return FALSE; + /* In dry run, we only emit progress once metadata is done */ + if (pull_data->dry_run && pull_data->n_outstanding_metadata_fetches > 0) + return TRUE; + outstanding_writes = pull_data->n_outstanding_content_write_requests + pull_data->n_outstanding_metadata_write_requests + pull_data->n_outstanding_deltapart_write_requests; @@ -707,8 +713,7 @@ content_fetch_on_complete (GObject *object, OstreeObjectType objtype; gboolean free_fetch_data = TRUE; - temp_path = _ostree_fetcher_mirrored_request_with_partial_finish (fetcher, result, error); - if (!temp_path) + if (!_ostree_fetcher_request_to_tmpfile_finish (fetcher, result, &temp_path, error)) goto out; ostree_object_name_deserialize (fetch_data->object, &checksum, &objtype); @@ -841,8 +846,7 @@ meta_fetch_on_complete (GObject *object, g_debug ("fetch of %s%s complete", checksum_obj, fetch_data->is_detached_meta ? " (detached)" : ""); - temp_path = _ostree_fetcher_mirrored_request_with_partial_finish (fetcher, result, error); - if (!temp_path) + if (!_ostree_fetcher_request_to_tmpfile_finish (fetcher, result, &temp_path, error)) { if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { @@ -982,8 +986,7 @@ static_deltapart_fetch_on_complete (GObject *object, g_debug ("fetch static delta part %s complete", fetch_data->expected_checksum); - temp_path = _ostree_fetcher_mirrored_request_with_partial_finish (fetcher, result, error); - if (!temp_path) + if (!_ostree_fetcher_request_to_tmpfile_finish (fetcher, result, &temp_path, error)) goto out; fd = openat (_ostree_fetcher_get_dfd (fetcher), temp_path, O_RDONLY | O_CLOEXEC); @@ -1264,7 +1267,7 @@ scan_one_metadata_object_c (OtPullData *pull_data, if (g_hash_table_lookup (pull_data->scanned_metadata, object)) return TRUE; - is_requested = g_hash_table_lookup (pull_data->requested_metadata, tmp_checksum) != NULL; + is_requested = g_hash_table_lookup (pull_data->requested_metadata, object) != NULL; if (!ostree_repo_has_object (pull_data->repo, objtype, tmp_checksum, &is_stored, cancellable, error)) goto out; @@ -1289,10 +1292,9 @@ scan_one_metadata_object_c (OtPullData *pull_data, if (!is_stored && !is_requested) { - char *duped_checksum = g_strdup (tmp_checksum); gboolean do_fetch_detached; - g_hash_table_add (pull_data->requested_metadata, duped_checksum); + g_hash_table_add (pull_data->requested_metadata, g_variant_ref (object)); do_fetch_detached = (objtype == OSTREE_OBJECT_TYPE_COMMIT); enqueue_one_object_request (pull_data, tmp_checksum, objtype, path, do_fetch_detached, FALSE); @@ -1382,12 +1384,12 @@ enqueue_one_object_request (OtPullData *pull_data, else expected_max_size = 0; - _ostree_fetcher_mirrored_request_with_partial_async (pull_data->fetcher, mirrorlist, - obj_subpath, expected_max_size, - is_meta ? OSTREE_REPO_PULL_METADATA_PRIORITY - : OSTREE_REPO_PULL_CONTENT_PRIORITY, - pull_data->cancellable, - is_meta ? meta_fetch_on_complete : content_fetch_on_complete, fetch_data); + _ostree_fetcher_request_to_tmpfile (pull_data->fetcher, mirrorlist, + obj_subpath, expected_max_size, + is_meta ? OSTREE_REPO_PULL_METADATA_PRIORITY + : OSTREE_REPO_PULL_CONTENT_PRIORITY, + pull_data->cancellable, + is_meta ? meta_fetch_on_complete : content_fetch_on_complete, fetch_data); } static gboolean @@ -1418,75 +1420,6 @@ load_remote_repo_config (OtPullData *pull_data, return ret; } -static gboolean -request_static_delta_superblock_sync (OtPullData *pull_data, - const char *from_revision, - const char *to_revision, - GVariant **out_delta_superblock, - GCancellable *cancellable, - GError **error) -{ - gboolean ret = FALSE; - g_autoptr(GVariant) ret_delta_superblock = NULL; - g_autofree char *delta_name = - _ostree_get_relative_static_delta_superblock_path (from_revision, to_revision); - g_autoptr(GBytes) delta_superblock_data = NULL; - - if (!_ostree_fetcher_mirrored_request_to_membuf (pull_data->fetcher, - pull_data->content_mirrorlist, - delta_name, FALSE, TRUE, - &delta_superblock_data, - OSTREE_MAX_METADATA_SIZE, - pull_data->cancellable, error)) - goto out; - - if (delta_superblock_data) - { - { - g_autofree gchar *delta = NULL; - g_autofree guchar *ret_csum = NULL; - guchar *summary_csum; - g_autoptr (GInputStream) summary_is = NULL; - - summary_is = g_memory_input_stream_new_from_data (g_bytes_get_data (delta_superblock_data, NULL), - g_bytes_get_size (delta_superblock_data), - NULL); - - if (!ot_gio_checksum_stream (summary_is, &ret_csum, cancellable, error)) - goto out; - - delta = g_strconcat (from_revision ? from_revision : "", from_revision ? "-" : "", to_revision, NULL); - summary_csum = g_hash_table_lookup (pull_data->summary_deltas_checksums, delta); - - /* At this point we've GPG verified the data, so in theory - * could trust that they provided the right data, but let's - * make this a hard error. - */ - if (pull_data->gpg_verify_summary && !summary_csum) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "GPG verification enabled, but no summary signatures found (use gpg-verify-summary=false in remote config to disable)"); - goto out; - } - - if (summary_csum && memcmp (summary_csum, ret_csum, 32)) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid checksum for static delta %s", delta); - goto out; - } - } - - ret_delta_superblock = g_variant_ref_sink (g_variant_new_from_bytes ((GVariantType*)OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT, - delta_superblock_data, FALSE)); - } - - ret = TRUE; - if (out_delta_superblock) - *out_delta_superblock = g_steal_pointer (&ret_delta_superblock); - out: - return ret; -} - static gboolean process_one_static_delta_fallback (OtPullData *pull_data, gboolean delta_byteswap, @@ -1533,10 +1466,11 @@ process_one_static_delta_fallback (OtPullData *pull_data, { if (OSTREE_OBJECT_TYPE_IS_META (objtype)) { - if (!g_hash_table_lookup (pull_data->requested_metadata, checksum)) + g_autoptr(GVariant) objname = ostree_object_name_serialize (checksum, objtype); + if (!g_hash_table_lookup (pull_data->requested_metadata, objname)) { gboolean do_fetch_detached; - g_hash_table_add (pull_data->requested_metadata, checksum); + g_hash_table_add (pull_data->requested_metadata, g_variant_ref (objname)); do_fetch_detached = (objtype == OSTREE_OBJECT_TYPE_COMMIT); enqueue_one_object_request (pull_data, checksum, objtype, NULL, do_fetch_detached, FALSE); @@ -1735,13 +1669,13 @@ process_one_static_delta (OtPullData *pull_data, } else { - _ostree_fetcher_mirrored_request_with_partial_async (pull_data->fetcher, - pull_data->content_mirrorlist, - deltapart_path, size, - OSTREE_FETCHER_DEFAULT_PRIORITY, - pull_data->cancellable, - static_deltapart_fetch_on_complete, - fetch_data); + _ostree_fetcher_request_to_tmpfile (pull_data->fetcher, + pull_data->content_mirrorlist, + deltapart_path, size, + OSTREE_FETCHER_DEFAULT_PRIORITY, + pull_data->cancellable, + static_deltapart_fetch_on_complete, + fetch_data); pull_data->n_outstanding_deltapart_fetches++; } } @@ -1751,6 +1685,100 @@ process_one_static_delta (OtPullData *pull_data, return ret; } +typedef struct { + OtPullData *pull_data; + char *from_revision; + char *to_revision; +} FetchDeltaSuperData; + +static void +on_superblock_fetched (GObject *src, + GAsyncResult *res, + gpointer data) + +{ + FetchDeltaSuperData *fdata = data; + OtPullData *pull_data = fdata->pull_data; + GError *local_error = NULL; + GError **error = &local_error; + g_autoptr(GBytes) delta_superblock_data = NULL; + const char *from_revision = fdata->from_revision; + const char *to_revision = fdata->to_revision; + + if (!_ostree_fetcher_request_to_membuf_finish ((OstreeFetcher*)src, + res, + &delta_superblock_data, + error)) + { + if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + goto out; + + g_clear_error (&local_error); + + if (pull_data->require_static_deltas) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Static deltas required, but none found for %s to %s", + from_revision, to_revision); + goto out; + } + + queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, 0); + } + else + { + g_autofree gchar *delta = NULL; + g_autofree guchar *ret_csum = NULL; + guchar *summary_csum; + g_autoptr (GInputStream) summary_is = NULL; + g_autoptr(GVariant) delta_superblock = NULL; + + summary_is = g_memory_input_stream_new_from_data (g_bytes_get_data (delta_superblock_data, NULL), + g_bytes_get_size (delta_superblock_data), + NULL); + + if (!ot_gio_checksum_stream (summary_is, &ret_csum, pull_data->cancellable, error)) + goto out; + + delta = g_strconcat (from_revision ? from_revision : "", from_revision ? "-" : "", to_revision, NULL); + summary_csum = g_hash_table_lookup (pull_data->summary_deltas_checksums, delta); + + /* At this point we've GPG verified the data, so in theory + * could trust that they provided the right data, but let's + * make this a hard error. + */ + if (pull_data->gpg_verify_summary && !summary_csum) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "GPG verification enabled, but no summary signatures found (use gpg-verify-summary=false in remote config to disable)"); + goto out; + } + + if (summary_csum && memcmp (summary_csum, ret_csum, 32)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid checksum for static delta %s", delta); + goto out; + } + + delta_superblock = g_variant_ref_sink (g_variant_new_from_bytes ((GVariantType*)OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT, + delta_superblock_data, FALSE)); + + g_ptr_array_add (pull_data->static_delta_superblocks, g_variant_ref (delta_superblock)); + if (!process_one_static_delta (pull_data, from_revision, to_revision, delta_superblock, + pull_data->cancellable, error)) + goto out; + } + + out: + g_free (fdata->from_revision); + g_free (fdata->to_revision); + g_free (fdata); + g_assert (pull_data->n_outstanding_metadata_fetches > 0); + pull_data->n_outstanding_metadata_fetches--; + pull_data->n_fetched_metadata++; + check_outstanding_requests_handle_error (pull_data, local_error); +} + static gboolean validate_variant_is_csum (GVariant *csum, GError **error) @@ -1923,17 +1951,7 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self, } else if (tls_client_cert_path != NULL) { - g_autoptr(GTlsCertificate) client_cert = NULL; - - g_assert (tls_client_key_path != NULL); - - client_cert = g_tls_certificate_new_from_files (tls_client_cert_path, - tls_client_key_path, - error); - if (client_cert == NULL) - goto out; - - _ostree_fetcher_set_client_cert (fetcher, client_cert); + _ostree_fetcher_set_client_cert (fetcher, tls_client_cert_path, tls_client_key_path); } } @@ -1947,13 +1965,7 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self, if (tls_ca_path != NULL) { - g_autoptr(GTlsDatabase) db = NULL; - - db = g_tls_file_database_new (tls_ca_path, error); - if (db == NULL) - goto out; - - _ostree_fetcher_set_tls_database (fetcher, db); + _ostree_fetcher_set_tls_database (fetcher, tls_ca_path); } } @@ -2346,7 +2358,6 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_autofree char **override_commit_ids = NULL; GSource *update_timeout = NULL; gboolean disable_static_deltas = FALSE; - gboolean require_static_deltas = FALSE; gboolean opt_gpg_verify_set = FALSE; gboolean opt_gpg_verify_summary_set = FALSE; const char *url_override = NULL; @@ -2370,7 +2381,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_variant_lookup (options, "gpg-verify-summary", "b", &pull_data->gpg_verify_summary); (void) g_variant_lookup (options, "depth", "i", &pull_data->maxdepth); (void) g_variant_lookup (options, "disable-static-deltas", "b", &disable_static_deltas); - (void) g_variant_lookup (options, "require-static-deltas", "b", &require_static_deltas); + (void) g_variant_lookup (options, "require-static-deltas", "b", &pull_data->require_static_deltas); (void) g_variant_lookup (options, "override-commit-ids", "^a&s", &override_commit_ids); (void) g_variant_lookup (options, "dry-run", "b", &pull_data->dry_run); (void) g_variant_lookup (options, "override-url", "&s", &url_override); @@ -2388,11 +2399,11 @@ ostree_repo_pull_with_options (OstreeRepo *self, for (i = 0; dirs_to_pull != NULL && dirs_to_pull[i] != NULL; i++) g_return_val_if_fail (dirs_to_pull[i][0] == '/', FALSE); - g_return_val_if_fail (!(disable_static_deltas && require_static_deltas), FALSE); + g_return_val_if_fail (!(disable_static_deltas && pull_data->require_static_deltas), FALSE); /* We only do dry runs with static deltas, because we don't really have any * in-advance information for bare fetches. */ - g_return_val_if_fail (!pull_data->dry_run || require_static_deltas, FALSE); + g_return_val_if_fail (!pull_data->dry_run || pull_data->require_static_deltas, FALSE); pull_data->is_mirror = (flags & OSTREE_REPO_PULL_FLAGS_MIRROR) > 0; pull_data->is_commit_only = (flags & OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY) > 0; @@ -2424,8 +2435,8 @@ ostree_repo_pull_with_options (OstreeRepo *self, (GDestroyNotify)g_variant_unref, NULL); pull_data->requested_content = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL); - pull_data->requested_metadata = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify)g_free, NULL); + pull_data->requested_metadata = g_hash_table_new_full (ostree_hash_object_name, g_variant_equal, + (GDestroyNotify)g_variant_unref, NULL); if (dir_to_pull != NULL || dirs_to_pull != NULL) { pull_data->dirs = g_ptr_array_new_with_free_func (g_free); @@ -2657,7 +2668,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, /* For local pulls, default to disabling static deltas so that the * exact object files are copied. */ - if (pull_data->remote_repo_local && !require_static_deltas) + if (pull_data->remote_repo_local && !pull_data->require_static_deltas) disable_static_deltas = TRUE; pull_data->static_delta_superblocks = g_ptr_array_new_with_free_func ((GDestroyNotify)g_variant_unref); @@ -2712,7 +2723,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, goto out; } - if (!bytes_summary && require_static_deltas) + if (!bytes_summary && pull_data->require_static_deltas) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Fetch configured to require static deltas, but no summary found"); @@ -2941,7 +2952,6 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_autofree char *from_revision = NULL; const char *ref = key; const char *to_revision = value; - g_autoptr(GVariant) delta_superblock = NULL; if (!ostree_repo_resolve_rev (pull_data->repo, ref, TRUE, &from_revision, error)) @@ -2950,31 +2960,25 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (!(disable_static_deltas || mirroring_into_archive || pull_data->is_commit_only) && (from_revision == NULL || g_strcmp0 (from_revision, to_revision) != 0)) { - if (!request_static_delta_superblock_sync (pull_data, from_revision, to_revision, - &delta_superblock, cancellable, error)) - goto out; - } - - if (!delta_superblock) - { - if (require_static_deltas) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Static deltas required, but none found for %s to %s", - from_revision, to_revision); - goto out; - } - g_debug ("no delta superblock for %s-%s", from_revision ? from_revision : "empty", to_revision); - queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, 0); + g_autofree char *delta_name = + _ostree_get_relative_static_delta_superblock_path (from_revision, to_revision); + FetchDeltaSuperData *fdata = g_new0(FetchDeltaSuperData, 1); + fdata->pull_data = pull_data; + fdata->from_revision = g_strdup (from_revision); + fdata->to_revision = g_strdup (to_revision); + + _ostree_fetcher_request_to_membuf (pull_data->fetcher, + pull_data->content_mirrorlist, + delta_name, 0, + OSTREE_MAX_METADATA_SIZE, + 0, pull_data->cancellable, + on_superblock_fetched, fdata); + pull_data->n_outstanding_metadata_fetches++; + pull_data->n_requested_metadata++; } else { - g_debug ("processing delta superblock for %s-%s", from_revision ? from_revision : "empty", to_revision); - g_ptr_array_add (pull_data->static_delta_superblocks, g_variant_ref (delta_superblock)); - if (!process_one_static_delta (pull_data, from_revision, to_revision, - delta_superblock, - cancellable, error)) - goto out; + queue_scan_one_metadata_object (pull_data, to_revision, OSTREE_OBJECT_TYPE_COMMIT, NULL, 0); } } diff --git a/src/libostree/ostree-repo-static-delta-compilation.c b/src/libostree/ostree-repo-static-delta-compilation.c index 1611d19e..657e8676 100644 --- a/src/libostree/ostree-repo-static-delta-compilation.c +++ b/src/libostree/ostree-repo-static-delta-compilation.c @@ -843,6 +843,25 @@ process_one_bsdiff (OstreeRepo *repo, return ret; } +static gboolean +check_object_world_readable (OstreeRepo *repo, + const char *checksum, + gboolean *out_readable, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GFileInfo) finfo = NULL; + guint32 mode; + + if (!ostree_repo_load_file (repo, checksum, NULL, &finfo, NULL, + cancellable, error)) + return FALSE; + + mode = g_file_info_get_attribute_uint32 (finfo, "unix::mode"); + *out_readable = (mode & S_IROTH); + return TRUE; +} + static gboolean generate_delta_lowlatency (OstreeRepo *repo, const char *from, @@ -973,6 +992,22 @@ generate_delta_lowlatency (OstreeRepo *repo, const char *from_checksum = value; ContentRollsum *rollsum; ContentBsdiff *bsdiff; + gboolean from_world_readable = FALSE; + + /* We only want to include in the delta objects that we are sure will + * be readable by the client when applying the delta, regardless its + * access privileges, so that we don't run into permissions problems + * when the client is trying to update a bare-user repository with a + * bare repository defined as its parent. + */ + if (!check_object_world_readable (repo, from_checksum, &from_world_readable, cancellable, error)) + goto out; + if (!from_world_readable) + { + g_hash_table_iter_steal (&hashiter); + g_hash_table_add (new_reachable_regfile_content, (char*)from_checksum); + continue; + } if (!try_content_rollsum (repo, opts, from_checksum, to_checksum, &rollsum, cancellable, error)) diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 1c4ae663..3b3aa664 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -2456,12 +2456,12 @@ list_loose_objects_at (OstreeRepo *self, continue; } - key = ostree_object_name_serialize (buf, objtype); - value = g_variant_new ("(b@as)", - TRUE, g_variant_new_strv (NULL, 0)); - /* transfer ownership */ - g_hash_table_replace (inout_objects, key, - g_variant_ref_sink (value)); + key = ostree_object_name_serialize (buf, objtype); + value = g_variant_new ("(b@as)", + TRUE, g_variant_new_strv (NULL, 0)); + /* transfer ownership */ + g_hash_table_replace (inout_objects, g_variant_ref_sink (key), + g_variant_ref_sink (value)); } ret = TRUE; @@ -3548,7 +3548,8 @@ ostree_repo_load_commit (OstreeRepo *self, * ostree_repo_list_objects: * @self: Repo * @flags: Flags controlling enumeration - * @out_objects: (out): Map of serialized object name to variant data + * @out_objects: (out) (transfer container) (element-type GVariant GVariant): + * Map of serialized object name to variant data * @cancellable: Cancellable * @error: Error * @@ -3605,7 +3606,8 @@ ostree_repo_list_objects (OstreeRepo *self, * ostree_repo_list_commit_objects_starting_with: * @self: Repo * @start: List commits starting with this checksum - * @out_commits: Array of GVariants + * @out_commits: (out) (transfer container) (element-type GVariant GVariant): + * Map of serialized commit name to variant data * @cancellable: Cancellable * @error: Error * diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index d5303e41..341a4d9c 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -970,6 +970,27 @@ gboolean ostree_repo_prune (OstreeRepo *self, GCancellable *cancellable, GError **error); +struct _OstreeRepoPruneOptions { + OstreeRepoPruneFlags flags; + + GHashTable *reachable; /* Set (object names) */ + + gboolean unused_bools[6]; + int unused_ints[6]; + gpointer unused_ptrs[7]; +}; + +typedef struct _OstreeRepoPruneOptions OstreeRepoPruneOptions; + +_OSTREE_PUBLIC +gboolean ostree_repo_prune_from_reachable (OstreeRepo *self, + OstreeRepoPruneOptions *options, + gint *out_objects_total, + gint *out_objects_pruned, + guint64 *out_pruned_object_size_total, + GCancellable *cancellable, + GError **error); + /** * OstreeRepoPullFlags: * @OSTREE_REPO_PULL_FLAGS_NONE: No special options for pull diff --git a/src/libostree/ostree-tls-cert-interaction.c b/src/libostree/ostree-tls-cert-interaction.c index 846d5725..7e60f9de 100644 --- a/src/libostree/ostree-tls-cert-interaction.c +++ b/src/libostree/ostree-tls-cert-interaction.c @@ -24,6 +24,8 @@ struct _OstreeTlsCertInteraction { GTlsInteraction parent_instance; + char *cert_path; + char *key_path; GTlsCertificate *cert; }; @@ -44,6 +46,14 @@ request_certificate (GTlsInteraction *interaction, GError **error) { OstreeTlsCertInteraction *self = (OstreeTlsCertInteraction*)interaction; + + if (!self->cert) + { + self->cert = g_tls_certificate_new_from_files (self->cert_path, self->key_path, error); + if (!self->cert) + return G_TLS_INTERACTION_FAILED; + } + g_tls_connection_set_certificate (connection, self->cert); return G_TLS_INTERACTION_HANDLED; } @@ -61,9 +71,11 @@ _ostree_tls_cert_interaction_class_init (OstreeTlsCertInteractionClass *klass) } OstreeTlsCertInteraction * -_ostree_tls_cert_interaction_new (GTlsCertificate *cert) +_ostree_tls_cert_interaction_new (const char *cert_path, + const char *key_path) { OstreeTlsCertInteraction *self = g_object_new (OSTREE_TYPE_TLS_CERT_INTERACTION, NULL); - self->cert = g_object_ref (cert); + self->cert_path = g_strdup (cert_path); + self->key_path = g_strdup (key_path); return self; } diff --git a/src/libostree/ostree-tls-cert-interaction.h b/src/libostree/ostree-tls-cert-interaction.h index c81097c5..ae4532f7 100644 --- a/src/libostree/ostree-tls-cert-interaction.h +++ b/src/libostree/ostree-tls-cert-interaction.h @@ -34,6 +34,7 @@ typedef struct _OstreeTlsCertInteractionClass OstreeTlsCertInteractionClass; GType _ostree_tls_cert_interaction_get_type (void) G_GNUC_CONST; -OstreeTlsCertInteraction * _ostree_tls_cert_interaction_new (GTlsCertificate *cert); +OstreeTlsCertInteraction * _ostree_tls_cert_interaction_new (const char *cert_path, + const char *key_path); G_END_DECLS diff --git a/src/ostree/ostree-trivial-httpd.c b/src/ostree/ostree-trivial-httpd.c new file mode 100644 index 00000000..ddcb2fc0 --- /dev/null +++ b/src/ostree/ostree-trivial-httpd.c @@ -0,0 +1,687 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2011,2013 Colin Walters + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include + +#include "ot-main.h" +#include "ot-builtins.h" +#include "ostree.h" +#include "otutil.h" + +#include +#include +#include +#include +#include + +static char *opt_port_file = NULL; +static char *opt_log = NULL; +static gboolean opt_daemonize; +static gboolean opt_autoexit; +static gboolean opt_force_ranges; +static int opt_random_500s_percentage; +/* We have a strong upper bound for any unlikely + * cases involving repeated random 500s. */ +static int opt_random_500s_max = 100; +static gint opt_port = 0; +static gchar **opt_expected_cookies; +static gchar **opt_expected_headers; + +static guint emitted_random_500s_count = 0; + +typedef struct { + int root_dfd; + gboolean running; + GOutputStream *log; +} OtTrivialHttpd; + +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 }, + { "port", 'P', 0, G_OPTION_ARG_INT, &opt_port, "Use the specified TCP port", NULL }, + { "port-file", 'p', 0, G_OPTION_ARG_FILENAME, &opt_port_file, "Write port number to PATH (- for standard output)", "PATH" }, + { "force-range-requests", 0, 0, G_OPTION_ARG_NONE, &opt_force_ranges, "Force range requests by only serving half of files", NULL }, + { "random-500s", 0, 0, G_OPTION_ARG_INT, &opt_random_500s_percentage, "Generate random HTTP 500 errors approximately for PERCENTAGE requests", "PERCENTAGE" }, + { "random-500s-max", 0, 0, G_OPTION_ARG_INT, &opt_random_500s_max, "Limit HTTP 500 errors to MAX (default 100)", "MAX" }, + { "log-file", 0, 0, G_OPTION_ARG_FILENAME, &opt_log, "Put logs here", "PATH" }, + { "expected-cookies", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_expected_cookies, "Expect given cookies in the http request", "KEY=VALUE" }, + { "expected-header", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_expected_headers, "Expect given headers in the http request", "KEY=VALUE" }, + { NULL } +}; + +static void +httpd_log (OtTrivialHttpd *httpd, const gchar *format, ...) __attribute__ ((format(printf, 2, 3))); + +static void +httpd_log (OtTrivialHttpd *httpd, const gchar *format, ...) +{ + g_autoptr(GString) str = NULL; + va_list args; + gsize written; + + if (!httpd->log) + return; + + { + g_autoptr(GDateTime) now = g_date_time_new_now_local (); + g_autofree char *timestamp = g_date_time_format (now, "%F %T"); + str = g_string_new (timestamp); + g_string_append_printf (str, ".%06d - ", g_date_time_get_microsecond (now)); + } + + va_start (args, 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); +} + +static int +compare_strings (gconstpointer a, gconstpointer b) +{ + const char **sa = (const char **)a; + const char **sb = (const char **)b; + + return strcmp (*sa, *sb); +} + +static GString * +get_directory_listing (int dfd, + const char *path) +{ + g_autoptr(GPtrArray) entries = g_ptr_array_new_with_free_func (g_free); + g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; + g_autoptr(GError) local_error = NULL; + GError **error = &local_error; + guint i; + char *escaped; + GString *listing; + + listing = g_string_new ("\r\n"); + + if (!glnx_dirfd_iterator_init_at (dfd, path, FALSE, &dfd_iter, error)) + goto out; + + while (TRUE) + { + struct dirent *dent; + + if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, NULL, error)) + goto out; + + if (dent == NULL) + break; + + escaped = g_markup_escape_text (dent->d_name, -1); + g_ptr_array_add (entries, escaped); + } + + g_ptr_array_sort (entries, (GCompareFunc)compare_strings); + + escaped = g_markup_escape_text (strchr (path, '/'), -1); + g_string_append_printf (listing, "Index of %s\r\n", escaped); + g_string_append_printf (listing, "

Index of %s

\r\n

\r\n", escaped); + g_free (escaped); + for (i = 0; i < entries->len; i++) + { + g_string_append_printf (listing, "%s
\r\n", + (char *)entries->pdata[i], + (char *)entries->pdata[i]); + g_free (g_steal_pointer (&entries->pdata[i])); + } + g_string_append (listing, "\r\n\r\n"); + out: + if (local_error) + g_printerr ("%s\n", local_error->message); + return listing; +} + +/* Only allow reading files that have o+r, and for directories, o+x. + * This makes this server relatively safe to use on multiuser + * machines. + */ +static gboolean +is_safe_to_access (struct stat *stbuf) +{ + /* Only regular files or directores */ + if (!(S_ISREG (stbuf->st_mode) || S_ISDIR (stbuf->st_mode))) + return FALSE; + /* Must be o+r */ + if (!(stbuf->st_mode & S_IROTH)) + return FALSE; + /* For directories, must be o+x */ + if (S_ISDIR (stbuf->st_mode) && !(stbuf->st_mode & S_IXOTH)) + return FALSE; + return TRUE; +} + +static void +close_socket (SoupMessage *msg, gpointer user_data) +{ + SoupSocket *sock = user_data; + int sockfd; + + /* Actually calling soup_socket_disconnect() here would cause + * us to leak memory, so just shutdown the socket instead. + */ + sockfd = soup_socket_get_fd (sock); +#ifdef G_OS_WIN32 + shutdown (sockfd, SD_SEND); +#else + shutdown (sockfd, SHUT_WR); +#endif +} + +static void +do_get (OtTrivialHttpd *self, + SoupServer *server, + SoupMessage *msg, + const char *path, + SoupClientContext *context) +{ + char *slash; + int ret; + struct stat stbuf; + + httpd_log (self, "serving %s\n", path); + + if (opt_expected_cookies) + { + GSList *cookies = soup_cookies_from_request (msg); + GSList *l; + int i; + + for (i = 0 ; opt_expected_cookies[i] != NULL; i++) + { + gboolean found = FALSE; + gchar *k = opt_expected_cookies[i]; + gchar *v = strchr (k, '=') + 1; + + for (l = cookies; l != NULL ; l = g_slist_next (l)) + { + SoupCookie *c = l->data; + + if (!strncmp (k, soup_cookie_get_name (c), v - k - 1) && + !strcmp (v, soup_cookie_get_value (c))) + { + found = TRUE; + break; + } + } + + if (!found) + { + httpd_log (self, "Expected cookie not found %s\n", k); + soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); + soup_cookies_free (cookies); + goto out; + } + } + soup_cookies_free (cookies); + } + + if (opt_expected_headers) + { + for (int i = 0 ; opt_expected_headers[i] != NULL; i++) + { + const gchar *kv = opt_expected_headers[i]; + const gchar *eq = strchr (kv, '='); + + g_assert (eq); + + { + g_autofree char *k = g_strndup (kv, eq - kv); + const gchar *expected_v = eq + 1; + const gchar *found_v = soup_message_headers_get_one (msg->request_headers, k); + + if (!found_v) + { + httpd_log (self, "Expected header not found %s\n", k); + soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); + goto out; + } + if (strcmp (found_v, expected_v) != 0) + { + httpd_log (self, "Expected header %s: %s but found %s\n", k, expected_v, found_v); + soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); + goto out; + } + } + } + } + + if (strstr (path, "../") != NULL) + { + soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); + goto out; + } + + if (opt_random_500s_percentage > 0 && + emitted_random_500s_count < opt_random_500s_max && + g_random_int_range (0, 100) < opt_random_500s_percentage) + { + emitted_random_500s_count++; + soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); + goto out; + } + + while (path[0] == '/') + path++; + + do + ret = fstatat (self->root_dfd, path, &stbuf, 0); + while (ret == -1 && errno == EINTR); + if (ret == -1) + { + if (errno == EPERM) + soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); + else if (errno == ENOENT) + soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND); + else + soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); + goto out; + } + + if (!is_safe_to_access (&stbuf)) + { + soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); + goto out; + } + + if (S_ISDIR (stbuf.st_mode)) + { + slash = strrchr (path, '/'); + if (!slash || slash[1]) + { + g_autofree char *redir_uri = NULL; + + redir_uri = g_strdup_printf ("%s/", soup_message_get_uri (msg)->path); + soup_message_set_redirect (msg, SOUP_STATUS_MOVED_PERMANENTLY, + redir_uri); + } + else + { + g_autofree char *index_realpath = g_strconcat (path, "/index.html", NULL); + if (fstatat (self->root_dfd, index_realpath, &stbuf, 0) != -1) + { + g_autofree char *index_path = g_strconcat (path, "/index.html", NULL); + do_get (self, server, msg, index_path, context); + } + else + { + GString *listing = get_directory_listing (self->root_dfd, path); + soup_message_set_response (msg, "text/html", + SOUP_MEMORY_TAKE, + listing->str, listing->len); + soup_message_set_status (msg, SOUP_STATUS_OK); + g_string_free (listing, FALSE); + } + } + } + else + { + if (!S_ISREG (stbuf.st_mode)) + { + soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); + goto out; + } + + if (msg->method == SOUP_METHOD_GET) + { + glnx_fd_close int fd = -1; + g_autoptr(GMappedFile) mapping = NULL; + gsize buffer_length, file_size; + SoupRange *ranges; + int ranges_length; + gboolean have_ranges; + + fd = openat (self->root_dfd, path, O_RDONLY | O_CLOEXEC); + if (fd < 0) + { + soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); + goto out; + } + + mapping = g_mapped_file_new_from_fd (fd, FALSE, NULL); + if (!mapping) + { + soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); + goto out; + } + (void) close (fd); fd = -1; + + file_size = g_mapped_file_get_length (mapping); + have_ranges = soup_message_headers_get_ranges(msg->request_headers, file_size, &ranges, &ranges_length); + if (opt_force_ranges && !have_ranges && g_strrstr (path, "/objects") != NULL) + { + SoupSocket *sock; + buffer_length = file_size/2; + soup_message_headers_set_content_length (msg->response_headers, file_size); + soup_message_headers_append (msg->response_headers, + "Connection", "close"); + + /* soup-message-io will wait for us to add + * another chunk after the first, to fill out + * the declared Content-Length. Instead, we + * forcibly close the socket at that point. + */ + sock = soup_client_context_get_socket (context); + g_signal_connect (msg, "wrote-chunk", G_CALLBACK (close_socket), sock); + } + else + buffer_length = file_size; + + if (have_ranges) + { + if (ranges_length > 0 && ranges[0].start >= file_size) + { + soup_message_set_status (msg, SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE); + soup_message_headers_free_ranges (msg->request_headers, ranges); + goto out; + } + soup_message_headers_free_ranges (msg->request_headers, ranges); + } + if (buffer_length > 0) + { + SoupBuffer *buffer; + + buffer = soup_buffer_new_with_owner (g_mapped_file_get_contents (mapping), + buffer_length, + g_mapped_file_ref (mapping), + (GDestroyNotify)g_mapped_file_unref); + soup_message_body_append_buffer (msg->response_body, buffer); + soup_buffer_free (buffer); + } + } + else /* msg->method == SOUP_METHOD_HEAD */ + { + g_autofree char *length = NULL; + + /* We could just use the same code for both GET and + * HEAD (soup-message-server-io.c will fix things up). + * But we'll optimize and avoid the extra I/O. + */ + length = g_strdup_printf ("%lu", (gulong)stbuf.st_size); + soup_message_headers_append (msg->response_headers, + "Content-Length", length); + } + soup_message_set_status (msg, SOUP_STATUS_OK); + } + out: + { + guint status = 0; + g_autofree gchar *reason = NULL; + + g_object_get (msg, + "status-code", &status, + "reason-phrase", &reason, + NULL); + httpd_log (self, " status: %s (%u)\n", reason, status); + } + return; +} + +static void +httpd_callback (SoupServer *server, SoupMessage *msg, + const char *path, GHashTable *query, + SoupClientContext *context, gpointer data) +{ + OtTrivialHttpd *self = data; + + if (msg->method == SOUP_METHOD_GET || msg->method == SOUP_METHOD_HEAD) + do_get (self, server, msg, path, context); + else + soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); +} + +static void +on_dir_changed (GFileMonitor *mon, + GFile *file, + GFile *other, + GFileMonitorEvent event, + gpointer user_data) +{ + OtTrivialHttpd *self = user_data; + + if (event == G_FILE_MONITOR_EVENT_DELETED) + { + self->running = FALSE; + g_main_context_wakeup (NULL); + } +} + +static gboolean +run (int argc, char **argv, GCancellable *cancellable, GError **error) +{ + gboolean ret = FALSE; + g_autoptr(GOptionContext) context = NULL; + const char *dirpath; + OtTrivialHttpd appstruct = { 0, }; + OtTrivialHttpd *app = &appstruct; + glnx_unref_object SoupServer *server = NULL; + g_autoptr(GFileMonitor) dirmon = NULL; + + context = g_option_context_new ("[DIR] - Simple webserver"); + g_option_context_add_main_entries (context, options, NULL); + + app->root_dfd = -1; + + if (!g_option_context_parse (context, &argc, &argv, error)) + goto out; + + if (argc > 1) + dirpath = argv[1]; + else + dirpath = "."; + + if (!glnx_opendirat (AT_FDCWD, dirpath, TRUE, &app->root_dfd, error)) + goto out; + + if (!(opt_random_500s_percentage >= 0 && opt_random_500s_percentage <= 99)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid --random-500s=%u", opt_random_500s_percentage); + goto out; + } + + if (opt_log) + { + GOutputStream *stream = NULL; + + if (g_strcmp0 (opt_log, "-") == 0) + { + if (opt_daemonize) + { + ot_util_usage_error (context, "Cannot use --log-file=- and --daemonize at the same time", error); + goto out; + } + stream = G_OUTPUT_STREAM (g_unix_output_stream_new (STDOUT_FILENO, FALSE)); + } + else + { + g_autoptr(GFile) log_file; + GFileOutputStream* log_stream; + + log_file = g_file_new_for_path (opt_log); + log_stream = g_file_create (log_file, + G_FILE_CREATE_PRIVATE, + cancellable, + error); + if (!log_stream) + goto out; + stream = G_OUTPUT_STREAM (log_stream); + } + + app->log = stream; + } + +#if SOUP_CHECK_VERSION(2, 48, 0) + server = soup_server_new (SOUP_SERVER_SERVER_HEADER, "ostree-httpd ", NULL); + if (!soup_server_listen_all (server, opt_port, 0, error)) + goto out; +#else + server = soup_server_new (SOUP_SERVER_PORT, opt_port, + SOUP_SERVER_SERVER_HEADER, "ostree-httpd ", + NULL); +#endif + + soup_server_add_handler (server, NULL, httpd_callback, app, NULL); + if (opt_port_file) + { + g_autofree char *portstr = NULL; +#if SOUP_CHECK_VERSION(2, 48, 0) + GSList *listeners = soup_server_get_listeners (server); + g_autoptr(GSocket) listener = NULL; + g_autoptr(GSocketAddress) addr = NULL; + + g_assert (listeners); + listener = g_object_ref (listeners->data); + g_slist_free (listeners); + listeners = NULL; + addr = g_socket_get_local_address (listener, error); + if (!addr) + goto out; + + g_assert (G_IS_INET_SOCKET_ADDRESS (addr)); + + portstr = g_strdup_printf ("%u\n", g_inet_socket_address_get_port ((GInetSocketAddress*)addr)); +#else + portstr = g_strdup_printf ("%u\n", soup_server_get_port (server)); +#endif + + if (g_strcmp0 ("-", opt_port_file) == 0) + { + fputs (portstr, stdout); // not g_print - this must go to stdout, not a handler + fflush (stdout); + } + else if (!g_file_set_contents (opt_port_file, portstr, strlen (portstr), error)) + goto out; + } +#if !SOUP_CHECK_VERSION(2, 48, 0) + soup_server_run_async (server); +#endif + + if (opt_daemonize) + { + pid_t pid = fork(); + if (pid == -1) + { + int errsv = errno; + g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), + g_strerror (errsv)); + goto out; + } + else if (pid > 0) + { + ret = TRUE; + goto out; + } + /* Child, continue */ + if (setsid () < 0) + err (1, "setsid"); + /* Daemonising: close stdout/stderr so $() et al work on us */ + freopen("/dev/null", "r", stdin); + freopen("/dev/null", "w", stdout); + freopen("/dev/null", "w", stderr); + } + else + { + /* Since we're used for testing purposes, let's just do this by + * default. This ensures we exit when our parent does. + */ + if (prctl (PR_SET_PDEATHSIG, SIGTERM) != 0) + { + if (errno != ENOSYS) + { + glnx_set_error_from_errno (error); + goto out; + } + } + } + + app->running = TRUE; + if (opt_autoexit) + { + gboolean is_symlink = FALSE; + g_autoptr(GFile) root = NULL; + g_autoptr(GFileInfo) info = NULL; + + root = g_file_new_for_path (dirpath); + info = g_file_query_info (root, + G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + cancellable, error); + if (!info) + goto out; + + is_symlink = g_file_info_get_is_symlink (info); + + if (is_symlink) + dirmon = g_file_monitor_file (root, 0, cancellable, error); + else + dirmon = g_file_monitor_directory (root, 0, cancellable, error); + + if (!dirmon) + goto out; + g_signal_connect (dirmon, "changed", G_CALLBACK (on_dir_changed), app); + } + httpd_log (app, "serving at root %s\n", dirpath); + while (app->running) + g_main_context_iteration (NULL, TRUE); + + ret = TRUE; + out: + if (app->root_dfd != -1) + (void) close (app->root_dfd); + g_clear_object (&app->log); + return ret; +} + +int +main (int argc, + char **argv) +{ + g_autoptr(GError) error = NULL; + g_autoptr(GCancellable) cancellable = NULL; + + setlocale (LC_ALL, ""); + + g_set_prgname (argv[0]); + + if (!run (argc, argv, cancellable, &error)) + { + int is_tty = isatty (1); + const char *prefix = ""; + const char *suffix = ""; + if (is_tty) + { + prefix = "\x1b[31m\x1b[1m"; /* red, bold */ + suffix = "\x1b[22m\x1b[0m"; /* bold off, color reset */ + } + g_printerr ("%serror: %s%s\n", prefix, suffix, error->message); + return 1; + } + + return 0; +} diff --git a/src/ostree/ot-admin-builtin-unlock.c b/src/ostree/ot-admin-builtin-unlock.c index 0f22d0a6..aecba51b 100644 --- a/src/ostree/ot-admin-builtin-unlock.c +++ b/src/ostree/ot-admin-builtin-unlock.c @@ -34,7 +34,7 @@ static gboolean opt_hotfix; static GOptionEntry options[] = { - { "hotfix", 0, 0, G_OPTION_ARG_NONE, &opt_hotfix, "Keep the current deployment as default", NULL }, + { "hotfix", 0, 0, G_OPTION_ARG_NONE, &opt_hotfix, "Retain changes across reboots", NULL }, { NULL } }; diff --git a/src/ostree/ot-admin-functions.c b/src/ostree/ot-admin-functions.c index ed4dfdfb..7ba2207e 100644 --- a/src/ostree/ot-admin-functions.c +++ b/src/ostree/ot-admin-functions.c @@ -164,7 +164,7 @@ ot_admin_execve_reboot (OstreeSysroot *sysroot, GError **error) if (g_file_equal (ostree_sysroot_get_path (sysroot), real_sysroot)) { - if (execl ("systemctl", "systemctl", "reboot", NULL) < 0) + if (execlp ("systemctl", "systemctl", "reboot", NULL) < 0) { glnx_set_error_from_errno (error); return FALSE; diff --git a/src/ostree/ot-builtin-prune.c b/src/ostree/ot-builtin-prune.c index d226c84b..853c051f 100644 --- a/src/ostree/ot-builtin-prune.c +++ b/src/ostree/ot-builtin-prune.c @@ -34,6 +34,7 @@ static gint opt_depth = -1; static gboolean opt_refs_only; static char *opt_delete_commit; static char *opt_keep_younger_than; +static char **opt_retain_branch_depth; static GOptionEntry options[] = { { "no-prune", 0, 0, G_OPTION_ARG_NONE, &opt_no_prune, "Only display unreachable objects; don't delete", NULL }, @@ -42,6 +43,7 @@ static GOptionEntry options[] = { { "delete-commit", 0, 0, G_OPTION_ARG_STRING, &opt_delete_commit, "Specify a commit to delete", "COMMIT" }, { "keep-younger-than", 0, 0, G_OPTION_ARG_STRING, &opt_keep_younger_than, "Prune all commits older than the specified date", "DATE" }, { "static-deltas-only", 0, 0, G_OPTION_ARG_NONE, &opt_static_deltas_only, "Change the behavior of delete-commit and keep-younger-than to prune only static deltas" }, + { "retain-branch-depth", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_retain_branch_depth, "Additionally retain BRANCH=DEPTH commits", "BRANCH=DEPTH" }, { NULL } }; @@ -82,87 +84,53 @@ delete_commit (OstreeRepo *repo, const char *commit_to_delete, GCancellable *can } static gboolean -prune_commits_keep_younger_than_date (OstreeRepo *repo, const char *date, GCancellable *cancellable, GError **error) +traverse_keep_younger_than (OstreeRepo *repo, const char *checksum, + struct timespec *ts, + GHashTable *reachable, + GCancellable *cancellable, GError **error) { - g_autoptr(GHashTable) refs = NULL; - g_autoptr(GHashTable) ref_heads = g_hash_table_new (g_str_hash, g_str_equal); - g_autoptr(GHashTable) objects = NULL; - GHashTableIter hash_iter; - gpointer key, value; - struct timespec ts; - gboolean ret = FALSE; + g_autofree char *next_checksum = g_strdup (checksum); + g_autoptr(GVariant) commit = NULL; - if (!parse_datetime (&ts, date, NULL)) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Could not parse '%s'", date); - goto out; - } - - if (!ot_enable_tombstone_commits (repo, error)) - goto out; - - if (!ostree_repo_list_refs (repo, NULL, &refs, cancellable, error)) - goto out; - - /* We used to prune the HEAD of a given ref by default, but that's - * broken for a few reasons. One is that people may use branches as - * tags. Second is that if we do it, we should be deleting the ref - * too, otherwise e.g. `summary -u` breaks trying to load it, etc. + /* This is the first commit in our loop, which has a ref pointing to it. We + * don't want to auto-prune it. */ - g_hash_table_iter_init (&hash_iter, refs); - while (g_hash_table_iter_next (&hash_iter, &key, &value)) + if (!ostree_repo_traverse_commit_union (repo, checksum, 0, reachable, + cancellable, error)) + return FALSE; + + while (TRUE) { - /* Value is lifecycle bound to refs */ - g_hash_table_add (ref_heads, (char*)value); - } - - if (!ostree_repo_list_objects (repo, OSTREE_REPO_LIST_OBJECTS_ALL, &objects, - cancellable, error)) - goto out; - - g_hash_table_iter_init (&hash_iter, objects); - - while (g_hash_table_iter_next (&hash_iter, &key, &value)) - { - GVariant *serialized_key = key; - const char *checksum; - OstreeObjectType objtype; guint64 commit_timestamp; - g_autoptr(GVariant) commit = NULL; - ostree_object_name_deserialize (serialized_key, &checksum, &objtype); + if (!ostree_repo_load_variant_if_exists (repo, OSTREE_OBJECT_TYPE_COMMIT, next_checksum, + &commit, error)) + return FALSE; - if (objtype != OSTREE_OBJECT_TYPE_COMMIT) - continue; - - if (g_hash_table_contains (ref_heads, checksum)) - continue; - - if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum, - &commit, error)) - goto out; + if (!commit) + break; /* This commit was pruned, so we're done */ commit_timestamp = ostree_commit_get_timestamp (commit); - if (commit_timestamp < ts.tv_sec) + /* Is this commit newer than our --keep-younger-than spec? */ + if (commit_timestamp >= ts->tv_sec) { - if (opt_static_deltas_only) - { - if(!ostree_repo_prune_static_deltas (repo, checksum, cancellable, error)) - goto out; - } + /* It's newer, traverse it */ + if (!ostree_repo_traverse_commit_union (repo, next_checksum, 0, reachable, + cancellable, error)) + return FALSE; + + g_free (next_checksum); + next_checksum = ostree_commit_get_parent (commit); + if (next_checksum) + g_clear_pointer (&commit, (GDestroyNotify)g_variant_unref); else - { - if (!ostree_repo_delete_object (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum, cancellable, error)) - goto out; - } + break; /* No parent, we're done */ } + else + break; /* It's older than our spec, we're done */ } - ret = TRUE; - - out: - return ret; + return TRUE; } gboolean @@ -185,6 +153,9 @@ ostree_builtin_prune (int argc, char **argv, GCancellable *cancellable, GError * if (!opt_no_prune && !ostree_ensure_repo_writable (repo, error)) goto out; + /* Special handling for explicit commit deletion here - we do this + * first. + */ if (opt_delete_commit) { if (opt_no_prune) @@ -200,26 +171,133 @@ ostree_builtin_prune (int argc, char **argv, GCancellable *cancellable, GError * else if (!delete_commit (repo, opt_delete_commit, cancellable, error)) goto out; } - if (opt_keep_younger_than) - { - if (opt_no_prune) - { - ot_util_usage_error (context, "Cannot specify both --keep-younger-than and --no-prune", error); - goto out; - } - if (!prune_commits_keep_younger_than_date (repo, opt_keep_younger_than, cancellable, error)) - goto out; - } if (opt_refs_only) pruneflags |= OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY; if (opt_no_prune) pruneflags |= OSTREE_REPO_PRUNE_FLAGS_NO_PRUNE; - if (!ostree_repo_prune (repo, pruneflags, opt_depth, - &n_objects_total, &n_objects_pruned, &objsize_total, - cancellable, error)) - goto out; + /* If no newer more complex options are specified, drop down to the original + * prune API - both to avoid code duplication, and to keep it run from the + * test suite. + */ + if (!(opt_retain_branch_depth || opt_keep_younger_than)) + { + if (!ostree_repo_prune (repo, pruneflags, opt_depth, + &n_objects_total, &n_objects_pruned, &objsize_total, + cancellable, error)) + goto out; + } + else + { + g_autoptr(GHashTable) all_refs = NULL; + g_autoptr(GHashTable) reachable = ostree_repo_traverse_new_reachable (); + g_autoptr(GHashTable) retain_branch_depth = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + struct timespec keep_younger_than_ts; + GHashTableIter hash_iter; + gpointer key, value; + + /* Otherwise, the default is --refs-only; we set this just as a note */ + opt_refs_only = TRUE; + + if (opt_keep_younger_than) + { + if (!parse_datetime (&keep_younger_than_ts, opt_keep_younger_than, NULL)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Could not parse '%s'", opt_keep_younger_than); + goto out; + } + } + + for (char **iter = opt_retain_branch_depth; iter && *iter; iter++) + { + /* bd should look like BRANCH=DEPTH where DEPTH is an int */ + const char *bd = *iter; + const char *eq = strchr (bd, '='); + const char *depthstr; + gint64 depth; + char *endptr; + + if (!eq) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid value %s, must specify BRANCH=DEPTH", + bd); + goto out; + } + depthstr = eq + 1; + errno = EPERM; + depth = g_ascii_strtoll (depthstr, &endptr, 10); + if (depth == 0) + { + if (errno == EINVAL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Out of range depth %s", depthstr); + goto out; + } + else if (endptr == depthstr) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid depth %s", depthstr); + goto out; + } + } + g_hash_table_insert (retain_branch_depth, g_strndup (bd, eq - bd), + GINT_TO_POINTER ((int)depth)); + } + + /* We start from the refs */ + if (!ostree_repo_list_refs (repo, NULL, &all_refs, + cancellable, error)) + return FALSE; + + g_hash_table_iter_init (&hash_iter, all_refs); + while (g_hash_table_iter_next (&hash_iter, &key, &value)) + { + const char *checksum = value; + gpointer depthp = g_hash_table_lookup (retain_branch_depth, key); + gint depth; + + /* Here, we handle a spec like + * --retain-branch-depth=myos/x86_64/stable=-1 + * --retain-branch-depth=myos/x86_64/dev=5 + */ + if (depthp) + depth = GPOINTER_TO_INT(depthp); + else if (opt_keep_younger_than) + { + if (!traverse_keep_younger_than (repo, checksum, + &keep_younger_than_ts, + reachable, + cancellable, error)) + goto out; + + /* Okay, we handled the younger-than case; the other + * two fall through to plain depth-based handling below. + */ + continue; /* Note again, we're skipping the below bit */ + } + else + depth = opt_depth; /* No --retain-branch-depth for this branch, use + the global default */ + + g_debug ("Finding objects to keep for commit %s", checksum); + if (!ostree_repo_traverse_commit_union (repo, checksum, depth, reachable, + cancellable, error)) + return FALSE; + } + + { OstreeRepoPruneOptions opts = { pruneflags, reachable }; + if (!ostree_repo_prune_from_reachable (repo, &opts, + &n_objects_total, + &n_objects_pruned, + &objsize_total, + cancellable, error)) + goto out; + } + } formatted_freed_size = g_format_size_full (objsize_total, 0); diff --git a/src/ostree/ot-builtin-trivial-httpd.c b/src/ostree/ot-builtin-trivial-httpd.c index 0a553858..206970c5 100644 --- a/src/ostree/ot-builtin-trivial-httpd.c +++ b/src/ostree/ot-builtin-trivial-httpd.c @@ -1,6 +1,6 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- * - * Copyright (C) 2011,2013 Colin Walters + * Copyright (C) 2016 Colin Walters * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,634 +20,22 @@ #include "config.h" -#include - -#include - #include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "otutil.h" -#include -#include -#include - -static char *opt_port_file = NULL; -static char *opt_log = NULL; -static gboolean opt_daemonize; -static gboolean opt_autoexit; -static gboolean opt_force_ranges; -static int opt_random_500s_percentage; -/* We have a strong upper bound for any unlikely - * cases involving repeated random 500s. */ -static int opt_random_500s_max = 100; -static gint opt_port = 0; -static gchar **opt_expected_cookies; -static gchar **opt_expected_headers; - -static guint emitted_random_500s_count = 0; - -typedef struct { - int root_dfd; - gboolean running; - GOutputStream *log; -} OtTrivialHttpd; - -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 }, - { "port", 'P', 0, G_OPTION_ARG_INT, &opt_port, "Use the specified TCP port", NULL }, - { "port-file", 'p', 0, G_OPTION_ARG_FILENAME, &opt_port_file, "Write port number to PATH (- for standard output)", "PATH" }, - { "force-range-requests", 0, 0, G_OPTION_ARG_NONE, &opt_force_ranges, "Force range requests by only serving half of files", NULL }, - { "random-500s", 0, 0, G_OPTION_ARG_INT, &opt_random_500s_percentage, "Generate random HTTP 500 errors approximately for PERCENTAGE requests", "PERCENTAGE" }, - { "random-500s-max", 0, 0, G_OPTION_ARG_INT, &opt_random_500s_max, "Limit HTTP 500 errors to MAX (default 100)", "MAX" }, - { "log-file", 0, 0, G_OPTION_ARG_FILENAME, &opt_log, "Put logs here", "PATH" }, - { "expected-cookies", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_expected_cookies, "Expect given cookies in the http request", "KEY=VALUE" }, - { "expected-header", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_expected_headers, "Expect given headers in the http request", "KEY=VALUE" }, - { NULL } -}; - -static void -httpd_log (OtTrivialHttpd *httpd, const gchar *format, ...) __attribute__ ((format(printf, 2, 3))); - -static void -httpd_log (OtTrivialHttpd *httpd, const gchar *format, ...) -{ - g_autoptr(GString) str = NULL; - va_list args; - gsize written; - - if (!httpd->log) - return; - - { - g_autoptr(GDateTime) now = g_date_time_new_now_local (); - g_autofree char *timestamp = g_date_time_format (now, "%F %T"); - str = g_string_new (timestamp); - g_string_append_printf (str, ".%06d - ", g_date_time_get_microsecond (now)); - } - - va_start (args, 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); -} - -static int -compare_strings (gconstpointer a, gconstpointer b) -{ - const char **sa = (const char **)a; - const char **sb = (const char **)b; - - return strcmp (*sa, *sb); -} - -static GString * -get_directory_listing (int dfd, - const char *path) -{ - g_autoptr(GPtrArray) entries = g_ptr_array_new_with_free_func (g_free); - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; - g_autoptr(GError) local_error = NULL; - GError **error = &local_error; - guint i; - char *escaped; - GString *listing; - - listing = g_string_new ("\r\n"); - - if (!glnx_dirfd_iterator_init_at (dfd, path, FALSE, &dfd_iter, error)) - goto out; - - while (TRUE) - { - struct dirent *dent; - - if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, NULL, error)) - goto out; - - if (dent == NULL) - break; - - escaped = g_markup_escape_text (dent->d_name, -1); - g_ptr_array_add (entries, escaped); - } - - g_ptr_array_sort (entries, (GCompareFunc)compare_strings); - - escaped = g_markup_escape_text (strchr (path, '/'), -1); - g_string_append_printf (listing, "Index of %s\r\n", escaped); - g_string_append_printf (listing, "

Index of %s

\r\n

\r\n", escaped); - g_free (escaped); - for (i = 0; i < entries->len; i++) - { - g_string_append_printf (listing, "%s
\r\n", - (char *)entries->pdata[i], - (char *)entries->pdata[i]); - g_free (g_steal_pointer (&entries->pdata[i])); - } - g_string_append (listing, "\r\n\r\n"); - out: - if (local_error) - g_printerr ("%s\n", local_error->message); - return listing; -} - -/* Only allow reading files that have o+r, and for directories, o+x. - * This makes this server relatively safe to use on multiuser - * machines. - */ -static gboolean -is_safe_to_access (struct stat *stbuf) -{ - /* Only regular files or directores */ - if (!(S_ISREG (stbuf->st_mode) || S_ISDIR (stbuf->st_mode))) - return FALSE; - /* Must be o+r */ - if (!(stbuf->st_mode & S_IROTH)) - return FALSE; - /* For directories, must be o+x */ - if (S_ISDIR (stbuf->st_mode) && !(stbuf->st_mode & S_IXOTH)) - return FALSE; - return TRUE; -} - -static void -close_socket (SoupMessage *msg, gpointer user_data) -{ - SoupSocket *sock = user_data; - int sockfd; - - /* Actually calling soup_socket_disconnect() here would cause - * us to leak memory, so just shutdown the socket instead. - */ - sockfd = soup_socket_get_fd (sock); -#ifdef G_OS_WIN32 - shutdown (sockfd, SD_SEND); -#else - shutdown (sockfd, SHUT_WR); -#endif -} - -static void -do_get (OtTrivialHttpd *self, - SoupServer *server, - SoupMessage *msg, - const char *path, - SoupClientContext *context) -{ - char *slash; - int ret; - struct stat stbuf; - - httpd_log (self, "serving %s\n", path); - - if (opt_expected_cookies) - { - GSList *cookies = soup_cookies_from_request (msg); - GSList *l; - int i; - - for (i = 0 ; opt_expected_cookies[i] != NULL; i++) - { - gboolean found = FALSE; - gchar *k = opt_expected_cookies[i]; - gchar *v = strchr (k, '=') + 1; - - for (l = cookies; l != NULL ; l = g_slist_next (l)) - { - SoupCookie *c = l->data; - - if (!strncmp (k, soup_cookie_get_name (c), v - k - 1) && - !strcmp (v, soup_cookie_get_value (c))) - { - found = TRUE; - break; - } - } - - if (!found) - { - httpd_log (self, "Expected cookie not found %s\n", k); - soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); - soup_cookies_free (cookies); - goto out; - } - } - soup_cookies_free (cookies); - } - - if (opt_expected_headers) - { - for (int i = 0 ; opt_expected_headers[i] != NULL; i++) - { - const gchar *kv = opt_expected_headers[i]; - const gchar *eq = strchr (kv, '='); - - g_assert (eq); - - { - g_autofree char *k = g_strndup (kv, eq - kv); - const gchar *expected_v = eq + 1; - const gchar *found_v = soup_message_headers_get_one (msg->request_headers, k); - - if (!found_v) - { - httpd_log (self, "Expected header not found %s\n", k); - soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); - goto out; - } - if (strcmp (found_v, expected_v) != 0) - { - httpd_log (self, "Expected header %s: %s but found %s\n", k, expected_v, found_v); - soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); - goto out; - } - } - } - } - - if (strstr (path, "../") != NULL) - { - soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); - goto out; - } - - if (opt_random_500s_percentage > 0 && - emitted_random_500s_count < opt_random_500s_max && - g_random_int_range (0, 100) < opt_random_500s_percentage) - { - emitted_random_500s_count++; - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); - goto out; - } - - while (path[0] == '/') - path++; - - do - ret = fstatat (self->root_dfd, path, &stbuf, 0); - while (ret == -1 && errno == EINTR); - if (ret == -1) - { - if (errno == EPERM) - soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); - else if (errno == ENOENT) - soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND); - else - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); - goto out; - } - - if (!is_safe_to_access (&stbuf)) - { - soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); - goto out; - } - - if (S_ISDIR (stbuf.st_mode)) - { - slash = strrchr (path, '/'); - if (!slash || slash[1]) - { - g_autofree char *redir_uri = NULL; - - redir_uri = g_strdup_printf ("%s/", soup_message_get_uri (msg)->path); - soup_message_set_redirect (msg, SOUP_STATUS_MOVED_PERMANENTLY, - redir_uri); - } - else - { - g_autofree char *index_realpath = g_strconcat (path, "/index.html", NULL); - if (fstatat (self->root_dfd, index_realpath, &stbuf, 0) != -1) - { - g_autofree char *index_path = g_strconcat (path, "/index.html", NULL); - do_get (self, server, msg, index_path, context); - } - else - { - GString *listing = get_directory_listing (self->root_dfd, path); - soup_message_set_response (msg, "text/html", - SOUP_MEMORY_TAKE, - listing->str, listing->len); - soup_message_set_status (msg, SOUP_STATUS_OK); - g_string_free (listing, FALSE); - } - } - } - else - { - if (!S_ISREG (stbuf.st_mode)) - { - soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN); - goto out; - } - - if (msg->method == SOUP_METHOD_GET) - { - glnx_fd_close int fd = -1; - g_autoptr(GMappedFile) mapping = NULL; - gsize buffer_length, file_size; - SoupRange *ranges; - int ranges_length; - gboolean have_ranges; - - fd = openat (self->root_dfd, path, O_RDONLY | O_CLOEXEC); - if (fd < 0) - { - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); - goto out; - } - - mapping = g_mapped_file_new_from_fd (fd, FALSE, NULL); - if (!mapping) - { - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); - goto out; - } - (void) close (fd); fd = -1; - - file_size = g_mapped_file_get_length (mapping); - have_ranges = soup_message_headers_get_ranges(msg->request_headers, file_size, &ranges, &ranges_length); - if (opt_force_ranges && !have_ranges && g_strrstr (path, "/objects") != NULL) - { - SoupSocket *sock; - buffer_length = file_size/2; - soup_message_headers_set_content_length (msg->response_headers, file_size); - soup_message_headers_append (msg->response_headers, - "Connection", "close"); - - /* soup-message-io will wait for us to add - * another chunk after the first, to fill out - * the declared Content-Length. Instead, we - * forcibly close the socket at that point. - */ - sock = soup_client_context_get_socket (context); - g_signal_connect (msg, "wrote-chunk", G_CALLBACK (close_socket), sock); - } - else - buffer_length = file_size; - - if (have_ranges) - { - if (ranges_length > 0 && ranges[0].start >= file_size) - { - soup_message_set_status (msg, SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE); - soup_message_headers_free_ranges (msg->request_headers, ranges); - goto out; - } - soup_message_headers_free_ranges (msg->request_headers, ranges); - } - if (buffer_length > 0) - { - SoupBuffer *buffer; - - buffer = soup_buffer_new_with_owner (g_mapped_file_get_contents (mapping), - buffer_length, - g_mapped_file_ref (mapping), - (GDestroyNotify)g_mapped_file_unref); - soup_message_body_append_buffer (msg->response_body, buffer); - soup_buffer_free (buffer); - } - } - else /* msg->method == SOUP_METHOD_HEAD */ - { - g_autofree char *length = NULL; - - /* We could just use the same code for both GET and - * HEAD (soup-message-server-io.c will fix things up). - * But we'll optimize and avoid the extra I/O. - */ - length = g_strdup_printf ("%lu", (gulong)stbuf.st_size); - soup_message_headers_append (msg->response_headers, - "Content-Length", length); - } - soup_message_set_status (msg, SOUP_STATUS_OK); - } - out: - { - guint status = 0; - g_autofree gchar *reason = NULL; - - g_object_get (msg, - "status-code", &status, - "reason-phrase", &reason, - NULL); - httpd_log (self, " status: %s (%u)\n", reason, status); - } - return; -} - -static void -httpd_callback (SoupServer *server, SoupMessage *msg, - const char *path, GHashTable *query, - SoupClientContext *context, gpointer data) -{ - OtTrivialHttpd *self = data; - - if (msg->method == SOUP_METHOD_GET || msg->method == SOUP_METHOD_HEAD) - do_get (self, server, msg, path, context); - else - soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); -} - -static void -on_dir_changed (GFileMonitor *mon, - GFile *file, - GFile *other, - GFileMonitorEvent event, - gpointer user_data) -{ - OtTrivialHttpd *self = user_data; - - if (event == G_FILE_MONITOR_EVENT_DELETED) - { - self->running = FALSE; - g_main_context_wakeup (NULL); - } -} - gboolean ostree_builtin_trivial_httpd (int argc, char **argv, GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; - g_autoptr(GOptionContext) context = NULL; - const char *dirpath; - OtTrivialHttpd appstruct = { 0, }; - OtTrivialHttpd *app = &appstruct; - glnx_unref_object SoupServer *server = NULL; - g_autoptr(GFileMonitor) dirmon = NULL; + g_autoptr(GPtrArray) new_argv = g_ptr_array_new (); - context = g_option_context_new ("[DIR] - Simple webserver"); - - app->root_dfd = -1; - - if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NO_REPO, NULL, cancellable, error)) - goto out; - - if (argc > 1) - dirpath = argv[1]; - else - dirpath = "."; - - if (!glnx_opendirat (AT_FDCWD, dirpath, TRUE, &app->root_dfd, error)) - goto out; - - if (!(opt_random_500s_percentage >= 0 && opt_random_500s_percentage <= 99)) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Invalid --random-500s=%u", opt_random_500s_percentage); - goto out; - } - - if (opt_log) - { - GOutputStream *stream = NULL; - - if (g_strcmp0 (opt_log, "-") == 0) - { - if (opt_daemonize) - { - ot_util_usage_error (context, "Cannot use --log-file=- and --daemonize at the same time", error); - goto out; - } - stream = G_OUTPUT_STREAM (g_unix_output_stream_new (STDOUT_FILENO, FALSE)); - } - else - { - g_autoptr(GFile) log_file; - GFileOutputStream* log_stream; - - log_file = g_file_new_for_path (opt_log); - log_stream = g_file_create (log_file, - G_FILE_CREATE_PRIVATE, - cancellable, - error); - if (!log_stream) - goto out; - stream = G_OUTPUT_STREAM (log_stream); - } - - app->log = stream; - } - -#if SOUP_CHECK_VERSION(2, 48, 0) - server = soup_server_new (SOUP_SERVER_SERVER_HEADER, "ostree-httpd ", NULL); - if (!soup_server_listen_all (server, opt_port, 0, error)) - goto out; -#else - server = soup_server_new (SOUP_SERVER_PORT, opt_port, - SOUP_SERVER_SERVER_HEADER, "ostree-httpd ", - NULL); -#endif - - soup_server_add_handler (server, NULL, httpd_callback, app, NULL); - if (opt_port_file) - { - g_autofree char *portstr = NULL; -#if SOUP_CHECK_VERSION(2, 48, 0) - GSList *listeners = soup_server_get_listeners (server); - g_autoptr(GSocket) listener = NULL; - g_autoptr(GSocketAddress) addr = NULL; - - g_assert (listeners); - listener = g_object_ref (listeners->data); - g_slist_free (listeners); - listeners = NULL; - addr = g_socket_get_local_address (listener, error); - if (!addr) - goto out; - - g_assert (G_IS_INET_SOCKET_ADDRESS (addr)); - - portstr = g_strdup_printf ("%u\n", g_inet_socket_address_get_port ((GInetSocketAddress*)addr)); -#else - portstr = g_strdup_printf ("%u\n", soup_server_get_port (server)); -#endif - - if (g_strcmp0 ("-", opt_port_file) == 0) - { - fputs (portstr, stdout); // not g_print - this must go to stdout, not a handler - fflush (stdout); - } - else if (!g_file_set_contents (opt_port_file, portstr, strlen (portstr), error)) - goto out; - } -#if !SOUP_CHECK_VERSION(2, 48, 0) - soup_server_run_async (server); -#endif - - if (opt_daemonize) - { - pid_t pid = fork(); - if (pid == -1) - { - int errsv = errno; - g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errsv), - g_strerror (errsv)); - goto out; - } - else if (pid > 0) - { - ret = TRUE; - goto out; - } - /* Child, continue */ - /* Daemonising: close stdout/stderr so $() et al work on us */ - fclose (stdout); - fclose (stdin); - } - else - { - /* Since we're used for testing purposes, let's just do this by - * default. This ensures we exit when our parent does. - */ - if (prctl (PR_SET_PDEATHSIG, SIGTERM) != 0) - { - if (errno != ENOSYS) - { - glnx_set_error_from_errno (error); - goto out; - } - } - } - - app->running = TRUE; - if (opt_autoexit) - { - gboolean is_symlink = FALSE; - g_autoptr(GFile) root = NULL; - g_autoptr(GFileInfo) info = NULL; - - root = g_file_new_for_path (dirpath); - info = g_file_query_info (root, - G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - cancellable, error); - if (!info) - goto out; - - is_symlink = g_file_info_get_is_symlink (info); - - if (is_symlink) - dirmon = g_file_monitor_file (root, 0, cancellable, error); - else - dirmon = g_file_monitor_directory (root, 0, cancellable, error); - - if (!dirmon) - goto out; - g_signal_connect (dirmon, "changed", G_CALLBACK (on_dir_changed), app); - } - httpd_log (app, "serving at root %s\n", dirpath); - while (app->running) - g_main_context_iteration (NULL, TRUE); - - ret = TRUE; - out: - if (app->root_dfd != -1) - (void) close (app->root_dfd); - g_clear_object (&app->log); - return ret; + g_ptr_array_add (new_argv, PKGLIBEXECDIR "/ostree-trivial-httpd"); + for (int i = 1; i < argc; i++) + g_ptr_array_add (new_argv, argv[i]); + g_ptr_array_add (new_argv, NULL); + execvp (new_argv->pdata[0], (char**)new_argv->pdata); + /* Fall through on error */ + glnx_set_error_from_errno (error); + return FALSE; } diff --git a/tests/admin-test.sh b/tests/admin-test.sh old mode 100755 new mode 100644 index 76fc8b85..cc06fe6f --- a/tests/admin-test.sh +++ b/tests/admin-test.sh @@ -1,4 +1,5 @@ -#!/bin/bash +# This file is to be sourced, not executed + # Copyright (C) 2011,2014 Colin Walters # # This library is free software; you can redistribute it and/or diff --git a/tests/archive-test.sh b/tests/archive-test.sh old mode 100755 new mode 100644 index e6f67cf5..9c5f8a47 --- a/tests/archive-test.sh +++ b/tests/archive-test.sh @@ -1,5 +1,5 @@ -#!/bin/bash -# +# This file is to be sourced, not executed + # Copyright (C) 2011 Colin Walters # # This library is free software; you can redistribute it and/or diff --git a/tests/basic-test.sh b/tests/basic-test.sh old mode 100755 new mode 100644 index bb387501..5cad8ab3 --- a/tests/basic-test.sh +++ b/tests/basic-test.sh @@ -1,5 +1,5 @@ -#!/bin/bash -# +# This file is to be sourced, not executed + # Copyright (C) 2011 Colin Walters # # This library is free software; you can redistribute it and/or @@ -26,7 +26,7 @@ echo "ok checkout" $OSTREE rev-parse test2 $OSTREE rev-parse 'test2^' -$OSTREE rev-parse 'test2^^' 2>/dev/null && (echo 1>&2 "rev-parse test2^^ unexpectedly succeeded!"; exit 1) +$OSTREE rev-parse 'test2^^' 2>/dev/null && fatal "rev-parse test2^^ unexpectedly succeeded!" echo "ok rev-parse" checksum=$($OSTREE rev-parse test2) @@ -294,7 +294,7 @@ rm repo3/refs/heads/* repo3/refs/remotes/* -rf ${CMD_PREFIX} ostree --repo=repo3 prune --refs-only find repo3/objects -name '*.commit' > objlist-after-prune if cmp -s objlist-before-prune objlist-after-prune; then - echo "Prune didn't delete anything!"; exit 1 + fatal "Prune didn't delete anything!" fi rm repo3 objlist-before-prune objlist-after-prune -rf echo "ok prune" diff --git a/tests/corrupt-repo-ref.js b/tests/corrupt-repo-ref.js old mode 100644 new mode 100755 diff --git a/tests/libtest.sh b/tests/libtest.sh index c0bf8d0d..927b8b1a 100755 --- a/tests/libtest.sh +++ b/tests/libtest.sh @@ -29,9 +29,13 @@ else test_builddir=$(dirname $0) fi -assert_not_reached () { +fatal() { echo $@ 1>&2; exit 1 } +# fatal() is shorter to type, but retain this alias +assert_not_reached () { + fatal "$@" +} test_tmpdir=$(pwd) @@ -102,55 +106,58 @@ else fi fi +if test -n "${OSTREE_UNINSTALLED:-}"; then + OSTREE_HTTPD=${OSTREE_UNINSTALLED}/ostree-trivial-httpd +else + OSTREE_HTTPD="${CMD_PREFIX} ostree trivial-httpd" +fi + assert_streq () { - test "$1" = "$2" || (echo 1>&2 "$1 != $2"; exit 1) + test "$1" = "$2" || fatal "$1 != $2" } assert_str_match () { if ! echo "$1" | grep -E -q "$2"; then - (echo 1>&2 "$1 does not match regexp $2"; exit 1) + fatal "$1 does not match regexp $2" fi } assert_not_streq () { - (! test "$1" = "$2") || (echo 1>&2 "$1 == $2"; exit 1) + (! test "$1" = "$2") || fatal "$1 == $2" } assert_has_file () { - test -f "$1" || (echo 1>&2 "Couldn't find '$1'"; exit 1) + test -f "$1" || fatal "Couldn't find '$1'" } assert_has_dir () { - test -d "$1" || (echo 1>&2 "Couldn't find '$1'"; exit 1) + test -d "$1" || fatal "Couldn't find '$1'" } assert_not_has_file () { if test -f "$1"; then sed -e 's/^/# /' < "$1" >&2 - echo 1>&2 "File '$1' exists" - exit 1 + fatal "File '$1' exists" fi } assert_not_file_has_content () { if grep -q -e "$2" "$1"; then sed -e 's/^/# /' < "$1" >&2 - echo 1>&2 "File '$1' incorrectly matches regexp '$2'" - exit 1 + fatal "File '$1' incorrectly matches regexp '$2'" fi } assert_not_has_dir () { if test -d "$1"; then - echo 1>&2 "Directory '$1' exists"; exit 1 + fatal "Directory '$1' exists" fi } assert_file_has_content () { if ! grep -q -e "$2" "$1"; then sed -e 's/^/# /' < "$1" >&2 - echo 1>&2 "File '$1' doesn't match regexp '$2'" - exit 1 + fatal "File '$1' doesn't match regexp '$2'" fi } @@ -169,8 +176,7 @@ assert_symlink_has_content () { assert_file_empty() { if test -s "$1"; then sed -e 's/^/# /' < "$1" >&2 - echo 1>&2 "File '$1' is not empty" - exit 1 + fatal "File '$1' is not empty" fi } @@ -178,8 +184,7 @@ assert_files_hardlinked() { f1=$(stat -c %i $1) f2=$(stat -c %i $2) if [ "$f1" != "$f2" ]; then - echo 1>&2 "Files '$1' and '$2' are not hardlinked" - exit 1 + fatal "Files '$1' and '$2' are not hardlinked" fi } @@ -257,7 +262,7 @@ setup_fake_remote_repo1() { mkdir ${test_tmpdir}/httpd cd httpd ln -s ${test_tmpdir}/ostree-srv ostree - ${CMD_PREFIX} ostree trivial-httpd --autoexit --daemonize -p ${test_tmpdir}/httpd-port $args + ${OSTREE_HTTPD} --autoexit --log-file $(pwd)/httpd.log --daemonize -p ${test_tmpdir}/httpd-port $args port=$(cat ${test_tmpdir}/httpd-port) echo "http://127.0.0.1:${port}" > ${test_tmpdir}/httpd-address cd ${oldpwd} @@ -379,7 +384,7 @@ EOF mkdir ${test_tmpdir}/httpd cd httpd ln -s ${test_tmpdir} ostree - ${CMD_PREFIX} ostree trivial-httpd --autoexit --daemonize -p ${test_tmpdir}/httpd-port + ${OSTREE_HTTPD} --autoexit --daemonize -p ${test_tmpdir}/httpd-port port=$(cat ${test_tmpdir}/httpd-port) echo "http://127.0.0.1:${port}" > ${test_tmpdir}/httpd-address cd ${oldpwd} diff --git a/tests/pull-test.sh b/tests/pull-test.sh old mode 100755 new mode 100644 index 56258b6c..56b24a0c --- a/tests/pull-test.sh +++ b/tests/pull-test.sh @@ -1,5 +1,5 @@ -#!/bin/bash -# +# This file is to be sourced, not executed + # Copyright (C) 2011 Colin Walters # # This library is free software; you can redistribute it and/or diff --git a/tests/test-basic-user.sh b/tests/test-basic-user.sh index 42e6a864..3e11545e 100755 --- a/tests/test-basic-user.sh +++ b/tests/test-basic-user.sh @@ -23,9 +23,6 @@ set -euo pipefail skip_without_user_xattrs -echo "1..1" - setup_test_repository "bare-user" -echo "ok setup" . $(dirname $0)/basic-test.sh diff --git a/tests/test-commit-sign.sh b/tests/test-commit-sign.sh index 60265c1a..f963b104 100755 --- a/tests/test-commit-sign.sh +++ b/tests/test-commit-sign.sh @@ -53,7 +53,7 @@ cd ${test_tmpdir} mkdir ${test_tmpdir}/httpd cd httpd ln -s ${test_tmpdir}/ostree-srv ostree -${CMD_PREFIX} ostree trivial-httpd --autoexit --daemonize -P 18081 -p ${test_tmpdir}/httpd-port +${OSTREE_HTTPD} --autoexit --daemonize -P 18081 -p ${test_tmpdir}/httpd-port port=$(cat ${test_tmpdir}/httpd-port) assert_streq $port 18081 echo "http://127.0.0.1:${port}" > ${test_tmpdir}/httpd-address diff --git a/tests/test-prune.sh b/tests/test-prune.sh index ce14ce67..51ec7948 100755 --- a/tests/test-prune.sh +++ b/tests/test-prune.sh @@ -25,7 +25,7 @@ skip_without_user_xattrs setup_fake_remote_repo1 "archive-z2" -echo '1..3' +echo '1..5' cd ${test_tmpdir} mkdir repo @@ -49,6 +49,7 @@ find repo | grep \.commit$ | wc -l > commitcount assert_file_has_content commitcount "^3$" find repo/objects -name '*.tombstone-commit' | wc -l > tombstonecommitcount assert_file_has_content tombstonecommitcount "^0$" +$OSTREE fsck ${CMD_PREFIX} ostree prune --repo=repo --refs-only --depth=1 -v find repo | grep \.commit$ | wc -l > commitcount @@ -73,6 +74,7 @@ find repo/objects -name '*.commit' | wc -l > commitcount assert_file_has_content commitcount "^1$" find repo/objects -name '*.tombstone-commit' | wc -l > tombstonecommitcount assert_not_file_has_content tombstonecommitcount "^0$" +$OSTREE fsck # and that tombstone are deleted once the commits are pulled again ${CMD_PREFIX} ostree --repo=repo pull --depth=-1 origin test @@ -83,6 +85,7 @@ COMMIT_TO_DELETE=$(${CMD_PREFIX} ostree --repo=repo log test | grep ^commit | cu ${CMD_PREFIX} ostree --repo=repo prune --delete-commit=$COMMIT_TO_DELETE find repo/objects -name '*.tombstone-commit' | wc -l > tombstonecommitcount assert_file_has_content tombstonecommitcount "^1$" +$OSTREE fsck ${CMD_PREFIX} ostree prune --repo=repo --refs-only --depth=0 -v find repo/objects -name '*.commit' | wc -l > commitcount @@ -94,6 +97,7 @@ assert_file_has_content commitcount "^3$" ${CMD_PREFIX} ostree --repo=repo prune --keep-younger-than="2015-10-29 12:43:29 +0000" find repo/objects -name '*.commit' | wc -l > commitcount assert_file_has_content commitcount "^2$" +$OSTREE fsck ${CMD_PREFIX} ostree prune --repo=repo --refs-only --depth=0 -v @@ -112,6 +116,7 @@ oldcommit_rev=$($OSTREE --repo=repo rev-parse oldcommit) $OSTREE ls ${oldcommit_rev} ${CMD_PREFIX} ostree --repo=repo prune --keep-younger-than="1 week ago" $OSTREE ls ${oldcommit_rev} +$OSTREE fsck ${CMD_PREFIX} ostree --repo=repo pull --depth=-1 origin test ${CMD_PREFIX} ostree --repo=repo commit --branch=test -m test -s test tree --timestamp="November 05 1955" @@ -124,6 +129,7 @@ ${CMD_PREFIX} ostree --repo=repo static-delta list | wc -l > deltascount assert_file_has_content deltascount "^2$" COMMIT_TO_DELETE=$(${CMD_PREFIX} ostree --repo=repo rev-parse test) ${CMD_PREFIX} ostree --repo=repo prune --static-deltas-only --delete-commit=$COMMIT_TO_DELETE +${CMD_PREFIX} ostree --repo=repo fsck ${CMD_PREFIX} ostree --repo=repo static-delta list | wc -l > deltascount assert_file_has_content deltascount "^1$" ${CMD_PREFIX} ostree --repo=repo static-delta generate test @@ -178,3 +184,62 @@ ${CMD_PREFIX} ostree --repo=child-repo prune --refs-only --depth=0 assert_has_n_objects child-repo 3 echo "ok prune with parent repo" + +# Delete all the above since I can't be bothered to think about how new tests +# would interact. We make a new repo test suite, then clone it +# for "subtests" below with reinitialize_datesnap_repo() +rm repo datetest-snapshot-repo -rf +${CMD_PREFIX} ostree --repo=datetest-snapshot-repo init --mode=archive +# Some ancient commits on the both a stable/dev branch +for day in $(seq 5); do + ${CMD_PREFIX} ostree --repo=datetest-snapshot-repo commit --branch=stable -m test -s "old stable build $day" tree --timestamp="October $day 1985" + ${CMD_PREFIX} ostree --repo=datetest-snapshot-repo commit --branch=dev -m test -s "old dev build $day" tree --timestamp="October $day 1985" +done +# And some new ones +for x in $(seq 3); do + ${CMD_PREFIX} ostree --repo=datetest-snapshot-repo commit --branch=stable -m test -s "new stable build $x" tree + ${CMD_PREFIX} ostree --repo=datetest-snapshot-repo commit --branch=dev -m test -s "new dev build $x" tree +done +find datetest-snapshot-repo/objects -name '*.commit' | wc -l > commitcount +assert_file_has_content commitcount "^16$" + +# Snapshot the above +reinitialize_datesnap_repo() { + rm repo -rf + ${CMD_PREFIX} ostree --repo=repo init --mode=archive + ${CMD_PREFIX} ostree --repo=repo pull-local --depth=-1 datetest-snapshot-repo +} + +# This test prunes with both younger than as well as a full strong ref to the +# stable branch +reinitialize_datesnap_repo +# First, a quick test of invalid input +if ${CMD_PREFIX} ostree --repo=repo prune --keep-younger-than="1 week ago" --retain-branch-depth=stable=BACON 2>err.txt; then + assert_not_reached "BACON is a number?!" +fi +assert_file_has_content err.txt 'Invalid depth BACON' +${CMD_PREFIX} ostree --repo=repo prune --keep-younger-than="1 week ago" --retain-branch-depth=stable=-1 +find repo/objects -name '*.commit' | wc -l > commitcount +assert_file_has_content commitcount "^11$" +# Double check our backup is unchanged +find datetest-snapshot-repo/objects -name '*.commit' | wc -l > commitcount +assert_file_has_content commitcount "^16$" +$OSTREE fsck + +# Again but this time only retain 6 (5+1) commits on stable. This should drop +# out 8 - 6 = 2 commits (so the 11 above minus 2 = 9) +${CMD_PREFIX} ostree --repo=repo prune --keep-younger-than="1 week ago" --retain-branch-depth=stable=5 +find repo/objects -name '*.commit' | wc -l > commitcount +assert_file_has_content commitcount "^9$" +$OSTREE fsck +echo "ok retain branch depth and keep-younger-than" + +# Just stable branch ref, we should prune everything except the tip of dev, +# so 8 stable + 1 dev = 9 +reinitialize_datesnap_repo +${CMD_PREFIX} ostree --repo=repo prune --depth=0 --retain-branch-depth=stable=-1 +find repo/objects -name '*.commit' | wc -l > commitcount +assert_file_has_content commitcount "^9$" +$OSTREE fsck + +echo "ok retain branch depth (alone)" diff --git a/tests/test-pull-c.c b/tests/test-pull-c.c index 43d5d61d..c2d64dcc 100644 --- a/tests/test-pull-c.c +++ b/tests/test-pull-c.c @@ -49,6 +49,8 @@ test_data_init (TestData *td) if (!g_file_get_contents ("httpd-address", &http_address, NULL, error)) goto out; + g_strstrip (http_address); + repo_url = g_strconcat (http_address, "/ostree/gnomerepo", NULL); { g_autoptr(GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); diff --git a/tests/test-pull-contenturl.sh b/tests/test-pull-contenturl.sh index 16dcbe4f..d74d619b 100755 --- a/tests/test-pull-contenturl.sh +++ b/tests/test-pull-contenturl.sh @@ -51,8 +51,7 @@ fi find ${test_tmpdir}/ostree-srv/gnomerepo/objects \ ! -name '*.commitmeta' -type f | xargs rm -${CMD_PREFIX} ostree trivial-httpd --autoexit --daemonize \ - -p ${test_tmpdir}/httpd-content-port +${OSTREE_HTTPD} --autoexit --daemonize -p ${test_tmpdir}/httpd-content-port content_port=$(cat ${test_tmpdir}/httpd-content-port) echo "http://127.0.0.1:${content_port}" > ${test_tmpdir}/httpd-content-address diff --git a/tests/test-pull-many.sh b/tests/test-pull-many.sh new file mode 100755 index 00000000..d90280d5 --- /dev/null +++ b/tests/test-pull-many.sh @@ -0,0 +1,100 @@ +#!/bin/bash +# +# Copyright (C) 2017 Colin Walters +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +set -euo pipefail + +. $(dirname $0)/libtest.sh + +setup_fake_remote_repo1 "archive-z2" +cd ${test_tmpdir} +rm ostree-srv/gnomerepo/ -rf +mkdir ostree-srv/gnomerepo/ +${CMD_PREFIX} ostree --repo=ostree-srv/gnomerepo init --mode=archive + +echo '1..1' + +# Simulate a large archive pull from scratch. Large here is +# something like the Fedora Atomic Workstation branch which has +# objects: meta: 7497 content: 103541 +# 9443 directories, 7097 symlinks, 112832 regfiles +# So we'll make ~11 files per dir, with one of them a symlink + +cd ${test_tmpdir} +rm main -rf +mkdir main +cd main +ndirs=9443 +depth=0 +echo "$(date): Generating content..." +set +x # No need to spam the logs for this +while [ $ndirs -gt 0 ]; do + # 2/3 of the time, recurse a dir, up to a max of 9, otherwise back up + x=$(($ndirs % 3)) + case $x in + 0) if [ $depth -gt 0 ]; then cd ..; depth=$((depth-1)); fi ;; + 1|2) if [ $depth -lt 9 ]; then + mkdir dir-${ndirs} + cd dir-${ndirs} + depth=$((depth+1)) + else + if [ $depth -gt 0 ]; then cd ..; depth=$((depth-1)); fi + fi ;; + esac + + # One symlink - we use somewhat predictable content to have dupes + ln -s $(($x % 20)) link-$ndirs + # 10 files + nfiles=10 + while [ $nfiles -gt 0 ]; do + echo file-$ndirs-$nfiles > f$ndirs-$nfiles + nfiles=$((nfiles-1)) + done + ndirs=$((ndirs-1)) +done +set -x +cd ${test_tmpdir} +mkdir build-repo +${CMD_PREFIX} ostree --repo=build-repo init --mode=bare-user +echo "$(date): Committing content..." +${CMD_PREFIX} ostree --repo=build-repo commit -b main -s 'big!' --tree=dir=main +for x in commit dirtree dirmeta file; do + find build-repo/objects -name '*.'${x} |wc -l > ${x}count + echo "$x: " $(cat ${x}count) +done +assert_file_has_content commitcount '^1$' +assert_file_has_content dirmetacount '^1$' +assert_file_has_content filecount '^94433$' +${CMD_PREFIX} ostree --repo=ostree-srv/gnomerepo pull-local build-repo + +echo "$(date): Pulling content..." +rm repo -rf +${CMD_PREFIX} ostree --repo=repo init --mode=archive +${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin $(cat httpd-address)/ostree/gnomerepo + +${CMD_PREFIX} ostree --repo=repo pull --mirror origin main +${CMD_PREFIX} ostree --repo=repo fsck +for x in commit dirtree dirmeta filez; do + find repo/objects -name '*.'${x} |wc -l > ${x}count + echo "$x: " $(cat ${x}count) +done +assert_file_has_content commitcount '^1$' +assert_file_has_content dirmetacount '^1$' +assert_file_has_content filezcount '^94433$' + +echo "ok" diff --git a/tests/test-pull-metalink.sh b/tests/test-pull-metalink.sh index 2a1a73e7..07d619df 100755 --- a/tests/test-pull-metalink.sh +++ b/tests/test-pull-metalink.sh @@ -29,7 +29,7 @@ echo '1..9' cd ${test_tmpdir} mkdir metalink-data cd metalink-data -${CMD_PREFIX} ostree trivial-httpd --autoexit --daemonize -p ${test_tmpdir}/metalink-httpd-port +${OSTREE_HTTPD} --autoexit --daemonize -p ${test_tmpdir}/metalink-httpd-port metalink_port=$(cat ${test_tmpdir}/metalink-httpd-port) echo "http://127.0.0.1:${metalink_port}" > ${test_tmpdir}/metalink-httpd-address diff --git a/tests/test-pull-mirrorlist.sh b/tests/test-pull-mirrorlist.sh index 454014ca..13f40e7a 100755 --- a/tests/test-pull-mirrorlist.sh +++ b/tests/test-pull-mirrorlist.sh @@ -33,7 +33,7 @@ setup_mirror () { cd $name cp -a ${test_tmpdir}/ostree-srv ostree - ${CMD_PREFIX} ostree trivial-httpd --autoexit --daemonize \ + ${OSTREE_HTTPD} --autoexit --daemonize \ -p ${test_tmpdir}/${name}-port port=$(cat ${test_tmpdir}/${name}-port) echo "http://127.0.0.1:${port}" > ${test_tmpdir}/${name}-address diff --git a/tests/test-pull-override-url.sh b/tests/test-pull-override-url.sh index d81b3454..928013a5 100755 --- a/tests/test-pull-override-url.sh +++ b/tests/test-pull-override-url.sh @@ -50,7 +50,7 @@ mkdir mirror-httpd cd mirror-httpd ln -s ${test_tmpdir}/mirror-srv ostree mirror_log="${test_tmpdir}/mirror_log" -${CMD_PREFIX} ostree trivial-httpd --log-file=${mirror_log} --autoexit --daemonize -p ${test_tmpdir}/mirror-httpd-port +${OSTREE_HTTPD} --log-file=${mirror_log} --autoexit --daemonize -p ${test_tmpdir}/mirror-httpd-port port=$(cat ${test_tmpdir}/mirror-httpd-port) echo "http://127.0.0.1:${port}" > ${test_tmpdir}/mirror-httpd-address diff --git a/tests/test-pull-repeated.sh b/tests/test-pull-repeated.sh index 5a3af81c..8934e430 100755 --- a/tests/test-pull-repeated.sh +++ b/tests/test-pull-repeated.sh @@ -34,7 +34,7 @@ for x in $(seq 200); do echo "Success on iteration ${x}" break; fi - assert_file_has_content err.txt "500.*Internal Server Error" + assert_file_has_content err.txt "\(500.*Internal Server Error\)\|\(HTTP 500\)" done ${CMD_PREFIX} ostree --repo=repo fsck diff --git a/tests/test-pull-resume.sh b/tests/test-pull-resume.sh index 1e7220d0..06cd0793 100755 --- a/tests/test-pull-resume.sh +++ b/tests/test-pull-resume.sh @@ -42,7 +42,7 @@ do if ${CMD_PREFIX} ostree --repo=repo pull origin main 2>err.log; then break fi - assert_file_has_content err.log 'error:.*Download incomplete' + assert_file_has_content err.log 'error:.*\(Download incomplete\)\|\(Transferred a partial file\)' done if ${CMD_PREFIX} ostree --repo=repo fsck; then echo "ok, pull succeeded!"