Merge tag 'upstream/2016.7' into debian/master
Upstream version 2016.7
This commit is contained in:
commit
902c4c7b0f
|
|
@ -38,6 +38,9 @@ endif
|
||||||
if BUILDOPT_SYSTEMD
|
if BUILDOPT_SYSTEMD
|
||||||
systemdsystemunit_DATA = src/boot/ostree-prepare-root.service \
|
systemdsystemunit_DATA = src/boot/ostree-prepare-root.service \
|
||||||
src/boot/ostree-remount.service
|
src/boot/ostree-remount.service
|
||||||
|
|
||||||
|
# Allow the distcheck install under $prefix test to pass
|
||||||
|
AM_DISTCHECK_CONFIGURE_FLAGS += --with-systemdsystemunitdir='$${libdir}/systemd/system'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if !BUILDOPT_BUILTIN_GRUB2_MKCONFIG
|
if !BUILDOPT_BUILTIN_GRUB2_MKCONFIG
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,7 @@ libostree_1_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/bsdiff -I$(srcdir)/libglnx -I$(
|
||||||
-fvisibility=hidden '-D_OSTREE_PUBLIC=__attribute__((visibility("default"))) extern'
|
-fvisibility=hidden '-D_OSTREE_PUBLIC=__attribute__((visibility("default"))) extern'
|
||||||
libostree_1_la_LDFLAGS = -version-number 1:0:0 -Bsymbolic-functions -Wl,--version-script=$(top_srcdir)/src/libostree/libostree.sym
|
libostree_1_la_LDFLAGS = -version-number 1:0:0 -Bsymbolic-functions -Wl,--version-script=$(top_srcdir)/src/libostree/libostree.sym
|
||||||
libostree_1_la_LIBADD = libotutil.la libbupsplit.la libglnx.la libbsdiff.la libostree-kernel-args.la $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) $(OT_DEP_LZMA_LIBS) $(OT_DEP_ZLIB_LIBS)
|
libostree_1_la_LIBADD = libotutil.la libbupsplit.la libglnx.la libbsdiff.la libostree-kernel-args.la $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) $(OT_DEP_LZMA_LIBS) $(OT_DEP_ZLIB_LIBS)
|
||||||
|
EXTRA_libostree_1_la_DEPENDENCIES = $(top_srcdir)/src/libostree/libostree.sym
|
||||||
|
|
||||||
EXTRA_DIST += src/libostree/libostree.sym
|
EXTRA_DIST += src/libostree/libostree.sym
|
||||||
|
|
||||||
|
|
@ -156,6 +157,11 @@ libostree_1_la_CFLAGS += $(OT_DEP_LIBARCHIVE_CFLAGS)
|
||||||
libostree_1_la_LIBADD += $(OT_DEP_LIBARCHIVE_LIBS)
|
libostree_1_la_LIBADD += $(OT_DEP_LIBARCHIVE_LIBS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if BUILDOPT_LIBSYSTEMD
|
||||||
|
libostree_1_la_CFLAGS += $(LIBSYSTEMD_CFLAGS)
|
||||||
|
libostree_1_la_LIBADD += $(LIBSYSTEMD_LIBS)
|
||||||
|
endif
|
||||||
|
|
||||||
if USE_LIBSOUP
|
if USE_LIBSOUP
|
||||||
libostree_1_la_SOURCES += \
|
libostree_1_la_SOURCES += \
|
||||||
src/libostree/ostree-fetcher.h \
|
src/libostree/ostree-fetcher.h \
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ ostree_bin_shared_cflags = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/sr
|
||||||
ostree_bin_shared_ldadd = libglnx.la libbsdiff.la libotutil.la libostree-kernel-args.la libostree-1.la
|
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
|
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)
|
ostree_LDADD = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_GIO_UNIX_LIBS) $(LIBSYSTEMD_LIBS)
|
||||||
|
|
||||||
if USE_LIBSOUP
|
if USE_LIBSOUP
|
||||||
ostree_SOURCES += \
|
ostree_SOURCES += \
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ libotutil_la_SOURCES = \
|
||||||
src/libotutil/ot-variant-utils.h \
|
src/libotutil/ot-variant-utils.h \
|
||||||
src/libotutil/ot-gio-utils.c \
|
src/libotutil/ot-gio-utils.c \
|
||||||
src/libotutil/ot-gio-utils.h \
|
src/libotutil/ot-gio-utils.h \
|
||||||
|
src/libotutil/ot-log-utils.c \
|
||||||
|
src/libotutil/ot-log-utils.h \
|
||||||
src/libotutil/ot-gpg-utils.c \
|
src/libotutil/ot-gpg-utils.c \
|
||||||
src/libotutil/ot-gpg-utils.h \
|
src/libotutil/ot-gpg-utils.h \
|
||||||
src/libotutil/otutil.c \
|
src/libotutil/otutil.c \
|
||||||
|
|
@ -43,5 +45,5 @@ libotutil_la_SOURCES = \
|
||||||
src/libotutil/ot-tool-util.c \
|
src/libotutil/ot-tool-util.c \
|
||||||
src/libotutil/ot-tool-util.h \
|
src/libotutil/ot-tool-util.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
libotutil_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libglnx -I$(srcdir)/src/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS)
|
libotutil_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libglnx -I$(srcdir)/src/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) $(LIBSYSTEMD_CFLAGS)
|
||||||
libotutil_la_LIBADD = $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS)
|
libotutil_la_LIBADD = $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) $(LIBSYSTEMD_LIBS)
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ dist_test_scripts = \
|
||||||
tests/test-pull-metalink.sh \
|
tests/test-pull-metalink.sh \
|
||||||
tests/test-pull-summary-sigs.sh \
|
tests/test-pull-summary-sigs.sh \
|
||||||
tests/test-pull-resume.sh \
|
tests/test-pull-resume.sh \
|
||||||
|
tests/test-pull-repeated.sh \
|
||||||
tests/test-pull-untrusted.sh \
|
tests/test-pull-untrusted.sh \
|
||||||
tests/test-pull-override-url.sh \
|
tests/test-pull-override-url.sh \
|
||||||
tests/test-local-pull.sh \
|
tests/test-local-pull.sh \
|
||||||
|
|
@ -232,12 +233,7 @@ EXTRA_DIST += \
|
||||||
tests/libostreetest.h \
|
tests/libostreetest.h \
|
||||||
tests/libtest.sh \
|
tests/libtest.sh \
|
||||||
tests/gpg-verify-data/README.md \
|
tests/gpg-verify-data/README.md \
|
||||||
tests/gpg-verify-data/lgpl2 \
|
$(NULL)
|
||||||
tests/gpg-verify-data/lgpl2.sig \
|
|
||||||
tests/gpg-verify-data/pubring.gpg \
|
|
||||||
tests/gpg-verify-data/secring.gpg \
|
|
||||||
tests/gpg-verify-data/trustdb.gpg \
|
|
||||||
tests/gpg-verify-data/gpg.conf
|
|
||||||
|
|
||||||
tests/libreaddir-rand.so: Makefile
|
tests/libreaddir-rand.so: Makefile
|
||||||
$(AM_V_GEN) ln -fns ../.libs/libreaddir-rand.so tests
|
$(AM_V_GEN) ln -fns ../.libs/libreaddir-rand.so tests
|
||||||
|
|
@ -245,7 +241,8 @@ ALL_LOCAL_RULES += tests/libreaddir-rand.so
|
||||||
CLEANFILES += tests/libreaddir-rand.so tests/ostree-symlink-stamp tests/ostree
|
CLEANFILES += tests/libreaddir-rand.so tests/ostree-symlink-stamp tests/ostree
|
||||||
|
|
||||||
tests/ostree-symlink-stamp: Makefile
|
tests/ostree-symlink-stamp: Makefile
|
||||||
@real_bin=`cd $(top_builddir) && libtool --mode=execute echo ostree`; \
|
@set -e; \
|
||||||
|
real_bin=`cd $(top_builddir) && ./libtool --mode=execute echo ostree`; \
|
||||||
ln -sf "$${real_bin}" tests/ostree; \
|
ln -sf "$${real_bin}" tests/ostree; \
|
||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,12 +60,14 @@ libglnx_srcpath := $(srcdir)/libglnx
|
||||||
libglnx_cflags := $(OT_DEP_GIO_UNIX_CFLAGS) "-I$(libglnx_srcpath)"
|
libglnx_cflags := $(OT_DEP_GIO_UNIX_CFLAGS) "-I$(libglnx_srcpath)"
|
||||||
libglnx_libs := $(OT_DEP_GIO_UNIX_LIBS)
|
libglnx_libs := $(OT_DEP_GIO_UNIX_LIBS)
|
||||||
include libglnx/Makefile-libglnx.am.inc
|
include libglnx/Makefile-libglnx.am.inc
|
||||||
|
EXTRA_DIST += libglnx/Makefile-libglnx.am
|
||||||
noinst_LTLIBRARIES += libglnx.la
|
noinst_LTLIBRARIES += libglnx.la
|
||||||
|
|
||||||
libbsdiff_srcpath := $(srcdir)/bsdiff
|
libbsdiff_srcpath := $(srcdir)/bsdiff
|
||||||
libbsdiff_cflags := $(OT_DEP_GIO_UNIX_CFLAGS) "-I$(bsdiff_srcpath)"
|
libbsdiff_cflags := $(OT_DEP_GIO_UNIX_CFLAGS) "-I$(bsdiff_srcpath)"
|
||||||
libbsdiff_libs := $(OT_DEP_GIO_UNIX_LIBS)
|
libbsdiff_libs := $(OT_DEP_GIO_UNIX_LIBS)
|
||||||
include bsdiff/Makefile-bsdiff.am.inc
|
include bsdiff/Makefile-bsdiff.am.inc
|
||||||
|
EXTRA_DIST += bsdiff/Makefile-bsdiff.am
|
||||||
noinst_LTLIBRARIES += libbsdiff.la
|
noinst_LTLIBRARIES += libbsdiff.la
|
||||||
|
|
||||||
include Makefile-otutil.am
|
include Makefile-otutil.am
|
||||||
|
|
|
||||||
|
|
@ -300,6 +300,7 @@ ostree_repo_write_content_trusted
|
||||||
ostree_repo_write_content_async
|
ostree_repo_write_content_async
|
||||||
ostree_repo_write_content_finish
|
ostree_repo_write_content_finish
|
||||||
ostree_repo_resolve_rev
|
ostree_repo_resolve_rev
|
||||||
|
ostree_repo_resolve_rev_ext
|
||||||
ostree_repo_list_refs
|
ostree_repo_list_refs
|
||||||
ostree_repo_list_refs_ext
|
ostree_repo_list_refs_ext
|
||||||
ostree_repo_remote_list_refs
|
ostree_repo_remote_list_refs
|
||||||
|
|
|
||||||
16
configure.ac
16
configure.ac
|
|
@ -1,5 +1,5 @@
|
||||||
AC_PREREQ([2.63])
|
AC_PREREQ([2.63])
|
||||||
AC_INIT([ostree], [2016.6], [walters@verbum.org])
|
AC_INIT([ostree], [2016.7], [walters@verbum.org])
|
||||||
AC_CONFIG_HEADER([config.h])
|
AC_CONFIG_HEADER([config.h])
|
||||||
AC_CONFIG_MACRO_DIR([buildutil])
|
AC_CONFIG_MACRO_DIR([buildutil])
|
||||||
AC_CONFIG_AUX_DIR([build-aux])
|
AC_CONFIG_AUX_DIR([build-aux])
|
||||||
|
|
@ -17,7 +17,7 @@ AC_PROG_YACC
|
||||||
|
|
||||||
changequote(,)dnl
|
changequote(,)dnl
|
||||||
if test "x$GCC" = "xyes"; then
|
if test "x$GCC" = "xyes"; then
|
||||||
WARN_CFLAGS="-Wall -Wstrict-prototypes -Werror=missing-prototypes \
|
WARN_CFLAGS="-Wall -Wempty-body -Wstrict-prototypes -Werror=missing-prototypes \
|
||||||
-Werror=implicit-function-declaration \
|
-Werror=implicit-function-declaration \
|
||||||
-Werror=pointer-arith -Werror=init-self -Werror=format=2 \
|
-Werror=pointer-arith -Werror=init-self -Werror=format=2 \
|
||||||
-Werror=format-security \
|
-Werror=format-security \
|
||||||
|
|
@ -251,7 +251,13 @@ AC_ARG_WITH(mkinitcpio,
|
||||||
[with_mkinitcpio=no])
|
[with_mkinitcpio=no])
|
||||||
AM_CONDITIONAL(BUILDOPT_MKINITCPIO, test x$with_mkinitcpio = xyes)
|
AM_CONDITIONAL(BUILDOPT_MKINITCPIO, test x$with_mkinitcpio = xyes)
|
||||||
|
|
||||||
AS_IF([test "x$with_dracut" = "xyes" || test "x$with_dracut" = "xyesbutnoconf" || test "x$with_mkinitcpio" = "xyes"], [
|
dnl We have separate checks for libsystemd and the unit dir for historical reasons
|
||||||
|
PKG_CHECK_MODULES([LIBSYSTEMD], [libsystemd], [have_libsystemd=yes], [have_libsystemd=no])
|
||||||
|
AM_CONDITIONAL(BUILDOPT_LIBSYSTEMD, test x$have_libsystemd = xyes)
|
||||||
|
AM_COND_IF(BUILDOPT_LIBSYSTEMD,
|
||||||
|
AC_DEFINE([HAVE_LIBSYSTEMD], 1, [Define if we have libsystemd]))
|
||||||
|
|
||||||
|
AS_IF([test "x$have_libsystemd" = "xyes"], [
|
||||||
with_systemd=yes
|
with_systemd=yes
|
||||||
AC_ARG_WITH([systemdsystemunitdir],
|
AC_ARG_WITH([systemdsystemunitdir],
|
||||||
AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
|
AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
|
||||||
|
|
@ -309,6 +315,7 @@ echo "
|
||||||
libsoup (retrieve remote HTTP repositories): $with_soup
|
libsoup (retrieve remote HTTP repositories): $with_soup
|
||||||
libsoup TLS client certs: $have_libsoup_client_certs
|
libsoup TLS client certs: $have_libsoup_client_certs
|
||||||
SELinux: $with_selinux
|
SELinux: $with_selinux
|
||||||
|
systemd: $have_libsystemd
|
||||||
libmount: $with_libmount
|
libmount: $with_libmount
|
||||||
libarchive (parse tar files directly): $with_libarchive
|
libarchive (parse tar files directly): $with_libarchive
|
||||||
static deltas: yes (always enabled now)
|
static deltas: yes (always enabled now)
|
||||||
|
|
@ -322,7 +329,4 @@ AS_IF([test x$with_builtin_grub2_mkconfig = xyes], [
|
||||||
], [
|
], [
|
||||||
echo " grub2-mkconfig path: $GRUB2_MKCONFIG"
|
echo " grub2-mkconfig path: $GRUB2_MKCONFIG"
|
||||||
])
|
])
|
||||||
AS_IF([test "x$with_systemd" = "xyes"], [
|
|
||||||
echo " systemd unit dir: $with_systemdsystemunitdir"
|
|
||||||
])
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
|
||||||
|
|
@ -268,3 +268,48 @@ developed by Fedora, Red Hat, and CentOS as part of Project Atomic.
|
||||||
This is a service that incrementally rebuilds and tests GNOME on every commit.
|
This is a service that incrementally rebuilds and tests GNOME on every commit.
|
||||||
The need to make and distribute snapshots for this system was the original
|
The need to make and distribute snapshots for this system was the original
|
||||||
inspiration for ostree.
|
inspiration for ostree.
|
||||||
|
|
||||||
|
## Docker
|
||||||
|
|
||||||
|
It makes sense to compare OSTree and Docker as far as *wire formats*
|
||||||
|
go. OSTree is not itself a container tool, but can be used as a
|
||||||
|
transport/storage format for container tools.
|
||||||
|
|
||||||
|
Docker has (at the time of this writing) two format versions (v1 and
|
||||||
|
v2). v1 is deprecated, so we'll look at [format version 2](https://github.com/docker/docker/blob/master/image/spec/v1.1.md).
|
||||||
|
|
||||||
|
A Docker image is a series of layers, and a layer is essentially JSON
|
||||||
|
metadata plus a tarball. The tarballs capture changes between layers,
|
||||||
|
including handling deleting files in higher layers.
|
||||||
|
|
||||||
|
Because the payload format is just tar, Docker hence captures
|
||||||
|
(numeric) uid/gid and xattrs.
|
||||||
|
|
||||||
|
This "layering" model is an interesting and powerful part of Docker,
|
||||||
|
allowing different images to reference a shared base. OSTree doesn't
|
||||||
|
implement this natively, but it's not difficult to implement in higher
|
||||||
|
level tools. For example in
|
||||||
|
[flatpak](https://github.com/flatpak/flatpak), there's a concept of a
|
||||||
|
SDK and runtime, and it would make a lot of sense for the SDK to
|
||||||
|
depend on the runtime, to avoid clients downloading data twice (even
|
||||||
|
if it's deduplicated on disk).
|
||||||
|
|
||||||
|
That gets to an advantage of OSTree over Docker; OSTree checksums
|
||||||
|
individual files (not tarballs), and uses this for deduplication.
|
||||||
|
Docker (natively) only shares storage via layering.
|
||||||
|
|
||||||
|
The biggest feature OSTree has over Docker though is support for
|
||||||
|
(static) deltas, and even without pre-configured static deltas, the
|
||||||
|
archive-z2 format has "natural" deltas. Particularly for a "base
|
||||||
|
operating system", one really wants on-wire deltas. It'd likely be
|
||||||
|
possible to extend Docker with this concept.
|
||||||
|
|
||||||
|
A core challenge both share is around metadata (particularly signing)
|
||||||
|
and search/discovery (the ostree `summary` file doesn't scale very
|
||||||
|
well).
|
||||||
|
|
||||||
|
One major issue Docker has is that it [checksums compressed data](https://github.com/projectatomic/skopeo/issues/11),
|
||||||
|
and furthermore the tar format is flexible, with multiple ways to represent data,
|
||||||
|
making it hard to impossible to reassemble and verify from on-disk state.
|
||||||
|
The [tarsum](https://github.com/docker/docker/blob/master/pkg/tarsum/tarsum_spec.md) effort
|
||||||
|
was intended to address this, but it was not adopted in the end for v2.
|
||||||
|
|
|
||||||
|
|
@ -341,15 +341,19 @@ global:
|
||||||
ostree_repo_remote_fetch_summary_with_options;
|
ostree_repo_remote_fetch_summary_with_options;
|
||||||
} LIBOSTREE_2016.5;
|
} LIBOSTREE_2016.5;
|
||||||
|
|
||||||
|
LIBOSTREE_2016.7 {
|
||||||
|
global:
|
||||||
|
ostree_repo_resolve_rev_ext;
|
||||||
|
} LIBOSTREE_2016.6;
|
||||||
|
|
||||||
/* NOTE NOTE NOTE
|
/* NOTE NOTE NOTE
|
||||||
* Versions above here are released. Only add symbols below this line.
|
* Versions above here are released. Only add symbols below this line.
|
||||||
* NOTE NOTE NOTE
|
* NOTE NOTE NOTE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Uncomment this when adding a new symbol */
|
/* UNCOMMENT WHEN ADDING THE FIRST NEW SYMBOL FOR 2016.8
|
||||||
/*
|
|
||||||
LIBOSTREE_2016.7 {
|
LIBOSTREE_2016.7 {
|
||||||
global:
|
global:
|
||||||
ostree_some_new_symbol;
|
insert_symbol_here;
|
||||||
} LIBOSTREE_2016.6;
|
} LIBOSTREE_2016.8;
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -83,8 +83,8 @@ _ostree_bootloader_grub2_query (OstreeBootloader *bootloader,
|
||||||
const char *fname;
|
const char *fname;
|
||||||
g_autofree char *subdir_grub_cfg = NULL;
|
g_autofree char *subdir_grub_cfg = NULL;
|
||||||
|
|
||||||
if (!gs_file_enumerator_iterate (direnum, &file_info, NULL,
|
if (!g_file_enumerator_iterate (direnum, &file_info, NULL,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
if (file_info == NULL)
|
if (file_info == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ ostree_cmd__private__ (void)
|
||||||
static OstreeCmdPrivateVTable table = {
|
static OstreeCmdPrivateVTable table = {
|
||||||
impl_ostree_generate_grub2_config,
|
impl_ostree_generate_grub2_config,
|
||||||
_ostree_repo_static_delta_dump,
|
_ostree_repo_static_delta_dump,
|
||||||
|
_ostree_repo_static_delta_query_exists,
|
||||||
_ostree_repo_static_delta_delete
|
_ostree_repo_static_delta_delete
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ G_BEGIN_DECLS
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gboolean (* ostree_generate_grub2_config) (OstreeSysroot *sysroot, int bootversion, int target_fd, GCancellable *cancellable, GError **error);
|
gboolean (* ostree_generate_grub2_config) (OstreeSysroot *sysroot, int bootversion, int target_fd, GCancellable *cancellable, GError **error);
|
||||||
gboolean (* ostree_static_delta_dump) (OstreeRepo *repo, const char *delta_id, GCancellable *cancellable, GError **error);
|
gboolean (* ostree_static_delta_dump) (OstreeRepo *repo, const char *delta_id, GCancellable *cancellable, GError **error);
|
||||||
|
gboolean (* ostree_static_delta_query_exists) (OstreeRepo *repo, const char *delta_id, gboolean *out_exists, GCancellable *cancellable, GError **error);
|
||||||
gboolean (* ostree_static_delta_delete) (OstreeRepo *repo, const char *delta_id, GCancellable *cancellable, GError **error);
|
gboolean (* ostree_static_delta_delete) (OstreeRepo *repo, const char *delta_id, GCancellable *cancellable, GError **error);
|
||||||
} OstreeCmdPrivateVTable;
|
} OstreeCmdPrivateVTable;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -128,13 +128,6 @@ _ostree_loose_path (char *buf,
|
||||||
OstreeObjectType objtype,
|
OstreeObjectType objtype,
|
||||||
OstreeRepoMode repo_mode);
|
OstreeRepoMode repo_mode);
|
||||||
|
|
||||||
void
|
|
||||||
_ostree_loose_path_with_suffix (char *buf,
|
|
||||||
const char *checksum,
|
|
||||||
OstreeObjectType objtype,
|
|
||||||
OstreeRepoMode repo_mode,
|
|
||||||
const char *suffix);
|
|
||||||
|
|
||||||
#define _OSTREE_METADATA_GPGSIGS_NAME "ostree.gpgsigs"
|
#define _OSTREE_METADATA_GPGSIGS_NAME "ostree.gpgsigs"
|
||||||
#define _OSTREE_METADATA_GPGSIGS_TYPE G_VARIANT_TYPE ("aay")
|
#define _OSTREE_METADATA_GPGSIGS_TYPE G_VARIANT_TYPE ("aay")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1047,6 +1047,8 @@ ostree_object_type_to_string (OstreeObjectType objtype)
|
||||||
return "commit";
|
return "commit";
|
||||||
case OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT:
|
case OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT:
|
||||||
return "tombstone-commit";
|
return "tombstone-commit";
|
||||||
|
case OSTREE_OBJECT_TYPE_COMMIT_META:
|
||||||
|
return "commitmeta";
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -1070,6 +1072,10 @@ ostree_object_type_from_string (const char *str)
|
||||||
return OSTREE_OBJECT_TYPE_DIR_META;
|
return OSTREE_OBJECT_TYPE_DIR_META;
|
||||||
else if (!strcmp (str, "commit"))
|
else if (!strcmp (str, "commit"))
|
||||||
return OSTREE_OBJECT_TYPE_COMMIT;
|
return OSTREE_OBJECT_TYPE_COMMIT;
|
||||||
|
else if (!strcmp (str, "tombstone-commit"))
|
||||||
|
return OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT;
|
||||||
|
else if (!strcmp (str, "commitmeta"))
|
||||||
|
return OSTREE_OBJECT_TYPE_COMMIT_META;
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1269,7 +1275,7 @@ ostree_checksum_to_bytes_v (const char *checksum)
|
||||||
/**
|
/**
|
||||||
* ostree_checksum_inplace_from_bytes: (skip)
|
* ostree_checksum_inplace_from_bytes: (skip)
|
||||||
* @csum: (array fixed-size=32): An binary checksum of length 32
|
* @csum: (array fixed-size=32): An binary checksum of length 32
|
||||||
* @buf: Output location, must be at least 65 bytes in length
|
* @buf: Output location, must be at least OSTREE_SHA256_STRING_LEN+1 bytes in length
|
||||||
*
|
*
|
||||||
* Overwrite the contents of @buf with stringified version of @csum.
|
* Overwrite the contents of @buf with stringified version of @csum.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1340,7 +1346,7 @@ ostree_checksum_b64_inplace_from_bytes (const guchar *csum,
|
||||||
char *
|
char *
|
||||||
ostree_checksum_from_bytes (const guchar *csum)
|
ostree_checksum_from_bytes (const guchar *csum)
|
||||||
{
|
{
|
||||||
char *ret = g_malloc (65);
|
char *ret = g_malloc (OSTREE_SHA256_STRING_LEN+1);
|
||||||
ostree_checksum_inplace_from_bytes (csum, ret);
|
ostree_checksum_inplace_from_bytes (csum, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -1414,7 +1420,13 @@ _ostree_loose_path (char *buf,
|
||||||
OstreeObjectType objtype,
|
OstreeObjectType objtype,
|
||||||
OstreeRepoMode mode)
|
OstreeRepoMode mode)
|
||||||
{
|
{
|
||||||
_ostree_loose_path_with_suffix (buf, checksum, objtype, mode, "");
|
*buf = checksum[0];
|
||||||
|
buf++;
|
||||||
|
*buf = checksum[1];
|
||||||
|
buf++;
|
||||||
|
snprintf (buf, _OSTREE_LOOSE_PATH_MAX - 2, "/%s.%s%s",
|
||||||
|
checksum + 2, ostree_object_type_to_string (objtype),
|
||||||
|
(!OSTREE_OBJECT_TYPE_IS_META (objtype) && mode == OSTREE_REPO_MODE_ARCHIVE_Z2) ? "z" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1442,33 +1454,6 @@ _ostree_header_gfile_info_new (mode_t mode, uid_t uid, gid_t gid)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* _ostree_loose_path_with_suffix:
|
|
||||||
* @buf: Output buffer, must be _OSTREE_LOOSE_PATH_MAX in size
|
|
||||||
* @checksum: ASCII checksum
|
|
||||||
* @objtype: Object type
|
|
||||||
* @mode: Repository mode
|
|
||||||
*
|
|
||||||
* Like _ostree_loose_path, but also append a further arbitrary
|
|
||||||
* suffix; useful for finding non-core objects.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
_ostree_loose_path_with_suffix (char *buf,
|
|
||||||
const char *checksum,
|
|
||||||
OstreeObjectType objtype,
|
|
||||||
OstreeRepoMode mode,
|
|
||||||
const char *suffix)
|
|
||||||
{
|
|
||||||
*buf = checksum[0];
|
|
||||||
buf++;
|
|
||||||
*buf = checksum[1];
|
|
||||||
buf++;
|
|
||||||
snprintf (buf, _OSTREE_LOOSE_PATH_MAX - 2, "/%s.%s%s%s",
|
|
||||||
checksum + 2, ostree_object_type_to_string (objtype),
|
|
||||||
(!OSTREE_OBJECT_TYPE_IS_META (objtype) && mode == OSTREE_REPO_MODE_ARCHIVE_Z2) ? "z" : "",
|
|
||||||
suffix);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _ostree_get_relative_object_path:
|
* _ostree_get_relative_object_path:
|
||||||
* @checksum: ASCII checksum string
|
* @checksum: ASCII checksum string
|
||||||
|
|
@ -1484,7 +1469,7 @@ _ostree_get_relative_object_path (const char *checksum,
|
||||||
{
|
{
|
||||||
GString *path;
|
GString *path;
|
||||||
|
|
||||||
g_assert (strlen (checksum) == 64);
|
g_assert (strlen (checksum) == OSTREE_SHA256_STRING_LEN);
|
||||||
|
|
||||||
path = g_string_new ("objects/");
|
path = g_string_new ("objects/");
|
||||||
|
|
||||||
|
|
@ -1759,7 +1744,7 @@ ostree_validate_structureof_checksum_string (const char *checksum,
|
||||||
int i = 0;
|
int i = 0;
|
||||||
size_t len = strlen (checksum);
|
size_t len = strlen (checksum);
|
||||||
|
|
||||||
if (len != 64)
|
if (len != OSTREE_SHA256_STRING_LEN)
|
||||||
{
|
{
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
"Invalid rev '%s'", checksum);
|
"Invalid rev '%s'", checksum);
|
||||||
|
|
@ -1993,8 +1978,9 @@ ostree_validate_structureof_dirmeta (GVariant *dirmeta,
|
||||||
/**
|
/**
|
||||||
* ostree_commit_get_parent:
|
* ostree_commit_get_parent:
|
||||||
* @commit_variant: Variant of type %OSTREE_OBJECT_TYPE_COMMIT
|
* @commit_variant: Variant of type %OSTREE_OBJECT_TYPE_COMMIT
|
||||||
*
|
*
|
||||||
* Returns: Binary checksum with parent of @commit_variant, or %NULL if none
|
* Returns: Checksum of the parent commit of @commit_variant, or %NULL
|
||||||
|
* if none
|
||||||
*/
|
*/
|
||||||
gchar *
|
gchar *
|
||||||
ostree_commit_get_parent (GVariant *commit_variant)
|
ostree_commit_get_parent (GVariant *commit_variant)
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,20 @@ G_BEGIN_DECLS
|
||||||
*/
|
*/
|
||||||
#define OSTREE_MAX_RECURSION (256)
|
#define OSTREE_MAX_RECURSION (256)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OSTREE_SHA256_DIGEST_LEN:
|
||||||
|
*
|
||||||
|
* Length of a sha256 digest when expressed as raw bytes
|
||||||
|
*/
|
||||||
#define OSTREE_SHA256_DIGEST_LEN (32)
|
#define OSTREE_SHA256_DIGEST_LEN (32)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OSTREE_SHA256_STRING_LEN:
|
||||||
|
*
|
||||||
|
* Length of a sha256 digest when expressed as a hexadecimal string
|
||||||
|
*/
|
||||||
|
#define OSTREE_SHA256_STRING_LEN (64)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OstreeObjectType:
|
* OstreeObjectType:
|
||||||
* @OSTREE_OBJECT_TYPE_FILE: Content; regular file, symbolic link
|
* @OSTREE_OBJECT_TYPE_FILE: Content; regular file, symbolic link
|
||||||
|
|
@ -60,6 +72,7 @@ G_BEGIN_DECLS
|
||||||
* @OSTREE_OBJECT_TYPE_DIR_META: Directory metadata
|
* @OSTREE_OBJECT_TYPE_DIR_META: Directory metadata
|
||||||
* @OSTREE_OBJECT_TYPE_COMMIT: Toplevel object, refers to tree and dirmeta for root
|
* @OSTREE_OBJECT_TYPE_COMMIT: Toplevel object, refers to tree and dirmeta for root
|
||||||
* @OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT: Toplevel object, refers to a deleted commit
|
* @OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT: Toplevel object, refers to a deleted commit
|
||||||
|
* @OSTREE_OBJECT_TYPE_COMMIT_META: Detached metadata for a commit
|
||||||
*
|
*
|
||||||
* Enumeration for core object types; %OSTREE_OBJECT_TYPE_FILE is for
|
* Enumeration for core object types; %OSTREE_OBJECT_TYPE_FILE is for
|
||||||
* content, the other types are metadata.
|
* content, the other types are metadata.
|
||||||
|
|
@ -70,6 +83,7 @@ typedef enum {
|
||||||
OSTREE_OBJECT_TYPE_DIR_META = 3, /* .dirmeta */
|
OSTREE_OBJECT_TYPE_DIR_META = 3, /* .dirmeta */
|
||||||
OSTREE_OBJECT_TYPE_COMMIT = 4, /* .commit */
|
OSTREE_OBJECT_TYPE_COMMIT = 4, /* .commit */
|
||||||
OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT = 5, /* .commit-tombstone */
|
OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT = 5, /* .commit-tombstone */
|
||||||
|
OSTREE_OBJECT_TYPE_COMMIT_META = 6, /* .commitmeta */
|
||||||
} OstreeObjectType;
|
} OstreeObjectType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -78,14 +92,14 @@ typedef enum {
|
||||||
*
|
*
|
||||||
* Returns: %TRUE if object type is metadata
|
* Returns: %TRUE if object type is metadata
|
||||||
*/
|
*/
|
||||||
#define OSTREE_OBJECT_TYPE_IS_META(t) (t >= 2 && t <= 5)
|
#define OSTREE_OBJECT_TYPE_IS_META(t) (t >= 2 && t <= 6)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OSTREE_OBJECT_TYPE_LAST:
|
* OSTREE_OBJECT_TYPE_LAST:
|
||||||
*
|
*
|
||||||
* Last valid object type; use this to validate ranges.
|
* Last valid object type; use this to validate ranges.
|
||||||
*/
|
*/
|
||||||
#define OSTREE_OBJECT_TYPE_LAST OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT
|
#define OSTREE_OBJECT_TYPE_LAST OSTREE_OBJECT_TYPE_COMMIT_META
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OSTREE_DIRMETA_GVARIANT_FORMAT:
|
* OSTREE_DIRMETA_GVARIANT_FORMAT:
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ typedef enum {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
volatile int ref_count;
|
volatile int ref_count;
|
||||||
|
|
||||||
SoupSession *session;
|
SoupSession *session; /* not referenced */
|
||||||
GMainContext *main_context;
|
GMainContext *main_context;
|
||||||
GMainLoop *main_loop;
|
GMainLoop *main_loop;
|
||||||
|
|
||||||
|
|
@ -88,8 +88,6 @@ typedef struct {
|
||||||
guint64 max_size;
|
guint64 max_size;
|
||||||
guint64 current_size;
|
guint64 current_size;
|
||||||
guint64 content_length;
|
guint64 content_length;
|
||||||
|
|
||||||
GTask *task;
|
|
||||||
} OstreeFetcherPendingURI;
|
} OstreeFetcherPendingURI;
|
||||||
|
|
||||||
/* Used by session_thread_idle_add() */
|
/* Used by session_thread_idle_add() */
|
||||||
|
|
@ -140,7 +138,8 @@ thread_closure_unref (ThreadClosure *thread_closure)
|
||||||
|
|
||||||
if (g_atomic_int_dec_and_test (&thread_closure->ref_count))
|
if (g_atomic_int_dec_and_test (&thread_closure->ref_count))
|
||||||
{
|
{
|
||||||
g_clear_object (&thread_closure->session);
|
/* The session thread should have cleared this by now. */
|
||||||
|
g_assert (thread_closure->session == NULL);
|
||||||
|
|
||||||
g_clear_pointer (&thread_closure->main_context, g_main_context_unref);
|
g_clear_pointer (&thread_closure->main_context, g_main_context_unref);
|
||||||
g_clear_pointer (&thread_closure->main_loop, g_main_loop_unref);
|
g_clear_pointer (&thread_closure->main_loop, g_main_loop_unref);
|
||||||
|
|
@ -156,11 +155,6 @@ thread_closure_unref (ThreadClosure *thread_closure)
|
||||||
g_free (thread_closure->tmpdir_name);
|
g_free (thread_closure->tmpdir_name);
|
||||||
glnx_release_lock_file (&thread_closure->tmpdir_lock);
|
glnx_release_lock_file (&thread_closure->tmpdir_lock);
|
||||||
|
|
||||||
while (!g_queue_is_empty (&thread_closure->pending_queue))
|
|
||||||
g_object_unref (g_queue_pop_head (&thread_closure->pending_queue));
|
|
||||||
|
|
||||||
g_clear_pointer (&thread_closure->outstanding, g_hash_table_unref);
|
|
||||||
|
|
||||||
g_clear_pointer (&thread_closure->output_stream_set, g_hash_table_unref);
|
g_clear_pointer (&thread_closure->output_stream_set, g_hash_table_unref);
|
||||||
g_mutex_clear (&thread_closure->output_stream_set_lock);
|
g_mutex_clear (&thread_closure->output_stream_set_lock);
|
||||||
|
|
||||||
|
|
@ -452,13 +446,15 @@ static gpointer
|
||||||
ostree_fetcher_session_thread (gpointer data)
|
ostree_fetcher_session_thread (gpointer data)
|
||||||
{
|
{
|
||||||
ThreadClosure *closure = data;
|
ThreadClosure *closure = data;
|
||||||
|
g_autoptr(GMainContext) mainctx = g_main_context_ref (closure->main_context);
|
||||||
gint max_conns;
|
gint max_conns;
|
||||||
|
|
||||||
/* This becomes the GMainContext that SoupSession schedules async
|
/* This becomes the GMainContext that SoupSession schedules async
|
||||||
* callbacks and emits signals from. Make it the thread-default
|
* callbacks and emits signals from. Make it the thread-default
|
||||||
* context for this thread before creating the session. */
|
* context for this thread before creating the session. */
|
||||||
g_main_context_push_thread_default (closure->main_context);
|
g_main_context_push_thread_default (mainctx);
|
||||||
|
|
||||||
|
/* We retain ownership of the SoupSession reference. */
|
||||||
closure->session = soup_session_async_new_with_options (SOUP_SESSION_USER_AGENT, "ostree ",
|
closure->session = soup_session_async_new_with_options (SOUP_SESSION_USER_AGENT, "ostree ",
|
||||||
SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE,
|
SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE,
|
||||||
SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
|
SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
|
||||||
|
|
@ -481,10 +477,21 @@ ostree_fetcher_session_thread (gpointer data)
|
||||||
|
|
||||||
g_main_loop_run (closure->main_loop);
|
g_main_loop_run (closure->main_loop);
|
||||||
|
|
||||||
g_main_context_pop_thread_default (closure->main_context);
|
/* Since the ThreadClosure may be finalized from any thread we
|
||||||
|
* unreference all data related to the SoupSession ourself to ensure
|
||||||
|
* it's freed in the same thread where it was created. */
|
||||||
|
g_clear_pointer (&closure->outstanding, g_hash_table_unref);
|
||||||
|
while (!g_queue_is_empty (&closure->pending_queue))
|
||||||
|
g_object_unref (g_queue_pop_head (&closure->pending_queue));
|
||||||
|
g_clear_pointer (&closure->session, g_object_unref);
|
||||||
|
|
||||||
thread_closure_unref (closure);
|
thread_closure_unref (closure);
|
||||||
|
|
||||||
|
/* Do this last, since libsoup uses g_main_current_source() which
|
||||||
|
* relies on it.
|
||||||
|
*/
|
||||||
|
g_main_context_pop_thread_default (mainctx);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "libglnx.h"
|
||||||
#include "ostree-gpg-verifier.h"
|
#include "ostree-gpg-verifier.h"
|
||||||
#include "ostree-gpg-verify-result-private.h"
|
#include "ostree-gpg-verify-result-private.h"
|
||||||
#include "otutil.h"
|
#include "otutil.h"
|
||||||
|
|
@ -253,8 +254,8 @@ _ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self,
|
||||||
GFile *path;
|
GFile *path;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
if (!gs_file_enumerator_iterate (enumerator, &file_info, &path,
|
if (!g_file_enumerator_iterate (enumerator, &file_info, &path,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
if (file_info == NULL)
|
if (file_info == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -346,7 +346,7 @@ checkout_file_hardlink (OstreeRepo *self,
|
||||||
again:
|
again:
|
||||||
if (linkat (srcfd, loose_path, destination_dfd, destination_name, 0) != -1)
|
if (linkat (srcfd, loose_path, destination_dfd, destination_name, 0) != -1)
|
||||||
ret_was_supported = TRUE;
|
ret_was_supported = TRUE;
|
||||||
else if (errno == EMLINK || errno == EXDEV || errno == EPERM)
|
else if (!options->no_copy_fallback && (errno == EMLINK || errno == EXDEV || errno == EPERM))
|
||||||
{
|
{
|
||||||
/* EMLINK, EXDEV and EPERM shouldn't be fatal; we just can't do the
|
/* EMLINK, EXDEV and EPERM shouldn't be fatal; we just can't do the
|
||||||
* optimization of hardlinking instead of copying.
|
* optimization of hardlinking instead of copying.
|
||||||
|
|
@ -480,7 +480,7 @@ checkout_one_file_at (OstreeRepo *repo,
|
||||||
key = g_new (OstreeDevIno, 1);
|
key = g_new (OstreeDevIno, 1);
|
||||||
key->dev = stbuf.st_dev;
|
key->dev = stbuf.st_dev;
|
||||||
key->ino = stbuf.st_ino;
|
key->ino = stbuf.st_ino;
|
||||||
memcpy (key->checksum, checksum, 65);
|
memcpy (key->checksum, checksum, OSTREE_SHA256_STRING_LEN+1);
|
||||||
|
|
||||||
g_hash_table_add ((GHashTable*)options->devino_to_csum_cache, key);
|
g_hash_table_add ((GHashTable*)options->devino_to_csum_cache, key);
|
||||||
}
|
}
|
||||||
|
|
@ -696,8 +696,8 @@ checkout_tree_at (OstreeRepo *self,
|
||||||
GFile *src_child;
|
GFile *src_child;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
if (!gs_file_enumerator_iterate (dir_enum, &file_info, &src_child,
|
if (!g_file_enumerator_iterate (dir_enum, &file_info, &src_child,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
if (file_info == NULL)
|
if (file_info == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1173,43 +1173,31 @@ rename_pending_loose_objects (OstreeRepo *self,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
gs_dirfd_iterator_cleanup GSDirFdIterator dfd_iter = { 0, };
|
g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
|
||||||
|
|
||||||
if (!gs_dirfd_iterator_init_at (self->commit_stagedir_fd, ".", FALSE, &dfd_iter, error))
|
if (!glnx_dirfd_iterator_init_at (self->commit_stagedir_fd, ".", FALSE, &dfd_iter, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Iterate over the outer checksum dir */
|
/* Iterate over the outer checksum dir */
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
struct dirent *dent;
|
struct dirent *dent;
|
||||||
gs_dirfd_iterator_cleanup GSDirFdIterator child_dfd_iter = { 0, };
|
g_auto(GLnxDirFdIterator) child_dfd_iter = { 0, };
|
||||||
struct stat stbuf;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
if (!gs_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error))
|
if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (dent == NULL)
|
if (dent == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
do
|
if (dent->d_type != DT_DIR)
|
||||||
res = fstatat (dfd_iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW);
|
|
||||||
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
|
||||||
if (res == -1)
|
|
||||||
{
|
|
||||||
glnx_set_error_from_errno (error);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!S_ISDIR (stbuf.st_mode))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* All object directories only have two character entries */
|
/* All object directories only have two character entries */
|
||||||
if (strlen (dent->d_name) != 2)
|
if (strlen (dent->d_name) != 2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!gs_dirfd_iterator_init_at (dfd_iter.fd, dent->d_name, FALSE,
|
if (!glnx_dirfd_iterator_init_at (dfd_iter.fd, dent->d_name, FALSE,
|
||||||
&child_dfd_iter, error))
|
&child_dfd_iter, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Iterate over inner checksum dir */
|
/* Iterate over inner checksum dir */
|
||||||
|
|
@ -1218,9 +1206,8 @@ rename_pending_loose_objects (OstreeRepo *self,
|
||||||
struct dirent *child_dent;
|
struct dirent *child_dent;
|
||||||
char loose_objpath[_OSTREE_LOOSE_PATH_MAX];
|
char loose_objpath[_OSTREE_LOOSE_PATH_MAX];
|
||||||
|
|
||||||
if (!gs_dirfd_iterator_next_dent (&child_dfd_iter, &child_dent, cancellable, error))
|
if (!glnx_dirfd_iterator_next_dent (&child_dfd_iter, &child_dent, cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (child_dent == NULL)
|
if (child_dent == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -2071,8 +2058,7 @@ _ostree_repo_get_commit_metadata_loose_path (OstreeRepo *self,
|
||||||
const char *checksum)
|
const char *checksum)
|
||||||
{
|
{
|
||||||
char buf[_OSTREE_LOOSE_PATH_MAX];
|
char buf[_OSTREE_LOOSE_PATH_MAX];
|
||||||
_ostree_loose_path_with_suffix (buf, checksum, OSTREE_OBJECT_TYPE_COMMIT, self->mode,
|
_ostree_loose_path (buf, checksum, OSTREE_OBJECT_TYPE_COMMIT_META, self->mode);
|
||||||
"meta");
|
|
||||||
return g_file_resolve_relative_path (self->objects_dir, buf);
|
return g_file_resolve_relative_path (self->objects_dir, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2412,7 +2398,7 @@ write_directory_to_mtree_internal (OstreeRepo *self,
|
||||||
GError **error);
|
GError **error);
|
||||||
static gboolean
|
static gboolean
|
||||||
write_dfd_iter_to_mtree_internal (OstreeRepo *self,
|
write_dfd_iter_to_mtree_internal (OstreeRepo *self,
|
||||||
GSDirFdIterator *src_dfd_iter,
|
GLnxDirFdIterator *src_dfd_iter,
|
||||||
OstreeMutableTree *mtree,
|
OstreeMutableTree *mtree,
|
||||||
OstreeRepoCommitModifier *modifier,
|
OstreeRepoCommitModifier *modifier,
|
||||||
GPtrArray *path,
|
GPtrArray *path,
|
||||||
|
|
@ -2423,7 +2409,7 @@ static gboolean
|
||||||
write_directory_content_to_mtree_internal (OstreeRepo *self,
|
write_directory_content_to_mtree_internal (OstreeRepo *self,
|
||||||
OstreeRepoFile *repo_dir,
|
OstreeRepoFile *repo_dir,
|
||||||
GFileEnumerator *dir_enum,
|
GFileEnumerator *dir_enum,
|
||||||
GSDirFdIterator *dfd_iter,
|
GLnxDirFdIterator *dfd_iter,
|
||||||
GFileInfo *child_info,
|
GFileInfo *child_info,
|
||||||
OstreeMutableTree *mtree,
|
OstreeMutableTree *mtree,
|
||||||
OstreeRepoCommitModifier *modifier,
|
OstreeRepoCommitModifier *modifier,
|
||||||
|
|
@ -2488,9 +2474,9 @@ write_directory_content_to_mtree_internal (OstreeRepo *self,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gs_dirfd_iterator_cleanup GSDirFdIterator child_dfd_iter = { 0, };
|
g_auto(GLnxDirFdIterator) child_dfd_iter = { 0, };
|
||||||
|
|
||||||
if (!gs_dirfd_iterator_init_at (dfd_iter->fd, name, FALSE, &child_dfd_iter, error))
|
if (!glnx_dirfd_iterator_init_at (dfd_iter->fd, name, FALSE, &child_dfd_iter, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!write_dfd_iter_to_mtree_internal (self, &child_dfd_iter, child_mtree,
|
if (!write_dfd_iter_to_mtree_internal (self, &child_dfd_iter, child_mtree,
|
||||||
|
|
@ -2672,8 +2658,8 @@ write_directory_to_mtree_internal (OstreeRepo *self,
|
||||||
{
|
{
|
||||||
GFileInfo *child_info;
|
GFileInfo *child_info;
|
||||||
|
|
||||||
if (!gs_file_enumerator_iterate (dir_enum, &child_info, NULL,
|
if (!g_file_enumerator_iterate (dir_enum, &child_info, NULL,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
if (child_info == NULL)
|
if (child_info == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
@ -2693,7 +2679,7 @@ write_directory_to_mtree_internal (OstreeRepo *self,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
write_dfd_iter_to_mtree_internal (OstreeRepo *self,
|
write_dfd_iter_to_mtree_internal (OstreeRepo *self,
|
||||||
GSDirFdIterator *src_dfd_iter,
|
GLnxDirFdIterator *src_dfd_iter,
|
||||||
OstreeMutableTree *mtree,
|
OstreeMutableTree *mtree,
|
||||||
OstreeRepoCommitModifier *modifier,
|
OstreeRepoCommitModifier *modifier,
|
||||||
GPtrArray *path,
|
GPtrArray *path,
|
||||||
|
|
@ -2760,9 +2746,8 @@ write_dfd_iter_to_mtree_internal (OstreeRepo *self,
|
||||||
g_autoptr(GFileInfo) child_info = NULL;
|
g_autoptr(GFileInfo) child_info = NULL;
|
||||||
const char *loose_checksum;
|
const char *loose_checksum;
|
||||||
|
|
||||||
if (!gs_dirfd_iterator_next_dent (src_dfd_iter, &dent, cancellable, error))
|
if (!glnx_dirfd_iterator_next_dent (src_dfd_iter, &dent, cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (dent == NULL)
|
if (dent == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -2888,15 +2873,14 @@ ostree_repo_write_dfd_to_mtree (OstreeRepo *self,
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
g_autoptr(GPtrArray) pathbuilder = NULL;
|
g_autoptr(GPtrArray) pathbuilder = NULL;
|
||||||
gs_dirfd_iterator_cleanup GSDirFdIterator dfd_iter = { 0, };
|
g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
|
||||||
|
|
||||||
if (modifier && modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES)
|
if (modifier && modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES)
|
||||||
self->generate_sizes = TRUE;
|
self->generate_sizes = TRUE;
|
||||||
|
|
||||||
pathbuilder = g_ptr_array_new ();
|
pathbuilder = g_ptr_array_new ();
|
||||||
|
|
||||||
if (!gs_dirfd_iterator_init_at (dfd, path, FALSE,
|
if (!glnx_dirfd_iterator_init_at (dfd, path, FALSE, &dfd_iter, error))
|
||||||
&dfd_iter, error))
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!write_dfd_iter_to_mtree_internal (self, &dfd_iter, mtree, modifier, pathbuilder,
|
if (!write_dfd_iter_to_mtree_internal (self, &dfd_iter, mtree, modifier, pathbuilder,
|
||||||
|
|
@ -2952,7 +2936,7 @@ ostree_repo_write_mtree (OstreeRepo *self,
|
||||||
g_autoptr(GHashTable) dir_contents_checksums = NULL;
|
g_autoptr(GHashTable) dir_contents_checksums = NULL;
|
||||||
g_autoptr(GVariant) serialized_tree = NULL;
|
g_autoptr(GVariant) serialized_tree = NULL;
|
||||||
g_autofree guchar *contents_csum = NULL;
|
g_autofree guchar *contents_csum = NULL;
|
||||||
char contents_checksum_buf[65];
|
char contents_checksum_buf[OSTREE_SHA256_STRING_LEN+1];
|
||||||
|
|
||||||
dir_contents_checksums = g_hash_table_new_full (g_str_hash, g_str_equal,
|
dir_contents_checksums = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
(GDestroyNotify)g_free, (GDestroyNotify)g_free);
|
(GDestroyNotify)g_free, (GDestroyNotify)g_free);
|
||||||
|
|
|
||||||
|
|
@ -113,9 +113,9 @@ _ostree_repo_file_new_root (OstreeRepo *repo,
|
||||||
|
|
||||||
g_return_val_if_fail (repo != NULL, NULL);
|
g_return_val_if_fail (repo != NULL, NULL);
|
||||||
g_return_val_if_fail (contents_checksum != NULL, NULL);
|
g_return_val_if_fail (contents_checksum != NULL, NULL);
|
||||||
g_return_val_if_fail (strlen (contents_checksum) == 64, NULL);
|
g_return_val_if_fail (strlen (contents_checksum) == OSTREE_SHA256_STRING_LEN, NULL);
|
||||||
g_return_val_if_fail (metadata_checksum != NULL, NULL);
|
g_return_val_if_fail (metadata_checksum != NULL, NULL);
|
||||||
g_return_val_if_fail (strlen (metadata_checksum) == 64, NULL);
|
g_return_val_if_fail (strlen (metadata_checksum) == OSTREE_SHA256_STRING_LEN, NULL);
|
||||||
|
|
||||||
self = g_object_new (OSTREE_TYPE_REPO_FILE, NULL);
|
self = g_object_new (OSTREE_TYPE_REPO_FILE, NULL);
|
||||||
self->repo = g_object_ref (repo);
|
self->repo = g_object_ref (repo);
|
||||||
|
|
@ -152,12 +152,12 @@ _ostree_repo_file_new_for_commit (OstreeRepo *repo,
|
||||||
g_autoptr(GVariant) commit_v = NULL;
|
g_autoptr(GVariant) commit_v = NULL;
|
||||||
g_autoptr(GVariant) tree_contents_csum_v = NULL;
|
g_autoptr(GVariant) tree_contents_csum_v = NULL;
|
||||||
g_autoptr(GVariant) tree_metadata_csum_v = NULL;
|
g_autoptr(GVariant) tree_metadata_csum_v = NULL;
|
||||||
char tree_contents_csum[65];
|
char tree_contents_csum[OSTREE_SHA256_STRING_LEN + 1];
|
||||||
char tree_metadata_csum[65];
|
char tree_metadata_csum[OSTREE_SHA256_STRING_LEN + 1];
|
||||||
|
|
||||||
g_return_val_if_fail (repo != NULL, NULL);
|
g_return_val_if_fail (repo != NULL, NULL);
|
||||||
g_return_val_if_fail (commit != NULL, NULL);
|
g_return_val_if_fail (commit != NULL, NULL);
|
||||||
g_return_val_if_fail (strlen (commit) == 64, NULL);
|
g_return_val_if_fail (strlen (commit) == OSTREE_SHA256_STRING_LEN, NULL);
|
||||||
|
|
||||||
if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT,
|
if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT,
|
||||||
commit, &commit_v, error))
|
commit, &commit_v, error))
|
||||||
|
|
@ -807,7 +807,7 @@ ostree_repo_file_tree_query_child (OstreeRepoFile *self,
|
||||||
g_autoptr(GVariant) dirs_variant = NULL;
|
g_autoptr(GVariant) dirs_variant = NULL;
|
||||||
g_autoptr(GVariant) content_csum_v = NULL;
|
g_autoptr(GVariant) content_csum_v = NULL;
|
||||||
g_autoptr(GVariant) meta_csum_v = NULL;
|
g_autoptr(GVariant) meta_csum_v = NULL;
|
||||||
char tmp_checksum[65];
|
char tmp_checksum[OSTREE_SHA256_STRING_LEN+1];
|
||||||
GFileAttributeMatcher *matcher = NULL;
|
GFileAttributeMatcher *matcher = NULL;
|
||||||
|
|
||||||
if (!ostree_repo_file_ensure_resolved (self, error))
|
if (!ostree_repo_file_ensure_resolved (self, error))
|
||||||
|
|
|
||||||
|
|
@ -1075,8 +1075,8 @@ write_directory_to_libarchive_recurse (OstreeRepo *self,
|
||||||
GFileInfo *file_info;
|
GFileInfo *file_info;
|
||||||
GFile *path;
|
GFile *path;
|
||||||
|
|
||||||
if (!gs_file_enumerator_iterate (dir_enum, &file_info, &path,
|
if (!g_file_enumerator_iterate (dir_enum, &file_info, &path,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
if (file_info == NULL)
|
if (file_info == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ struct OstreeRepo {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
dev_t dev;
|
dev_t dev;
|
||||||
ino_t ino;
|
ino_t ino;
|
||||||
char checksum[65];
|
char checksum[OSTREE_SHA256_STRING_LEN+1];
|
||||||
} OstreeDevIno;
|
} OstreeDevIno;
|
||||||
|
|
||||||
#define OSTREE_REPO_TMPDIR_STAGING "staging-"
|
#define OSTREE_REPO_TMPDIR_STAGING "staging-"
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,12 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "libglnx.h"
|
||||||
#include "ostree.h"
|
#include "ostree.h"
|
||||||
#include "otutil.h"
|
#include "otutil.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBSOUP
|
#ifdef HAVE_LIBSOUP
|
||||||
|
|
||||||
#include "libglnx.h"
|
|
||||||
#include "ostree-core-private.h"
|
#include "ostree-core-private.h"
|
||||||
#include "ostree-repo-private.h"
|
#include "ostree-repo-private.h"
|
||||||
#include "ostree-repo-static-delta-private.h"
|
#include "ostree-repo-static-delta-private.h"
|
||||||
|
|
@ -415,6 +415,26 @@ fetch_uri_contents_utf8_sync (OtPullData *pull_data,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
write_commitpartial_for (OtPullData *pull_data,
|
||||||
|
const char *checksum,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (checksum);
|
||||||
|
glnx_fd_close int fd = -1;
|
||||||
|
|
||||||
|
fd = openat (pull_data->repo->repo_dir_fd, commitpartial_path, O_EXCL | O_CREAT | O_WRONLY | O_CLOEXEC | O_NOCTTY, 0600);
|
||||||
|
if (fd == -1)
|
||||||
|
{
|
||||||
|
if (errno != EEXIST)
|
||||||
|
{
|
||||||
|
glnx_set_error_from_errno (error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
enqueue_one_object_request (OtPullData *pull_data,
|
enqueue_one_object_request (OtPullData *pull_data,
|
||||||
const char *checksum,
|
const char *checksum,
|
||||||
|
|
@ -683,6 +703,7 @@ content_fetch_on_complete (GObject *object,
|
||||||
const char *checksum;
|
const char *checksum;
|
||||||
g_autofree char *checksum_obj = NULL;
|
g_autofree char *checksum_obj = NULL;
|
||||||
OstreeObjectType objtype;
|
OstreeObjectType objtype;
|
||||||
|
gboolean free_fetch_data = TRUE;
|
||||||
|
|
||||||
temp_path = _ostree_fetcher_request_uri_with_partial_finish (fetcher, result, error);
|
temp_path = _ostree_fetcher_request_uri_with_partial_finish (fetcher, result, error);
|
||||||
if (!temp_path)
|
if (!temp_path)
|
||||||
|
|
@ -741,11 +762,17 @@ content_fetch_on_complete (GObject *object,
|
||||||
object_input, length,
|
object_input, length,
|
||||||
cancellable,
|
cancellable,
|
||||||
content_fetch_on_write_complete, fetch_data);
|
content_fetch_on_write_complete, fetch_data);
|
||||||
|
free_fetch_data = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
pull_data->n_outstanding_content_fetches--;
|
pull_data->n_outstanding_content_fetches--;
|
||||||
check_outstanding_requests_handle_error (pull_data, local_error);
|
check_outstanding_requests_handle_error (pull_data, local_error);
|
||||||
|
if (free_fetch_data)
|
||||||
|
{
|
||||||
|
g_variant_unref (fetch_data->object);
|
||||||
|
g_free (fetch_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -809,7 +836,7 @@ meta_fetch_on_complete (GObject *object,
|
||||||
GError *local_error = NULL;
|
GError *local_error = NULL;
|
||||||
GError **error = &local_error;
|
GError **error = &local_error;
|
||||||
glnx_fd_close int fd = -1;
|
glnx_fd_close int fd = -1;
|
||||||
gboolean free_fetch_data = FALSE;
|
gboolean free_fetch_data = TRUE;
|
||||||
|
|
||||||
ostree_object_name_deserialize (fetch_data->object, &checksum, &objtype);
|
ostree_object_name_deserialize (fetch_data->object, &checksum, &objtype);
|
||||||
checksum_obj = ostree_object_to_string (checksum, objtype);
|
checksum_obj = ostree_object_to_string (checksum, objtype);
|
||||||
|
|
@ -875,8 +902,6 @@ meta_fetch_on_complete (GObject *object,
|
||||||
|
|
||||||
if (!fetch_data->object_is_stored)
|
if (!fetch_data->object_is_stored)
|
||||||
enqueue_one_object_request (pull_data, checksum, objtype, FALSE, FALSE);
|
enqueue_one_object_request (pull_data, checksum, objtype, FALSE, FALSE);
|
||||||
|
|
||||||
free_fetch_data = TRUE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -889,24 +914,15 @@ meta_fetch_on_complete (GObject *object,
|
||||||
/* Write the commitpartial file now while we're still fetching data */
|
/* Write the commitpartial file now while we're still fetching data */
|
||||||
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
|
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
|
||||||
{
|
{
|
||||||
g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (checksum);
|
if (!write_commitpartial_for (pull_data, checksum, error))
|
||||||
glnx_fd_close int fd = -1;
|
goto out;
|
||||||
|
|
||||||
fd = openat (pull_data->repo->repo_dir_fd, commitpartial_path, O_EXCL | O_CREAT | O_WRONLY | O_CLOEXEC | O_NOCTTY, 0600);
|
|
||||||
if (fd == -1)
|
|
||||||
{
|
|
||||||
if (errno != EEXIST)
|
|
||||||
{
|
|
||||||
glnx_set_error_from_errno (error);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ostree_repo_write_metadata_async (pull_data->repo, objtype, checksum, metadata,
|
ostree_repo_write_metadata_async (pull_data->repo, objtype, checksum, metadata,
|
||||||
pull_data->cancellable,
|
pull_data->cancellable,
|
||||||
on_metadata_written, fetch_data);
|
on_metadata_written, fetch_data);
|
||||||
pull_data->n_outstanding_metadata_write_requests++;
|
pull_data->n_outstanding_metadata_write_requests++;
|
||||||
|
free_fetch_data = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
@ -914,7 +930,7 @@ meta_fetch_on_complete (GObject *object,
|
||||||
pull_data->n_outstanding_metadata_fetches--;
|
pull_data->n_outstanding_metadata_fetches--;
|
||||||
pull_data->n_fetched_metadata++;
|
pull_data->n_fetched_metadata++;
|
||||||
check_outstanding_requests_handle_error (pull_data, local_error);
|
check_outstanding_requests_handle_error (pull_data, local_error);
|
||||||
if (local_error || free_fetch_data)
|
if (free_fetch_data)
|
||||||
{
|
{
|
||||||
g_variant_unref (fetch_data->object);
|
g_variant_unref (fetch_data->object);
|
||||||
g_free (fetch_data);
|
g_free (fetch_data);
|
||||||
|
|
@ -968,6 +984,7 @@ static_deltapart_fetch_on_complete (GObject *object,
|
||||||
GError *local_error = NULL;
|
GError *local_error = NULL;
|
||||||
GError **error = &local_error;
|
GError **error = &local_error;
|
||||||
glnx_fd_close int fd = -1;
|
glnx_fd_close int fd = -1;
|
||||||
|
gboolean free_fetch_data = TRUE;
|
||||||
|
|
||||||
g_debug ("fetch static delta part %s complete", fetch_data->expected_checksum);
|
g_debug ("fetch static delta part %s complete", fetch_data->expected_checksum);
|
||||||
|
|
||||||
|
|
@ -1005,13 +1022,14 @@ static_deltapart_fetch_on_complete (GObject *object,
|
||||||
on_static_delta_written,
|
on_static_delta_written,
|
||||||
fetch_data);
|
fetch_data);
|
||||||
pull_data->n_outstanding_deltapart_write_requests++;
|
pull_data->n_outstanding_deltapart_write_requests++;
|
||||||
|
free_fetch_data = FALSE;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
g_assert (pull_data->n_outstanding_deltapart_fetches > 0);
|
g_assert (pull_data->n_outstanding_deltapart_fetches > 0);
|
||||||
pull_data->n_outstanding_deltapart_fetches--;
|
pull_data->n_outstanding_deltapart_fetches--;
|
||||||
pull_data->n_fetched_deltaparts++;
|
pull_data->n_fetched_deltaparts++;
|
||||||
check_outstanding_requests_handle_error (pull_data, local_error);
|
check_outstanding_requests_handle_error (pull_data, local_error);
|
||||||
if (local_error)
|
if (free_fetch_data)
|
||||||
fetch_static_delta_data_free (fetch_data);
|
fetch_static_delta_data_free (fetch_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1096,7 +1114,7 @@ scan_commit_object (OtPullData *pull_data,
|
||||||
}
|
}
|
||||||
else if (parent_csum_bytes != NULL && depth > 0)
|
else if (parent_csum_bytes != NULL && depth > 0)
|
||||||
{
|
{
|
||||||
char parent_checksum[65];
|
char parent_checksum[OSTREE_SHA256_STRING_LEN+1];
|
||||||
gpointer parent_depthp;
|
gpointer parent_depthp;
|
||||||
int parent_depth;
|
int parent_depth;
|
||||||
|
|
||||||
|
|
@ -1205,11 +1223,18 @@ scan_one_metadata_object_c (OtPullData *pull_data,
|
||||||
|
|
||||||
if (pull_data->remote_repo_local)
|
if (pull_data->remote_repo_local)
|
||||||
{
|
{
|
||||||
if (!is_stored &&
|
if (!is_stored)
|
||||||
!ostree_repo_import_object_from_with_trust (pull_data->repo, pull_data->remote_repo_local,
|
{
|
||||||
objtype, tmp_checksum, !pull_data->is_untrusted,
|
if (!ostree_repo_import_object_from_with_trust (pull_data->repo, pull_data->remote_repo_local,
|
||||||
cancellable, error))
|
objtype, tmp_checksum, !pull_data->is_untrusted,
|
||||||
goto out;
|
cancellable, error))
|
||||||
|
goto out;
|
||||||
|
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
|
||||||
|
{
|
||||||
|
if (!write_commitpartial_for (pull_data, tmp_checksum, error))
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
is_stored = TRUE;
|
is_stored = TRUE;
|
||||||
is_requested = TRUE;
|
is_requested = TRUE;
|
||||||
}
|
}
|
||||||
|
|
@ -1316,8 +1341,7 @@ enqueue_one_object_request (OtPullData *pull_data,
|
||||||
if (is_detached_meta)
|
if (is_detached_meta)
|
||||||
{
|
{
|
||||||
char buf[_OSTREE_LOOSE_PATH_MAX];
|
char buf[_OSTREE_LOOSE_PATH_MAX];
|
||||||
_ostree_loose_path_with_suffix (buf, checksum, OSTREE_OBJECT_TYPE_COMMIT,
|
_ostree_loose_path (buf, checksum, OSTREE_OBJECT_TYPE_COMMIT_META, pull_data->remote_mode);
|
||||||
pull_data->remote_mode, "meta");
|
|
||||||
obj_uri = suburi_new (pull_data->base_uri, "objects", buf, NULL);
|
obj_uri = suburi_new (pull_data->base_uri, "objects", buf, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -100,14 +100,51 @@ write_checksum_file_at (OstreeRepo *self,
|
||||||
{
|
{
|
||||||
size_t l = strlen (sha256);
|
size_t l = strlen (sha256);
|
||||||
char *bufnl = alloca (l + 2);
|
char *bufnl = alloca (l + 2);
|
||||||
|
g_autoptr(GError) temp_error = NULL;
|
||||||
|
|
||||||
memcpy (bufnl, sha256, l);
|
memcpy (bufnl, sha256, l);
|
||||||
bufnl[l] = '\n';
|
bufnl[l] = '\n';
|
||||||
bufnl[l+1] = '\0';
|
bufnl[l+1] = '\0';
|
||||||
|
|
||||||
if (!_ostree_repo_file_replace_contents (self, dfd, name, (guint8*)bufnl, l + 1,
|
if (!_ostree_repo_file_replace_contents (self, dfd, name, (guint8*)bufnl, l + 1,
|
||||||
cancellable, error))
|
cancellable, &temp_error))
|
||||||
goto out;
|
{
|
||||||
|
if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY))
|
||||||
|
{
|
||||||
|
g_autoptr(GHashTable) refs = NULL;
|
||||||
|
GHashTableIter hashiter;
|
||||||
|
gpointer hashkey, hashvalue;
|
||||||
|
|
||||||
|
g_clear_error (&temp_error);
|
||||||
|
|
||||||
|
if (!ostree_repo_list_refs (self, name, &refs, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&hashiter, refs);
|
||||||
|
|
||||||
|
while ((g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue)))
|
||||||
|
{
|
||||||
|
if (strcmp (name, (char *)hashkey) != 0)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Conflict: %s exists under %s when attempting write", (char*)hashkey, name);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!glnx_shutil_rm_rf_at (dfd, name, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!_ostree_repo_file_replace_contents (self, dfd, name, (guint8*)bufnl, l + 1,
|
||||||
|
cancellable, error))
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_propagate_error (error, g_steal_pointer (&temp_error));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
@ -162,6 +199,7 @@ resolve_refspec (OstreeRepo *self,
|
||||||
const char *remote,
|
const char *remote,
|
||||||
const char *ref,
|
const char *ref,
|
||||||
gboolean allow_noent,
|
gboolean allow_noent,
|
||||||
|
gboolean fallback_remote,
|
||||||
char **out_rev,
|
char **out_rev,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
|
@ -170,6 +208,7 @@ resolve_refspec_fallback (OstreeRepo *self,
|
||||||
const char *remote,
|
const char *remote,
|
||||||
const char *ref,
|
const char *ref,
|
||||||
gboolean allow_noent,
|
gboolean allow_noent,
|
||||||
|
gboolean fallback_remote,
|
||||||
char **out_rev,
|
char **out_rev,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
|
|
@ -179,8 +218,8 @@ resolve_refspec_fallback (OstreeRepo *self,
|
||||||
|
|
||||||
if (self->parent_repo)
|
if (self->parent_repo)
|
||||||
{
|
{
|
||||||
if (!resolve_refspec (self->parent_repo, remote, ref,
|
if (!resolve_refspec (self->parent_repo, remote, ref, allow_noent,
|
||||||
allow_noent, &ret_rev, error))
|
fallback_remote, &ret_rev, error))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
else if (!allow_noent)
|
else if (!allow_noent)
|
||||||
|
|
@ -204,6 +243,7 @@ resolve_refspec (OstreeRepo *self,
|
||||||
const char *remote,
|
const char *remote,
|
||||||
const char *ref,
|
const char *ref,
|
||||||
gboolean allow_noent,
|
gboolean allow_noent,
|
||||||
|
gboolean fallback_remote,
|
||||||
char **out_rev,
|
char **out_rev,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
|
@ -233,7 +273,7 @@ resolve_refspec (OstreeRepo *self,
|
||||||
if (!ot_openat_ignore_enoent (self->repo_dir_fd, local_ref, &target_fd, error))
|
if (!ot_openat_ignore_enoent (self->repo_dir_fd, local_ref, &target_fd, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (target_fd == -1)
|
if (target_fd == -1 && fallback_remote)
|
||||||
{
|
{
|
||||||
local_ref = glnx_strjoina ("refs/remotes/", ref);
|
local_ref = glnx_strjoina ("refs/remotes/", ref);
|
||||||
|
|
||||||
|
|
@ -263,7 +303,7 @@ resolve_refspec (OstreeRepo *self,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!resolve_refspec_fallback (self, remote, ref, allow_noent,
|
if (!resolve_refspec_fallback (self, remote, ref, allow_noent, fallback_remote,
|
||||||
&ret_rev, cancellable, error))
|
&ret_rev, cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
@ -304,10 +344,10 @@ ostree_repo_resolve_partial_checksum (OstreeRepo *self,
|
||||||
|
|
||||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||||
|
|
||||||
/* If the input is longer than 64 chars or contains non-hex chars,
|
/* If the input is longer than OSTREE_SHA256_STRING_LEN chars or contains non-hex chars,
|
||||||
don't bother looking for it as an object */
|
don't bother looking for it as an object */
|
||||||
off = strspn (refspec, hexchars);
|
off = strspn (refspec, hexchars);
|
||||||
if (off > 64 || refspec[off] != '\0')
|
if (off > OSTREE_SHA256_STRING_LEN || refspec[off] != '\0')
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* this looks through all objects and adds them to the ref_list if:
|
/* this looks through all objects and adds them to the ref_list if:
|
||||||
|
|
@ -351,23 +391,13 @@ ostree_repo_resolve_partial_checksum (OstreeRepo *self,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static gboolean
|
||||||
* ostree_repo_resolve_rev:
|
_ostree_repo_resolve_rev_internal (OstreeRepo *self,
|
||||||
* @self: Repo
|
const char *refspec,
|
||||||
* @refspec: A refspec
|
gboolean allow_noent,
|
||||||
* @allow_noent: Do not throw an error if refspec does not exist
|
gboolean fallback_remote,
|
||||||
* @out_rev: (out) (transfer full): A checksum,or %NULL if @allow_noent is true and it does not exist
|
char **out_rev,
|
||||||
* @error: Error
|
GError **error)
|
||||||
*
|
|
||||||
* Look up the given refspec, returning the checksum it references in
|
|
||||||
* the parameter @out_rev.
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
ostree_repo_resolve_rev (OstreeRepo *self,
|
|
||||||
const char *refspec,
|
|
||||||
gboolean allow_noent,
|
|
||||||
char **out_rev,
|
|
||||||
GError **error)
|
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
g_autofree char *ret_rev = NULL;
|
g_autofree char *ret_rev = NULL;
|
||||||
|
|
@ -419,7 +449,7 @@ ostree_repo_resolve_rev (OstreeRepo *self,
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!resolve_refspec (self, remote, ref, allow_noent,
|
if (!resolve_refspec (self, remote, ref, allow_noent,
|
||||||
&ret_rev, error))
|
fallback_remote, &ret_rev, error))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -430,6 +460,53 @@ ostree_repo_resolve_rev (OstreeRepo *self,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ostree_repo_resolve_rev:
|
||||||
|
* @self: Repo
|
||||||
|
* @refspec: A refspec
|
||||||
|
* @allow_noent: Do not throw an error if refspec does not exist
|
||||||
|
* @out_rev: (out) (transfer full): A checksum,or %NULL if @allow_noent is true and it does not exist
|
||||||
|
* @error: Error
|
||||||
|
*
|
||||||
|
* Look up the given refspec, returning the checksum it references in
|
||||||
|
* the parameter @out_rev. Will fall back on remote directory if cannot
|
||||||
|
* find the given refspec in local.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
ostree_repo_resolve_rev (OstreeRepo *self,
|
||||||
|
const char *refspec,
|
||||||
|
gboolean allow_noent,
|
||||||
|
char **out_rev,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
return _ostree_repo_resolve_rev_internal (self, refspec, allow_noent, TRUE, out_rev, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ostree_repo_resolve_rev_ext:
|
||||||
|
* @self: Repo
|
||||||
|
* @refspec: A refspec
|
||||||
|
* @allow_noent: Do not throw an error if refspec does not exist
|
||||||
|
* @flags: Options controlling behavior
|
||||||
|
* @out_rev: (out) (transfer full): A checksum,or %NULL if @allow_noent is true and it does not exist
|
||||||
|
* @error: Error
|
||||||
|
*
|
||||||
|
* Look up the given refspec, returning the checksum it references in
|
||||||
|
* the parameter @out_rev. Differently from ostree_repo_resolve_rev(),
|
||||||
|
* this will not fall back to searching through remote repos if a
|
||||||
|
* local ref is specified but not found.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
ostree_repo_resolve_rev_ext (OstreeRepo *self,
|
||||||
|
const char *refspec,
|
||||||
|
gboolean allow_noent,
|
||||||
|
OstreeRepoResolveRevExtFlags flags,
|
||||||
|
char **out_rev,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
return _ostree_repo_resolve_rev_internal (self, refspec, allow_noent, FALSE, out_rev, error);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
enumerate_refs_recurse (OstreeRepo *repo,
|
enumerate_refs_recurse (OstreeRepo *repo,
|
||||||
const char *remote,
|
const char *remote,
|
||||||
|
|
@ -703,7 +780,7 @@ ostree_repo_remote_list_refs (OstreeRepo *self,
|
||||||
{
|
{
|
||||||
const char *ref_name = NULL;
|
const char *ref_name = NULL;
|
||||||
g_autoptr(GVariant) csum_v = NULL;
|
g_autoptr(GVariant) csum_v = NULL;
|
||||||
char tmp_checksum[65];
|
char tmp_checksum[OSTREE_SHA256_STRING_LEN+1];
|
||||||
|
|
||||||
g_variant_get_child (child, 0, "&s", &ref_name);
|
g_variant_get_child (child, 0, "&s", &ref_name);
|
||||||
|
|
||||||
|
|
@ -772,8 +849,10 @@ _ostree_repo_write_ref (OstreeRepo *self,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!glnx_opendirat (refs_remotes_dfd, remote, TRUE, &dfd, error))
|
dfd = glnx_opendirat_with_errno (refs_remotes_dfd, remote, TRUE);
|
||||||
|
if (dfd < 0 && (errno != ENOENT || rev != NULL))
|
||||||
{
|
{
|
||||||
|
glnx_set_error_from_errno (error);
|
||||||
g_prefix_error (error, "Opening remotes/ dir %s: ", remote);
|
g_prefix_error (error, "Opening remotes/ dir %s: ", remote);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
@ -781,13 +860,16 @@ _ostree_repo_write_ref (OstreeRepo *self,
|
||||||
|
|
||||||
if (rev == NULL)
|
if (rev == NULL)
|
||||||
{
|
{
|
||||||
if (unlinkat (dfd, ref, 0) != 0)
|
if (dfd >= 0)
|
||||||
{
|
{
|
||||||
if (errno != ENOENT)
|
if (unlinkat (dfd, ref, 0) != 0)
|
||||||
{
|
{
|
||||||
glnx_set_error_from_errno (error);
|
if (errno != ENOENT)
|
||||||
goto out;
|
{
|
||||||
}
|
glnx_set_error_from_errno (error);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -94,8 +94,8 @@ ostree_repo_list_static_delta_names (OstreeRepo *self,
|
||||||
GFileInfo *file_info;
|
GFileInfo *file_info;
|
||||||
GFile *child;
|
GFile *child;
|
||||||
|
|
||||||
if (!gs_file_enumerator_iterate (dir_enum, &file_info, &child,
|
if (!g_file_enumerator_iterate (dir_enum, &file_info, &child,
|
||||||
NULL, error))
|
NULL, error))
|
||||||
goto out;
|
goto out;
|
||||||
if (file_info == NULL)
|
if (file_info == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
@ -117,8 +117,8 @@ ostree_repo_list_static_delta_names (OstreeRepo *self,
|
||||||
const char *name1;
|
const char *name1;
|
||||||
const char *name2;
|
const char *name2;
|
||||||
|
|
||||||
if (!gs_file_enumerator_iterate (dir_enum2, &file_info2, &child2,
|
if (!g_file_enumerator_iterate (dir_enum2, &file_info2, &child2,
|
||||||
NULL, error))
|
NULL, error))
|
||||||
goto out;
|
goto out;
|
||||||
if (file_info2 == NULL)
|
if (file_info2 == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
@ -136,7 +136,7 @@ ostree_repo_list_static_delta_names (OstreeRepo *self,
|
||||||
{
|
{
|
||||||
g_autofree char *buf = g_strconcat (name1, name2, NULL);
|
g_autofree char *buf = g_strconcat (name1, name2, NULL);
|
||||||
GString *out = g_string_new ("");
|
GString *out = g_string_new ("");
|
||||||
char checksum[65];
|
char checksum[OSTREE_SHA256_STRING_LEN+1];
|
||||||
guchar csum[OSTREE_SHA256_DIGEST_LEN];
|
guchar csum[OSTREE_SHA256_DIGEST_LEN];
|
||||||
const char *dash = strchr (buf, '-');
|
const char *dash = strchr (buf, '-');
|
||||||
|
|
||||||
|
|
@ -187,7 +187,7 @@ _ostree_repo_static_delta_part_have_all_objects (OstreeRepo *repo,
|
||||||
{
|
{
|
||||||
guint8 objtype = *checksums_data;
|
guint8 objtype = *checksums_data;
|
||||||
const guint8 *csum = checksums_data + 1;
|
const guint8 *csum = checksums_data + 1;
|
||||||
char tmp_checksum[65];
|
char tmp_checksum[OSTREE_SHA256_STRING_LEN+1];
|
||||||
|
|
||||||
if (G_UNLIKELY(!ostree_validate_structureof_objtype (objtype, error)))
|
if (G_UNLIKELY(!ostree_validate_structureof_objtype (objtype, error)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -354,7 +354,7 @@ ostree_repo_static_delta_execute_offline (OstreeRepo *self,
|
||||||
guint64 size;
|
guint64 size;
|
||||||
guint64 usize;
|
guint64 usize;
|
||||||
const guchar *csum;
|
const guchar *csum;
|
||||||
char checksum[65];
|
char checksum[OSTREE_SHA256_STRING_LEN+1];
|
||||||
gboolean have_all;
|
gboolean have_all;
|
||||||
g_autoptr(GInputStream) part_in = NULL;
|
g_autoptr(GInputStream) part_in = NULL;
|
||||||
g_autoptr(GBytes) delta_data = NULL;
|
g_autoptr(GBytes) delta_data = NULL;
|
||||||
|
|
@ -819,6 +819,38 @@ _ostree_repo_static_delta_delete (OstreeRepo *self,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_ostree_repo_static_delta_query_exists (OstreeRepo *self,
|
||||||
|
const char *delta_id,
|
||||||
|
gboolean *out_exists,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_autofree char *from = NULL;
|
||||||
|
g_autofree char *to = NULL;
|
||||||
|
g_autofree char *superblock_path = NULL;
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
|
_ostree_parse_delta_name (delta_id, &from, &to);
|
||||||
|
superblock_path = _ostree_get_relative_static_delta_superblock_path (from, to);
|
||||||
|
|
||||||
|
if (fstatat (self->repo_dir_fd, superblock_path, &stbuf, 0) < 0)
|
||||||
|
{
|
||||||
|
if (errno == ENOENT)
|
||||||
|
{
|
||||||
|
*out_exists = FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glnx_set_error_from_errno (error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*out_exists = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_ostree_repo_static_delta_dump (OstreeRepo *self,
|
_ostree_repo_static_delta_dump (OstreeRepo *self,
|
||||||
const char *delta_id,
|
const char *delta_id,
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,13 @@ _ostree_delta_compute_similar_objects (OstreeRepo *repo,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_ostree_repo_static_delta_query_exists (OstreeRepo *repo,
|
||||||
|
const char *delta_id,
|
||||||
|
gboolean *out_exists,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_ostree_repo_static_delta_dump (OstreeRepo *repo,
|
_ostree_repo_static_delta_dump (OstreeRepo *repo,
|
||||||
const char *delta_id,
|
const char *delta_id,
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ typedef struct {
|
||||||
OstreeRepoContentBareCommit barecommitstate;
|
OstreeRepoContentBareCommit barecommitstate;
|
||||||
guint64 content_size;
|
guint64 content_size;
|
||||||
GOutputStream *content_out;
|
GOutputStream *content_out;
|
||||||
char checksum[65];
|
char checksum[OSTREE_SHA256_STRING_LEN+1];
|
||||||
char *read_source_object;
|
char *read_source_object;
|
||||||
int read_source_fd;
|
int read_source_fd;
|
||||||
gboolean have_obj;
|
gboolean have_obj;
|
||||||
|
|
@ -78,7 +78,7 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
StaticDeltaExecutionState *state;
|
StaticDeltaExecutionState *state;
|
||||||
char checksum[65];
|
char checksum[OSTREE_SHA256_STRING_LEN+1];
|
||||||
} StaticDeltaContentWrite;
|
} StaticDeltaContentWrite;
|
||||||
|
|
||||||
typedef gboolean (*DispatchOpFunc) (OstreeRepo *repo,
|
typedef gboolean (*DispatchOpFunc) (OstreeRepo *repo,
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ struct _OstreeRepoRealCommitTraverseIter {
|
||||||
const char *name;
|
const char *name;
|
||||||
OstreeRepoCommitIterResult state;
|
OstreeRepoCommitIterResult state;
|
||||||
guint idx;
|
guint idx;
|
||||||
char checksum_content[65];
|
char checksum_content[OSTREE_SHA256_STRING_LEN+1];
|
||||||
char checksum_meta[65];
|
char checksum_meta[OSTREE_SHA256_STRING_LEN+1];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -2070,8 +2070,8 @@ append_remotes_d (OstreeRepo *self,
|
||||||
const char *name;
|
const char *name;
|
||||||
guint32 type;
|
guint32 type;
|
||||||
|
|
||||||
if (!gs_file_enumerator_iterate (direnum, &file_info, &path,
|
if (!g_file_enumerator_iterate (direnum, &file_info, &path,
|
||||||
NULL, error))
|
NULL, error))
|
||||||
goto out;
|
goto out;
|
||||||
if (file_info == NULL)
|
if (file_info == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
@ -2445,7 +2445,7 @@ list_loose_objects_at (OstreeRepo *self,
|
||||||
const char *name = dent->d_name;
|
const char *name = dent->d_name;
|
||||||
const char *dot;
|
const char *dot;
|
||||||
OstreeObjectType objtype;
|
OstreeObjectType objtype;
|
||||||
char buf[65];
|
char buf[OSTREE_SHA256_STRING_LEN+1];
|
||||||
|
|
||||||
if (strcmp (name, ".") == 0 ||
|
if (strcmp (name, ".") == 0 ||
|
||||||
strcmp (name, "..") == 0)
|
strcmp (name, "..") == 0)
|
||||||
|
|
@ -2715,18 +2715,29 @@ _ostree_repo_read_bare_fd (OstreeRepo *self,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
char loose_path_buf[_OSTREE_LOOSE_PATH_MAX];
|
char loose_path_buf[_OSTREE_LOOSE_PATH_MAX];
|
||||||
|
|
||||||
g_assert (self->mode == OSTREE_REPO_MODE_BARE ||
|
g_assert (self->mode == OSTREE_REPO_MODE_BARE ||
|
||||||
self->mode == OSTREE_REPO_MODE_BARE_USER);
|
self->mode == OSTREE_REPO_MODE_BARE_USER);
|
||||||
|
|
||||||
_ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_FILE, self->mode);
|
_ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_FILE, self->mode);
|
||||||
|
|
||||||
*out_fd = openat (self->objects_dir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
|
if (!ot_openat_ignore_enoent (self->objects_dir_fd, loose_path_buf, out_fd, error))
|
||||||
if (*out_fd < 0)
|
return FALSE;
|
||||||
|
|
||||||
|
if (*out_fd == -1)
|
||||||
{
|
{
|
||||||
glnx_set_error_from_errno (error);
|
if (self->parent_repo)
|
||||||
|
return _ostree_repo_read_bare_fd (self->parent_repo,
|
||||||
|
checksum,
|
||||||
|
out_fd,
|
||||||
|
cancellable,
|
||||||
|
error);
|
||||||
|
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
||||||
|
"No such file object %s", checksum);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2837,9 +2848,12 @@ ostree_repo_load_file (OstreeRepo *self,
|
||||||
*/
|
*/
|
||||||
if (S_ISLNK (mode) || out_input)
|
if (S_ISLNK (mode) || out_input)
|
||||||
{
|
{
|
||||||
if (!gs_file_openat_noatime (self->objects_dir_fd, loose_path_buf, &fd,
|
fd = openat (self->objects_dir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
|
||||||
cancellable, error))
|
if (fd < 0)
|
||||||
goto out;
|
{
|
||||||
|
glnx_set_error_from_errno (error);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (S_ISREG (mode) && out_input)
|
if (S_ISREG (mode) && out_input)
|
||||||
|
|
@ -2876,9 +2890,12 @@ ostree_repo_load_file (OstreeRepo *self,
|
||||||
{
|
{
|
||||||
glnx_fd_close int fd = -1;
|
glnx_fd_close int fd = -1;
|
||||||
|
|
||||||
if (!gs_file_openat_noatime (self->objects_dir_fd, loose_path_buf, &fd,
|
fd = openat (self->objects_dir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
|
||||||
cancellable, error))
|
if (fd < 0)
|
||||||
goto out;
|
{
|
||||||
|
glnx_set_error_from_errno (error);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (out_xattrs)
|
if (out_xattrs)
|
||||||
{
|
{
|
||||||
|
|
@ -3114,8 +3131,7 @@ ostree_repo_delete_object (OstreeRepo *self,
|
||||||
{
|
{
|
||||||
char meta_loose[_OSTREE_LOOSE_PATH_MAX];
|
char meta_loose[_OSTREE_LOOSE_PATH_MAX];
|
||||||
|
|
||||||
_ostree_loose_path_with_suffix (meta_loose, sha256,
|
_ostree_loose_path (meta_loose, sha256, OSTREE_OBJECT_TYPE_COMMIT_META, self->mode);
|
||||||
OSTREE_OBJECT_TYPE_COMMIT, self->mode, "meta");
|
|
||||||
|
|
||||||
do
|
do
|
||||||
res = unlinkat (self->objects_dir_fd, meta_loose, 0);
|
res = unlinkat (self->objects_dir_fd, meta_loose, 0);
|
||||||
|
|
@ -4825,7 +4841,6 @@ _ostree_repo_allocate_tmpdir (int tmpdir_dfd,
|
||||||
|
|
||||||
while (tmpdir_name == NULL)
|
while (tmpdir_name == NULL)
|
||||||
{
|
{
|
||||||
gs_dirfd_iterator_cleanup GSDirFdIterator child_dfd_iter = { 0, };
|
|
||||||
struct dirent *dent;
|
struct dirent *dent;
|
||||||
glnx_fd_close int existing_tmpdir_fd = -1;
|
glnx_fd_close int existing_tmpdir_fd = -1;
|
||||||
g_autoptr(GError) local_error = NULL;
|
g_autoptr(GError) local_error = NULL;
|
||||||
|
|
|
||||||
|
|
@ -382,6 +382,22 @@ gboolean ostree_repo_resolve_rev (OstreeRepo *self,
|
||||||
char **out_rev,
|
char **out_rev,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OstreeRepoResolveRevExtFlags:
|
||||||
|
* @OSTREE_REPO_RESOLVE_REV_EXT_NONE: No flags.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
OSTREE_REPO_RESOLVE_REV_EXT_NONE = 0,
|
||||||
|
} OstreeRepoResolveRevExtFlags;
|
||||||
|
|
||||||
|
_OSTREE_PUBLIC
|
||||||
|
gboolean ostree_repo_resolve_rev_ext (OstreeRepo *self,
|
||||||
|
const char *refspec,
|
||||||
|
gboolean allow_noent,
|
||||||
|
OstreeRepoResolveRevExtFlags flags,
|
||||||
|
char **out_rev,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
_OSTREE_PUBLIC
|
_OSTREE_PUBLIC
|
||||||
gboolean ostree_repo_list_refs (OstreeRepo *self,
|
gboolean ostree_repo_list_refs (OstreeRepo *self,
|
||||||
const char *refspec_prefix,
|
const char *refspec_prefix,
|
||||||
|
|
@ -734,7 +750,8 @@ typedef struct {
|
||||||
guint enable_uncompressed_cache : 1;
|
guint enable_uncompressed_cache : 1;
|
||||||
guint disable_fsync : 1;
|
guint disable_fsync : 1;
|
||||||
guint process_whiteouts : 1;
|
guint process_whiteouts : 1;
|
||||||
guint reserved : 29;
|
guint no_copy_fallback : 1;
|
||||||
|
guint reserved : 28;
|
||||||
|
|
||||||
const char *subpath;
|
const char *subpath;
|
||||||
|
|
||||||
|
|
@ -866,7 +883,7 @@ gboolean ostree_repo_traverse_commit_union (OstreeRepo *repo,
|
||||||
struct _OstreeRepoCommitTraverseIter {
|
struct _OstreeRepoCommitTraverseIter {
|
||||||
gboolean initialized;
|
gboolean initialized;
|
||||||
gpointer dummy[10];
|
gpointer dummy[10];
|
||||||
char dummy_checksum_data[65*2];
|
char dummy_checksum_data[(OSTREE_SHA256_STRING_LEN+1)*2];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _OstreeRepoCommitTraverseIter OstreeRepoCommitTraverseIter;
|
typedef struct _OstreeRepoCommitTraverseIter OstreeRepoCommitTraverseIter;
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,8 @@ _ostree_sysroot_list_deployment_dirs_for_os (GFile *osdir,
|
||||||
g_autofree char *csum = NULL;
|
g_autofree char *csum = NULL;
|
||||||
gint deployserial;
|
gint deployserial;
|
||||||
|
|
||||||
if (!gs_file_enumerator_iterate (dir_enum, &file_info, &child,
|
if (!g_file_enumerator_iterate (dir_enum, &file_info, &child,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
if (file_info == NULL)
|
if (file_info == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
@ -127,8 +127,8 @@ list_all_deployment_directories (OstreeSysroot *self,
|
||||||
GFileInfo *file_info = NULL;
|
GFileInfo *file_info = NULL;
|
||||||
GFile *child = NULL;
|
GFile *child = NULL;
|
||||||
|
|
||||||
if (!gs_file_enumerator_iterate (dir_enum, &file_info, &child,
|
if (!g_file_enumerator_iterate (dir_enum, &file_info, &child,
|
||||||
NULL, error))
|
NULL, error))
|
||||||
goto out;
|
goto out;
|
||||||
if (file_info == NULL)
|
if (file_info == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
@ -215,8 +215,8 @@ list_all_boot_directories (OstreeSysroot *self,
|
||||||
GFile *child = NULL;
|
GFile *child = NULL;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
if (!gs_file_enumerator_iterate (dir_enum, &file_info, &child,
|
if (!g_file_enumerator_iterate (dir_enum, &file_info, &child,
|
||||||
NULL, error))
|
NULL, error))
|
||||||
goto out;
|
goto out;
|
||||||
if (file_info == NULL)
|
if (file_info == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -473,7 +473,7 @@ merge_etc_changes (GFile *orig_etc,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_log_structured_print_id_v (OSTREE_CONFIGMERGE_ID,
|
ot_log_structured_print_id_v (OSTREE_CONFIGMERGE_ID,
|
||||||
"Copying /etc changes: %u modified, %u removed, %u added",
|
"Copying /etc changes: %u modified, %u removed, %u added",
|
||||||
modified->len,
|
modified->len,
|
||||||
removed->len,
|
removed->len,
|
||||||
|
|
@ -773,7 +773,7 @@ selinux_relabel_var_if_needed (OstreeSysroot *sysroot,
|
||||||
|
|
||||||
if (!g_file_query_exists (deployment_var_labeled, NULL))
|
if (!g_file_query_exists (deployment_var_labeled, NULL))
|
||||||
{
|
{
|
||||||
gs_log_structured_print_id_v (OSTREE_VARRELABEL_ID,
|
ot_log_structured_print_id_v (OSTREE_VARRELABEL_ID,
|
||||||
"Relabeling /var (no stamp file '%s' found)",
|
"Relabeling /var (no stamp file '%s' found)",
|
||||||
gs_file_get_path_cached (deployment_var_labeled));
|
gs_file_get_path_cached (deployment_var_labeled));
|
||||||
|
|
||||||
|
|
@ -1927,7 +1927,7 @@ ostree_sysroot_write_deployments (OstreeSysroot *self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_log_structured_print_id_v (OSTREE_DEPLOYMENT_COMPLETE_ID,
|
ot_log_structured_print_id_v (OSTREE_DEPLOYMENT_COMPLETE_ID,
|
||||||
"%s; bootconfig swap: %s deployment count change: %i",
|
"%s; bootconfig swap: %s deployment count change: %i",
|
||||||
(bootloader_is_atomic ? "Transaction complete" : "Bootloader updated"),
|
(bootloader_is_atomic ? "Transaction complete" : "Bootloader updated"),
|
||||||
requires_new_bootversion ? "yes" : "no",
|
requires_new_bootversion ? "yes" : "no",
|
||||||
|
|
|
||||||
|
|
@ -493,3 +493,55 @@ ot_util_ensure_directory_and_fsync (GFile *dir,
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !GLIB_CHECK_VERSION(2, 44, 0)
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
ot_file_enumerator_iterate (GFileEnumerator *direnum,
|
||||||
|
GFileInfo **out_info,
|
||||||
|
GFile **out_child,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
GError *temp_error = NULL;
|
||||||
|
|
||||||
|
static GQuark cached_info_quark;
|
||||||
|
static GQuark cached_child_quark;
|
||||||
|
static gsize quarks_initialized;
|
||||||
|
|
||||||
|
g_return_val_if_fail (direnum != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (out_info != NULL, FALSE);
|
||||||
|
|
||||||
|
if (g_once_init_enter (&quarks_initialized))
|
||||||
|
{
|
||||||
|
cached_info_quark = g_quark_from_static_string ("ot-cached-info");
|
||||||
|
cached_child_quark = g_quark_from_static_string ("ot-cached-child");
|
||||||
|
g_once_init_leave (&quarks_initialized, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_info = g_file_enumerator_next_file (direnum, cancellable, &temp_error);
|
||||||
|
if (out_child)
|
||||||
|
*out_child = NULL;
|
||||||
|
if (temp_error != NULL)
|
||||||
|
{
|
||||||
|
g_propagate_error (error, temp_error);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
else if (*out_info != NULL)
|
||||||
|
{
|
||||||
|
g_object_set_qdata_full ((GObject*)direnum, cached_info_quark, *out_info, (GDestroyNotify)g_object_unref);
|
||||||
|
if (out_child != NULL)
|
||||||
|
{
|
||||||
|
const char *name = g_file_info_get_name (*out_info);
|
||||||
|
*out_child = g_file_get_child (g_file_enumerator_get_container (direnum), name);
|
||||||
|
g_object_set_qdata_full ((GObject*)direnum, cached_child_quark, *out_child, (GDestroyNotify)g_object_unref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = TRUE;
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -93,4 +93,26 @@ gboolean ot_util_fsync_directory (GFile *dir,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
#if !GLIB_CHECK_VERSION(2, 44, 0)
|
||||||
|
gboolean
|
||||||
|
ot_file_enumerator_iterate (GFileEnumerator *direnum,
|
||||||
|
GFileInfo **out_info,
|
||||||
|
GFile **out_child,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
#else
|
||||||
|
static inline gboolean
|
||||||
|
ot_file_enumerator_iterate (GFileEnumerator *direnum,
|
||||||
|
GFileInfo **out_info,
|
||||||
|
GFile **out_child,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||||
|
return (g_file_enumerator_iterate) (direnum, out_info, out_child, cancellable, error);
|
||||||
|
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#define g_file_enumerator_iterate ot_file_enumerator_iterate
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Colin Walters <walters@verbum.org>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Author: Colin Walters <walters@verbum.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "otutil.h"
|
||||||
|
#include "libglnx.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBSYSTEMD
|
||||||
|
#define SD_JOURNAL_SUPPRESS_LOCATION
|
||||||
|
#include <systemd/sd-journal.h>
|
||||||
|
#endif
|
||||||
|
#include <glib-unix.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ot_log_structured:
|
||||||
|
* @message: Text message to send
|
||||||
|
* @keys: (allow-none) (array zero-terminated=1) (element-type utf8): Optional structured data
|
||||||
|
*
|
||||||
|
* Log structured data in an operating-system specific fashion. The
|
||||||
|
* parameter @opts should be an array of UTF-8 KEY=VALUE strings.
|
||||||
|
* This function does not support binary data. See
|
||||||
|
* http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html
|
||||||
|
* for more information about fields that can be used on a systemd
|
||||||
|
* system.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ot_log_structured (const char *message,
|
||||||
|
const char *const *keys)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_LIBSYSTEMD
|
||||||
|
const char *const*iter;
|
||||||
|
g_autofree char *msgkey = NULL;
|
||||||
|
guint i, n_opts;
|
||||||
|
struct iovec *iovs;
|
||||||
|
|
||||||
|
for (n_opts = 0, iter = keys; *iter; iter++, n_opts++)
|
||||||
|
;
|
||||||
|
|
||||||
|
n_opts++; /* Add one for MESSAGE= */
|
||||||
|
iovs = g_alloca (sizeof (struct iovec) * n_opts);
|
||||||
|
|
||||||
|
for (i = 0, iter = keys; *iter; iter++, i++) {
|
||||||
|
iovs[i].iov_base = (char*)keys[i];
|
||||||
|
iovs[i].iov_len = strlen (keys[i]);
|
||||||
|
}
|
||||||
|
g_assert(i == n_opts-1);
|
||||||
|
msgkey = g_strconcat ("MESSAGE=", message, NULL);
|
||||||
|
iovs[i].iov_base = msgkey;
|
||||||
|
iovs[i].iov_len = strlen (msgkey);
|
||||||
|
|
||||||
|
// The code location isn't useful since we're wrapping
|
||||||
|
sd_journal_sendv (iovs, n_opts);
|
||||||
|
#else
|
||||||
|
g_print ("%s\n", message);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ot_stdout_is_journal:
|
||||||
|
*
|
||||||
|
* Use this function when you want your code to behave differently
|
||||||
|
* depeneding on whether your program was started as a systemd unit,
|
||||||
|
* or e.g. interactively at a terminal.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if stdout is (probably) connnected to the systemd journal
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
ot_stdout_is_journal (void)
|
||||||
|
{
|
||||||
|
static gsize initialized;
|
||||||
|
static gboolean stdout_is_socket;
|
||||||
|
|
||||||
|
if (g_once_init_enter (&initialized))
|
||||||
|
{
|
||||||
|
guint64 pid = (guint64) getpid ();
|
||||||
|
g_autofree char *fdpath = g_strdup_printf ("/proc/%" G_GUINT64_FORMAT "/fd/1", pid);
|
||||||
|
char buf[1024];
|
||||||
|
ssize_t bytes_read;
|
||||||
|
|
||||||
|
if ((bytes_read = readlink (fdpath, buf, sizeof(buf) - 1)) != -1)
|
||||||
|
{
|
||||||
|
buf[bytes_read] = '\0';
|
||||||
|
stdout_is_socket = g_str_has_prefix (buf, "socket:");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
stdout_is_socket = FALSE;
|
||||||
|
|
||||||
|
g_once_init_leave (&initialized, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stdout_is_socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gs_log_structured_print:
|
||||||
|
* @message: A message to log
|
||||||
|
* @keys: (allow-none) (array zero-terminated=1) (element-type utf8): Optional structured data
|
||||||
|
*
|
||||||
|
* Like gs_log_structured(), but also print to standard output (if it
|
||||||
|
* is not already connected to the system log).
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ot_log_structured_print (const char *message,
|
||||||
|
const char *const *keys)
|
||||||
|
{
|
||||||
|
ot_log_structured (message, keys);
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBSYSTEMD
|
||||||
|
if (!ot_stdout_is_journal ())
|
||||||
|
g_print ("%s\n", message);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ot_log_structured_print_id_v:
|
||||||
|
* @message_id: A unique MESSAGE_ID
|
||||||
|
* @format: A format string
|
||||||
|
*
|
||||||
|
* The provided @message_id is a unique MESSAGE_ID (see <ulink url="http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html"> for more information).
|
||||||
|
*
|
||||||
|
* This function otherwise acts as ot_log_structured_print(), taking
|
||||||
|
* @format as a format string.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ot_log_structured_print_id_v (const char *message_id,
|
||||||
|
const char *format,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
const char *key0 = glnx_strjoina ("MESSAGE_ID=", message_id);
|
||||||
|
const char *keys[] = { key0, NULL };
|
||||||
|
g_autofree char *msg = NULL;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start (args, format);
|
||||||
|
msg = g_strdup_vprintf (format, args);
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
ot_log_structured_print (msg, (const char *const *)keys);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Colin Walters <walters@verbum.org>.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ot-unix-utils.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
void ot_log_structured_print_id_v (const char *message_id,
|
||||||
|
const char *format,
|
||||||
|
...);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
@ -47,5 +47,6 @@
|
||||||
#include <ot-spawn-utils.h>
|
#include <ot-spawn-utils.h>
|
||||||
#include <ot-checksum-utils.h>
|
#include <ot-checksum-utils.h>
|
||||||
#include <ot-gpg-utils.h>
|
#include <ot-gpg-utils.h>
|
||||||
|
#include <ot-log-utils.h>
|
||||||
|
|
||||||
void ot_ptrarray_add_many (GPtrArray *a, ...) G_GNUC_NULL_TERMINATED;
|
void ot_ptrarray_add_many (GPtrArray *a, ...) G_GNUC_NULL_TERMINATED;
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ ot_admin_builtin_switch (int argc, char **argv, GCancellable *cancellable, GErro
|
||||||
GKeyFile *old_origin;
|
GKeyFile *old_origin;
|
||||||
GKeyFile *new_origin = NULL;
|
GKeyFile *new_origin = NULL;
|
||||||
|
|
||||||
context = g_option_context_new ("REF - Construct new tree from current origin and deploy it, if it changed");
|
context = g_option_context_new ("REF - Construct new tree from REF and deploy it");
|
||||||
|
|
||||||
if (!ostree_admin_option_context_parse (context, options, &argc, &argv,
|
if (!ostree_admin_option_context_parse (context, options, &argc, &argv,
|
||||||
OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER,
|
OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER,
|
||||||
|
|
|
||||||
|
|
@ -114,8 +114,8 @@ relabel_recursively (OstreeSePolicy *sepolicy,
|
||||||
GFile *child;
|
GFile *child;
|
||||||
GFileType ftype;
|
GFileType ftype;
|
||||||
|
|
||||||
if (!gs_file_enumerator_iterate (direnum, &file_info, &child,
|
if (!g_file_enumerator_iterate (direnum, &file_info, &child,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
if (file_info == NULL)
|
if (file_info == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ static gboolean opt_whiteouts;
|
||||||
static gboolean opt_from_stdin;
|
static gboolean opt_from_stdin;
|
||||||
static char *opt_from_file;
|
static char *opt_from_file;
|
||||||
static gboolean opt_disable_fsync;
|
static gboolean opt_disable_fsync;
|
||||||
|
static gboolean opt_require_hardlinks;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
parse_fsync_cb (const char *option_name,
|
parse_fsync_cb (const char *option_name,
|
||||||
|
|
@ -67,6 +68,7 @@ static GOptionEntry options[] = {
|
||||||
{ "from-stdin", 0, 0, G_OPTION_ARG_NONE, &opt_from_stdin, "Process many checkouts from standard input", NULL },
|
{ "from-stdin", 0, 0, G_OPTION_ARG_NONE, &opt_from_stdin, "Process many checkouts from standard input", NULL },
|
||||||
{ "from-file", 0, 0, G_OPTION_ARG_STRING, &opt_from_file, "Process many checkouts from input file", "FILE" },
|
{ "from-file", 0, 0, G_OPTION_ARG_STRING, &opt_from_file, "Process many checkouts from input file", "FILE" },
|
||||||
{ "fsync", 0, 0, G_OPTION_ARG_CALLBACK, parse_fsync_cb, "Specify how to invoke fsync()", "POLICY" },
|
{ "fsync", 0, 0, G_OPTION_ARG_CALLBACK, parse_fsync_cb, "Specify how to invoke fsync()", "POLICY" },
|
||||||
|
{ "require-hardlinks", 'H', 0, G_OPTION_ARG_NONE, &opt_require_hardlinks, "Do not fall back to full copies if hardlinking fails", NULL },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -85,7 +87,7 @@ process_one_checkout (OstreeRepo *repo,
|
||||||
* `ostree_repo_checkout_tree_at` until such time as we have a more
|
* `ostree_repo_checkout_tree_at` until such time as we have a more
|
||||||
* convenient infrastructure for testing C APIs with data.
|
* convenient infrastructure for testing C APIs with data.
|
||||||
*/
|
*/
|
||||||
if (opt_disable_cache || opt_whiteouts)
|
if (opt_disable_cache || opt_whiteouts || opt_require_hardlinks)
|
||||||
{
|
{
|
||||||
OstreeRepoCheckoutOptions options = { 0, };
|
OstreeRepoCheckoutOptions options = { 0, };
|
||||||
|
|
||||||
|
|
@ -97,6 +99,7 @@ process_one_checkout (OstreeRepo *repo,
|
||||||
options.process_whiteouts = TRUE;
|
options.process_whiteouts = TRUE;
|
||||||
if (subpath)
|
if (subpath)
|
||||||
options.subpath = subpath;
|
options.subpath = subpath;
|
||||||
|
options.no_copy_fallback = opt_require_hardlinks;
|
||||||
|
|
||||||
if (!ostree_repo_checkout_tree_at (repo, &options,
|
if (!ostree_repo_checkout_tree_at (repo, &options,
|
||||||
AT_FDCWD, destination,
|
AT_FDCWD, destination,
|
||||||
|
|
|
||||||
|
|
@ -428,7 +428,15 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError
|
||||||
else if (!opt_orphan)
|
else if (!opt_orphan)
|
||||||
{
|
{
|
||||||
if (!ostree_repo_resolve_rev (repo, opt_branch, TRUE, &parent, error))
|
if (!ostree_repo_resolve_rev (repo, opt_branch, TRUE, &parent, error))
|
||||||
goto out;
|
{
|
||||||
|
if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY))
|
||||||
|
{
|
||||||
|
/* A folder exists with the specified ref name,
|
||||||
|
* which is handled by _ostree_repo_write_ref */
|
||||||
|
g_clear_error (error);
|
||||||
|
}
|
||||||
|
else goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_editor)
|
if (opt_editor)
|
||||||
|
|
|
||||||
|
|
@ -72,9 +72,19 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab
|
||||||
{
|
{
|
||||||
g_autofree char *checksum = NULL;
|
g_autofree char *checksum = NULL;
|
||||||
g_autofree char *checksum_existing = NULL;
|
g_autofree char *checksum_existing = NULL;
|
||||||
|
g_autofree char *remote = NULL;
|
||||||
|
g_autofree char *ref = NULL;
|
||||||
|
|
||||||
if (!ostree_repo_resolve_rev (repo, opt_create, TRUE, &checksum_existing, error))
|
if (!ostree_repo_resolve_rev_ext (repo, opt_create, TRUE, OSTREE_REPO_RESOLVE_REV_EXT_NONE, &checksum_existing, error))
|
||||||
goto out;
|
{
|
||||||
|
if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY))
|
||||||
|
{
|
||||||
|
/* A folder exists with the specified ref name,
|
||||||
|
* which is handled by _ostree_repo_write_ref */
|
||||||
|
g_clear_error (error);
|
||||||
|
}
|
||||||
|
else goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (checksum_existing != NULL)
|
if (checksum_existing != NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -86,7 +96,10 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab
|
||||||
if (!ostree_repo_resolve_rev (repo, refspec_prefix, FALSE, &checksum, error))
|
if (!ostree_repo_resolve_rev (repo, refspec_prefix, FALSE, &checksum, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!ostree_repo_set_ref_immediate (repo, NULL, opt_create, checksum,
|
if (!ostree_parse_refspec (opt_create, &remote, &ref, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!ostree_repo_set_ref_immediate (repo, remote, ref, checksum,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ static gboolean opt_empty;
|
||||||
static gboolean opt_swap_endianness;
|
static gboolean opt_swap_endianness;
|
||||||
static gboolean opt_inline;
|
static gboolean opt_inline;
|
||||||
static gboolean opt_disable_bsdiff;
|
static gboolean opt_disable_bsdiff;
|
||||||
|
static gboolean opt_if_not_exists;
|
||||||
|
|
||||||
#define BUILTINPROTO(name) static gboolean ot_static_delta_builtin_ ## name (int argc, char **argv, GCancellable *cancellable, GError **error)
|
#define BUILTINPROTO(name) static gboolean ot_static_delta_builtin_ ## name (int argc, char **argv, GCancellable *cancellable, GError **error)
|
||||||
|
|
||||||
|
|
@ -64,6 +65,7 @@ static GOptionEntry generate_options[] = {
|
||||||
{ "inline", 0, 0, G_OPTION_ARG_NONE, &opt_inline, "Inline delta parts into main delta", NULL },
|
{ "inline", 0, 0, G_OPTION_ARG_NONE, &opt_inline, "Inline delta parts into main delta", NULL },
|
||||||
{ "to", 0, 0, G_OPTION_ARG_STRING, &opt_to_rev, "Create delta to revision REV", "REV" },
|
{ "to", 0, 0, G_OPTION_ARG_STRING, &opt_to_rev, "Create delta to revision REV", "REV" },
|
||||||
{ "disable-bsdiff", 0, 0, G_OPTION_ARG_NONE, &opt_disable_bsdiff, "Disable use of bsdiff", NULL },
|
{ "disable-bsdiff", 0, 0, G_OPTION_ARG_NONE, &opt_disable_bsdiff, "Disable use of bsdiff", NULL },
|
||||||
|
{ "if-not-exists", 'n', 0, G_OPTION_ARG_NONE, &opt_if_not_exists, "Only generate if a delta does not already exist", NULL },
|
||||||
{ "set-endianness", 0, 0, G_OPTION_ARG_STRING, &opt_endianness, "Choose metadata endianness ('l' or 'B')", "ENDIAN" },
|
{ "set-endianness", 0, 0, G_OPTION_ARG_STRING, &opt_endianness, "Choose metadata endianness ('l' or 'B')", "ENDIAN" },
|
||||||
{ "swap-endianness", 0, 0, G_OPTION_ARG_NONE, &opt_swap_endianness, "Swap metadata endianness from host order", NULL },
|
{ "swap-endianness", 0, 0, G_OPTION_ARG_NONE, &opt_swap_endianness, "Swap metadata endianness from host order", NULL },
|
||||||
{ "min-fallback-size", 0, 0, G_OPTION_ARG_STRING, &opt_min_fallback_size, "Minimum uncompressed size in megabytes for individual HTTP request", NULL},
|
{ "min-fallback-size", 0, 0, G_OPTION_ARG_STRING, &opt_min_fallback_size, "Minimum uncompressed size in megabytes for individual HTTP request", NULL},
|
||||||
|
|
@ -264,6 +266,20 @@ ot_static_delta_builtin_generate (int argc, char **argv, GCancellable *cancellab
|
||||||
}
|
}
|
||||||
if (!ostree_repo_resolve_rev (repo, opt_to_rev, FALSE, &to_resolved, error))
|
if (!ostree_repo_resolve_rev (repo, opt_to_rev, FALSE, &to_resolved, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (opt_if_not_exists)
|
||||||
|
{
|
||||||
|
gboolean does_exist;
|
||||||
|
g_autofree char *delta_id = from_resolved ? g_strconcat (from_resolved, "-", to_resolved, NULL) : g_strdup (to_resolved);
|
||||||
|
if (!ostree_cmd__private__ ()->ostree_static_delta_query_exists (repo, delta_id, &does_exist, cancellable, error))
|
||||||
|
goto out;
|
||||||
|
if (does_exist)
|
||||||
|
{
|
||||||
|
g_print ("Delta %s already exists.\n", delta_id);
|
||||||
|
ret = TRUE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (opt_endianness)
|
if (opt_endianness)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,14 @@ static char *opt_log = NULL;
|
||||||
static gboolean opt_daemonize;
|
static gboolean opt_daemonize;
|
||||||
static gboolean opt_autoexit;
|
static gboolean opt_autoexit;
|
||||||
static gboolean opt_force_ranges;
|
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 gint opt_port = 0;
|
||||||
|
|
||||||
|
static guint emitted_random_500s_count = 0;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GFile *root;
|
GFile *root;
|
||||||
gboolean running;
|
gboolean running;
|
||||||
|
|
@ -52,6 +58,8 @@ static GOptionEntry options[] = {
|
||||||
{ "port", 'P', 0, G_OPTION_ARG_INT, &opt_port, "Use the specified TCP port", 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" },
|
{ "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 },
|
{ "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" },
|
{ "log-file", 0, 0, G_OPTION_ARG_FILENAME, &opt_log, "Put logs here", "PATH" },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
@ -187,6 +195,15 @@ do_get (OtTrivialHttpd *self,
|
||||||
goto out;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
if (path[0] == '/')
|
if (path[0] == '/')
|
||||||
path++;
|
path++;
|
||||||
|
|
||||||
|
|
@ -388,6 +405,13 @@ ostree_builtin_trivial_httpd (int argc, char **argv, GCancellable *cancellable,
|
||||||
|
|
||||||
app->root = g_file_new_for_path (dirpath);
|
app->root = g_file_new_for_path (dirpath);
|
||||||
|
|
||||||
|
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)
|
if (opt_log)
|
||||||
{
|
{
|
||||||
GOutputStream *stream = NULL;
|
GOutputStream *stream = NULL;
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ dump_summary_ref (const char *ref_name,
|
||||||
csum_bytes = ostree_checksum_bytes_peek_validate (csum_v, &csum_error);
|
csum_bytes = ostree_checksum_bytes_peek_validate (csum_v, &csum_error);
|
||||||
if (csum_error == NULL)
|
if (csum_error == NULL)
|
||||||
{
|
{
|
||||||
char csum[65];
|
char csum[OSTREE_SHA256_STRING_LEN+1];
|
||||||
|
|
||||||
ostree_checksum_inplace_from_bytes (csum_bytes, csum);
|
ostree_checksum_inplace_from_bytes (csum_bytes, csum);
|
||||||
g_print (" %s\n", csum);
|
g_print (" %s\n", csum);
|
||||||
|
|
|
||||||
|
|
@ -261,8 +261,11 @@ can_write (const char *path)
|
||||||
else
|
else
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
if (!devino_set_contains (stbuf.st_dev, stbuf.st_ino))
|
if (!S_ISDIR (stbuf.st_mode))
|
||||||
return -EROFS;
|
{
|
||||||
|
if (!devino_set_contains (stbuf.st_dev, stbuf.st_ino))
|
||||||
|
return -EROFS;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,9 @@ ot_test_setup_sysroot (GCancellable *cancellable,
|
||||||
if (!ot_test_run_libtest ("setup_os_repository \"archive-z2\" \"syslinux\"", error))
|
if (!ot_test_run_libtest ("setup_os_repository \"archive-z2\" \"syslinux\"", error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
/* Make sure deployments are mutable */
|
||||||
|
g_setenv ("OSTREE_SYSROOT_DEBUG", "mutable-deployments", TRUE);
|
||||||
|
|
||||||
ret_sysroot = ostree_sysroot_new (sysroot_path);
|
ret_sysroot = ostree_sysroot_new (sysroot_path);
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,7 @@ assert_file_has_content () {
|
||||||
if ! grep -q -e "$2" "$1"; then
|
if ! grep -q -e "$2" "$1"; then
|
||||||
sed -e 's/^/# /' < "$1" >&2
|
sed -e 's/^/# /' < "$1" >&2
|
||||||
echo 1>&2 "File '$1' doesn't match regexp '$2'"
|
echo 1>&2 "File '$1' doesn't match regexp '$2'"
|
||||||
|
cat $1
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,9 @@ assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'option
|
||||||
echo "ok deploy with --karg, but same config"
|
echo "ok deploy with --karg, but same config"
|
||||||
|
|
||||||
${CMD_PREFIX} ostree admin deploy --karg-proc-cmdline --os=testos testos:testos/buildmaster/x86_64-runtime
|
${CMD_PREFIX} ostree admin deploy --karg-proc-cmdline --os=testos testos:testos/buildmaster/x86_64-runtime
|
||||||
# Here we're asserting that the *host* system has a root= kernel
|
for arg in $(cat /proc/cmdline); do
|
||||||
# argument. I think it's unlikely that anyone doesn't have one, but
|
assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf "options.*$arg"
|
||||||
# if this is not true for you, please file a bug!
|
done
|
||||||
assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'options.*root=.'
|
|
||||||
|
|
||||||
echo "ok deploy --karg-proc-cmdline"
|
echo "ok deploy --karg-proc-cmdline"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,7 @@ assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'option
|
||||||
echo "ok instutil set-kargs --append"
|
echo "ok instutil set-kargs --append"
|
||||||
|
|
||||||
${CMD_PREFIX} ostree admin instutil set-kargs --import-proc-cmdline
|
${CMD_PREFIX} ostree admin instutil set-kargs --import-proc-cmdline
|
||||||
# Here we're asserting that the *host* system has a root= kernel
|
for arg in $(cat /proc/cmdline); do
|
||||||
# argument. I think it's unlikely that anyone doesn't have one, but
|
assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf "options.*$arg"
|
||||||
# if this is not true for you, please file a bug!
|
done
|
||||||
assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'options.*root=.'
|
|
||||||
echo "ok instutil set-kargs --import-proc-cmdline"
|
echo "ok instutil set-kargs --import-proc-cmdline"
|
||||||
|
|
|
||||||
|
|
@ -31,30 +31,30 @@ mkdir test
|
||||||
|
|
||||||
echo hello > test/a
|
echo hello > test/a
|
||||||
|
|
||||||
${CMD_PREFIX} $OSTREE commit -b test -s "A commit" test
|
$OSTREE commit -b test -s "A commit" test
|
||||||
echo "ok commit 1"
|
echo "ok commit 1"
|
||||||
|
|
||||||
${CMD_PREFIX} $OSTREE summary --update
|
$OSTREE summary --update
|
||||||
|
|
||||||
OLD_MD5=$(md5sum repo/summary)
|
OLD_MD5=$(md5sum repo/summary)
|
||||||
|
|
||||||
echo hello2 > test/a
|
echo hello2 > test/a
|
||||||
|
|
||||||
${CMD_PREFIX} $OSTREE commit -b test -s "Another commit" test
|
$OSTREE commit -b test -s "Another commit" test
|
||||||
echo "ok commit 2"
|
echo "ok commit 2"
|
||||||
|
|
||||||
assert_streq "$OLD_MD5" "$(md5sum repo/summary)"
|
assert_streq "$OLD_MD5" "$(md5sum repo/summary)"
|
||||||
|
|
||||||
${CMD_PREFIX} $OSTREE --repo=repo config set core.commit-update-summary true
|
$OSTREE --repo=repo config set core.commit-update-summary true
|
||||||
|
|
||||||
echo hello3 > test/a
|
echo hello3 > test/a
|
||||||
|
|
||||||
${CMD_PREFIX} $OSTREE commit -b test -s "Another commit..." test
|
$OSTREE commit -b test -s "Another commit..." test
|
||||||
echo "ok commit 3"
|
echo "ok commit 3"
|
||||||
|
|
||||||
assert_not_streq "$OLD_MD5" "$(md5sum repo/summary)"
|
assert_not_streq "$OLD_MD5" "$(md5sum repo/summary)"
|
||||||
|
|
||||||
# Check that summary --update deletes the .sig file
|
# Check that summary --update deletes the .sig file
|
||||||
touch repo/summary.sig
|
touch repo/summary.sig
|
||||||
${CMD_PREFIX} $OSTREE summary --update
|
$OSTREE summary --update
|
||||||
assert_not_has_file repo/summary.sig
|
assert_not_has_file repo/summary.sig
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,8 @@ get_assert_one_direntry_matching() {
|
||||||
origrev=$(${CMD_PREFIX} ostree --repo=repo rev-parse test)
|
origrev=$(${CMD_PREFIX} ostree --repo=repo rev-parse test)
|
||||||
|
|
||||||
${CMD_PREFIX} ostree --repo=repo static-delta generate --empty --to=${origrev}
|
${CMD_PREFIX} ostree --repo=repo static-delta generate --empty --to=${origrev}
|
||||||
|
${CMD_PREFIX} ostree --repo=repo static-delta generate --if-not-exists --empty --to=${origrev} > out.txt
|
||||||
|
assert_file_has_content out.txt "${origrev} already exists"
|
||||||
${CMD_PREFIX} ostree --repo=repo static-delta list | grep ${origrev} || exit 1
|
${CMD_PREFIX} ostree --repo=repo static-delta list | grep ${origrev} || exit 1
|
||||||
${CMD_PREFIX} ostree --repo=repo prune
|
${CMD_PREFIX} ostree --repo=repo prune
|
||||||
${CMD_PREFIX} ostree --repo=repo static-delta list | grep ${origrev} || exit 1
|
${CMD_PREFIX} ostree --repo=repo static-delta list | grep ${origrev} || exit 1
|
||||||
|
|
@ -91,7 +93,12 @@ ${CMD_PREFIX} ostree --repo=repo commit -b test -s test --tree=dir=files
|
||||||
|
|
||||||
newrev=$(${CMD_PREFIX} ostree --repo=repo rev-parse test)
|
newrev=$(${CMD_PREFIX} ostree --repo=repo rev-parse test)
|
||||||
|
|
||||||
${CMD_PREFIX} ostree --repo=repo static-delta generate --from=${origrev} --to=${newrev} --inline
|
${CMD_PREFIX} ostree --repo=repo static-delta generate --if-not-exists --from=${origrev} --to=${newrev} --inline
|
||||||
|
${CMD_PREFIX} ostree --repo=repo static-delta generate --if-not-exists --from=${origrev} --to=${newrev} --inline > out.txt
|
||||||
|
assert_file_has_content out.txt "${origrev}-${newrev} already exists"
|
||||||
|
# Should regenerate
|
||||||
|
${CMD_PREFIX} ostree --repo=repo static-delta generate --from=${origrev} --to=${newrev} --inline > out.txt
|
||||||
|
assert_not_file_has_content out.txt "${origrev}-${newrev} already exists"
|
||||||
|
|
||||||
deltaprefix=$(get_assert_one_direntry_matching repo/deltas '.')
|
deltaprefix=$(get_assert_one_direntry_matching repo/deltas '.')
|
||||||
deltadir=$(get_assert_one_direntry_matching repo/deltas/${deltaprefix} '-')
|
deltadir=$(get_assert_one_direntry_matching repo/deltas/${deltaprefix} '-')
|
||||||
|
|
|
||||||
|
|
@ -433,6 +433,9 @@ entry_pathname_test_helper (gconstpointer data, gboolean on)
|
||||||
OstreeRepoCommitModifier *modifier = NULL;
|
OstreeRepoCommitModifier *modifier = NULL;
|
||||||
gboolean met_etc_file = FALSE;
|
gboolean met_etc_file = FALSE;
|
||||||
|
|
||||||
|
if (skip_if_no_xattr (td))
|
||||||
|
goto out;
|
||||||
|
|
||||||
modifier = ostree_repo_commit_modifier_new (0, NULL, NULL, NULL);
|
modifier = ostree_repo_commit_modifier_new (0, NULL, NULL, NULL);
|
||||||
ostree_repo_commit_modifier_set_xattr_callback (modifier, path_cb,
|
ostree_repo_commit_modifier_set_xattr_callback (modifier, path_cb,
|
||||||
NULL, &met_etc_file);
|
NULL, &met_etc_file);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Copyright (C) 2016 Red Hat
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
|
||||||
|
echo "1..1"
|
||||||
|
|
||||||
|
COMMIT_SIGN="--gpg-homedir=${TEST_GPG_KEYHOME} --gpg-sign=${TEST_GPG_KEYID_1}"
|
||||||
|
setup_fake_remote_repo1 "archive-z2" "${COMMIT_SIGN}" --random-500s=50
|
||||||
|
|
||||||
|
cd ${test_tmpdir}
|
||||||
|
${CMD_PREFIX} ostree --repo=repo init --mode=archive-z2
|
||||||
|
${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin $(cat httpd-address)/ostree/gnomerepo
|
||||||
|
for x in $(seq 200); do
|
||||||
|
if ${CMD_PREFIX} ostree --repo=repo pull --mirror origin main 2>err.txt; then
|
||||||
|
echo "Success on iteration ${x}"
|
||||||
|
break;
|
||||||
|
fi
|
||||||
|
assert_file_has_content err.txt "500.*Internal Server Error"
|
||||||
|
done
|
||||||
|
|
||||||
|
${CMD_PREFIX} ostree --repo=repo fsck
|
||||||
|
${CMD_PREFIX} ostree --repo=repo rev-parse main
|
||||||
|
|
||||||
|
echo "ok repeated pull after 500s"
|
||||||
|
|
@ -23,16 +23,18 @@ set -euo pipefail
|
||||||
|
|
||||||
setup_fake_remote_repo1 "archive-z2"
|
setup_fake_remote_repo1 "archive-z2"
|
||||||
|
|
||||||
echo '1..1'
|
echo '1..2'
|
||||||
|
|
||||||
repopath=${test_tmpdir}/ostree-srv/gnomerepo
|
repopath=${test_tmpdir}/ostree-srv/gnomerepo
|
||||||
cp -a ${repopath} ${repopath}.orig
|
cp -a ${repopath} ${repopath}.orig
|
||||||
|
|
||||||
|
for remoteurl in $(cat httpd-address)/ostree/gnomerepo \
|
||||||
|
file://$(pwd)/ostree-srv/gnomerepo; do
|
||||||
cd ${test_tmpdir}
|
cd ${test_tmpdir}
|
||||||
rm repo -rf
|
rm repo -rf
|
||||||
mkdir repo
|
mkdir repo
|
||||||
${CMD_PREFIX} ostree --repo=repo init
|
${CMD_PREFIX} ostree --repo=repo init
|
||||||
${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin $(cat httpd-address)/ostree/gnomerepo
|
${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin ${remoteurl}
|
||||||
|
|
||||||
${CMD_PREFIX} ostree --repo=repo pull --subpath=/baz origin main
|
${CMD_PREFIX} ostree --repo=repo pull --subpath=/baz origin main
|
||||||
|
|
||||||
|
|
@ -51,5 +53,5 @@ ${CMD_PREFIX} ostree --repo=repo ls origin:main /firstfile
|
||||||
${CMD_PREFIX} ostree --repo=repo pull origin main
|
${CMD_PREFIX} ostree --repo=repo pull origin main
|
||||||
assert_not_has_file repo/state/${rev}.commitpartial
|
assert_not_has_file repo/state/${rev}.commitpartial
|
||||||
${CMD_PREFIX} ostree --repo=repo fsck
|
${CMD_PREFIX} ostree --repo=repo fsck
|
||||||
|
|
||||||
echo "ok"
|
echo "ok"
|
||||||
|
done
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,28 @@ fi
|
||||||
${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create1
|
${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create1
|
||||||
assert_file_has_content refscount.create1 "^5$"
|
assert_file_has_content refscount.create1 "^5$"
|
||||||
|
|
||||||
${CMD_PREFIX} ostree --repo=repo refs ctest --create ctest-new
|
${CMD_PREFIX} ostree --repo=repo refs ctest --create=ctest-new
|
||||||
${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create2
|
${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create2
|
||||||
assert_file_has_content refscount.create2 "^6$"
|
assert_file_has_content refscount.create2 "^6$"
|
||||||
|
|
||||||
|
#Check to see if a deleted folder can be re-used as the name of a ref
|
||||||
|
${CMD_PREFIX} ostree --repo=repo refs foo/ctest --delete
|
||||||
|
${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create3
|
||||||
|
assert_file_has_content refscount.create3 "^5$"
|
||||||
|
${CMD_PREFIX} ostree --repo=repo refs ctest --create=foo
|
||||||
|
${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create4
|
||||||
|
assert_file_has_content refscount.create4 "^6$"
|
||||||
|
|
||||||
|
#Check if a name for a ref in remote repo can be used locally, and vice versa.
|
||||||
|
${CMD_PREFIX} ostree --repo=repo commit --branch=origin:remote1
|
||||||
|
${CMD_PREFIX} ostree --repo=repo commit --branch=local1
|
||||||
|
${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create5
|
||||||
|
assert_file_has_content refscount.create5 "^8$"
|
||||||
|
|
||||||
|
${CMD_PREFIX} ostree --repo=repo refs origin:remote1 --create=remote1
|
||||||
|
${CMD_PREFIX} ostree --repo=repo refs origin:remote1 --create=origin/remote1
|
||||||
|
${CMD_PREFIX} ostree --repo=repo refs local1 --create=origin:local1
|
||||||
|
${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create6
|
||||||
|
assert_file_has_content refscount.create6 "^11$"
|
||||||
|
|
||||||
echo "ok refs"
|
echo "ok refs"
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ skip_without_user_xattrs
|
||||||
|
|
||||||
setup_test_repository "bare-user"
|
setup_test_repository "bare-user"
|
||||||
|
|
||||||
echo "1..5"
|
echo "1..6"
|
||||||
|
|
||||||
mkdir mnt
|
mkdir mnt
|
||||||
|
|
||||||
|
|
@ -71,3 +71,13 @@ echo "ok deletion"
|
||||||
${CMD_PREFIX} ostree --repo=repo commit -b test2 -s fromfuse --link-checkout-speedup --tree=dir=checkout-test2
|
${CMD_PREFIX} ostree --repo=repo commit -b test2 -s fromfuse --link-checkout-speedup --tree=dir=checkout-test2
|
||||||
|
|
||||||
echo "ok commit"
|
echo "ok commit"
|
||||||
|
|
||||||
|
${CMD_PREFIX} ostree --repo=repo checkout -U test2 mnt/test2-checkout-copy-fallback
|
||||||
|
assert_file_has_content mnt/test2-checkout-copy-fallback/anewfile-for-fuse anewfile-for-fuse
|
||||||
|
|
||||||
|
if ${CMD_PREFIX} ostree --repo=repo checkout -UH test2 mnt/test2-checkout-copy-hardlinked 2>err.txt; then
|
||||||
|
assert_not_reached "Checking out via hardlinks across mountpoint unexpectedly succeeded!"
|
||||||
|
fi
|
||||||
|
assert_file_has_content err.txt "Invalid cross-device link"
|
||||||
|
|
||||||
|
echo "ok checkout copy fallback"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue