Merge tag 'upstream/2016.5' into debian/master
Upstream version 2016.5
This commit is contained in:
commit
fa16aa8401
|
|
@ -1,80 +0,0 @@
|
|||
# Standard C/Automake goo
|
||||
.deps
|
||||
.libs
|
||||
.dirstamp
|
||||
*.typelib
|
||||
*.la
|
||||
*.lo
|
||||
*.o
|
||||
*.pyc
|
||||
*.stamp
|
||||
*~
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
compile
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
gtk-doc.make
|
||||
INSTALL
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
stamp-h1
|
||||
ylwrap
|
||||
py-compile
|
||||
config
|
||||
m4
|
||||
po
|
||||
ABOUT-NLS
|
||||
_build
|
||||
|
||||
/build-aux/test-driver
|
||||
|
||||
/doc/ostree-decl.txt
|
||||
/doc/ostree-overrides.txt
|
||||
/doc/ostree-undeclared.txt
|
||||
/doc/ostree-undocumented.txt
|
||||
/doc/ostree-unused.txt
|
||||
/doc/ostree.types
|
||||
/doc/version.xml
|
||||
/doc/tmpl
|
||||
/doc/html
|
||||
/doc/xml
|
||||
/doc/ostree.1
|
||||
|
||||
/ostree
|
||||
/ostree-prepare-root
|
||||
/ostree-remount
|
||||
/OSTree-1.0.gir
|
||||
|
||||
/src/libostree/ostree-1.pc
|
||||
|
||||
/test-admin-deploy-1.test
|
||||
/test-admin-deploy-2.test
|
||||
/test-archivez.test
|
||||
/test-basic.test
|
||||
/test-corruption.test
|
||||
/test-libarchive.test
|
||||
/test-pull-archive-z.test
|
||||
/test-pull-corruption.test
|
||||
/test-pull-resume.test
|
||||
/test-remote-add.test
|
||||
/test-setuid.test
|
||||
/test-xattrs.test
|
||||
test-varint
|
||||
test*.test
|
||||
*.trs
|
||||
*.log
|
||||
|
||||
*.tar.xz
|
||||
*.src.rpm
|
||||
packaging/*.spec
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# We're just using a "stubbed out" Travis right now so we can
|
||||
# use Homu <https://github.com/barosl/homu> to auto-squash
|
||||
# etc.
|
||||
#
|
||||
# In the future we'll hook up better tests.
|
||||
language: c
|
||||
dist: trusty
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- automake
|
||||
- autotools-dev
|
||||
script:
|
||||
- env NOCONFIGURE=1 ./autogen.sh
|
||||
|
||||
notifications:
|
||||
# This is Colin's personal Homu instance. We will
|
||||
# also work on productizing this in Project Atomic.
|
||||
webhooks: http://escher.verbum.org:54856/travis
|
||||
email: false
|
||||
|
||||
branches:
|
||||
only:
|
||||
- auto
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# Makefile for dracut module
|
||||
# Makefile for boot module
|
||||
#
|
||||
# Copyright (C) 2013 Colin Walters <walters@verbum.org>
|
||||
#
|
||||
|
|
@ -39,14 +39,17 @@ systemdsystemunit_DATA = src/boot/ostree-prepare-root.service \
|
|||
src/boot/ostree-remount.service
|
||||
endif
|
||||
|
||||
dist_pkglibexec_SCRIPTS = src/boot/grub2-15_ostree
|
||||
|
||||
if BUILDOPT_GRUB2
|
||||
if !BUILDOPT_BUILTIN_GRUB2_MKCONFIG
|
||||
# We're using the system grub2-mkconfig generator
|
||||
pkglibexec_SCRIPTS += src/boot/grub2/grub2-15_ostree
|
||||
install-grub2-config-hook:
|
||||
mkdir -p $(DESTDIR)$(grub2configdir)
|
||||
ln -sf $(pkglibexecdir)/grub2-15_ostree $(DESTDIR)$(grub2configdir)/15_ostree
|
||||
grub2configdir = $(sysconfdir)/grub.d
|
||||
INSTALL_DATA_HOOKS += install-grub2-config-hook
|
||||
else
|
||||
# We're using our internal generator
|
||||
libexec_SCRIPTS = src/boot/grub2/ostree-grub-generator
|
||||
endif
|
||||
|
||||
EXTRA_DIST += src/boot/dracut/module-setup.sh \
|
||||
|
|
@ -54,4 +57,6 @@ EXTRA_DIST += src/boot/dracut/module-setup.sh \
|
|||
src/boot/mkinitcpio/ostree \
|
||||
src/boot/ostree-prepare-root.service \
|
||||
src/boot/ostree-remount.service \
|
||||
src/boot/grub2/grub2-15_ostree \
|
||||
src/boot/grub2/ostree-grub-generator \
|
||||
$(NULL)
|
||||
|
|
|
|||
|
|
@ -43,9 +43,10 @@ gir_DATA =
|
|||
typelibdir = $(libdir)/girepository-1.0
|
||||
typelib_DATA =
|
||||
gsettings_SCHEMAS =
|
||||
# git.mk
|
||||
GITIGNOREFILES =
|
||||
|
||||
# This is a special facility to chain together hooks easily
|
||||
INSTALL_DATA_HOOKS =
|
||||
install-data-hook: $(INSTALL_DATA_HOOKS)
|
||||
|
||||
ALL_LOCAL_RULES =
|
||||
all-local: $(ALL_LOCAL_RULES)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,12 @@ include $(top_srcdir)/buildutil/glib-tap.mk
|
|||
# include the builddir in $PATH so we find our just-built ostree
|
||||
# binary.
|
||||
TESTS_ENVIRONMENT += OT_TESTS_DEBUG=1 \
|
||||
PATH=$$(cd $(top_builddir) && pwd):$${PATH}
|
||||
GI_TYPELIB_PATH=$$(cd $(top_builddir) && pwd) \
|
||||
LD_LIBRARY_PATH=$$(cd $(top_builddir)/.libs && pwd) \
|
||||
PATH=$$(cd $(top_builddir) && pwd):$${PATH} \
|
||||
$(NULL)
|
||||
|
||||
uninstalled_test_scripts = tests/test-abi.sh
|
||||
|
||||
test_scripts = \
|
||||
tests/test-basic.sh \
|
||||
|
|
@ -35,6 +40,7 @@ test_scripts = \
|
|||
tests/test-export.sh \
|
||||
tests/test-help.sh \
|
||||
tests/test-libarchive.sh \
|
||||
tests/test-parent.sh \
|
||||
tests/test-pull-archive-z.sh \
|
||||
tests/test-pull-commit-only.sh \
|
||||
tests/test-pull-corruption.sh \
|
||||
|
|
@ -44,6 +50,8 @@ test_scripts = \
|
|||
tests/test-pull-metalink.sh \
|
||||
tests/test-pull-summary-sigs.sh \
|
||||
tests/test-pull-resume.sh \
|
||||
tests/test-pull-untrusted.sh \
|
||||
tests/test-local-pull.sh \
|
||||
tests/test-local-pull-depth.sh \
|
||||
tests/test-gpg-signed-commit.sh \
|
||||
tests/test-admin-upgrade-unconfigured.sh \
|
||||
|
|
@ -53,6 +61,7 @@ test_scripts = \
|
|||
tests/test-admin-deploy-switch.sh \
|
||||
tests/test-admin-deploy-etcmerge-cornercases.sh \
|
||||
tests/test-admin-deploy-uboot.sh \
|
||||
tests/test-admin-deploy-grub2.sh \
|
||||
tests/test-admin-instutil-set-kargs.sh \
|
||||
tests/test-admin-upgrade-not-backwards.sh \
|
||||
tests/test-admin-pull-deploy-commit.sh \
|
||||
|
|
@ -85,13 +94,13 @@ installed_test_data = tests/archive-test.sh \
|
|||
tests/admin-test.sh \
|
||||
tests/basic-test.sh \
|
||||
tests/test-basic-user.sh \
|
||||
tests/test-local-pull.sh \
|
||||
tests/corrupt-repo-ref.js \
|
||||
tests/pre-endian-deltas-repo-big.tar.xz \
|
||||
tests/pre-endian-deltas-repo-little.tar.xz \
|
||||
$(NULL)
|
||||
|
||||
test_extra_scripts = tests/syslinux-entries-crosscheck.py
|
||||
test_extra_scripts = tests/bootloader-entries-crosscheck.py \
|
||||
tests/ostree-grub-generator
|
||||
|
||||
# We can't use nobase_ as we need to strip off the tests/, can't
|
||||
# use plain installed_ as we do need the gpghome/ prefix.
|
||||
|
|
@ -123,6 +132,9 @@ libreaddir_rand_la_SOURCES = tests/readdir-rand.c
|
|||
libreaddir_rand_la_CFLAGS = $(OT_INTERNAL_GIO_UNIX_CFLAGS)
|
||||
libreaddir_rand_la_LIBADD = $(OT_INTERNAL_GIO_UNIX_LIBS)
|
||||
libreaddir_rand_la_LDFLAGS = -avoid-version
|
||||
if !ENABLE_INSTALLED_TESTS
|
||||
libreaddir_rand_la_LDFLAGS += -rpath $(abs_builddir)
|
||||
endif
|
||||
|
||||
test_programs = tests/test-varint tests/test-ot-unix-utils tests/test-bsdiff tests/test-mutable-tree \
|
||||
tests/test-keyfile-utils tests/test-ot-opt-utils tests/test-ot-tool-util \
|
||||
|
|
@ -203,6 +215,7 @@ tests_test_gpg_verify_result_CFLAGS = $(TESTS_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS
|
|||
tests_test_gpg_verify_result_LDADD = $(TESTS_LDADD) $(OT_INTERNAL_GPGME_LIBS)
|
||||
|
||||
EXTRA_DIST += \
|
||||
tests/libostreetest.h \
|
||||
tests/gpg-verify-data/README.md \
|
||||
tests/gpg-verify-data/lgpl2 \
|
||||
tests/gpg-verify-data/lgpl2.sig \
|
||||
|
|
@ -211,6 +224,11 @@ EXTRA_DIST += \
|
|||
tests/gpg-verify-data/trustdb.gpg \
|
||||
tests/gpg-verify-data/gpg.conf
|
||||
|
||||
tests/libreaddir-rand.so: Makefile
|
||||
$(AM_V_GEN) ln -fns ../.libs/libreaddir-rand.so tests
|
||||
ALL_LOCAL_RULES += tests/libreaddir-rand.so
|
||||
CLEANFILES += tests/libreaddir-rand.so
|
||||
|
||||
# Unfortunately the glib test data APIs don't actually handle
|
||||
# non-recursive Automake, so we change our code to canonically look
|
||||
# for tests/ which is just a symlink when installed.
|
||||
|
|
|
|||
|
|
@ -24,11 +24,14 @@ AM_CPPFLAGS += -DDATADIR='"$(datadir)"' -DLIBEXECDIR='"$(libexecdir)"' \
|
|||
-DLOCALEDIR=\"$(datadir)/locale\" -DSYSCONFDIR=\"$(sysconfdir)\" \
|
||||
-DSHORTENED_SYSCONFDIR=\"$(shortened_sysconfdir)\" \
|
||||
-DOSTREE_FEATURES='"$(OSTREE_FEATURES)"' \
|
||||
-DG_LOG_DOMAIN=\"OSTree\" \
|
||||
-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_40 -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_40 \
|
||||
-DSOUP_VERSION_MIN_REQUIRED=SOUP_VERSION_2_40 -DSOUP_VERSION_MAX_ALLOWED=SOUP_VERSION_2_48
|
||||
AM_CFLAGS += $(WARN_CFLAGS)
|
||||
DISTCHECK_CONFIGURE_FLAGS += --enable-gtk-doc --disable-maintainer-mode
|
||||
|
||||
GITIGNOREFILES = aclocal.m4 build-aux/ buildutil/*.m4 config.h.in gtk-doc.make
|
||||
|
||||
SUBDIRS += .
|
||||
|
||||
if ENABLE_GTK_DOC
|
||||
|
|
@ -100,3 +103,5 @@ release-tarball-embedded:
|
|||
$(embed_dependency) embedded-dependencies/libsoup; \
|
||||
mv ostree-embeddeps-$${GITVERSION}.tar{.tmp,}; \
|
||||
gzip -f ostree-embeddeps-$${GITVERSION}.tar
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
|
|
|
|||
|
|
@ -1,2 +1,51 @@
|
|||
ostree*.1
|
||||
ostree*.5
|
||||
*.lo
|
||||
*.o
|
||||
.deps
|
||||
.libs
|
||||
/*.bak
|
||||
/*.gcda
|
||||
/*.gcno
|
||||
/*.orig
|
||||
/*.rej
|
||||
/*.tab.c
|
||||
/*~
|
||||
/.*.sw[nop]
|
||||
/.dirstamp
|
||||
/.gitignore
|
||||
/GPATH
|
||||
/GRTAGS
|
||||
/GSYMS
|
||||
/GTAGS
|
||||
/ID
|
||||
/Makefile
|
||||
/Makefile.in
|
||||
/TAGS
|
||||
/gtkdoc-check.test
|
||||
/html
|
||||
/html-build.stamp
|
||||
/html.stamp
|
||||
/ostree-decl-list.txt
|
||||
/ostree-decl.txt
|
||||
/ostree-undeclared.txt
|
||||
/ostree-undocumented.txt
|
||||
/ostree-unused.txt
|
||||
/ostree.args
|
||||
/ostree.hierarchy
|
||||
/ostree.interfaces
|
||||
/ostree.pdf
|
||||
/ostree.prerequisites
|
||||
/ostree.signals
|
||||
/ostree.types
|
||||
/pdf-build.stamp
|
||||
/pdf.stamp
|
||||
/scan-build.stamp
|
||||
/setup-build.stamp
|
||||
/sgml-build.stamp
|
||||
/sgml.stamp
|
||||
/so_locations
|
||||
/tags
|
||||
/tmpl
|
||||
/tmpl/*.bak
|
||||
/tmpl/ostree-unused.sgml
|
||||
/xml
|
||||
_libs
|
||||
|
|
|
|||
|
|
@ -121,3 +121,5 @@ EXTRA_DIST += \
|
|||
version.xml \
|
||||
ostree-sections.txt \
|
||||
$(NULL)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
||||
|
|
|
|||
|
|
@ -269,6 +269,7 @@ ostree_repo_load_file
|
|||
ostree_repo_load_object_stream
|
||||
ostree_repo_query_object_storage_size
|
||||
ostree_repo_import_object_from
|
||||
ostree_repo_import_object_from_with_trust
|
||||
ostree_repo_delete_object
|
||||
OstreeRepoCommitFilterResult
|
||||
OstreeRepoCommitFilter
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ touch ${tempdir}/.testtmp
|
|||
function cleanup () {
|
||||
if test -n "${TEST_SKIP_CLEANUP:-}"; then
|
||||
echo "Skipping cleanup of ${tempdir}"
|
||||
else if test -f ${tempdir}/.test; then
|
||||
else if test -f ${tempdir}/.testtmp; then
|
||||
rm "${tempdir}" -rf
|
||||
fi
|
||||
fi
|
||||
|
|
|
|||
2
cfg.mk
2
cfg.mk
|
|
@ -1,4 +1,4 @@
|
|||
export VC_LIST_EXCEPT_DEFAULT=^(lib/.*|m4/.*|md5/.*|build-aux/.*|src/gettext\.h|.*ChangeLog|buildutil/.*)$$
|
||||
export VC_LIST_EXCEPT_DEFAULT=^(docs/.*|git.mk|lib/.*|m4/.*|md5/.*|build-aux/.*|src/gettext\.h|.*ChangeLog|buildutil/.*)$$
|
||||
|
||||
local-checks-to-skip = \
|
||||
sc_const_long_option \
|
||||
|
|
|
|||
29
configure.ac
29
configure.ac
|
|
@ -1,5 +1,5 @@
|
|||
AC_PREREQ([2.63])
|
||||
AC_INIT([ostree], [2016.4], [walters@verbum.org])
|
||||
AC_INIT([ostree], [2016.5], [walters@verbum.org])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
AC_CONFIG_MACRO_DIR([buildutil])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
|
|
@ -251,11 +251,23 @@ AS_IF([test "x$with_dracut" = "xyes" || test "x$with_mkinitcpio" = "xyes"], [
|
|||
])
|
||||
AM_CONDITIONAL(BUILDOPT_SYSTEMD, test x$with_systemd = xyes)
|
||||
|
||||
AC_ARG_WITH(grub2,
|
||||
AS_HELP_STRING([--with-grub2],
|
||||
[Install grub2 hook (default: yes)]),,
|
||||
[with_grub2=yes])
|
||||
AM_CONDITIONAL(BUILDOPT_GRUB2, test x$with_grub2 = xyes)
|
||||
AC_ARG_WITH(builtin-grub2-mkconfig,
|
||||
AS_HELP_STRING([--with-builtin-grub2-mkconfig],
|
||||
[Use a builtin minimal grub2-mkconfig to generate a GRUB2 configuration file (default: no)]),,
|
||||
[with_builtin_grub2_mkconfig=no])
|
||||
AM_CONDITIONAL(BUILDOPT_BUILTIN_GRUB2_MKCONFIG, test x$with_builtin_grub2_mkconfig = xyes)
|
||||
AM_COND_IF(BUILDOPT_BUILTIN_GRUB2_MKCONFIG,
|
||||
AC_DEFINE([USE_BUILTIN_GRUB2_MKCONFIG], 1, [Define if using internal ostree-grub-generator]))
|
||||
AC_ARG_WITH(grub2-mkconfig-path,
|
||||
AS_HELP_STRING([--with-grub2-mkconfig-path],
|
||||
[Path to grub2-mkconfig]))
|
||||
AS_IF([test x$with_grub2_mkconfig_path = x], [
|
||||
dnl Otherwise, look for the path to the system generator. On some
|
||||
dnl distributions GRUB2 *-mkconfig executable has 'grub2' prefix and
|
||||
dnl on some 'grub'. We default to grub2-mkconfig.
|
||||
AC_CHECK_PROGS(GRUB2_MKCONFIG, [grub2-mkconfig grub-mkconfig], [grub2-mkconfig])
|
||||
],[GRUB2_MKCONFIG=$with_grub2_mkconfig_path])
|
||||
AC_DEFINE_UNQUOTED([GRUB2_MKCONFIG_PATH], ["$GRUB2_MKCONFIG"], [The system grub2-mkconfig executible name])
|
||||
|
||||
dnl for tests
|
||||
AS_IF([test "x$found_introspection" = xyes], [
|
||||
|
|
@ -293,6 +305,11 @@ echo "
|
|||
gjs-based tests: $have_gjs
|
||||
dracut: $with_dracut
|
||||
mkinitcpio: $with_mkinitcpio"
|
||||
AS_IF([test x$with_builtin_grub2_mkconfig = xyes], [
|
||||
echo " builtin grub2-mkconfig (instead of system): $with_builtin_grub2_mkconfig"
|
||||
], [
|
||||
echo " grub2-mkconfig path: $GRUB2_MKCONFIG"
|
||||
])
|
||||
AS_IF([test "x$with_systemd" = "xyes"], [
|
||||
echo " systemd unit dir: $with_systemdsystemunitdir"
|
||||
])
|
||||
|
|
|
|||
|
|
@ -47,50 +47,50 @@ func GoBool(b C.gboolean) bool {
|
|||
}
|
||||
|
||||
type GError struct {
|
||||
ptr unsafe.Pointer
|
||||
ptr unsafe.Pointer
|
||||
}
|
||||
|
||||
func NewGError() GError {
|
||||
return GError{nil}
|
||||
return GError{nil}
|
||||
}
|
||||
|
||||
func (e *GError) Native() *C.GError {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
return (*C.GError)(e.ptr)
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
return (*C.GError)(e.ptr)
|
||||
}
|
||||
|
||||
func ConvertGError(e *C.GError) error {
|
||||
defer C.g_error_free(e)
|
||||
return errors.New(C.GoString((*C.char)(C._g_error_get_message(e))))
|
||||
defer C.g_error_free(e)
|
||||
return errors.New(C.GoString((*C.char)(C._g_error_get_message(e))))
|
||||
}
|
||||
|
||||
type GType uint
|
||||
|
||||
func (t GType) Name() string {
|
||||
return C.GoString((*C.char)(C.g_type_name(C.GType(t))))
|
||||
return C.GoString((*C.char)(C.g_type_name(C.GType(t))))
|
||||
}
|
||||
|
||||
|
||||
type GVariant struct {
|
||||
ptr unsafe.Pointer
|
||||
ptr unsafe.Pointer
|
||||
}
|
||||
|
||||
func GVariantNew(p unsafe.Pointer) *GVariant {
|
||||
o := &GVariant{p}
|
||||
runtime.SetFinalizer(o, (*GVariant).Unref)
|
||||
return o;
|
||||
o := &GVariant{p}
|
||||
runtime.SetFinalizer(o, (*GVariant).Unref)
|
||||
return o;
|
||||
}
|
||||
|
||||
func GVariantNewSink(p unsafe.Pointer) *GVariant {
|
||||
o := &GVariant{p}
|
||||
runtime.SetFinalizer(o, (*GVariant).Unref)
|
||||
o.RefSink()
|
||||
return o;
|
||||
o := &GVariant{p}
|
||||
runtime.SetFinalizer(o, (*GVariant).Unref)
|
||||
o.RefSink()
|
||||
return o;
|
||||
}
|
||||
|
||||
func (v *GVariant) native() *C.GVariant {
|
||||
return (*C.GVariant)(v.ptr);
|
||||
return (*C.GVariant)(v.ptr);
|
||||
}
|
||||
|
||||
func (v *GVariant) Ref() {
|
||||
|
|
@ -98,7 +98,7 @@ func (v *GVariant) Ref() {
|
|||
}
|
||||
|
||||
func (v *GVariant) Unref() {
|
||||
C.g_variant_unref(v.native())
|
||||
C.g_variant_unref(v.native())
|
||||
}
|
||||
|
||||
func (v *GVariant) RefSink() {
|
||||
|
|
@ -116,14 +116,14 @@ func (v *GVariant) GetChildValue(i int) *GVariant {
|
|||
}
|
||||
|
||||
func (v *GVariant) LookupString(key string) (string, error) {
|
||||
ckey := C.CString(key)
|
||||
defer C.free(unsafe.Pointer(ckey))
|
||||
// TODO: Find a way to have constant C strings in golang
|
||||
cstr := C._g_variant_lookup_string(v.native(), ckey)
|
||||
if cstr == nil {
|
||||
return "", fmt.Errorf("No such key: %s", key)
|
||||
}
|
||||
return C.GoString(cstr), nil
|
||||
ckey := C.CString(key)
|
||||
defer C.free(unsafe.Pointer(ckey))
|
||||
// TODO: Find a way to have constant C strings in golang
|
||||
cstr := C._g_variant_lookup_string(v.native(), ckey)
|
||||
if cstr == nil {
|
||||
return "", fmt.Errorf("No such key: %s", key)
|
||||
}
|
||||
return C.GoString(cstr), nil
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -144,9 +144,9 @@ type GObject struct {
|
|||
}
|
||||
|
||||
func GObjectNew(p unsafe.Pointer) *GObject {
|
||||
o := &GObject{p}
|
||||
runtime.SetFinalizer(o, (*GObject).Unref)
|
||||
return o;
|
||||
o := &GObject{p}
|
||||
runtime.SetFinalizer(o, (*GObject).Unref)
|
||||
return o;
|
||||
}
|
||||
|
||||
func (v *GObject) Ptr() unsafe.Pointer {
|
||||
|
|
@ -172,7 +172,7 @@ func (v *GObject) Ref() {
|
|||
}
|
||||
|
||||
func (v *GObject) Unref() {
|
||||
C.g_object_unref(C.gpointer(v.ptr))
|
||||
C.g_object_unref(C.gpointer(v.ptr))
|
||||
}
|
||||
|
||||
func (v *GObject) RefSink() {
|
||||
|
|
@ -191,7 +191,7 @@ func (v *GObject) ForceFloating() {
|
|||
// GIO types
|
||||
|
||||
type GCancellable struct {
|
||||
*GObject
|
||||
*GObject
|
||||
}
|
||||
|
||||
func (self *GCancellable) native() *C.GCancellable {
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@ import (
|
|||
import "C"
|
||||
|
||||
type Repo struct {
|
||||
*GObject
|
||||
*GObject
|
||||
}
|
||||
|
||||
func RepoGetType() GType {
|
||||
return GType(C.ostree_repo_get_type())
|
||||
return GType(C.ostree_repo_get_type())
|
||||
}
|
||||
|
||||
func (r *Repo) native() *C.OstreeRepo {
|
||||
|
|
@ -28,67 +28,67 @@ func (r *Repo) native() *C.OstreeRepo {
|
|||
}
|
||||
|
||||
func repoFromNative(p *C.OstreeRepo) *Repo {
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
o := GObjectNew(unsafe.Pointer(p))
|
||||
r := &Repo{o}
|
||||
return r
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
o := GObjectNew(unsafe.Pointer(p))
|
||||
r := &Repo{o}
|
||||
return r
|
||||
}
|
||||
|
||||
func RepoNewOpen(path string) (*Repo, error) {
|
||||
var cerr *C.GError = nil
|
||||
cpath := C.CString(path)
|
||||
pathc := C.g_file_new_for_path(cpath);
|
||||
defer C.g_object_unref(C.gpointer(pathc))
|
||||
crepo := C.ostree_repo_new(pathc)
|
||||
repo := repoFromNative(crepo);
|
||||
r := GoBool(C.ostree_repo_open(repo.native(), nil, &cerr))
|
||||
if !r {
|
||||
return nil, ConvertGError(cerr)
|
||||
}
|
||||
return repo, nil
|
||||
var cerr *C.GError = nil
|
||||
cpath := C.CString(path)
|
||||
pathc := C.g_file_new_for_path(cpath);
|
||||
defer C.g_object_unref(C.gpointer(pathc))
|
||||
crepo := C.ostree_repo_new(pathc)
|
||||
repo := repoFromNative(crepo);
|
||||
r := GoBool(C.ostree_repo_open(repo.native(), nil, &cerr))
|
||||
if !r {
|
||||
return nil, ConvertGError(cerr)
|
||||
}
|
||||
return repo, nil
|
||||
}
|
||||
|
||||
func (r *Repo) GetParent() *Repo {
|
||||
return repoFromNative(C.ostree_repo_get_parent(r.native()))
|
||||
return repoFromNative(C.ostree_repo_get_parent(r.native()))
|
||||
}
|
||||
|
||||
type ObjectType int
|
||||
|
||||
const (
|
||||
OBJECT_TYPE_FILE ObjectType = C.OSTREE_OBJECT_TYPE_FILE
|
||||
OBJECT_TYPE_DIR_TREE = C.OSTREE_OBJECT_TYPE_DIR_TREE
|
||||
OBJECT_TYPE_DIR_META = C.OSTREE_OBJECT_TYPE_DIR_META
|
||||
OBJECT_TYPE_COMMIT = C.OSTREE_OBJECT_TYPE_COMMIT
|
||||
OBJECT_TYPE_TOMBSTONE_COMMIT = C.OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT
|
||||
OBJECT_TYPE_FILE ObjectType = C.OSTREE_OBJECT_TYPE_FILE
|
||||
OBJECT_TYPE_DIR_TREE = C.OSTREE_OBJECT_TYPE_DIR_TREE
|
||||
OBJECT_TYPE_DIR_META = C.OSTREE_OBJECT_TYPE_DIR_META
|
||||
OBJECT_TYPE_COMMIT = C.OSTREE_OBJECT_TYPE_COMMIT
|
||||
OBJECT_TYPE_TOMBSTONE_COMMIT = C.OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT
|
||||
)
|
||||
|
||||
func (repo *Repo) LoadVariant(t ObjectType, checksum string) (*GVariant, error) {
|
||||
var cerr *C.GError = nil
|
||||
var cvariant *C.GVariant = nil
|
||||
var cerr *C.GError = nil
|
||||
var cvariant *C.GVariant = nil
|
||||
|
||||
r := GoBool(C.ostree_repo_load_variant(repo.native(), C.OstreeObjectType(t), C.CString(checksum), &cvariant, &cerr))
|
||||
if !r {
|
||||
return nil, ConvertGError(cerr)
|
||||
}
|
||||
variant := GVariantNew(unsafe.Pointer(cvariant))
|
||||
return variant, nil
|
||||
r := GoBool(C.ostree_repo_load_variant(repo.native(), C.OstreeObjectType(t), C.CString(checksum), &cvariant, &cerr))
|
||||
if !r {
|
||||
return nil, ConvertGError(cerr)
|
||||
}
|
||||
variant := GVariantNew(unsafe.Pointer(cvariant))
|
||||
return variant, nil
|
||||
}
|
||||
|
||||
func (repo *Repo) ResolveRev(ref string) (string, error) {
|
||||
var cerr *C.GError = nil
|
||||
var crev *C.char = nil
|
||||
var cerr *C.GError = nil
|
||||
var crev *C.char = nil
|
||||
|
||||
r := GoBool(C.ostree_repo_resolve_rev(repo.native(), C.CString(ref), GBool(true), &crev, &cerr))
|
||||
if !r {
|
||||
return "", ConvertGError(cerr)
|
||||
}
|
||||
defer C.free(unsafe.Pointer(crev))
|
||||
return C.GoString(crev), nil
|
||||
r := GoBool(C.ostree_repo_resolve_rev(repo.native(), C.CString(ref), GBool(true), &crev, &cerr))
|
||||
if !r {
|
||||
return "", ConvertGError(cerr)
|
||||
}
|
||||
defer C.free(unsafe.Pointer(crev))
|
||||
return C.GoString(crev), nil
|
||||
}
|
||||
|
||||
func (commit *GVariant) CommitGetMetadataKeyString(key string) (string, error) {
|
||||
cmeta := GVariantNew(unsafe.Pointer(C.g_variant_get_child_value(commit.native(), 0)))
|
||||
return cmeta.LookupString(key)
|
||||
cmeta := GVariantNew(unsafe.Pointer(C.g_variant_get_child_value(commit.native(), 0)))
|
||||
return cmeta.LookupString(key)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,47 +9,47 @@ import (
|
|||
)
|
||||
|
||||
func TestTypeName(t *testing.T) {
|
||||
name := RepoGetType().Name();
|
||||
if name != "OstreeRepo" {
|
||||
t.Errorf("%s != OstreeRepo");
|
||||
}
|
||||
name := RepoGetType().Name();
|
||||
if name != "OstreeRepo" {
|
||||
t.Errorf("%s != OstreeRepo");
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepoNew(t *testing.T) {
|
||||
r, err := RepoNewOpen("/ostree/repo")
|
||||
if err != nil {
|
||||
t.Errorf("%s", err);
|
||||
return
|
||||
}
|
||||
parent := r.GetParent()
|
||||
if parent != nil {
|
||||
t.Errorf("Expected no parent")
|
||||
return
|
||||
}
|
||||
r, err := RepoNewOpen("/ostree/repo")
|
||||
if err != nil {
|
||||
t.Errorf("%s", err);
|
||||
return
|
||||
}
|
||||
parent := r.GetParent()
|
||||
if parent != nil {
|
||||
t.Errorf("Expected no parent")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepoGetMetadataVersion(t *testing.T) {
|
||||
r, err := RepoNewOpen("/ostree/repo")
|
||||
if err != nil {
|
||||
t.Errorf("%s", err);
|
||||
return
|
||||
}
|
||||
commit,err := r.ResolveRev("rhel-atomic-host/7/x86_64/standard")
|
||||
if err != nil {
|
||||
t.Errorf("%s", err)
|
||||
return
|
||||
}
|
||||
commitv,err := r.LoadVariant(OBJECT_TYPE_COMMIT, commit)
|
||||
if err != nil {
|
||||
t.Errorf("%s", err)
|
||||
return
|
||||
}
|
||||
ver, err := commitv.CommitGetMetadataKeyString("version")
|
||||
if err != nil {
|
||||
t.Errorf("%s", err)
|
||||
return
|
||||
}
|
||||
if ver != "7.1.3" {
|
||||
t.Errorf("expected 7.1.3")
|
||||
}
|
||||
r, err := RepoNewOpen("/ostree/repo")
|
||||
if err != nil {
|
||||
t.Errorf("%s", err);
|
||||
return
|
||||
}
|
||||
commit,err := r.ResolveRev("rhel-atomic-host/7/x86_64/standard")
|
||||
if err != nil {
|
||||
t.Errorf("%s", err)
|
||||
return
|
||||
}
|
||||
commitv,err := r.LoadVariant(OBJECT_TYPE_COMMIT, commit)
|
||||
if err != nil {
|
||||
t.Errorf("%s", err)
|
||||
return
|
||||
}
|
||||
ver, err := commitv.CommitGetMetadataKeyString("version")
|
||||
if err != nil {
|
||||
t.Errorf("%s", err)
|
||||
return
|
||||
}
|
||||
if ver != "7.1.3" {
|
||||
t.Errorf("expected 7.1.3")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,46 @@
|
|||
Submitting patches
|
||||
------------------
|
||||
|
||||
You can:
|
||||
A majority of current maintainers prefer the Github pull request
|
||||
model, and this motivated moving the primary git repository to
|
||||
<https://github.com/ostreedev/ostree>.
|
||||
|
||||
However, we do not use the "Merge pull request" button, because we do
|
||||
not like merge commits for one-patch pull requests, among other
|
||||
reasons. See [this issue](https://github.com/isaacs/github/issues/2)
|
||||
for more information. Instead, we use an instance of
|
||||
[Homu](https://github.com/servo/homu), currently known as
|
||||
`cgwalters-bot`.
|
||||
|
||||
As a review proceeeds, the preferred method is to push `fixup!`
|
||||
commits via `git commit --fixup`. Homu knows how to use
|
||||
`--autosquash` when performing the final merge. See the
|
||||
[Git documentation](https://git-scm.com/docs/git-rebase]) for more
|
||||
information.
|
||||
|
||||
Alternative methods if you don't like Github (also fully supported):
|
||||
|
||||
1. Send mail to <ostree-list@gnome.org>, with the patch attached
|
||||
1. Submit a pull request against <https://github.com/GNOME/ostree>
|
||||
1. Attach them to <https://bugzilla.gnome.org/>
|
||||
|
||||
Please look at `git log` and match the commit log style.
|
||||
It is likely however once a patch is ready to apply a maintainer
|
||||
will push it to a github PR, and merge via Homu.
|
||||
|
||||
Commit message style
|
||||
--------------------
|
||||
|
||||
Please look at `git log` and match the commit log style, which is very
|
||||
similar to the
|
||||
[Linux kernel](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git).
|
||||
|
||||
You may use `Signed-off-by`, but we're not requiring it.
|
||||
|
||||
Running the test suite
|
||||
----------------------
|
||||
|
||||
Currently, OSTree uses <https://wiki.gnome.org/GnomeGoals/InstalledTests>
|
||||
|
||||
To run just OSTree's tests:
|
||||
|
||||
./configure ... --enable-installed-tests
|
||||
gnome-desktop-testing-runner -p 0 ostree/
|
||||
|
||||
Also, there is a regular:
|
||||
|
||||
make check
|
||||
|
||||
That runs a different set of tests.
|
||||
OSTree uses both `make check` and supports the
|
||||
[Installed Tests](https://wiki.gnome.org/GnomeGoals/InstalledTests)
|
||||
model as well (if `--enable-installed-tests` is provided).
|
||||
|
||||
Coding style
|
||||
------------
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ deployment.
|
|||
Because OSTree only preserves `/var` across upgrades (each
|
||||
deployment's chroot directory will be garbage collected
|
||||
eventually), you will need to choose how to handle other
|
||||
toplevel writable directories specified by the [Filesystem Hierarchy Standard](http://www.pathname.com/fhs/")
|
||||
toplevel writable directories specified by the [Filesystem Hierarchy Standard](http://www.pathname.com/fhs/).
|
||||
Your operating system may of course choose
|
||||
not to support some of these such as `/usr/local`, but following is the
|
||||
recommended set:
|
||||
|
|
@ -37,9 +37,9 @@ recommended set:
|
|||
- `/tmp` → `/sysroot/tmp`
|
||||
|
||||
Furthermore, since `/var` is empty by default, your operating system
|
||||
will need to dynamically create the <emphasis>targets</emphasis> of
|
||||
these at boot. A good way to do this is using `systemd-tmpfiles`, if
|
||||
your OS uses systemd. For example:
|
||||
will need to dynamically create the *targets* of these at boot. A
|
||||
good way to do this is using `systemd-tmpfiles`, if your OS uses
|
||||
systemd. For example:
|
||||
|
||||
```
|
||||
d /var/log/journal 0755 root root -
|
||||
|
|
@ -64,10 +64,10 @@ d /run/media 0755 root root -
|
|||
Particularly note here the double indirection of `/home`. By default,
|
||||
each deployment will share the global toplevel `/home` directory on
|
||||
the physical root filesystem. It is then up to higher levels of
|
||||
management tools to keep <filename>/etc/passwd</filename> or
|
||||
equivalent synchronized between operating systems. Each deployment
|
||||
can easily be reconfigured to have its own home directory set simply
|
||||
by making `/var/home` a real directory. </chapter>
|
||||
management tools to keep `/etc/passwd` or equivalent synchronized
|
||||
between operating systems. Each deployment can easily be reconfigured
|
||||
to have its own home directory set simply by making `/var/home` a real
|
||||
directory.
|
||||
|
||||
## Booting and initramfs technology
|
||||
|
||||
|
|
@ -144,11 +144,11 @@ these new packages on top. A command like this:
|
|||
|
||||
```
|
||||
ostree commit -b osname/releasename/description
|
||||
--tree=ref=$osname/releasename/description
|
||||
--tree=ref=$osname/$releasename/$description
|
||||
--tree=dir=/var/tmp/newpackages.13A8D0/
|
||||
```
|
||||
|
||||
will create a new commit in the `$osname/releasename/description`
|
||||
will create a new commit in the `$osname/$releasename/$description`
|
||||
branch. The OSTree SHA256 checksum of all the files in
|
||||
`/var/tmp/newpackages.13A8D0/` will be computed, but we will not
|
||||
re-checksum the present existing tree. In this layering model,
|
||||
|
|
@ -156,4 +156,4 @@ earlier directories will take precedence, but files in later layers
|
|||
will silently override earlier layers.
|
||||
|
||||
Then to actually deploy this tree for the next boot:
|
||||
`ostree admin deploy <replaceable>osname/releasename/description`
|
||||
`ostree admin deploy $osname/$releasename/$description`
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ implements this.
|
|||
To begin a simple upgrade, OSTree fetches the contents of the ref from
|
||||
the remote server. Suppose we're tracking a ref named
|
||||
`exampleos/buildmaster/x86_64-runtime`. OSTree fetches the URL
|
||||
`http://$example.com/repo/refs/exampleos/buildmaster/x86_64-runtime`,
|
||||
`http://example.com/repo/refs/exampleos/buildmaster/x86_64-runtime`,
|
||||
which contains a SHA256 checksum. This determines the tree to deploy,
|
||||
and `/etc` will be merged from currently booted tree.
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ we need to perform a deployment.
|
|||
|
||||
As mentioned in the introduction, OSTree is also designed to allow a
|
||||
model where filesystem trees are computed on the client. It is
|
||||
completely agnostic as to how those trees are generated; hey could be
|
||||
completely agnostic as to how those trees are generated; they could be
|
||||
computed with traditional packages, packages with post-deployment
|
||||
scripts on top, or built by developers directly from revision control
|
||||
locally, etc.
|
||||
|
|
@ -58,7 +58,7 @@ Given a commit to deploy, OSTree first allocates a directory for
|
|||
it. This is of the form `/boot/loader/entries/ostree-$osname-$checksum.$serial.conf`.
|
||||
The `$serial` is normally 0, but if a
|
||||
given commit is deployed more than once, it will be incremented.
|
||||
his is supported because the previous deployment may have
|
||||
This is supported because the previous deployment may have
|
||||
configuration in `/etc` that we do not want to use or overwrite.
|
||||
|
||||
Now that we have a deployment directory, a 3-way merge is
|
||||
|
|
@ -94,7 +94,7 @@ collected at any point.
|
|||
|
||||
## The /ostree/boot directory
|
||||
|
||||
However, we want to optimize for the case where we the set of
|
||||
However, we want to optimize for the case where the set of
|
||||
kernel/initramfs pairs is the same between both the old and new
|
||||
deployment lists. This happens when doing an upgrade that does not
|
||||
include the kernel; think of a simple translation update. OSTree
|
||||
|
|
@ -106,11 +106,11 @@ automatically remount read-write just for the portion of time
|
|||
necessary to update the bootloader configuration.
|
||||
|
||||
To implement this, OSTree also maintains the directory
|
||||
`/ostree/boot.<replaceable>bootversion</replaceable>`, which is a set
|
||||
`/ostree/boot.$bootversion`, which is a set
|
||||
of symbolic links to the deployment directories. The
|
||||
<replaceable>bootversion</replaceable> here must match the version of
|
||||
`$bootversion` here must match the version of
|
||||
`/boot`. However, in order to allow atomic transitions of
|
||||
<emphasis>this</emphasis> directory, this is also a swapped directory,
|
||||
*this* directory, this is also a swapped directory,
|
||||
so just like `/boot`, it has a version of `0` or `1` appended.
|
||||
|
||||
Each bootloader entry has a special `ostree=` argument which refers to
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ But let's discuss building our own. If you're just experimenting,
|
|||
it's quite easy to start with the command line. We'll assume for this
|
||||
purpose that you have a build process that outputs a directory tree -
|
||||
we'll call this tool `$pkginstallroot` (which could be `yum
|
||||
--installroot` or `dbootstrap`, etc.).
|
||||
--installroot` or `debootstrap`, etc.).
|
||||
|
||||
Your initial prototype is going to look like:
|
||||
|
||||
|
|
@ -132,7 +132,7 @@ the desired version).
|
|||
Now, to construct our final tree:
|
||||
|
||||
```
|
||||
rm exampleos-build -rf
|
||||
rm -rf exampleos-build
|
||||
for package in bash systemd; do
|
||||
ostree --repo=build-repo checkout -U --union exampleos/x86_64/${package} exampleos-build
|
||||
done
|
||||
|
|
@ -178,3 +178,8 @@ commit.
|
|||
```
|
||||
ostree --repo=repo static-delta generate exampleos/x86_64/standard
|
||||
```
|
||||
|
||||
## More sophisticated repository management
|
||||
|
||||
Next, see [Repository Management](repository-management.md) for the
|
||||
next steps in managing content in OSTree repositories.
|
||||
|
|
|
|||
|
|
@ -54,9 +54,9 @@ to avoid computing checksums on the client by default.
|
|||
The deployment should not have a traditional UNIX `/etc`; instead, it
|
||||
should include `/usr/etc`. This is the "default configuration". When
|
||||
OSTree creates a deployment, it performs a 3-way merge using the
|
||||
<emphasis>old</emphasis> default configuration, the active system's
|
||||
`/etc`, and the new default configuration. In the final filesystem
|
||||
tree for a deployment then, `/etc` is a regular writable directory.
|
||||
*old* default configuration, the active system's `/etc`, and the new
|
||||
default configuration. In the final filesystem tree for a deployment
|
||||
then, `/etc` is a regular writable directory.
|
||||
|
||||
Besides the exceptions of `/var` and `/etc` then, the rest of the
|
||||
contents of the tree are checked out as hard links into the
|
||||
|
|
@ -87,4 +87,4 @@ deployment.
|
|||
|
||||
At present, not all bootloaders implement the BootLoaderSpec, so
|
||||
OSTree contains code for some of these to regenerate native config
|
||||
files (such as `/boot/syslinux/syslinux.conf` based on the entries.
|
||||
files (such as `/boot/syslinux/syslinux.conf`) based on the entries.
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ date, and relatively agnostic.
|
|||
Broadly speaking, projects in this area fall into two camps; either
|
||||
a tool to snapshot systems on the client side (dpkg/rpm + BTRFS/LVM),
|
||||
or a tool to compose on a server and replicate (ChromiumOS, Clear
|
||||
Linux). OSTree is flexible enough to do both.
|
||||
Linux). OSTree is flexible enough to do both.
|
||||
|
||||
## Combining dpkg/rpm + (BTRFS/LVM)
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ awareness of BTRFS in dpkg/rpm itself) will be required.
|
|||
The OSTree author believes that having total freedom at the block
|
||||
storage layer is better for general purpose operating systems. For
|
||||
example, with OSTree, one is free to use BTRFS in any way you like -
|
||||
you can use a subvolume for `/home`, or you can not.
|
||||
you may decide to use a subvolume for `/home`, or not.
|
||||
|
||||
Furthermore, in its most basic incarnation, the rpm/dpkg + BTRFS
|
||||
doesn't solve the race conditions that happen when unpacking packages
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ two different generated filesystem trees. In this example, the
|
|||
"runtime" tree contains just enough to run a basic system, and
|
||||
"devel-debug" contains all of the developer tools and debuginfo.
|
||||
|
||||
The `ostree` supports a simple syntax using the carat `^` to refer to
|
||||
The `ostree` supports a simple syntax using the caret `^` to refer to
|
||||
the parent of a given commit. For example,
|
||||
`exampleos/buildmaster/x86_64-runtime^` refers to the previous build,
|
||||
and `exampleos/buildmaster/x86_64-runtime^^` refers to the one before
|
||||
|
|
|
|||
|
|
@ -0,0 +1,211 @@
|
|||
# Managing content in OSTree repositories
|
||||
|
||||
Once you have a build system going, if you actually want client
|
||||
systems to retrieve the content, you will quickly feel a need for
|
||||
"repository management".
|
||||
|
||||
OSTree itself does not currently come with tools to do this. One
|
||||
reason is that how content is delivered and managed has concerns very
|
||||
specific to the organization. For example, some operating system
|
||||
content vendors may want integration with a specific errata
|
||||
notification system.
|
||||
|
||||
In this section, we will describe some high level ideas and methods
|
||||
for managing content in OSTree repositories, mostly independent of any
|
||||
particular model or tool. That said, a goal is to include at least
|
||||
some sample scripts and workflows upstream in a potential new
|
||||
"contrib" git repository.
|
||||
|
||||
One example of software which can assist in managing OSTree
|
||||
repositories today is the [Pulp Project](http://www.pulpproject.org/),
|
||||
which has a
|
||||
[Pulp OSTree plugin](https://pulp-ostree.readthedocs.org/en/latest/).
|
||||
|
||||
## Separate development vs release repositories
|
||||
|
||||
By default, OSTree accumulates server side history. This is actually
|
||||
optional in that your build system can (using the API) write a commit
|
||||
with no parent. But first, we'll investigate the ramifications of
|
||||
server side history.
|
||||
|
||||
Many content vendors will want to separate their internal development
|
||||
with what is made public to the world. Therefore, you will want (at
|
||||
least) two OSTree repositories, we'll call them "dev" and "prod".
|
||||
|
||||
To phrase this another way, let's say you have a continuous delivery
|
||||
system which is building from git and committing into your "dev"
|
||||
OSTree repository. This might happen tens to hundreds of times per
|
||||
day. That's a substantial amount of history over time, and it's
|
||||
unlikely most of your content consumers (i.e. not developers/testers)
|
||||
will be interested in all of it.
|
||||
|
||||
The original vision of OSTree was to fulfill this "dev" role, and in
|
||||
particular the "archive-z2" format was designed for it.
|
||||
|
||||
Then, what you'll want to do is promote content from "dev" to "prod".
|
||||
We'll discuss this later, but first, let's talk about promotion
|
||||
*inside* our "dev" repository.
|
||||
|
||||
## Promoting content along OSTree branches - "buildmaster", "smoketested"
|
||||
|
||||
Besides multiple repositories, OSTree also supports multiple branches
|
||||
inside one repository, equivalent to git's branches. We saw in an
|
||||
earlier section an example branch name like
|
||||
`exampleos/x86_64/standard`. Choosing the branch name for your "prod"
|
||||
repository is absolutely critical as client systems will reference it.
|
||||
It becomes an important part of your face to the world, in the same
|
||||
way the "master" branch in a git repository is.
|
||||
|
||||
But with your "dev" repository internally, it can be very useful to
|
||||
use OSTree's branching concepts to represent different stages in a
|
||||
software delivery pipeline.
|
||||
|
||||
Deriving from `exampleos/x86_64/standard`, let's say our "dev"
|
||||
repository contains `exampleos/x86_64/buildmaster/standard`. We choose the
|
||||
term "buildmaster" to represent something that came straight from git
|
||||
master. It may not be tested very much.
|
||||
|
||||
Our next step should be to hook up a testing system (Jenkins,
|
||||
Buildbot, etc.) to this. When a build (commit) passes some tests, we
|
||||
want to "promote" that commit. Let's create a new branch called
|
||||
`smoketested` to say that some basic sanity checks pass on the
|
||||
complete system. This might be where human testers get involved, for
|
||||
example.
|
||||
|
||||
The build system can "promote" the `buildmaster` commit that passed
|
||||
testing like this:
|
||||
|
||||
```
|
||||
ostree commit -b exampleos/x86_64/smoketested/standard -s 'Passed tests' --tree=ref=aec070645fe53...
|
||||
```
|
||||
|
||||
Here we're generating a new commit object (perhaps include in the commit
|
||||
log links to build logs, etc.), but we're reusing the *content* from the `buildmaster`
|
||||
commit `aec070645fe53` that passed the smoketests.
|
||||
|
||||
We can easily generalize this model to have an arbitrary number of
|
||||
stages like `exampleos/x86_64/stage-1-pass/standard`,
|
||||
`exampleos/x86_64/stage-2-pass/standard`, etc. depending on business
|
||||
requirements and logic.
|
||||
|
||||
In this suggested model, the "stages" are increasingly expensive. The
|
||||
logic is that we don't want to spend substantial time on e.g. network
|
||||
performance tests if something basic like a systemd unit file fails on
|
||||
bootup.
|
||||
|
||||
|
||||
## Promoting content between OSTree repositories
|
||||
|
||||
Now, we have our internal continuous delivery stream flowing, it's
|
||||
being tested and works. We want to periodically take the latest
|
||||
commit on `exampleos/x86_64/stage-3-pass/standard` and expose it in
|
||||
our "prod" repository as `exampleos/x86_64/standard`, with a much
|
||||
smaller history.
|
||||
|
||||
We'll have other business requirements such as writing release notes
|
||||
(and potentially putting them in the OSTree commit message), etc.
|
||||
|
||||
In [Build Systems](buildsystem-and-repos.md) we saw how the
|
||||
`pull-local` command can be used to migrate content from the "build"
|
||||
repository (in `bare-user` mode) into an `archive-z2` repository for
|
||||
serving to client systems.
|
||||
|
||||
Following this section, we now have three repositories, let's call
|
||||
them `repo-build`, `repo-dev`, and `repo-prod`. We've been pulling
|
||||
content from `repo-build` into `repo-dev` (which involves gzip
|
||||
compression among other things since it is a format change).
|
||||
|
||||
When using `pull-local` to migrate content between two `archive-z2`
|
||||
repositories, the binary content is taken unmodified. Let's go ahead
|
||||
and generate a new commit in our prod repository:
|
||||
|
||||
```
|
||||
checksum=$(ostree --repo=repo-dev rev-parse exampleos/x86_64/stage-3-pass/standard`)
|
||||
ostree --repo=repo-prod pull-local repo-dev ${checksum}
|
||||
ostree --repo=repo-prod commit -b exampleos/x86_64/standard \
|
||||
-s 'Release 1.2.3' --add-metadata-string=ostree.version=1.2.3 \
|
||||
--tree=ref=${checksum}
|
||||
```
|
||||
|
||||
There are a few things going on here. First, we found the latest
|
||||
commit checksum for the "stage-3 dev", and told `pull-local` to copy
|
||||
it, without using the branch name. We do this because we don't want
|
||||
to expose the `exampleos/x86_64/stage-3-pass/standard` branch name in
|
||||
our "prod" repository.
|
||||
|
||||
Next, we generate a new commit in prod that's referencing the exact
|
||||
binary content in dev. If the "dev" and "prod" repositories are on
|
||||
the same Unix filesystem, (like git) OSTree will make use of hard
|
||||
links to avoid copying any content at all - making the process very
|
||||
fast.
|
||||
|
||||
Another interesting thing to notice here is that we're adding an
|
||||
`ostree.version` metadata string to the commit. This is an optional
|
||||
piece of metadata, but we are encouraging its use in the OSTree
|
||||
ecosystem of tools. Commands like `ostree admin status` show it by
|
||||
default.
|
||||
|
||||
## Derived data - static deltas and the summary file
|
||||
|
||||
As discussed in [Formats](formats.md), the `archive-z2` repository we
|
||||
use for "prod" requires one HTTP fetch per client request by default.
|
||||
If we're only performing a release e.g. once a week, it's appropriate
|
||||
to use "static deltas" to speed up client updates.
|
||||
|
||||
So once we've used the above command to pull content from `repo-dev`
|
||||
into `repo-prod`, let's generate a delta against the previous commit:
|
||||
|
||||
```
|
||||
ostree --repo=repo-prod static-delta generate exampleos/x86_64/standard
|
||||
```
|
||||
|
||||
We may also want to support client systems upgrading from *two*
|
||||
commits previous.
|
||||
|
||||
```
|
||||
ostree --repo=repo-prod static-delta generate --from=exampleos/x86_64/standard^^ --to=exampleos/x86_64/standard
|
||||
```
|
||||
|
||||
Generating a full permutation of deltas across all prior versions can
|
||||
get expensive, and there is some support in the OSTree core for static
|
||||
deltas which "recurse" to a parent. This can help create a model
|
||||
where clients download a chain of deltas. Support for this is not
|
||||
fully implemented yet however.
|
||||
|
||||
Regardless of whether or not you choose to generate static deltas,
|
||||
you should update the summary file:
|
||||
|
||||
```
|
||||
ostree --repo=repo-prod summary -u
|
||||
```
|
||||
|
||||
(Remember, the `summary` command cannot be run concurrently, so this
|
||||
should be triggered serially by other jobs).
|
||||
|
||||
There is some more information on the design of the summary file in
|
||||
[Repo](repo.md).
|
||||
|
||||
## Pruning our build and dev repositories
|
||||
|
||||
First, the OSTree author believes you should *not* use OSTree as a
|
||||
"primary content store". The binaries in an OSTree repository should
|
||||
be derived from a git repository. Your build system should record
|
||||
proper metadata such as the configuration options used to generate the
|
||||
build, and you should be able to rebuild it if necessary. Art assets
|
||||
should be stored in a system that's designed for that
|
||||
(e.g. [Git LFS](https://git-lfs.github.com/)).
|
||||
|
||||
Another way to say this is that five years down the line, we are
|
||||
unlikely to care about retaining the exact binaries from an OS build
|
||||
on Wednesday afternoon three years ago.
|
||||
|
||||
We want to save space and prune our "dev" repository.
|
||||
|
||||
```
|
||||
ostree --repo=repo-dev prune --refs-only --keep-younger-than="6 months ago"
|
||||
```
|
||||
|
||||
That will truncate the history older than 6 months. Deleted commits
|
||||
will have "tombstone markers" added so that you know they were
|
||||
explicitly deleted, but all content in them (that is not referenced by
|
||||
a still retained commit) will be garbage collected.
|
||||
|
|
@ -0,0 +1,348 @@
|
|||
# git.mk, a small Makefile to autogenerate .gitignore files
|
||||
# for autotools-based projects.
|
||||
#
|
||||
# Copyright 2009, Red Hat, Inc.
|
||||
# Copyright 2010,2011,2012,2013 Behdad Esfahbod
|
||||
# Written by Behdad Esfahbod
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification,
|
||||
# is permitted in any medium without royalty provided the copyright
|
||||
# notice and this notice are preserved.
|
||||
#
|
||||
# The latest version of this file can be downloaded from:
|
||||
GIT_MK_URL = https://raw.githubusercontent.com/behdad/git.mk/master/git.mk
|
||||
#
|
||||
# Bugs, etc, should be reported upstream at:
|
||||
# https://github.com/behdad/git.mk
|
||||
#
|
||||
# To use in your project, import this file in your git repo's toplevel,
|
||||
# then do "make -f git.mk". This modifies all Makefile.am files in
|
||||
# your project to -include git.mk. Remember to add that line to new
|
||||
# Makefile.am files you create in your project, or just rerun the
|
||||
# "make -f git.mk".
|
||||
#
|
||||
# This enables automatic .gitignore generation. If you need to ignore
|
||||
# more files, add them to the GITIGNOREFILES variable in your Makefile.am.
|
||||
# But think twice before doing that. If a file has to be in .gitignore,
|
||||
# chances are very high that it's a generated file and should be in one
|
||||
# of MOSTLYCLEANFILES, CLEANFILES, DISTCLEANFILES, or MAINTAINERCLEANFILES.
|
||||
#
|
||||
# The only case that you need to manually add a file to GITIGNOREFILES is
|
||||
# when remove files in one of mostlyclean-local, clean-local, distclean-local,
|
||||
# or maintainer-clean-local make targets.
|
||||
#
|
||||
# Note that for files like editor backup, etc, there are better places to
|
||||
# ignore them. See "man gitignore".
|
||||
#
|
||||
# If "make maintainer-clean" removes the files but they are not recognized
|
||||
# by this script (that is, if "git status" shows untracked files still), send
|
||||
# me the output of "git status" as well as your Makefile.am and Makefile for
|
||||
# the directories involved and I'll diagnose.
|
||||
#
|
||||
# For a list of toplevel files that should be in MAINTAINERCLEANFILES, see
|
||||
# Makefile.am.sample in the git.mk git repo.
|
||||
#
|
||||
# Don't EXTRA_DIST this file. It is supposed to only live in git clones,
|
||||
# not tarballs. It serves no useful purpose in tarballs and clutters the
|
||||
# build dir.
|
||||
#
|
||||
# This file knows how to handle autoconf, automake, libtool, gtk-doc,
|
||||
# gnome-doc-utils, yelp.m4, mallard, intltool, gsettings, dejagnu, appdata,
|
||||
# appstream.
|
||||
#
|
||||
# This makefile provides the following targets:
|
||||
#
|
||||
# - all: "make all" will build all gitignore files.
|
||||
# - gitignore: makes all gitignore files in the current dir and subdirs.
|
||||
# - .gitignore: make gitignore file for the current dir.
|
||||
# - gitignore-recurse: makes all gitignore files in the subdirs.
|
||||
#
|
||||
# KNOWN ISSUES:
|
||||
#
|
||||
# - Recursive configure doesn't work as $(top_srcdir)/git.mk inside the
|
||||
# submodule doesn't find us. If you have configure.{in,ac} files in
|
||||
# subdirs, add a proxy git.mk file in those dirs that simply does:
|
||||
# "include $(top_srcdir)/../git.mk". Add more ..'s to your taste.
|
||||
# And add those files to git. See vte/gnome-pty-helper/git.mk for
|
||||
# example.
|
||||
#
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Variables user modules may want to add to toplevel MAINTAINERCLEANFILES:
|
||||
###############################################################################
|
||||
|
||||
#
|
||||
# Most autotools-using modules should be fine including this variable in their
|
||||
# toplevel MAINTAINERCLEANFILES:
|
||||
GITIGNORE_MAINTAINERCLEANFILES_TOPLEVEL = \
|
||||
$(srcdir)/aclocal.m4 \
|
||||
$(srcdir)/autoscan.log \
|
||||
$(srcdir)/configure.scan \
|
||||
`AUX_DIR=$(srcdir)/$$(cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_AUX_DIR:$$1' ./configure.ac); \
|
||||
test "x$$AUX_DIR" = "x$(srcdir)/" && AUX_DIR=$(srcdir); \
|
||||
for x in \
|
||||
ar-lib \
|
||||
compile \
|
||||
config.guess \
|
||||
config.sub \
|
||||
depcomp \
|
||||
install-sh \
|
||||
ltmain.sh \
|
||||
missing \
|
||||
mkinstalldirs \
|
||||
test-driver \
|
||||
ylwrap \
|
||||
; do echo "$$AUX_DIR/$$x"; done` \
|
||||
`cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_HEADERS:$$1' ./configure.ac | \
|
||||
head -n 1 | while read f; do echo "$(srcdir)/$$f.in"; done`
|
||||
#
|
||||
# All modules should also be fine including the following variable, which
|
||||
# removes automake-generated Makefile.in files:
|
||||
GITIGNORE_MAINTAINERCLEANFILES_MAKEFILE_IN = \
|
||||
`cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_FILES:$$1' ./configure.ac | \
|
||||
while read f; do \
|
||||
case $$f in Makefile|*/Makefile) \
|
||||
test -f "$(srcdir)/$$f.am" && echo "$(srcdir)/$$f.in";; esac; \
|
||||
done`
|
||||
#
|
||||
# Modules that use libtool and use AC_CONFIG_MACRO_DIR() may also include this,
|
||||
# though it's harmless to include regardless.
|
||||
GITIGNORE_MAINTAINERCLEANFILES_M4_LIBTOOL = \
|
||||
`MACRO_DIR=$(srcdir)/$$(cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_MACRO_DIR:$$1' ./configure.ac); \
|
||||
if test "x$$MACRO_DIR" != "x$(srcdir)/"; then \
|
||||
for x in \
|
||||
libtool.m4 \
|
||||
ltoptions.m4 \
|
||||
ltsugar.m4 \
|
||||
ltversion.m4 \
|
||||
lt~obsolete.m4 \
|
||||
; do echo "$$MACRO_DIR/$$x"; done; \
|
||||
fi`
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Default rule is to install ourselves in all Makefile.am files:
|
||||
###############################################################################
|
||||
|
||||
git-all: git-mk-install
|
||||
|
||||
git-mk-install:
|
||||
@echo "Installing git makefile"
|
||||
@any_failed=; \
|
||||
find "`test -z "$(top_srcdir)" && echo . || echo "$(top_srcdir)"`" -name Makefile.am | while read x; do \
|
||||
if grep 'include .*/git.mk' $$x >/dev/null; then \
|
||||
echo "$$x already includes git.mk"; \
|
||||
else \
|
||||
failed=; \
|
||||
echo "Updating $$x"; \
|
||||
{ cat $$x; \
|
||||
echo ''; \
|
||||
echo '-include $$(top_srcdir)/git.mk'; \
|
||||
} > $$x.tmp || failed=1; \
|
||||
if test x$$failed = x; then \
|
||||
mv $$x.tmp $$x || failed=1; \
|
||||
fi; \
|
||||
if test x$$failed = x; then : else \
|
||||
echo "Failed updating $$x"; >&2 \
|
||||
any_failed=1; \
|
||||
fi; \
|
||||
fi; done; test -z "$$any_failed"
|
||||
|
||||
git-mk-update:
|
||||
wget $(GIT_MK_URL) -O $(top_srcdir)/git.mk
|
||||
|
||||
.PHONY: git-all git-mk-install git-mk-update
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Actual .gitignore generation:
|
||||
###############################################################################
|
||||
|
||||
$(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk
|
||||
@echo "git.mk: Generating $@"
|
||||
@{ \
|
||||
if test "x$(DOC_MODULE)" = x -o "x$(DOC_MAIN_SGML_FILE)" = x; then :; else \
|
||||
for x in \
|
||||
$(DOC_MODULE)-decl-list.txt \
|
||||
$(DOC_MODULE)-decl.txt \
|
||||
tmpl/$(DOC_MODULE)-unused.sgml \
|
||||
"tmpl/*.bak" \
|
||||
$(REPORT_FILES) \
|
||||
$(DOC_MODULE).pdf \
|
||||
xml html \
|
||||
; do echo "/$$x"; done; \
|
||||
FLAVOR=$$(cd $(top_srcdir); $(AUTOCONF) --trace 'GTK_DOC_CHECK:$$2' ./configure.ac); \
|
||||
case $$FLAVOR in *no-tmpl*) echo /tmpl;; esac; \
|
||||
if echo "$(SCAN_OPTIONS)" | grep -q "\-\-rebuild-types"; then \
|
||||
echo "/$(DOC_MODULE).types"; \
|
||||
fi; \
|
||||
if echo "$(SCAN_OPTIONS)" | grep -q "\-\-rebuild-sections"; then \
|
||||
echo "/$(DOC_MODULE)-sections.txt"; \
|
||||
fi; \
|
||||
if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \
|
||||
for x in \
|
||||
$(SETUP_FILES) \
|
||||
$(DOC_MODULE).types \
|
||||
; do echo "/$$x"; done; \
|
||||
fi; \
|
||||
fi; \
|
||||
if test "x$(DOC_MODULE)$(DOC_ID)" = x -o "x$(DOC_LINGUAS)" = x; then :; else \
|
||||
for lc in $(DOC_LINGUAS); do \
|
||||
for x in \
|
||||
$(if $(DOC_MODULE),$(DOC_MODULE).xml) \
|
||||
$(DOC_PAGES) \
|
||||
$(DOC_INCLUDES) \
|
||||
; do echo "/$$lc/$$x"; done; \
|
||||
done; \
|
||||
for x in \
|
||||
$(_DOC_OMF_ALL) \
|
||||
$(_DOC_DSK_ALL) \
|
||||
$(_DOC_HTML_ALL) \
|
||||
$(_DOC_MOFILES) \
|
||||
$(DOC_H_FILE) \
|
||||
"*/.xml2po.mo" \
|
||||
"*/*.omf.out" \
|
||||
; do echo /$$x; done; \
|
||||
fi; \
|
||||
if test "x$(HELP_ID)" = x -o "x$(HELP_LINGUAS)" = x; then :; else \
|
||||
for lc in $(HELP_LINGUAS); do \
|
||||
for x in \
|
||||
$(HELP_FILES) \
|
||||
"$$lc.stamp" \
|
||||
"$$lc.mo" \
|
||||
; do echo "/$$lc/$$x"; done; \
|
||||
done; \
|
||||
fi; \
|
||||
if test "x$(gsettings_SCHEMAS)" = x; then :; else \
|
||||
for x in \
|
||||
$(gsettings_SCHEMAS:.xml=.valid) \
|
||||
$(gsettings__enum_file) \
|
||||
; do echo "/$$x"; done; \
|
||||
fi; \
|
||||
if test "x$(appdata_XML)" = x; then :; else \
|
||||
for x in \
|
||||
$(appdata_XML:.xml=.valid) \
|
||||
; do echo "/$$x"; done; \
|
||||
fi; \
|
||||
if test "x$(appstream_XML)" = x; then :; else \
|
||||
for x in \
|
||||
$(appstream_XML:.xml=.valid) \
|
||||
; do echo "/$$x"; done; \
|
||||
fi; \
|
||||
if test -f $(srcdir)/po/Makefile.in.in; then \
|
||||
for x in \
|
||||
po/Makefile.in.in \
|
||||
po/Makefile.in.in~ \
|
||||
po/Makefile.in \
|
||||
po/Makefile \
|
||||
po/Makevars.template \
|
||||
po/POTFILES \
|
||||
po/Rules-quot \
|
||||
po/stamp-it \
|
||||
po/stamp-po \
|
||||
po/.intltool-merge-cache \
|
||||
"po/*.gmo" \
|
||||
"po/*.header" \
|
||||
"po/*.mo" \
|
||||
"po/*.sed" \
|
||||
"po/*.sin" \
|
||||
po/$(GETTEXT_PACKAGE).pot \
|
||||
intltool-extract.in \
|
||||
intltool-merge.in \
|
||||
intltool-update.in \
|
||||
; do echo "/$$x"; done; \
|
||||
fi; \
|
||||
if test -f $(srcdir)/configure; then \
|
||||
for x in \
|
||||
autom4te.cache \
|
||||
configure \
|
||||
config.h \
|
||||
stamp-h1 \
|
||||
libtool \
|
||||
config.lt \
|
||||
; do echo "/$$x"; done; \
|
||||
fi; \
|
||||
if test "x$(DEJATOOL)" = x; then :; else \
|
||||
for x in \
|
||||
$(DEJATOOL) \
|
||||
; do echo "/$$x.sum"; echo "/$$x.log"; done; \
|
||||
echo /site.exp; \
|
||||
fi; \
|
||||
if test "x$(am__dirstamp)" = x; then :; else \
|
||||
echo "$(am__dirstamp)"; \
|
||||
fi; \
|
||||
if test "x$(findstring libtool,$(LTCOMPILE))" = x -a "x$(findstring libtool,$(LTCXXCOMPILE))" = x -a "x$(GTKDOC_RUN)" = x; then :; else \
|
||||
for x in \
|
||||
"*.lo" \
|
||||
".libs" "_libs" \
|
||||
; do echo "$$x"; done; \
|
||||
fi; \
|
||||
for x in \
|
||||
.gitignore \
|
||||
$(GITIGNOREFILES) \
|
||||
$(CLEANFILES) \
|
||||
$(PROGRAMS) $(check_PROGRAMS) $(EXTRA_PROGRAMS) \
|
||||
$(LIBRARIES) $(check_LIBRARIES) $(EXTRA_LIBRARIES) \
|
||||
$(LTLIBRARIES) $(check_LTLIBRARIES) $(EXTRA_LTLIBRARIES) \
|
||||
so_locations \
|
||||
$(MOSTLYCLEANFILES) \
|
||||
$(TEST_LOGS) \
|
||||
$(TEST_LOGS:.log=.trs) \
|
||||
$(TEST_SUITE_LOG) \
|
||||
$(TESTS:=.test) \
|
||||
"*.gcda" \
|
||||
"*.gcno" \
|
||||
$(DISTCLEANFILES) \
|
||||
$(am__CONFIG_DISTCLEAN_FILES) \
|
||||
$(CONFIG_CLEAN_FILES) \
|
||||
TAGS ID GTAGS GRTAGS GSYMS GPATH tags \
|
||||
"*.tab.c" \
|
||||
$(MAINTAINERCLEANFILES) \
|
||||
$(BUILT_SOURCES) \
|
||||
$(patsubst %.vala,%.c,$(filter %.vala,$(SOURCES))) \
|
||||
$(filter %_vala.stamp,$(DIST_COMMON)) \
|
||||
$(filter %.vapi,$(DIST_COMMON)) \
|
||||
$(filter $(addprefix %,$(notdir $(patsubst %.vapi,%.h,$(filter %.vapi,$(DIST_COMMON))))),$(DIST_COMMON)) \
|
||||
Makefile \
|
||||
Makefile.in \
|
||||
"*.orig" \
|
||||
"*.rej" \
|
||||
"*.bak" \
|
||||
"*~" \
|
||||
".*.sw[nop]" \
|
||||
".dirstamp" \
|
||||
; do echo "/$$x"; done; \
|
||||
for x in \
|
||||
"*.$(OBJEXT)" \
|
||||
$(DEPDIR) \
|
||||
; do echo "$$x"; done; \
|
||||
} | \
|
||||
sed "s@^/`echo "$(srcdir)" | sed 's/\(.\)/[\1]/g'`/@/@" | \
|
||||
sed 's@/[.]/@/@g' | \
|
||||
LC_ALL=C sort | uniq > $@.tmp && \
|
||||
mv $@.tmp $@;
|
||||
|
||||
all: $(srcdir)/.gitignore gitignore-recurse-maybe
|
||||
gitignore: $(srcdir)/.gitignore gitignore-recurse
|
||||
|
||||
gitignore-recurse-maybe:
|
||||
@for subdir in $(DIST_SUBDIRS); do \
|
||||
case " $(SUBDIRS) " in \
|
||||
*" $$subdir "*) :;; \
|
||||
*) test "$$subdir" = . -o -e "$$subdir/.git" || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) gitignore || echo "Skipping $$subdir");; \
|
||||
esac; \
|
||||
done
|
||||
gitignore-recurse:
|
||||
@for subdir in $(DIST_SUBDIRS); do \
|
||||
test "$$subdir" = . -o -e "$$subdir/.git" || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) gitignore || echo "Skipping $$subdir"); \
|
||||
done
|
||||
|
||||
maintainer-clean: gitignore-clean
|
||||
gitignore-clean:
|
||||
-rm -f $(srcdir)/.gitignore
|
||||
|
||||
.PHONY: gitignore-clean gitignore gitignore-recurse gitignore-recurse-maybe
|
||||
|
|
@ -80,6 +80,14 @@ Boston, MA 02111-1307, USA.
|
|||
Do no invoke fsync().
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--untrusted</option></term>
|
||||
|
||||
<listitem><para>
|
||||
Do not trust source, verify checksums and don't hardlink into source.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,14 @@ Boston, MA 02111-1307, USA.
|
|||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--untrusted</option></term>
|
||||
|
||||
<listitem><para>
|
||||
Do not trust local sources, verify checksums and don't hardlink into source.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--disable-static-deltas</option></term>
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,12 @@ Boston, MA 02111-1307, USA.
|
|||
<cmdsynopsis>
|
||||
<command>ostree static-delta list</command>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>ostree static-delta show</command>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>ostree static-delta delete</command>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>ostree static-delta generate</command> <arg choice="req">--to=REV</arg> <arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
</cmdsynopsis>
|
||||
|
|
|
|||
|
|
@ -195,6 +195,15 @@ Boston, MA 02111-1307, USA.
|
|||
ignored.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Per-remote GPG keyrings and verification</title>
|
||||
<para>
|
||||
OSTree supports a per-remote GPG keyring. For more information see
|
||||
<citerefentry><refentrytitle>ostree</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
|
||||
in the section <literal>GPG verification</literal>.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>See Also</title>
|
||||
|
|
|
|||
|
|
@ -425,13 +425,25 @@ Boston, MA 02111-1307, USA.
|
|||
<title>GPG verification</title>
|
||||
|
||||
<para>
|
||||
OSTree supports signing commits with GPG. The set of
|
||||
trusted public keys is stored as keyring files in
|
||||
<filename>/usr/share/ostree/trusted.gpg.d</filename>. Any
|
||||
public key in a keyring file in that directory will be
|
||||
trusted by the client. No private keys should be present
|
||||
in this directory.
|
||||
OSTree supports signing commits with GPG. Operations on the system
|
||||
repository by default use keyring files in
|
||||
<filename>/usr/share/ostree/trusted.gpg.d</filename>. Any
|
||||
public key in a keyring file in that directory will be
|
||||
trusted by the client. No private keys should be present
|
||||
in this directory.
|
||||
</para>
|
||||
<para>
|
||||
In addition to the system repository, OSTree supports a
|
||||
per-remote
|
||||
<filename><replaceable>remotename</replaceable>.trustedkeys.gpg</filename>
|
||||
file stored in the toplevel of the repository (alongside
|
||||
<filename>objects/</filename> and such). This is
|
||||
particularly useful when downloading content that may not
|
||||
be fully trusted (e.g. you want to inspect it but not
|
||||
deploy it as an OS), or use it for containers. This file
|
||||
is written via <command>ostree remote add
|
||||
--gpg-import</command>.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
|
|
|||
|
|
@ -10,4 +10,5 @@ pages:
|
|||
- Adapting Existing Systems: 'manual/adapting-existing.md'
|
||||
- Formats: 'manual/formats.md'
|
||||
- Build Systems and Repos: 'manual/buildsystem-and-repos.md'
|
||||
- Repository Management: 'manual/repository-management.md'
|
||||
- Related Projects: 'manual/related-projects.md'
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ dist-snapshot:
|
|||
tar -A -f $${TARFILE_TMP} submodule.tar; \
|
||||
rm submodule.tar; \
|
||||
done; \
|
||||
mv $(PKG_VER).tar{.tmp,}; \
|
||||
mv $(PKG_VER).tar.tmp $(PKG_VER).tar; \
|
||||
rm -f $(PKG_VER).tar.xz; \
|
||||
xz $(PKG_VER).tar
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
#!/bin/sh
|
||||
|
||||
# To use a custrom script for generating grub.cfg, set the --with-grub2-mkconfig=no
|
||||
# configure switch when configuring and building OSTree.
|
||||
#
|
||||
# This script is called by ostree/src/libostree/ostree-bootloader-grub2.c whenever
|
||||
# boot loader configuration file needs to be updated. It can be used as a template
|
||||
# for a custom grub.cfg generator. What to consider when writing a custom grub.cfg
|
||||
# generator:
|
||||
#
|
||||
# - The populate_menu() function converts boot loader entries as defined by
|
||||
# https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/ into GRUB2
|
||||
# menuentry sections. This is the core logic that is required by OSTree
|
||||
# based system.
|
||||
#
|
||||
# - Embedded systems: Be aware that this script is executed not only on a host machine by OS
|
||||
# installer, but also on a target device, thus think about shell portability. A target device
|
||||
# for example might be using busybox with a limited shell.
|
||||
#
|
||||
# Feel free to edit this script to fit your requirements.
|
||||
|
||||
set -e
|
||||
|
||||
script=$(basename ${0})
|
||||
# Atomically safe location where to generete grub.cfg when executing system upgrade.
|
||||
new_grub2_cfg=${2}
|
||||
entries_path=$(dirname $new_grub2_cfg)/entries
|
||||
|
||||
read_config()
|
||||
{
|
||||
config_file=${entries_path}/${1}
|
||||
title=""
|
||||
initrd=""
|
||||
options=""
|
||||
linux=""
|
||||
|
||||
while read -r line
|
||||
do
|
||||
record=$(echo ${line} | cut -f 1 -d ' ')
|
||||
value=$(echo ${line} | cut -s -f2- -d ' ')
|
||||
case "${record}" in
|
||||
"title")
|
||||
title=${value}
|
||||
;;
|
||||
"initrd")
|
||||
initrd=${value}
|
||||
;;
|
||||
"linux")
|
||||
linux=${value}
|
||||
;;
|
||||
"options")
|
||||
options=${value}
|
||||
;;
|
||||
esac
|
||||
done < ${config_file}
|
||||
|
||||
if [ -z "${title}" ]; then
|
||||
title="(Untitled)"
|
||||
fi
|
||||
}
|
||||
|
||||
populate_menu()
|
||||
{
|
||||
boot_prefix="${OSTREE_BOOT_PARTITION}"
|
||||
for config in $(ls ${entries_path}); do
|
||||
read_config ${config}
|
||||
menu="${menu}menuentry '${title}' {\n"
|
||||
menu="${menu}\t linux ${boot_prefix}${linux} ${options}\n"
|
||||
menu="${menu}\t initrd ${boot_prefix}${initrd}\n"
|
||||
menu="${menu}}\n\n"
|
||||
done
|
||||
# The printf command seems to be more reliable across shells for special character (\n, \t) evaluation
|
||||
printf "$menu" >> ${new_grub2_cfg}
|
||||
}
|
||||
|
||||
populate_warning()
|
||||
{
|
||||
cat >> ${new_grub2_cfg} <<EOF
|
||||
# This file was generated by ${script}. Do not modify the generated file - all changes will
|
||||
# be lost the next time file is regenerated. For more details refer to the ${script} script.
|
||||
EOF
|
||||
}
|
||||
|
||||
populate_header()
|
||||
{
|
||||
cat >> ${new_grub2_cfg} <<EOF
|
||||
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
|
||||
default=boot
|
||||
timeout=10
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
generate_grub2_cfg()
|
||||
{
|
||||
populate_warning
|
||||
populate_header
|
||||
populate_menu
|
||||
}
|
||||
|
||||
generate_grub2_cfg
|
||||
|
|
@ -328,8 +328,12 @@ global:
|
|||
* NOTE NOTE NOTE
|
||||
*/
|
||||
|
||||
/* UNCOMMENT WITH NEW SYMBOLS HERE:
|
||||
LIBOSTREE_2016.5 {
|
||||
global:
|
||||
ostree_repo_import_object_from_with_trust;
|
||||
ostree_sepolicy_get_csum;
|
||||
ostree_repo_get_remote_option;
|
||||
ostree_repo_get_remote_list_option;
|
||||
ostree_repo_get_remote_boolean_option;
|
||||
ostree_repo_set_cache_dir;
|
||||
} LIBOSTREE_2016.4;
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -299,8 +299,25 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader,
|
|||
g_autofree char *bootversion_str = g_strdup_printf ("%u", (guint)bootversion);
|
||||
g_autoptr(GFile) config_path_efi_dir = NULL;
|
||||
g_autofree char *grub2_mkconfig_chroot = NULL;
|
||||
gboolean use_system_grub2_mkconfig = TRUE;
|
||||
const gchar *grub_exec = NULL;
|
||||
|
||||
if (ostree_sysroot_get_booted_deployment (self->sysroot) == NULL
|
||||
#ifdef USE_BUILTIN_GRUB2_MKCONFIG
|
||||
use_system_grub2_mkconfig = FALSE;
|
||||
#endif
|
||||
/* Autotests can set this envvar to select which code path to test, useful for OS installers as well */
|
||||
grub_exec = g_getenv ("OSTREE_GRUB2_EXEC");
|
||||
if (grub_exec)
|
||||
{
|
||||
if (g_str_has_suffix (grub_exec, GRUB2_MKCONFIG_PATH))
|
||||
use_system_grub2_mkconfig = TRUE;
|
||||
else
|
||||
use_system_grub2_mkconfig = FALSE;
|
||||
}
|
||||
else
|
||||
grub_exec = use_system_grub2_mkconfig ? GRUB2_MKCONFIG_PATH : LIBEXECDIR "/ostree-grub-generator";
|
||||
|
||||
if (use_system_grub2_mkconfig && ostree_sysroot_get_booted_deployment (self->sysroot) == NULL
|
||||
&& g_file_has_parent (self->sysroot->path, NULL))
|
||||
{
|
||||
g_autoptr(GPtrArray) deployments = NULL;
|
||||
|
|
@ -318,6 +335,9 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader,
|
|||
*
|
||||
* In the case of an installer, use the first deployment root (which
|
||||
* will most likely be the only one.
|
||||
*
|
||||
* This all only applies if we're not using the builtin
|
||||
* generator, which handles being run outside of the root.
|
||||
*/
|
||||
tool_deployment_root = ostree_sysroot_get_deployment_directory (self->sysroot, tool_deployment);
|
||||
grub2_mkconfig_chroot = g_file_get_path (tool_deployment_root);
|
||||
|
|
@ -361,7 +381,7 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader,
|
|||
Upstream is fixed though.
|
||||
*/
|
||||
proc = g_subprocess_launcher_spawn (launcher, error,
|
||||
"grub2-mkconfig", "-o",
|
||||
grub_exec, "-o",
|
||||
gs_file_get_path_cached (new_config_path),
|
||||
NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ ostree_cmd__private__ (void)
|
|||
{
|
||||
static OstreeCmdPrivateVTable table = {
|
||||
impl_ostree_generate_grub2_config,
|
||||
_ostree_repo_static_delta_dump
|
||||
_ostree_repo_static_delta_dump,
|
||||
_ostree_repo_static_delta_delete
|
||||
};
|
||||
|
||||
return &table;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ G_BEGIN_DECLS
|
|||
typedef struct {
|
||||
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_delete) (OstreeRepo *repo, const char *delta_id, GCancellable *cancellable, GError **error);
|
||||
} OstreeCmdPrivateVTable;
|
||||
|
||||
/* Note this not really "public", we just export the symbol, but not the header */
|
||||
|
|
|
|||
|
|
@ -541,6 +541,7 @@ _ostree_fetcher_constructed (GObject *object)
|
|||
self->thread_closure->output_stream_set = g_hash_table_new_full (NULL, NULL,
|
||||
(GDestroyNotify) NULL,
|
||||
(GDestroyNotify) g_object_unref);
|
||||
g_mutex_init (&self->thread_closure->output_stream_set_lock);
|
||||
|
||||
if (g_getenv ("OSTREE_DEBUG_HTTP"))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -491,7 +491,7 @@ try_metalink_targets (OstreeMetalinkRequest *self,
|
|||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
SoupURI *target_uri;
|
||||
SoupURI *target_uri = NULL;
|
||||
|
||||
if (!self->found_a_file_element)
|
||||
{
|
||||
|
|
@ -564,7 +564,7 @@ try_metalink_targets (OstreeMetalinkRequest *self,
|
|||
self->urls->len, self->last_metalink_error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
ret = TRUE;
|
||||
if (out_target_uri)
|
||||
*out_target_uri = soup_uri_copy (target_uri);
|
||||
|
|
|
|||
|
|
@ -2525,7 +2525,7 @@ write_directory_content_to_mtree_internal (OstreeRepo *self,
|
|||
}
|
||||
|
||||
if (!get_modified_xattrs (self, modifier,
|
||||
child_relpath, child_info, child, dfd_iter->fd, name,
|
||||
child_relpath, child_info, child, dfd_iter != NULL ? dfd_iter->fd : -1, name,
|
||||
&xattrs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -745,52 +745,6 @@ query_child_info_dir (OstreeRepo *repo,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
bsearch_in_file_variant (GVariant *variant,
|
||||
const char *name,
|
||||
int *out_pos)
|
||||
{
|
||||
gsize imax, imin;
|
||||
gsize imid;
|
||||
gsize n;
|
||||
|
||||
n = g_variant_n_children (variant);
|
||||
if (n == 0)
|
||||
return FALSE;
|
||||
|
||||
imax = n - 1;
|
||||
imin = 0;
|
||||
while (imax >= imin)
|
||||
{
|
||||
g_autoptr(GVariant) child = NULL;
|
||||
const char *cur;
|
||||
int cmp;
|
||||
|
||||
imid = (imin + imax) / 2;
|
||||
|
||||
child = g_variant_get_child_value (variant, imid);
|
||||
g_variant_get_child (child, 0, "&s", &cur, NULL);
|
||||
|
||||
cmp = strcmp (cur, name);
|
||||
if (cmp < 0)
|
||||
imin = imid + 1;
|
||||
else if (cmp > 0)
|
||||
{
|
||||
if (imid == 0)
|
||||
break;
|
||||
imax = imid - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*out_pos = imid;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
*out_pos = imid;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
ostree_repo_file_tree_find_child (OstreeRepoFile *self,
|
||||
const char *name,
|
||||
|
|
@ -806,7 +760,7 @@ ostree_repo_file_tree_find_child (OstreeRepoFile *self,
|
|||
dirs_variant = g_variant_get_child_value (self->tree_contents, 1);
|
||||
|
||||
i = -1;
|
||||
if (bsearch_in_file_variant (files_variant, name, &i))
|
||||
if (ot_variant_bsearch_str (files_variant, name, &i))
|
||||
{
|
||||
*is_dir = FALSE;
|
||||
ret_container = files_variant;
|
||||
|
|
@ -814,7 +768,7 @@ ostree_repo_file_tree_find_child (OstreeRepoFile *self,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (bsearch_in_file_variant (dirs_variant, name, &i))
|
||||
if (ot_variant_bsearch_str (dirs_variant, name, &i))
|
||||
{
|
||||
*is_dir = TRUE;
|
||||
ret_container = dirs_variant;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ G_BEGIN_DECLS
|
|||
|
||||
#define _OSTREE_OBJECT_SIZES_ENTRY_SIGNATURE "ay"
|
||||
|
||||
#define _OSTREE_SUMMARY_CACHE_PATH "tmp/cache/summaries"
|
||||
#define _OSTREE_SUMMARY_CACHE_DIR "summaries"
|
||||
#define _OSTREE_CACHE_DIR "cache"
|
||||
|
||||
/**
|
||||
* OstreeRepo:
|
||||
|
|
@ -52,6 +53,8 @@ struct OstreeRepo {
|
|||
int repo_dir_fd;
|
||||
GFile *tmp_dir;
|
||||
int tmp_dir_fd;
|
||||
int cache_dir_fd;
|
||||
char *cache_dir;
|
||||
GFile *objects_dir;
|
||||
GFile *state_dir;
|
||||
int objects_dir_fd;
|
||||
|
|
@ -60,6 +63,7 @@ struct OstreeRepo {
|
|||
int uncompressed_objects_dir_fd;
|
||||
GFile *config_file;
|
||||
GFile *sysroot_dir;
|
||||
char *remotes_config_dir;
|
||||
|
||||
GFile *transaction_lock_path;
|
||||
GHashTable *txn_refs;
|
||||
|
|
@ -195,36 +199,6 @@ _ostree_repo_commit_modifier_apply (OstreeRepo *self,
|
|||
gboolean
|
||||
_ostree_repo_remote_name_is_file (const char *remote_name);
|
||||
|
||||
gboolean
|
||||
_ostree_repo_get_remote_option (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *option_name,
|
||||
const char *default_value,
|
||||
char **out_value,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
_ostree_repo_get_remote_list_option (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *option_name,
|
||||
char ***out_value,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
_ostree_repo_get_remote_boolean_option (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *option_name,
|
||||
gboolean default_value,
|
||||
gboolean *out_value,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
_ostree_repo_get_remote_option_inherit (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *option_name,
|
||||
char **out_value,
|
||||
GError **error);
|
||||
|
||||
#ifdef HAVE_LIBSOUP
|
||||
OstreeFetcher *
|
||||
_ostree_repo_remote_new_fetcher (OstreeRepo *self,
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ maybe_prune_loose_object (OtPruneData *data,
|
|||
|
||||
if (!g_hash_table_lookup_extended (data->reachable, key, NULL, NULL))
|
||||
{
|
||||
g_debug ("Pruning unneeded object %s.%s", checksum,
|
||||
ostree_object_type_to_string (objtype));
|
||||
if (!(flags & OSTREE_REPO_PRUNE_FLAGS_NO_PRUNE))
|
||||
{
|
||||
guint64 storage_size = 0;
|
||||
|
|
@ -101,6 +103,8 @@ maybe_prune_loose_object (OtPruneData *data,
|
|||
}
|
||||
else
|
||||
{
|
||||
g_debug ("Keeping needed object %s.%s", checksum,
|
||||
ostree_object_type_to_string (objtype));
|
||||
if (OSTREE_OBJECT_TYPE_IS_META (objtype))
|
||||
data->n_reachable_meta++;
|
||||
else
|
||||
|
|
@ -121,7 +125,10 @@ _ostree_repo_prune_tmp (OstreeRepo *self,
|
|||
g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
|
||||
glnx_fd_close int fd = -1;
|
||||
|
||||
fd = glnx_opendirat_with_errno (self->repo_dir_fd, _OSTREE_SUMMARY_CACHE_PATH, FALSE);
|
||||
if (self->cache_dir_fd == -1)
|
||||
return TRUE;
|
||||
|
||||
fd = glnx_opendirat_with_errno (self->cache_dir_fd, _OSTREE_SUMMARY_CACHE_DIR, FALSE);
|
||||
if (fd < 0)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
|
|
@ -234,6 +241,7 @@ ostree_repo_prune_static_deltas (OstreeRepo *self, const char *commit,
|
|||
continue;
|
||||
}
|
||||
|
||||
g_debug ("Trying to prune static delta %s", deltaname);
|
||||
deltadir = _ostree_get_relative_static_delta_path (from, to, NULL);
|
||||
|
||||
if (!glnx_shutil_rm_rf_at (self->repo_dir_fd, deltadir,
|
||||
|
|
@ -310,6 +318,7 @@ ostree_repo_prune (OstreeRepo *self,
|
|||
error))
|
||||
goto out;
|
||||
|
||||
g_debug ("Finding objects to keep for commit %s", checksum);
|
||||
if (!ostree_repo_traverse_commit_union (self, checksum, depth, data.reachable,
|
||||
cancellable, &local_error))
|
||||
{
|
||||
|
|
@ -352,6 +361,7 @@ ostree_repo_prune (OstreeRepo *self,
|
|||
error))
|
||||
goto out;
|
||||
|
||||
g_debug ("Finding objects to keep for commit %s", checksum);
|
||||
if (!ostree_repo_traverse_commit_union (self, checksum, depth, data.reachable,
|
||||
cancellable, &local_error))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ typedef struct {
|
|||
|
||||
gboolean is_mirror;
|
||||
gboolean is_commit_only;
|
||||
gboolean is_untrusted;
|
||||
|
||||
char *dir;
|
||||
gboolean commitpartial_exists;
|
||||
|
|
@ -447,12 +448,7 @@ scan_dirtree_object (OtPullData *pull_data,
|
|||
files_variant = g_variant_get_child_value (tree, 0);
|
||||
dirs_variant = g_variant_get_child_value (tree, 1);
|
||||
|
||||
/* Skip files if we're traversing a request only directory */
|
||||
if (pull_data->dir)
|
||||
n = 0;
|
||||
else
|
||||
n = g_variant_n_children (files_variant);
|
||||
|
||||
n = g_variant_n_children (files_variant);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
const char *filename;
|
||||
|
|
@ -465,6 +461,14 @@ scan_dirtree_object (OtPullData *pull_data,
|
|||
if (!ot_util_filename_validate (filename, error))
|
||||
goto out;
|
||||
|
||||
/* Skip files if we're traversing a request only directory, unless it exactly
|
||||
* matches the path */
|
||||
if (pull_data->dir &&
|
||||
/* Should always an initial slash, we assert it in scan_dirtree_object */
|
||||
pull_data->dir[0] == '/' &&
|
||||
strcmp (pull_data->dir+1, filename) != 0)
|
||||
continue;
|
||||
|
||||
file_checksum = ostree_checksum_from_bytes_v (csum);
|
||||
|
||||
if (!ostree_repo_has_object (pull_data->repo, OSTREE_OBJECT_TYPE_FILE, file_checksum,
|
||||
|
|
@ -473,9 +477,9 @@ scan_dirtree_object (OtPullData *pull_data,
|
|||
|
||||
if (!file_is_stored && pull_data->remote_repo_local)
|
||||
{
|
||||
if (!ostree_repo_import_object_from (pull_data->repo, pull_data->remote_repo_local,
|
||||
OSTREE_OBJECT_TYPE_FILE, file_checksum,
|
||||
cancellable, error))
|
||||
if (!ostree_repo_import_object_from_with_trust (pull_data->repo, pull_data->remote_repo_local,
|
||||
OSTREE_OBJECT_TYPE_FILE, file_checksum, !pull_data->is_untrusted,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else if (!file_is_stored && !g_hash_table_lookup (pull_data->requested_content, file_checksum))
|
||||
|
|
@ -1189,9 +1193,9 @@ scan_one_metadata_object_c (OtPullData *pull_data,
|
|||
if (pull_data->remote_repo_local)
|
||||
{
|
||||
if (!is_stored &&
|
||||
!ostree_repo_import_object_from (pull_data->repo, pull_data->remote_repo_local,
|
||||
objtype, tmp_checksum,
|
||||
cancellable, error))
|
||||
!ostree_repo_import_object_from_with_trust (pull_data->repo, pull_data->remote_repo_local,
|
||||
objtype, tmp_checksum, !pull_data->is_untrusted,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
is_stored = TRUE;
|
||||
is_requested = TRUE;
|
||||
|
|
@ -1779,12 +1783,15 @@ _ostree_repo_load_cache_summary_if_same_sig (OstreeRepo *self,
|
|||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
const char *summary_cache_sig_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_PATH, "/", remote, ".sig");
|
||||
const char *summary_cache_sig_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote, ".sig");
|
||||
|
||||
glnx_fd_close int prev_fd = -1;
|
||||
g_autoptr(GBytes) old_sig_contents = NULL;
|
||||
|
||||
if (!ot_openat_ignore_enoent (self->repo_dir_fd, summary_cache_sig_file, &prev_fd, error))
|
||||
if (self->cache_dir_fd == -1)
|
||||
return TRUE;
|
||||
|
||||
if (!ot_openat_ignore_enoent (self->cache_dir_fd, summary_cache_sig_file, &prev_fd, error))
|
||||
goto out;
|
||||
|
||||
if (prev_fd < 0)
|
||||
|
|
@ -1799,17 +1806,17 @@ _ostree_repo_load_cache_summary_if_same_sig (OstreeRepo *self,
|
|||
|
||||
if (g_bytes_compare (old_sig_contents, summary_sig) == 0)
|
||||
{
|
||||
const char *summary_cache_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_PATH, "/", remote);
|
||||
const char *summary_cache_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote);
|
||||
glnx_fd_close int summary_fd = -1;
|
||||
GBytes *summary_data;
|
||||
|
||||
|
||||
summary_fd = openat (self->repo_dir_fd, summary_cache_file, O_CLOEXEC | O_RDONLY);
|
||||
summary_fd = openat (self->cache_dir_fd, summary_cache_file, O_CLOEXEC | O_RDONLY);
|
||||
if (summary_fd < 0)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
(void) unlinkat (self->repo_dir_fd, summary_cache_sig_file, 0);
|
||||
(void) unlinkat (self->cache_dir_fd, summary_cache_sig_file, 0);
|
||||
ret = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -1838,13 +1845,16 @@ _ostree_repo_cache_summary (OstreeRepo *self,
|
|||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
const char *summary_cache_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_PATH, "/", remote);
|
||||
const char *summary_cache_sig_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_PATH, "/", remote, ".sig");
|
||||
const char *summary_cache_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote);
|
||||
const char *summary_cache_sig_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote, ".sig");
|
||||
|
||||
if (!glnx_shutil_mkdir_p_at (self->repo_dir_fd, _OSTREE_SUMMARY_CACHE_PATH, 0775, cancellable, error))
|
||||
if (self->cache_dir_fd == -1)
|
||||
return TRUE;
|
||||
|
||||
if (!glnx_shutil_mkdir_p_at (self->cache_dir_fd, _OSTREE_SUMMARY_CACHE_DIR, 0775, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!glnx_file_replace_contents_at (self->repo_dir_fd,
|
||||
if (!glnx_file_replace_contents_at (self->cache_dir_fd,
|
||||
summary_cache_file,
|
||||
g_bytes_get_data (summary, NULL),
|
||||
g_bytes_get_size (summary),
|
||||
|
|
@ -1852,7 +1862,7 @@ _ostree_repo_cache_summary (OstreeRepo *self,
|
|||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!glnx_file_replace_contents_at (self->repo_dir_fd,
|
||||
if (!glnx_file_replace_contents_at (self->cache_dir_fd,
|
||||
summary_cache_sig_file,
|
||||
g_bytes_get_data (summary_sig, NULL),
|
||||
g_bytes_get_size (summary_sig),
|
||||
|
|
@ -1899,16 +1909,20 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
|||
GSource *update_timeout = NULL;
|
||||
gboolean disable_static_deltas = FALSE;
|
||||
gboolean require_static_deltas = FALSE;
|
||||
gboolean opt_gpg_verify = FALSE;
|
||||
gboolean opt_gpg_verify_summary = FALSE;
|
||||
|
||||
if (options)
|
||||
{
|
||||
int flags_i;
|
||||
int flags_i = OSTREE_REPO_PULL_FLAGS_NONE;
|
||||
(void) g_variant_lookup (options, "refs", "^a&s", &refs_to_fetch);
|
||||
(void) g_variant_lookup (options, "flags", "i", &flags_i);
|
||||
/* Reduce risk of issues if enum happens to be 64 bit for some reason */
|
||||
flags = flags_i;
|
||||
(void) g_variant_lookup (options, "subdir", "&s", &dir_to_pull);
|
||||
(void) g_variant_lookup (options, "override-remote-name", "s", &pull_data->remote_name);
|
||||
(void) g_variant_lookup (options, "gpg-verify", "b", &opt_gpg_verify);
|
||||
(void) g_variant_lookup (options, "gpg-verify-summary", "b", &opt_gpg_verify_summary);
|
||||
(void) g_variant_lookup (options, "depth", "i", &pull_data->maxdepth);
|
||||
(void) g_variant_lookup (options, "disable-static-deltas", "b", &disable_static_deltas);
|
||||
(void) g_variant_lookup (options, "require-static-deltas", "b", &require_static_deltas);
|
||||
|
|
@ -1931,6 +1945,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
|||
|
||||
pull_data->is_mirror = (flags & OSTREE_REPO_PULL_FLAGS_MIRROR) > 0;
|
||||
pull_data->is_commit_only = (flags & OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY) > 0;
|
||||
pull_data->is_untrusted = (flags & OSTREE_REPO_PULL_FLAGS_UNTRUSTED) > 0;
|
||||
|
||||
if (error)
|
||||
pull_data->async_error = &pull_data->cached_async_error;
|
||||
|
|
@ -1965,18 +1980,26 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
|||
if (_ostree_repo_remote_name_is_file (remote_name_or_baseurl))
|
||||
{
|
||||
/* For compatibility with pull-local, don't gpg verify local
|
||||
* pulls.
|
||||
* pulls by default.
|
||||
*/
|
||||
pull_data->gpg_verify = FALSE;
|
||||
pull_data->gpg_verify_summary = FALSE;
|
||||
pull_data->gpg_verify = opt_gpg_verify;
|
||||
pull_data->gpg_verify_summary = opt_gpg_verify_summary;
|
||||
|
||||
if ((pull_data->gpg_verify || pull_data->gpg_verify_summary) &&
|
||||
pull_data->remote_name == NULL)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Must specify remote name to enable gpg verification");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pull_data->remote_name = g_strdup (remote_name_or_baseurl);
|
||||
if (!ostree_repo_remote_get_gpg_verify (self, remote_name_or_baseurl,
|
||||
if (!ostree_repo_remote_get_gpg_verify (self, pull_data->remote_name,
|
||||
&pull_data->gpg_verify, error))
|
||||
goto out;
|
||||
if (!ostree_repo_remote_get_gpg_verify_summary (self, remote_name_or_baseurl,
|
||||
if (!ostree_repo_remote_get_gpg_verify_summary (self, pull_data->remote_name,
|
||||
&pull_data->gpg_verify_summary, error))
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -1991,9 +2014,9 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
|||
requested_refs_to_fetch = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||
commits_to_fetch = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
|
||||
if (!_ostree_repo_get_remote_option (self,
|
||||
remote_name_or_baseurl, "metalink",
|
||||
NULL, &metalink_url_str, error))
|
||||
if (!ostree_repo_get_remote_option (self,
|
||||
remote_name_or_baseurl, "metalink",
|
||||
NULL, &metalink_url_str, error))
|
||||
goto out;
|
||||
|
||||
if (!metalink_url_str)
|
||||
|
|
@ -2047,9 +2070,9 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
|||
summary_bytes, FALSE);
|
||||
}
|
||||
|
||||
if (!_ostree_repo_get_remote_list_option (self,
|
||||
remote_name_or_baseurl, "branches",
|
||||
&configured_branches, error))
|
||||
if (!ostree_repo_get_remote_list_option (self,
|
||||
remote_name_or_baseurl, "branches",
|
||||
&configured_branches, error))
|
||||
goto out;
|
||||
|
||||
if (strcmp (soup_uri_get_scheme (pull_data->base_uri), "file") == 0)
|
||||
|
|
@ -2105,12 +2128,14 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
|||
soup_uri_free (uri);
|
||||
}
|
||||
|
||||
if (bytes_sig && !_ostree_repo_load_cache_summary_if_same_sig (self,
|
||||
remote_name_or_baseurl,
|
||||
bytes_sig,
|
||||
&bytes_summary,
|
||||
cancellable,
|
||||
error))
|
||||
if (bytes_sig &&
|
||||
!pull_data->remote_repo_local &&
|
||||
!_ostree_repo_load_cache_summary_if_same_sig (self,
|
||||
remote_name_or_baseurl,
|
||||
bytes_sig,
|
||||
&bytes_summary,
|
||||
cancellable,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
if (bytes_summary)
|
||||
|
|
@ -2158,7 +2183,8 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
|||
|
||||
if (!summary_from_cache && bytes_summary && bytes_sig)
|
||||
{
|
||||
if (!_ostree_repo_cache_summary (self,
|
||||
if (!pull_data->remote_repo_local &&
|
||||
!_ostree_repo_cache_summary (self,
|
||||
remote_name_or_baseurl,
|
||||
bytes_summary,
|
||||
bytes_sig,
|
||||
|
|
@ -2176,7 +2202,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
|||
result = _ostree_repo_gpg_verify_with_metadata (self,
|
||||
bytes_summary,
|
||||
sig_variant,
|
||||
remote_name_or_baseurl,
|
||||
pull_data->remote_name,
|
||||
NULL,
|
||||
NULL,
|
||||
cancellable,
|
||||
|
|
|
|||
|
|
@ -749,7 +749,10 @@ _ostree_repo_write_ref (OstreeRepo *self,
|
|||
{
|
||||
if (!glnx_opendirat (self->repo_dir_fd, "refs/heads", TRUE,
|
||||
&dfd, error))
|
||||
goto out;
|
||||
{
|
||||
g_prefix_error (error, "Opening %s: ", "refs/heads");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -757,7 +760,10 @@ _ostree_repo_write_ref (OstreeRepo *self,
|
|||
|
||||
if (!glnx_opendirat (self->repo_dir_fd, "refs/remotes", TRUE,
|
||||
&refs_remotes_dfd, error))
|
||||
goto out;
|
||||
{
|
||||
g_prefix_error (error, "Opening %s: ", "refs/remotes");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (rev != NULL)
|
||||
{
|
||||
|
|
@ -767,7 +773,10 @@ _ostree_repo_write_ref (OstreeRepo *self,
|
|||
}
|
||||
|
||||
if (!glnx_opendirat (refs_remotes_dfd, remote, TRUE, &dfd, error))
|
||||
goto out;
|
||||
{
|
||||
g_prefix_error (error, "Opening remotes/ dir %s: ", remote);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (rev == NULL)
|
||||
|
|
|
|||
|
|
@ -455,7 +455,7 @@ get_unpacked_unlinked_content (OstreeRepo *repo,
|
|||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
g_autofree char *tmpname = g_strdup ("tmpostree-deltaobj-XXXXXX");
|
||||
g_autofree char *tmpname = g_strdup ("/var/tmp/tmpostree-deltaobj-XXXXXX");
|
||||
glnx_fd_close int fd = -1;
|
||||
g_autoptr(GBytes) ret_content = NULL;
|
||||
g_autoptr(GInputStream) istream = NULL;
|
||||
|
|
|
|||
|
|
@ -782,6 +782,41 @@ _ostree_delta_needs_byteswap (GVariant *superblock)
|
|||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
_ostree_repo_static_delta_delete (OstreeRepo *self,
|
||||
const char *delta_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
g_autofree char *from = NULL;
|
||||
g_autofree char *to = NULL;
|
||||
g_autofree char *deltadir = NULL;
|
||||
struct stat buf;
|
||||
|
||||
_ostree_parse_delta_name (delta_id, &from, &to);
|
||||
deltadir = _ostree_get_relative_static_delta_path (from, to, NULL);
|
||||
|
||||
if (fstatat (self->repo_dir_fd, deltadir, &buf, 0) != 0)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
||||
"Can't find delta %s", delta_id);
|
||||
else
|
||||
glnx_set_error_from_errno (error);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!glnx_shutil_rm_rf_at (self->repo_dir_fd, deltadir,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_ostree_repo_static_delta_dump (OstreeRepo *self,
|
||||
const char *delta_id,
|
||||
|
|
|
|||
|
|
@ -196,6 +196,12 @@ _ostree_repo_static_delta_dump (OstreeRepo *repo,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
_ostree_repo_static_delta_delete (OstreeRepo *repo,
|
||||
const char *delta_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
/* Used for static deltas which due to a historical mistake are
|
||||
* inconsistent endian.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -106,6 +106,12 @@ OPPROTO(close)
|
|||
OPPROTO(bspatch)
|
||||
#undef OPPROTO
|
||||
|
||||
static void
|
||||
static_delta_execution_state_init (StaticDeltaExecutionState *state)
|
||||
{
|
||||
state->read_source_fd = -1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
read_varuint64 (StaticDeltaExecutionState *state,
|
||||
guint64 *out_value,
|
||||
|
|
@ -195,6 +201,8 @@ _ostree_static_delta_part_execute (OstreeRepo *repo,
|
|||
StaticDeltaExecutionState *state = &statedata;
|
||||
guint n_executed = 0;
|
||||
|
||||
static_delta_execution_state_init (&statedata);
|
||||
|
||||
state->repo = repo;
|
||||
state->async_error = error;
|
||||
state->trusted = trusted;
|
||||
|
|
|
|||
|
|
@ -328,6 +328,7 @@ traverse_iter (OstreeRepo *repo,
|
|||
|
||||
ostree_repo_commit_traverse_iter_get_file (iter, &name, &checksum);
|
||||
|
||||
g_debug ("Found file object %s", checksum);
|
||||
key = ostree_object_name_serialize (checksum, OSTREE_OBJECT_TYPE_FILE);
|
||||
g_hash_table_replace (inout_reachable, key, key);
|
||||
key = NULL;
|
||||
|
|
@ -341,6 +342,8 @@ traverse_iter (OstreeRepo *repo,
|
|||
ostree_repo_commit_traverse_iter_get_dir (iter, &name, &content_checksum,
|
||||
&meta_checksum);
|
||||
|
||||
g_debug ("Found dirtree object %s", content_checksum);
|
||||
g_debug ("Found dirmeta object %s", meta_checksum);
|
||||
key = ostree_object_name_serialize (meta_checksum, OSTREE_OBJECT_TYPE_DIR_META);
|
||||
g_hash_table_replace (inout_reachable, key, key);
|
||||
key = NULL;
|
||||
|
|
@ -381,6 +384,7 @@ traverse_dirtree (OstreeRepo *repo,
|
|||
&dirtree, error))
|
||||
goto out;
|
||||
|
||||
g_debug ("Traversing dirtree %s", checksum);
|
||||
if (!ostree_repo_commit_traverse_iter_init_dirtree (&iter, repo, dirtree,
|
||||
OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE,
|
||||
error))
|
||||
|
|
@ -444,6 +448,7 @@ ostree_repo_traverse_commit_union (OstreeRepo *repo,
|
|||
g_hash_table_add (inout_reachable, key);
|
||||
key = NULL;
|
||||
|
||||
g_debug ("Traversing commit %s", commit_checksum);
|
||||
if (!ostree_repo_commit_traverse_iter_init_commit (&iter, repo, commit,
|
||||
OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE,
|
||||
error))
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ enum {
|
|||
PROP_0,
|
||||
|
||||
PROP_PATH,
|
||||
PROP_REMOTES_CONFIG_DIR,
|
||||
PROP_SYSROOT_PATH
|
||||
};
|
||||
|
||||
|
|
@ -217,6 +218,27 @@ ost_repo_get_remote (OstreeRepo *self,
|
|||
return remote;
|
||||
}
|
||||
|
||||
static OstreeRemote *
|
||||
ost_repo_get_remote_inherited (OstreeRepo *self,
|
||||
const char *name,
|
||||
GError **error)
|
||||
{
|
||||
local_cleanup_remote OstreeRemote *remote = NULL;
|
||||
g_autoptr(GError) temp_error = NULL;
|
||||
|
||||
remote = ost_repo_get_remote (self, name, &temp_error);
|
||||
if (remote == NULL)
|
||||
{
|
||||
if (self->parent_repo != NULL)
|
||||
return ost_repo_get_remote_inherited (self->parent_repo, name, error);
|
||||
|
||||
g_propagate_error (error, g_steal_pointer (&temp_error));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_steal_pointer (&remote);
|
||||
}
|
||||
|
||||
static void
|
||||
ost_repo_add_remote (OstreeRepo *self,
|
||||
OstreeRemote *remote)
|
||||
|
|
@ -257,16 +279,34 @@ _ostree_repo_remote_name_is_file (const char *remote_name)
|
|||
return g_str_has_prefix (remote_name, "file://");
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_get_remote_option:
|
||||
* @self: A OstreeRepo
|
||||
* @remote_name: Name
|
||||
* @option_name: Option
|
||||
* @default_value: (allow-none): Value returned if @option_name is not present
|
||||
* @out_value: (out): Return location for value
|
||||
* @error: Error
|
||||
*
|
||||
* OSTree remotes are represented by keyfile groups, formatted like:
|
||||
* `[remote "remotename"]`. This function returns a value named @option_name
|
||||
* underneath that group, or @default_value if the remote exists but not the
|
||||
* option name.
|
||||
*
|
||||
* Returns: %TRUE on success, otherwise %FALSE with @error set
|
||||
*/
|
||||
gboolean
|
||||
_ostree_repo_get_remote_option (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *option_name,
|
||||
const char *default_value,
|
||||
char **out_value,
|
||||
GError **error)
|
||||
ostree_repo_get_remote_option (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *option_name,
|
||||
const char *default_value,
|
||||
char **out_value,
|
||||
GError **error)
|
||||
{
|
||||
local_cleanup_remote OstreeRemote *remote = NULL;
|
||||
gboolean ret = FALSE;
|
||||
g_autoptr(GError) temp_error = NULL;
|
||||
g_autofree char *value = NULL;
|
||||
|
||||
if (_ostree_repo_remote_name_is_file (remote_name))
|
||||
{
|
||||
|
|
@ -274,30 +314,71 @@ _ostree_repo_get_remote_option (OstreeRepo *self,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
remote = ost_repo_get_remote (self, remote_name, error);
|
||||
|
||||
remote = ost_repo_get_remote (self, remote_name, &temp_error);
|
||||
if (remote != NULL)
|
||||
{
|
||||
ret = ot_keyfile_get_value_with_default (remote->options,
|
||||
remote->group,
|
||||
option_name,
|
||||
default_value,
|
||||
out_value,
|
||||
error);
|
||||
}
|
||||
value = g_key_file_get_string (remote->options, remote->group, option_name, &temp_error);
|
||||
if (value == NULL)
|
||||
{
|
||||
if (g_error_matches (temp_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND))
|
||||
{
|
||||
if (self->parent_repo != NULL)
|
||||
return ostree_repo_get_remote_option (self->parent_repo,
|
||||
remote_name, option_name,
|
||||
default_value,
|
||||
out_value,
|
||||
error);
|
||||
|
||||
value = g_strdup (default_value);
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
g_propagate_error (error, g_steal_pointer (&temp_error));
|
||||
}
|
||||
else
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (self->parent_repo != NULL)
|
||||
return ostree_repo_get_remote_option (self->parent_repo,
|
||||
remote_name, option_name,
|
||||
default_value,
|
||||
out_value,
|
||||
error);
|
||||
else
|
||||
g_propagate_error (error, g_steal_pointer (&temp_error));
|
||||
|
||||
*out_value = g_steal_pointer (&value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_get_remote_list_option:
|
||||
* @self: A OstreeRepo
|
||||
* @remote_name: Name
|
||||
* @option_name: Option
|
||||
* @out_value: (out) (array zero-terminated=1): location to store the list
|
||||
* of strings. The list should be freed with
|
||||
* g_strfreev().
|
||||
* @error: Error
|
||||
*
|
||||
* OSTree remotes are represented by keyfile groups, formatted like:
|
||||
* `[remote "remotename"]`. This function returns a value named @option_name
|
||||
* underneath that group, and returns it as an zero terminated array of strings.
|
||||
* If the option is not set, @out_value will be set to %NULL.
|
||||
*
|
||||
* Returns: %TRUE on success, otherwise %FALSE with @error set
|
||||
*/
|
||||
gboolean
|
||||
_ostree_repo_get_remote_list_option (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *option_name,
|
||||
char ***out_value,
|
||||
GError **error)
|
||||
ostree_repo_get_remote_list_option (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *option_name,
|
||||
char ***out_value,
|
||||
GError **error)
|
||||
{
|
||||
local_cleanup_remote OstreeRemote *remote = NULL;
|
||||
gboolean ret = FALSE;
|
||||
g_autoptr(GError) temp_error = NULL;
|
||||
g_auto(GStrv) value = NULL;
|
||||
|
||||
if (_ostree_repo_remote_name_is_file (remote_name))
|
||||
{
|
||||
|
|
@ -305,96 +386,110 @@ _ostree_repo_get_remote_list_option (OstreeRepo *self,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
remote = ost_repo_get_remote (self, remote_name, error);
|
||||
|
||||
remote = ost_repo_get_remote (self, remote_name, &temp_error);
|
||||
if (remote != NULL)
|
||||
{
|
||||
g_auto(GStrv) value = NULL;
|
||||
GError *local_error = NULL;
|
||||
|
||||
value = g_key_file_get_string_list (remote->options,
|
||||
remote->group,
|
||||
option_name,
|
||||
NULL, &local_error);
|
||||
NULL, &temp_error);
|
||||
|
||||
/* Default value if key not found is always NULL. */
|
||||
if (g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND))
|
||||
g_clear_error (&local_error);
|
||||
|
||||
if (local_error == NULL)
|
||||
if (g_error_matches (temp_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND))
|
||||
{
|
||||
ot_transfer_out_value (out_value, &value);
|
||||
if (self->parent_repo != NULL)
|
||||
return ostree_repo_get_remote_list_option (self->parent_repo,
|
||||
remote_name, option_name,
|
||||
out_value,
|
||||
error);
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (temp_error)
|
||||
g_propagate_error (error, g_steal_pointer (&temp_error));
|
||||
else
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (self->parent_repo != NULL)
|
||||
return ostree_repo_get_remote_list_option (self->parent_repo,
|
||||
remote_name, option_name,
|
||||
out_value,
|
||||
error);
|
||||
else
|
||||
g_propagate_error (error, g_steal_pointer (&temp_error));
|
||||
|
||||
*out_value = g_steal_pointer (&value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_get_remote_boolean_option:
|
||||
* @self: A OstreeRepo
|
||||
* @remote_name: Name
|
||||
* @option_name: Option
|
||||
* @default_value: (allow-none): Value returned if @option_name is not present
|
||||
* @out_value: (out) : location to store the result.
|
||||
* @error: Error
|
||||
*
|
||||
* OSTree remotes are represented by keyfile groups, formatted like:
|
||||
* `[remote "remotename"]`. This function returns a value named @option_name
|
||||
* underneath that group, and returns it as a boolean.
|
||||
* If the option is not set, @out_value will be set to @default_value.
|
||||
*
|
||||
* Returns: %TRUE on success, otherwise %FALSE with @error set
|
||||
*/
|
||||
gboolean
|
||||
_ostree_repo_get_remote_boolean_option (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *option_name,
|
||||
gboolean default_value,
|
||||
gboolean *out_value,
|
||||
GError **error)
|
||||
ostree_repo_get_remote_boolean_option (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *option_name,
|
||||
gboolean default_value,
|
||||
gboolean *out_value,
|
||||
GError **error)
|
||||
{
|
||||
local_cleanup_remote OstreeRemote *remote = NULL;
|
||||
g_autoptr(GError) temp_error = NULL;
|
||||
gboolean ret = FALSE;
|
||||
gboolean value = FALSE;
|
||||
|
||||
if (_ostree_repo_remote_name_is_file (remote_name))
|
||||
{
|
||||
*out_value = default_value;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
remote = ost_repo_get_remote (self, remote_name, error);
|
||||
|
||||
remote = ost_repo_get_remote (self, remote_name, &temp_error);
|
||||
if (remote != NULL)
|
||||
{
|
||||
ret = ot_keyfile_get_boolean_with_default (remote->options,
|
||||
remote->group,
|
||||
option_name,
|
||||
default_value,
|
||||
out_value,
|
||||
error);
|
||||
value = g_key_file_get_boolean (remote->options, remote->group, option_name, &temp_error);
|
||||
if (temp_error != NULL)
|
||||
{
|
||||
if (g_error_matches (temp_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND))
|
||||
{
|
||||
if (self->parent_repo != NULL)
|
||||
return ostree_repo_get_remote_boolean_option (self->parent_repo,
|
||||
remote_name, option_name,
|
||||
default_value,
|
||||
out_value,
|
||||
error);
|
||||
|
||||
value = default_value;
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
g_propagate_error (error, g_steal_pointer (&temp_error));
|
||||
}
|
||||
else
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (self->parent_repo != NULL)
|
||||
return ostree_repo_get_remote_boolean_option (self->parent_repo,
|
||||
remote_name, option_name,
|
||||
default_value,
|
||||
out_value,
|
||||
error);
|
||||
else
|
||||
g_propagate_error (error, g_steal_pointer (&temp_error));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_ostree_repo_get_remote_option_inherit (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *option_name,
|
||||
char **out_value,
|
||||
GError **error)
|
||||
{
|
||||
OstreeRepo *parent = ostree_repo_get_parent (self);
|
||||
g_autofree char *value = NULL;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
if (!_ostree_repo_get_remote_option (self,
|
||||
remote_name, option_name,
|
||||
NULL, &value, error))
|
||||
goto out;
|
||||
|
||||
if (value == NULL && parent != NULL)
|
||||
{
|
||||
if (!_ostree_repo_get_remote_option_inherit (parent,
|
||||
remote_name, option_name,
|
||||
&value, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Success here just means no error occurred during lookup,
|
||||
* not necessarily that we found a value for the option name. */
|
||||
if (out_value != NULL)
|
||||
*out_value = g_steal_pointer (&value);
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
*out_value = value;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -412,9 +507,9 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self,
|
|||
g_return_val_if_fail (OSTREE_IS_REPO (self), NULL);
|
||||
g_return_val_if_fail (remote_name != NULL, NULL);
|
||||
|
||||
if (!_ostree_repo_get_remote_boolean_option (self, remote_name,
|
||||
"tls-permissive", FALSE,
|
||||
&tls_permissive, error))
|
||||
if (!ostree_repo_get_remote_boolean_option (self, remote_name,
|
||||
"tls-permissive", FALSE,
|
||||
&tls_permissive, error))
|
||||
goto out;
|
||||
|
||||
if (tls_permissive)
|
||||
|
|
@ -426,13 +521,13 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self,
|
|||
g_autofree char *tls_client_cert_path = NULL;
|
||||
g_autofree char *tls_client_key_path = NULL;
|
||||
|
||||
if (!_ostree_repo_get_remote_option (self, remote_name,
|
||||
"tls-client-cert-path", NULL,
|
||||
&tls_client_cert_path, error))
|
||||
if (!ostree_repo_get_remote_option (self, remote_name,
|
||||
"tls-client-cert-path", NULL,
|
||||
&tls_client_cert_path, error))
|
||||
goto out;
|
||||
if (!_ostree_repo_get_remote_option (self, remote_name,
|
||||
"tls-client-key-path", NULL,
|
||||
&tls_client_key_path, error))
|
||||
if (!ostree_repo_get_remote_option (self, remote_name,
|
||||
"tls-client-key-path", NULL,
|
||||
&tls_client_key_path, error))
|
||||
goto out;
|
||||
|
||||
if ((tls_client_cert_path != NULL) != (tls_client_key_path != NULL))
|
||||
|
|
@ -462,9 +557,9 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self,
|
|||
{
|
||||
g_autofree char *tls_ca_path = NULL;
|
||||
|
||||
if (!_ostree_repo_get_remote_option (self, remote_name,
|
||||
"tls-ca-path", NULL,
|
||||
&tls_ca_path, error))
|
||||
if (!ostree_repo_get_remote_option (self, remote_name,
|
||||
"tls-ca-path", NULL,
|
||||
&tls_ca_path, error))
|
||||
goto out;
|
||||
|
||||
if (tls_ca_path != NULL)
|
||||
|
|
@ -482,9 +577,9 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self,
|
|||
{
|
||||
g_autofree char *http_proxy = NULL;
|
||||
|
||||
if (!_ostree_repo_get_remote_option (self, remote_name,
|
||||
"proxy", NULL,
|
||||
&http_proxy, error))
|
||||
if (!ostree_repo_get_remote_option (self, remote_name,
|
||||
"proxy", NULL,
|
||||
&http_proxy, error))
|
||||
goto out;
|
||||
|
||||
if (http_proxy != NULL)
|
||||
|
|
@ -519,6 +614,8 @@ ostree_repo_finalize (GObject *object)
|
|||
g_clear_object (&self->tmp_dir);
|
||||
if (self->tmp_dir_fd)
|
||||
(void) close (self->tmp_dir_fd);
|
||||
if (self->cache_dir_fd)
|
||||
(void) close (self->cache_dir_fd);
|
||||
g_clear_object (&self->objects_dir);
|
||||
if (self->objects_dir_fd != -1)
|
||||
(void) close (self->objects_dir_fd);
|
||||
|
|
@ -529,6 +626,7 @@ ostree_repo_finalize (GObject *object)
|
|||
(void) close (self->uncompressed_objects_dir_fd);
|
||||
g_clear_object (&self->config_file);
|
||||
g_clear_object (&self->sysroot_dir);
|
||||
g_free (self->remotes_config_dir);
|
||||
|
||||
g_clear_object (&self->transaction_lock_path);
|
||||
|
||||
|
|
@ -568,6 +666,9 @@ ostree_repo_set_property(GObject *object,
|
|||
case PROP_SYSROOT_PATH:
|
||||
self->sysroot_dir = g_value_dup_object (value);
|
||||
break;
|
||||
case PROP_REMOTES_CONFIG_DIR:
|
||||
self->remotes_config_dir = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -590,6 +691,9 @@ ostree_repo_get_property(GObject *object,
|
|||
case PROP_SYSROOT_PATH:
|
||||
g_value_set_object (value, self->sysroot_dir);
|
||||
break;
|
||||
case PROP_REMOTES_CONFIG_DIR:
|
||||
g_value_set_string (value, self->remotes_config_dir);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -643,6 +747,13 @@ ostree_repo_class_init (OstreeRepoClass *klass)
|
|||
"",
|
||||
G_TYPE_FILE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_REMOTES_CONFIG_DIR,
|
||||
g_param_spec_string ("remotes-config-dir",
|
||||
"",
|
||||
"",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
/**
|
||||
* OstreeRepo::gpg-verify-result:
|
||||
|
|
@ -690,6 +801,7 @@ ostree_repo_init (OstreeRepo *self)
|
|||
g_mutex_init (&self->remotes_lock);
|
||||
|
||||
self->repo_dir_fd = -1;
|
||||
self->cache_dir_fd = -1;
|
||||
self->commit_stagedir_fd = -1;
|
||||
self->objects_dir_fd = -1;
|
||||
self->uncompressed_objects_dir_fd = -1;
|
||||
|
|
@ -1216,6 +1328,25 @@ ostree_repo_remote_change (OstreeRepo *self,
|
|||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
static void
|
||||
_ostree_repo_remote_list (OstreeRepo *self,
|
||||
GHashTable *out)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
g_mutex_lock (&self->remotes_lock);
|
||||
|
||||
g_hash_table_iter_init (&iter, self->remotes);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
g_hash_table_insert (out, g_strdup (key), NULL);
|
||||
|
||||
g_mutex_unlock (&self->remotes_lock);
|
||||
|
||||
if (self->parent_repo)
|
||||
_ostree_repo_remote_list (self, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_remote_list:
|
||||
* @self: Repo
|
||||
|
|
@ -1233,10 +1364,15 @@ ostree_repo_remote_list (OstreeRepo *self,
|
|||
{
|
||||
char **remotes = NULL;
|
||||
guint n_remotes;
|
||||
g_autoptr(GHashTable) remotes_ht = NULL;
|
||||
|
||||
g_mutex_lock (&self->remotes_lock);
|
||||
remotes_ht = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
(GDestroyNotify) g_free,
|
||||
(GDestroyNotify) NULL);
|
||||
|
||||
n_remotes = g_hash_table_size (self->remotes);
|
||||
_ostree_repo_remote_list (self, remotes_ht);
|
||||
|
||||
n_remotes = g_hash_table_size (remotes_ht);
|
||||
|
||||
if (n_remotes > 0)
|
||||
{
|
||||
|
|
@ -1245,7 +1381,7 @@ ostree_repo_remote_list (OstreeRepo *self,
|
|||
|
||||
remotes = g_new (char *, n_remotes + 1);
|
||||
|
||||
list = g_hash_table_get_keys (self->remotes);
|
||||
list = g_hash_table_get_keys (remotes_ht);
|
||||
list = g_list_sort (list, (GCompareFunc) strcmp);
|
||||
|
||||
for (link = list; link != NULL; link = link->next)
|
||||
|
|
@ -1256,8 +1392,6 @@ ostree_repo_remote_list (OstreeRepo *self,
|
|||
remotes[ii] = NULL;
|
||||
}
|
||||
|
||||
g_mutex_unlock (&self->remotes_lock);
|
||||
|
||||
if (out_n_remotes)
|
||||
*out_n_remotes = n_remotes;
|
||||
|
||||
|
|
@ -1293,7 +1427,7 @@ ostree_repo_remote_get_url (OstreeRepo *self,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!_ostree_repo_get_remote_option_inherit (self, name, "url", &url, error))
|
||||
if (!ostree_repo_get_remote_option (self, name, "url", NULL, &url, error))
|
||||
goto out;
|
||||
|
||||
if (url == NULL)
|
||||
|
|
@ -1343,8 +1477,8 @@ ostree_repo_remote_get_gpg_verify (OstreeRepo *self,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
return _ostree_repo_get_remote_boolean_option (self, name, "gpg-verify",
|
||||
TRUE, out_gpg_verify, error);
|
||||
return ostree_repo_get_remote_boolean_option (self, name, "gpg-verify",
|
||||
TRUE, out_gpg_verify, error);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1366,8 +1500,8 @@ ostree_repo_remote_get_gpg_verify_summary (OstreeRepo *self,
|
|||
gboolean *out_gpg_verify_summary,
|
||||
GError **error)
|
||||
{
|
||||
return _ostree_repo_get_remote_boolean_option (self, name, "gpg-verify-summary",
|
||||
FALSE, out_gpg_verify_summary, error);
|
||||
return ostree_repo_get_remote_boolean_option (self, name, "gpg-verify-summary",
|
||||
FALSE, out_gpg_verify_summary, error);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1420,7 +1554,7 @@ ostree_repo_remote_gpg_import (OstreeRepo *self,
|
|||
|
||||
/* First make sure the remote name is valid. */
|
||||
|
||||
remote = ost_repo_get_remote (self, name, error);
|
||||
remote = ost_repo_get_remote_inherited (self, name, error);
|
||||
if (remote == NULL)
|
||||
goto out;
|
||||
|
||||
|
|
@ -1889,8 +2023,8 @@ ostree_repo_remote_fetch_summary (OstreeRepo *self,
|
|||
g_return_val_if_fail (OSTREE_REPO (self), FALSE);
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
|
||||
if (!_ostree_repo_get_remote_option (self, name, "metalink", NULL,
|
||||
&metalink_url_string, error))
|
||||
if (!ostree_repo_get_remote_option (self, name, "metalink", NULL,
|
||||
&metalink_url_string, error))
|
||||
goto out;
|
||||
|
||||
if (!repo_remote_fetch_summary (self,
|
||||
|
|
@ -2196,19 +2330,32 @@ append_one_remote_config (OstreeRepo *self,
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static GFile *
|
||||
get_remotes_d_dir (OstreeRepo *self)
|
||||
{
|
||||
if (self->remotes_config_dir != NULL)
|
||||
return g_file_resolve_relative_path (self->sysroot_dir, self->remotes_config_dir);
|
||||
else if (ostree_repo_is_system (self))
|
||||
return g_file_resolve_relative_path (self->sysroot_dir, SYSCONF_REMOTES);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
append_remotes_d (OstreeRepo *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
g_autoptr(GFile) etc_ostree_remotes_d = NULL;
|
||||
g_autoptr(GFile) remotes_d = NULL;
|
||||
g_autoptr(GFileEnumerator) direnum = NULL;
|
||||
|
||||
etc_ostree_remotes_d = g_file_resolve_relative_path (self->sysroot_dir, SYSCONF_REMOTES);
|
||||
remotes_d = get_remotes_d_dir (self);
|
||||
if (remotes_d == NULL)
|
||||
return TRUE;
|
||||
|
||||
if (!enumerate_directory_allow_noent (etc_ostree_remotes_d, OSTREE_GIO_FAST_QUERYINFO, 0,
|
||||
if (!enumerate_directory_allow_noent (remotes_d, OSTREE_GIO_FAST_QUERYINFO, 0,
|
||||
&direnum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
|
@ -2255,6 +2402,7 @@ ostree_repo_open (OstreeRepo *self,
|
|||
g_autofree char *version = NULL;
|
||||
g_autofree char *mode = NULL;
|
||||
g_autofree char *parent_repo_path = NULL;
|
||||
g_autoptr(GError) temp_error = NULL;
|
||||
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
|
|
@ -2382,15 +2530,40 @@ ostree_repo_open (OstreeRepo *self,
|
|||
ostree_repo_set_disable_fsync (self, TRUE);
|
||||
}
|
||||
|
||||
if (ostree_repo_is_system (self))
|
||||
{
|
||||
if (!append_remotes_d (self, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
if (!append_remotes_d (self, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!glnx_opendirat (self->repo_dir_fd, "tmp", TRUE, &self->tmp_dir_fd, error))
|
||||
goto out;
|
||||
|
||||
if (!glnx_shutil_mkdir_p_at (self->tmp_dir_fd, _OSTREE_CACHE_DIR, 0775, cancellable, &temp_error))
|
||||
{
|
||||
if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED))
|
||||
{
|
||||
g_clear_error (&temp_error);
|
||||
g_debug ("No permissions to create cache dir");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_propagate_error (error, g_steal_pointer (&temp_error));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!glnx_opendirat (self->tmp_dir_fd, _OSTREE_CACHE_DIR, TRUE, &self->cache_dir_fd, &temp_error))
|
||||
{
|
||||
if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||||
{
|
||||
g_clear_error (&temp_error);
|
||||
g_debug ("No cache dir");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_propagate_error (error, g_steal_pointer (&temp_error));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (self->mode == OSTREE_REPO_MODE_ARCHIVE_Z2 && self->enable_uncompressed_cache)
|
||||
{
|
||||
if (!gs_file_ensure_directory (self->uncompressed_objects_dir, TRUE, cancellable, error))
|
||||
|
|
@ -2425,6 +2598,36 @@ ostree_repo_set_disable_fsync (OstreeRepo *self,
|
|||
self->disable_fsync = disable_fsync;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_set_cache_dir:
|
||||
* @self: An #OstreeRepo
|
||||
* @dfd: directory fd
|
||||
* @path: subpath in @dfd
|
||||
*
|
||||
* Set a custom location for the cache directory used for e.g.
|
||||
* per-remote summary caches. Setting this manually is useful when
|
||||
* doing operations on a system repo as a user because you don't have
|
||||
* write permissions in the repo, where the cache is normally stored.
|
||||
*/
|
||||
gboolean
|
||||
ostree_repo_set_cache_dir (OstreeRepo *self,
|
||||
int dfd,
|
||||
const char *path,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (!glnx_opendirat (dfd, path, TRUE, &fd, error))
|
||||
return FALSE;
|
||||
|
||||
if (self->cache_dir_fd != -1)
|
||||
close (self->cache_dir_fd);
|
||||
self->cache_dir_fd = fd;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_get_disable_fsync:
|
||||
* @self: An #OstreeRepo
|
||||
|
|
@ -3310,24 +3513,37 @@ import_one_object_copy (OstreeRepo *self,
|
|||
OstreeRepo *source,
|
||||
const char *checksum,
|
||||
OstreeObjectType objtype,
|
||||
gboolean trusted,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
guint64 length;
|
||||
g_autoptr(GInputStream) object = NULL;
|
||||
g_autoptr(GInputStream) object_stream = NULL;
|
||||
|
||||
if (!ostree_repo_load_object_stream (source, objtype, checksum,
|
||||
&object, &length,
|
||||
&object_stream, &length,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (objtype == OSTREE_OBJECT_TYPE_FILE)
|
||||
{
|
||||
if (!ostree_repo_write_content_trusted (self, checksum,
|
||||
object, length,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
if (trusted)
|
||||
{
|
||||
if (!ostree_repo_write_content_trusted (self, checksum,
|
||||
object_stream, length,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_autofree guchar *real_csum = NULL;
|
||||
if (!ostree_repo_write_content (self, checksum,
|
||||
object_stream, length,
|
||||
&real_csum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -3336,10 +3552,29 @@ import_one_object_copy (OstreeRepo *self,
|
|||
if (!copy_detached_metadata (self, source, checksum, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
if (!ostree_repo_write_metadata_stream_trusted (self, objtype,
|
||||
checksum, object, length,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (trusted)
|
||||
{
|
||||
if (!ostree_repo_write_metadata_stream_trusted (self, objtype,
|
||||
checksum, object_stream, length,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_autofree guchar *real_csum = NULL;
|
||||
g_autoptr(GVariant) variant = NULL;
|
||||
|
||||
if (!ostree_repo_load_variant (source, objtype, checksum,
|
||||
&variant, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_repo_write_metadata (self, objtype,
|
||||
checksum, variant,
|
||||
&real_csum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
|
|
@ -3419,11 +3654,43 @@ ostree_repo_import_object_from (OstreeRepo *self,
|
|||
const char *checksum,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
return
|
||||
ostree_repo_import_object_from_with_trust (self, source, objtype,
|
||||
checksum, TRUE, cancellable, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_import_object_from_with_trust:
|
||||
* @self: Destination repo
|
||||
* @source: Source repo
|
||||
* @objtype: Object type
|
||||
* @checksum: checksum
|
||||
* @trusted: If %TRUE, assume the source repo is valid and trusted
|
||||
* @cancellable: Cancellable
|
||||
* @error: Error
|
||||
*
|
||||
* Copy object named by @objtype and @checksum into @self from the
|
||||
* source repository @source. If both repositories are of the same
|
||||
* type and on the same filesystem, this will simply be a fast Unix
|
||||
* hard link operation.
|
||||
*
|
||||
* Otherwise, a copy will be performed.
|
||||
*/
|
||||
gboolean
|
||||
ostree_repo_import_object_from_with_trust (OstreeRepo *self,
|
||||
OstreeRepo *source,
|
||||
OstreeObjectType objtype,
|
||||
const char *checksum,
|
||||
gboolean trusted,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gboolean hardlink_was_supported = FALSE;
|
||||
|
||||
if (self->mode == source->mode)
|
||||
|
||||
if (trusted && /* Don't hardlink into untrusted remotes */
|
||||
self->mode == source->mode)
|
||||
{
|
||||
if (!import_one_object_link (self, source, checksum, objtype,
|
||||
&hardlink_was_supported,
|
||||
|
|
@ -3438,10 +3705,10 @@ ostree_repo_import_object_from (OstreeRepo *self,
|
|||
if (!ostree_repo_has_object (self, objtype, checksum, &has_object,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
|
||||
if (!has_object)
|
||||
{
|
||||
if (!import_one_object_copy (self, source, checksum, objtype,
|
||||
if (!import_one_object_copy (self, source, checksum, objtype, trusted,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -3452,6 +3719,7 @@ ostree_repo_import_object_from (OstreeRepo *self,
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ostree_repo_query_object_storage_size:
|
||||
* @self: Repo
|
||||
|
|
@ -3818,11 +4086,17 @@ ostree_repo_pull_one_dir (OstreeRepo *self,
|
|||
* Like ostree_repo_pull(), but supports an extensible set of flags.
|
||||
* The following are currently defined:
|
||||
*
|
||||
* * subdir (s): Pull just this subdirectory
|
||||
* * refs (as): Array of string refs
|
||||
* * flags (i): An instance of #OstreeRepoPullFlags
|
||||
* * refs: (as): Array of string refs
|
||||
* * depth: (i): How far in the history to traverse; default is 0, -1 means infinite
|
||||
* * override-commit-ids: (as): Array of specific commit IDs to fetch for refs
|
||||
* * subdir (s): Pull just this subdirectory
|
||||
* * override-remote-name (s): If local, add this remote to refspec
|
||||
* * gpg-verify (b): GPG verify commits
|
||||
* * gpg-verify-summary (b): GPG verify summary
|
||||
* * depth (i): How far in the history to traverse; default is 0, -1 means infinite
|
||||
* * disable-static-deltas (b): Do not use static deltas
|
||||
* * require-static-deltas (b): Require static deltas
|
||||
* * override-commit-ids (as): Array of specific commit IDs to fetch for refs
|
||||
* * dry-run (b): Only print information on what will be downloaded (requires static deltas)
|
||||
*/
|
||||
gboolean
|
||||
ostree_repo_pull_with_options (OstreeRepo *self,
|
||||
|
|
@ -4296,6 +4570,35 @@ ostree_repo_add_gpg_signature_summary (OstreeRepo *self,
|
|||
/* Special remote for _ostree_repo_gpg_verify_with_metadata() */
|
||||
static const char *OSTREE_ALL_REMOTES = "__OSTREE_ALL_REMOTES__";
|
||||
|
||||
static GFile *
|
||||
find_keyring (OstreeRepo *self,
|
||||
OstreeRemote *remote,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
g_autoptr(GFile) remotes_d = NULL;
|
||||
g_autoptr(GFile) file = NULL;
|
||||
file = g_file_get_child (self->repodir, remote->keyring);
|
||||
|
||||
if (g_file_query_exists (file, cancellable))
|
||||
{
|
||||
return g_steal_pointer (&file);
|
||||
}
|
||||
|
||||
remotes_d = get_remotes_d_dir (self);
|
||||
if (remotes_d)
|
||||
{
|
||||
g_autoptr(GFile) file2 = g_file_get_child (remotes_d, remote->keyring);
|
||||
|
||||
if (g_file_query_exists (file2, cancellable))
|
||||
return g_steal_pointer (&file2);
|
||||
}
|
||||
|
||||
if (self->parent_repo)
|
||||
return find_keyring (self->parent_repo, remote, cancellable);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
OstreeGpgVerifyResult *
|
||||
_ostree_repo_gpg_verify_with_metadata (OstreeRepo *self,
|
||||
GBytes *signed_data,
|
||||
|
|
@ -4332,13 +4635,13 @@ _ostree_repo_gpg_verify_with_metadata (OstreeRepo *self,
|
|||
OstreeRemote *remote;
|
||||
g_autoptr(GFile) file = NULL;
|
||||
|
||||
remote = ost_repo_get_remote (self, remote_name, error);
|
||||
remote = ost_repo_get_remote_inherited (self, remote_name, error);
|
||||
if (remote == NULL)
|
||||
goto out;
|
||||
|
||||
file = g_file_get_child (self->repodir, remote->keyring);
|
||||
file = find_keyring (self, remote, cancellable);
|
||||
|
||||
if (g_file_query_exists (file, cancellable))
|
||||
if (file != NULL)
|
||||
{
|
||||
_ostree_gpg_verifier_add_keyring (verifier, file);
|
||||
add_global_keyring_dir = FALSE;
|
||||
|
|
|
|||
|
|
@ -63,6 +63,13 @@ _OSTREE_PUBLIC
|
|||
void ostree_repo_set_disable_fsync (OstreeRepo *self,
|
||||
gboolean disable_fsync);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_set_cache_dir (OstreeRepo *self,
|
||||
int dfd,
|
||||
const char *path,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_get_disable_fsync (OstreeRepo *self);
|
||||
|
||||
|
|
@ -147,6 +154,29 @@ gboolean ostree_repo_remote_get_gpg_verify_summary (OstreeRepo *self,
|
|||
gboolean *out_gpg_verify_summary,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_get_remote_option (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *option_name,
|
||||
const char *default_value,
|
||||
char **out_value,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_get_remote_list_option (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *option_name,
|
||||
char ***out_value,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_get_remote_boolean_option (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *option_name,
|
||||
gboolean default_value,
|
||||
gboolean *out_value,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_remote_gpg_import (OstreeRepo *self,
|
||||
const char *name,
|
||||
|
|
@ -423,6 +453,14 @@ gboolean ostree_repo_import_object_from (OstreeRepo *self,
|
|||
const char *checksum,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_import_object_from_with_trust (OstreeRepo *self,
|
||||
OstreeRepo *source,
|
||||
OstreeObjectType objtype,
|
||||
const char *checksum,
|
||||
gboolean trusted,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_repo_delete_object (OstreeRepo *self,
|
||||
|
|
@ -891,11 +929,13 @@ gboolean ostree_repo_prune (OstreeRepo *self,
|
|||
* @OSTREE_REPO_PULL_FLAGS_NONE: No special options for pull
|
||||
* @OSTREE_REPO_PULL_FLAGS_MIRROR: Write out refs suitable for mirrors
|
||||
* @OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY: Fetch only the commit metadata
|
||||
* @OSTREE_REPO_PULL_FLAGS_UNTRUSTED: Don't trust local remote
|
||||
*/
|
||||
typedef enum {
|
||||
OSTREE_REPO_PULL_FLAGS_NONE,
|
||||
OSTREE_REPO_PULL_FLAGS_MIRROR = (1 << 0),
|
||||
OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY = (1 << 1)
|
||||
OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY = (1 << 1),
|
||||
OSTREE_REPO_PULL_FLAGS_UNTRUSTED = (1 << 2)
|
||||
} OstreeRepoPullFlags;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ struct OstreeSePolicy {
|
|||
GFile *selinux_policy_root;
|
||||
struct selabel_handle *selinux_hnd;
|
||||
char *selinux_policy_name;
|
||||
char *selinux_policy_csum;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -77,6 +78,7 @@ ostree_sepolicy_finalize (GObject *object)
|
|||
#ifdef HAVE_SELINUX
|
||||
g_clear_object (&self->selinux_policy_root);
|
||||
g_clear_pointer (&self->selinux_policy_name, g_free);
|
||||
g_clear_pointer (&self->selinux_policy_csum, g_free);
|
||||
if (self->selinux_hnd)
|
||||
{
|
||||
selabel_close (self->selinux_hnd);
|
||||
|
|
@ -155,6 +157,93 @@ ostree_sepolicy_class_init (OstreeSePolicyClass *klass)
|
|||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
|
||||
/* Find the latest policy file in our root and return its checksum. */
|
||||
static gboolean
|
||||
get_policy_checksum (char **out_csum,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
|
||||
const char *binary_policy_path = selinux_binary_policy_path ();
|
||||
const char *binfile_prefix = glnx_basename (binary_policy_path);
|
||||
g_autofree char *bindir_path = g_path_get_dirname (binary_policy_path);
|
||||
|
||||
glnx_fd_close int bindir_dfd = -1;
|
||||
|
||||
g_autofree char *best_policy = NULL;
|
||||
int best_version = 0;
|
||||
|
||||
g_auto(GLnxDirFdIterator) dfd_iter = { 0,};
|
||||
|
||||
if (!glnx_opendirat (AT_FDCWD, bindir_path, TRUE, &bindir_dfd, error))
|
||||
goto out;
|
||||
|
||||
if (!glnx_dirfd_iterator_init_at (bindir_dfd, ".", FALSE, &dfd_iter, error))
|
||||
goto out;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
struct dirent *dent = NULL;
|
||||
|
||||
if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (dent == NULL)
|
||||
break;
|
||||
|
||||
if (dent->d_type == DT_REG)
|
||||
{
|
||||
/* We could probably save a few hundred nanoseconds if we accept that
|
||||
* the prefix will always be "policy" and hardcode that in a static
|
||||
* compile-once GRegex... But picture how exciting it'd be if it *did*
|
||||
* somehow change; there would be cheers & slow-mo high-fives at the
|
||||
* sight of our code not breaking. Is that hope not worth a fraction
|
||||
* of a millisecond? I believe it is... or maybe I'm just lazy. */
|
||||
g_autofree char *regex = g_strdup_printf ("^\\Q%s\\E\\.[0-9]+$",
|
||||
binfile_prefix);
|
||||
|
||||
/* we could use match groups to extract the version, but mehhh, we
|
||||
* already have the prefix on hand */
|
||||
if (g_regex_match_simple (regex, dent->d_name, 0, 0))
|
||||
{
|
||||
int version = /* do +1 for the period */
|
||||
(int)g_ascii_strtoll (dent->d_name + strlen (binfile_prefix)+1,
|
||||
NULL, 10);
|
||||
g_assert (version > 0);
|
||||
|
||||
if (version > best_version)
|
||||
{
|
||||
best_version = version;
|
||||
g_free (best_policy);
|
||||
best_policy = g_strdup (dent->d_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!best_policy)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Could not find binary policy file");
|
||||
goto out;
|
||||
}
|
||||
|
||||
*out_csum = ot_checksum_file_at (bindir_dfd, best_policy, G_CHECKSUM_SHA256,
|
||||
cancellable, error);
|
||||
if (*out_csum == NULL)
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
initable_init (GInitable *initable,
|
||||
GCancellable *cancellable,
|
||||
|
|
@ -257,6 +346,12 @@ initable_init (GInitable *initable,
|
|||
freecon (con);
|
||||
}
|
||||
|
||||
if (!get_policy_checksum (&self->selinux_policy_csum, cancellable, error))
|
||||
{
|
||||
g_prefix_error (error, "While calculating SELinux checksum: ");
|
||||
goto out;
|
||||
}
|
||||
|
||||
self->selinux_policy_name = g_strdup (policytype);
|
||||
self->selinux_policy_root = g_object_ref (etc_selinux_dir);
|
||||
}
|
||||
|
|
@ -306,6 +401,12 @@ ostree_sepolicy_get_path (OstreeSePolicy *self)
|
|||
return self->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_sepolicy_get_name:
|
||||
* @self:
|
||||
*
|
||||
* Returns: (transfer none): Type of current policy
|
||||
*/
|
||||
const char *
|
||||
ostree_sepolicy_get_name (OstreeSePolicy *self)
|
||||
{
|
||||
|
|
@ -316,6 +417,22 @@ ostree_sepolicy_get_name (OstreeSePolicy *self)
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_sepolicy_get_csum:
|
||||
* @self:
|
||||
*
|
||||
* Returns: (transfer none): Checksum of current policy
|
||||
*/
|
||||
const char *
|
||||
ostree_sepolicy_get_csum (OstreeSePolicy *self)
|
||||
{
|
||||
#ifdef HAVE_SELINUX
|
||||
return self->selinux_policy_csum;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_sepolicy_get_label:
|
||||
* @self: Self
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@ GFile * ostree_sepolicy_get_path (OstreeSePolicy *self);
|
|||
_OSTREE_PUBLIC
|
||||
const char *ostree_sepolicy_get_name (OstreeSePolicy *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
const char *ostree_sepolicy_get_csum (OstreeSePolicy *self);
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
gboolean ostree_sepolicy_get_label (OstreeSePolicy *self,
|
||||
const char *relpath,
|
||||
|
|
|
|||
|
|
@ -1850,4 +1850,3 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self,
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -140,17 +140,17 @@ ot_gio_checksum_stream (GInputStream *in,
|
|||
}
|
||||
|
||||
char *
|
||||
ot_checksum_file (GFile *file,
|
||||
GChecksumType checksum_type,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
ot_checksum_file_at (int dfd,
|
||||
const char *path,
|
||||
GChecksumType checksum_type,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
GChecksum *checksum = NULL;
|
||||
char *ret = NULL;
|
||||
g_autoptr(GInputStream) in = NULL;
|
||||
|
||||
in = (GInputStream*)g_file_read (file, cancellable, error);
|
||||
if (!in)
|
||||
if (!ot_openat_read_stream (dfd, path, TRUE, &in, cancellable, error))
|
||||
goto out;
|
||||
|
||||
checksum = g_checksum_new (checksum_type);
|
||||
|
|
|
|||
|
|
@ -53,10 +53,11 @@ gboolean ot_gio_checksum_stream (GInputStream *in,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
char * ot_checksum_file (GFile *file,
|
||||
GChecksumType checksum_type,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
char * ot_checksum_file_at (int dfd,
|
||||
const char *path,
|
||||
GChecksumType checksum_type,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
void ot_gio_checksum_stream_async (GInputStream *in,
|
||||
int io_priority,
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@ ot_variant_bsearch_str (GVariant *array,
|
|||
int *out_pos)
|
||||
{
|
||||
gsize imax, imin;
|
||||
gsize imid;
|
||||
gsize imid = -1;
|
||||
gsize n;
|
||||
|
||||
n = g_variant_n_children (array);
|
||||
|
|
@ -337,7 +337,7 @@ ot_variant_bsearch_str (GVariant *array,
|
|||
imid = (imin + imax) / 2;
|
||||
|
||||
child = g_variant_get_child_value (array, imid);
|
||||
g_variant_get_child (child, 0, "&s", &cur, NULL);
|
||||
g_variant_get_child (child, 0, "&s", &cur, NULL);
|
||||
|
||||
cmp = strcmp (cur, str);
|
||||
if (cmp < 0)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
static char *opt_subject;
|
||||
static char *opt_body;
|
||||
static char *opt_parent;
|
||||
static gboolean opt_orphan;
|
||||
static char *opt_branch;
|
||||
static char *opt_statoverride_file;
|
||||
static char **opt_metadata_strings;
|
||||
|
|
@ -67,9 +69,11 @@ parse_fsync_cb (const char *option_name,
|
|||
}
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{ "parent", 0, 0, G_OPTION_ARG_STRING, &opt_parent, "Parent ref, or \"none\"", "REF" },
|
||||
{ "subject", 's', 0, G_OPTION_ARG_STRING, &opt_subject, "One line subject", "SUBJECT" },
|
||||
{ "body", 'm', 0, G_OPTION_ARG_STRING, &opt_body, "Full description", "BODY" },
|
||||
{ "branch", 'b', 0, G_OPTION_ARG_STRING, &opt_branch, "Branch", "BRANCH" },
|
||||
{ "orphan", 0, 0, G_OPTION_ARG_NONE, &opt_orphan, "Create a commit without writing a ref", NULL },
|
||||
{ "tree", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_trees, "Overlay the given argument as a tree", "dir=PATH or tar=TARFILE or ref=COMMIT" },
|
||||
{ "add-metadata-string", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_metadata_strings, "Add a key/value pair to metadata", "KEY=VALUE" },
|
||||
{ "add-detached-metadata-string", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_detached_metadata_strings, "Add a key/value pair to detached metadata", "KEY=VALUE" },
|
||||
|
|
@ -190,9 +194,8 @@ commit_editor (OstreeRepo *repo,
|
|||
input = g_strdup_printf ("\n"
|
||||
"# Please enter the commit message for your changes. The first line will\n"
|
||||
"# become the subject, and the remainder the body. Lines starting\n"
|
||||
"# with '#' will be ignored, and an empty message aborts the commit.\n"
|
||||
"#\n"
|
||||
"# Branch: %s\n", branch);
|
||||
"# with '#' will be ignored, and an empty message aborts the commit."
|
||||
"%s%s\n", branch ? "\n#\n# Branch: " : "", branch ?: "");
|
||||
|
||||
output = ot_editor_prompt (repo, input, cancellable, error);
|
||||
if (output == NULL)
|
||||
|
|
@ -338,10 +341,10 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (!opt_branch)
|
||||
if (!(opt_branch || opt_orphan))
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"A branch must be specified with --branch");
|
||||
"A branch must be specified with --branch, or use --orphan");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -361,8 +364,22 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError
|
|||
modifier = ostree_repo_commit_modifier_new (flags, commit_filter, mode_adds, NULL);
|
||||
}
|
||||
|
||||
if (!ostree_repo_resolve_rev (repo, opt_branch, TRUE, &parent, error))
|
||||
goto out;
|
||||
if (opt_parent)
|
||||
{
|
||||
if (g_str_equal (opt_parent, "none"))
|
||||
parent = NULL;
|
||||
else
|
||||
{
|
||||
if (!ostree_validate_checksum_string (opt_parent, error))
|
||||
goto out;
|
||||
parent = g_strdup (opt_parent);
|
||||
}
|
||||
}
|
||||
else if (!opt_orphan)
|
||||
{
|
||||
if (!ostree_repo_resolve_rev (repo, opt_branch, TRUE, &parent, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!opt_subject && !opt_body)
|
||||
{
|
||||
|
|
@ -547,7 +564,10 @@ ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError
|
|||
}
|
||||
}
|
||||
|
||||
ostree_repo_transaction_set_ref (repo, NULL, opt_branch, commit_checksum);
|
||||
if (opt_branch)
|
||||
ostree_repo_transaction_set_ref (repo, NULL, opt_branch, commit_checksum);
|
||||
else
|
||||
g_assert (opt_orphan);
|
||||
|
||||
if (!ostree_repo_commit_transaction (repo, &stats, cancellable, error))
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -32,11 +32,17 @@
|
|||
|
||||
static char *opt_remote;
|
||||
static gboolean opt_disable_fsync;
|
||||
static gboolean opt_untrusted;
|
||||
static gboolean opt_gpg_verify;
|
||||
static gboolean opt_gpg_verify_summary;
|
||||
static int opt_depth = 0;
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{ "remote", 0, 0, G_OPTION_ARG_STRING, &opt_remote, "Add REMOTE to refspec", "REMOTE" },
|
||||
{ "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL },
|
||||
{ "untrusted", 0, 0, G_OPTION_ARG_NONE, &opt_untrusted, "Do not trust source", NULL },
|
||||
{ "gpg-verify", 0, 0, G_OPTION_ARG_NONE, &opt_gpg_verify, "GPG verify commits (must specify --remote)", NULL },
|
||||
{ "gpg-verify-summary", 0, 0, G_OPTION_ARG_NONE, &opt_gpg_verify_summary, "GPG verify summary (must specify --remote)", NULL },
|
||||
{ "depth", 0, 0, G_OPTION_ARG_INT, &opt_depth, "Traverse DEPTH parents (-1=infinite) (default: 0)", "DEPTH" },
|
||||
{ NULL }
|
||||
};
|
||||
|
|
@ -54,6 +60,7 @@ ostree_builtin_pull_local (int argc, char **argv, GCancellable *cancellable, GEr
|
|||
glnx_unref_object OstreeAsyncProgress *progress = NULL;
|
||||
g_autoptr(GPtrArray) refs_to_fetch = NULL;
|
||||
g_autoptr(GHashTable) source_objects = NULL;
|
||||
OstreeRepoPullFlags pullflags = 0;
|
||||
|
||||
context = g_option_context_new ("SRC_REPO [REFS...] - Copy data from SRC_REPO");
|
||||
|
||||
|
|
@ -83,6 +90,9 @@ ostree_builtin_pull_local (int argc, char **argv, GCancellable *cancellable, GEr
|
|||
src_repo_uri = g_strconcat ("file://", cwd, "/", src_repo_arg, NULL);
|
||||
}
|
||||
|
||||
if (opt_untrusted)
|
||||
pullflags |= OSTREE_REPO_PULL_FLAGS_UNTRUSTED;
|
||||
|
||||
if (opt_disable_fsync)
|
||||
ostree_repo_set_disable_fsync (repo, TRUE);
|
||||
|
||||
|
|
@ -133,15 +143,21 @@ ostree_builtin_pull_local (int argc, char **argv, GCancellable *cancellable, GEr
|
|||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
|
||||
|
||||
g_variant_builder_add (&builder, "{s@v}", "flags",
|
||||
g_variant_new_variant (g_variant_new_int32 (OSTREE_REPO_PULL_FLAGS_NONE)));
|
||||
g_variant_new_variant (g_variant_new_int32 (pullflags)));
|
||||
g_variant_builder_add (&builder, "{s@v}", "refs",
|
||||
g_variant_new_variant (g_variant_new_strv ((const char *const*) refs_to_fetch->pdata, -1)));
|
||||
if (opt_remote)
|
||||
g_variant_builder_add (&builder, "{s@v}", "override-remote-name",
|
||||
g_variant_new_variant (g_variant_new_string (opt_remote)));
|
||||
if (opt_gpg_verify)
|
||||
g_variant_builder_add (&builder, "{s@v}", "gpg-verify",
|
||||
g_variant_new_variant (g_variant_new_boolean (TRUE)));
|
||||
if (opt_gpg_verify_summary)
|
||||
g_variant_builder_add (&builder, "{s@v}", "gpg-verify-summary",
|
||||
g_variant_new_variant (g_variant_new_boolean (TRUE)));
|
||||
g_variant_builder_add (&builder, "{s@v}", "depth",
|
||||
g_variant_new_variant (g_variant_new_int32 (opt_depth)));
|
||||
|
||||
|
||||
if (!ostree_repo_pull_with_options (repo, src_repo_uri,
|
||||
g_variant_builder_end (&builder),
|
||||
progress,
|
||||
|
|
|
|||
|
|
@ -33,16 +33,20 @@ static gboolean opt_commit_only;
|
|||
static gboolean opt_dry_run;
|
||||
static gboolean opt_disable_static_deltas;
|
||||
static gboolean opt_require_static_deltas;
|
||||
static gboolean opt_untrusted;
|
||||
static char* opt_subpath;
|
||||
static char* opt_cache_dir;
|
||||
static int opt_depth = 0;
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{ "commit-metadata-only", 0, 0, G_OPTION_ARG_NONE, &opt_commit_only, "Fetch only the commit metadata", NULL },
|
||||
{ "cache-dir", 0, 0, G_OPTION_ARG_STRING, &opt_cache_dir, "Use custom cache dir", NULL },
|
||||
{ "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL },
|
||||
{ "disable-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_disable_static_deltas, "Do not use static deltas", NULL },
|
||||
{ "require-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_require_static_deltas, "Require static deltas", NULL },
|
||||
{ "mirror", 0, 0, G_OPTION_ARG_NONE, &opt_mirror, "Write refs suitable for a mirror", NULL },
|
||||
{ "subpath", 0, 0, G_OPTION_ARG_STRING, &opt_subpath, "Only pull the provided subpath", NULL },
|
||||
{ "untrusted", 0, 0, G_OPTION_ARG_NONE, &opt_untrusted, "Do not trust (local) sources", NULL },
|
||||
{ "dry-run", 0, 0, G_OPTION_ARG_NONE, &opt_dry_run, "Only print information on what will be downloaded (requires static deltas)", NULL },
|
||||
{ "depth", 0, 0, G_OPTION_ARG_INT, &opt_depth, "Traverse DEPTH parents (-1=infinite) (default: 0)", "DEPTH" },
|
||||
{ NULL }
|
||||
|
|
@ -128,12 +132,21 @@ ostree_builtin_pull (int argc, char **argv, GCancellable *cancellable, GError **
|
|||
if (opt_disable_fsync)
|
||||
ostree_repo_set_disable_fsync (repo, TRUE);
|
||||
|
||||
if (opt_cache_dir)
|
||||
{
|
||||
if (!ostree_repo_set_cache_dir (repo, AT_FDCWD, opt_cache_dir, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (opt_mirror)
|
||||
pullflags |= OSTREE_REPO_PULL_FLAGS_MIRROR;
|
||||
|
||||
if (opt_commit_only)
|
||||
pullflags |= OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY;
|
||||
|
||||
if (opt_untrusted)
|
||||
pullflags |= OSTREE_REPO_PULL_FLAGS_UNTRUSTED;
|
||||
|
||||
if (opt_dry_run && !opt_require_static_deltas)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ static gboolean opt_disable_bsdiff;
|
|||
|
||||
BUILTINPROTO(list);
|
||||
BUILTINPROTO(show);
|
||||
BUILTINPROTO(delete);
|
||||
BUILTINPROTO(generate);
|
||||
BUILTINPROTO(apply_offline);
|
||||
|
||||
|
|
@ -50,6 +51,7 @@ BUILTINPROTO(apply_offline);
|
|||
static OstreeCommand static_delta_subcommands[] = {
|
||||
{ "list", ot_static_delta_builtin_list },
|
||||
{ "show", ot_static_delta_builtin_show },
|
||||
{ "delete", ot_static_delta_builtin_delete },
|
||||
{ "generate", ot_static_delta_builtin_generate },
|
||||
{ "apply-offline", ot_static_delta_builtin_apply_offline },
|
||||
{ NULL, NULL }
|
||||
|
|
@ -168,6 +170,39 @@ ot_static_delta_builtin_show (int argc, char **argv, GCancellable *cancellable,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ot_static_delta_builtin_delete (int argc, char **argv, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GOptionContext *context;
|
||||
glnx_unref_object OstreeRepo *repo = NULL;
|
||||
const char *delta_id = NULL;
|
||||
|
||||
context = g_option_context_new ("DELETE - Remove a delta");
|
||||
|
||||
if (!ostree_option_context_parse (context, list_options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"DELTA must be specified");
|
||||
goto out;
|
||||
}
|
||||
|
||||
delta_id = argv[2];
|
||||
|
||||
if (!ostree_cmd__private__ ()->ostree_static_delta_delete (repo, delta_id, cancellable, error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
if (context)
|
||||
g_option_context_free (context);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
ot_static_delta_builtin_generate (int argc, char **argv, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ ostree_run (int argc,
|
|||
/* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */
|
||||
g_setenv ("GIO_USE_VFS", "local", TRUE);
|
||||
|
||||
g_log_set_handler (NULL, G_LOG_LEVEL_MESSAGE, message_handler, NULL);
|
||||
g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, message_handler, NULL);
|
||||
|
||||
/*
|
||||
* Parse the global options. We rearrange the options as
|
||||
|
|
@ -255,7 +255,7 @@ ostree_option_context_parse (GOptionContext *context,
|
|||
}
|
||||
|
||||
if (opt_verbose)
|
||||
g_log_set_handler (NULL, G_LOG_LEVEL_DEBUG, message_handler, NULL);
|
||||
g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, message_handler, NULL);
|
||||
|
||||
if (opt_repo == NULL && !(flags & OSTREE_BUILTIN_FLAG_NO_REPO))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,7 +25,10 @@
|
|||
#include "ot-main.h"
|
||||
#include "ot-remote-builtins.h"
|
||||
|
||||
static char* opt_cache_dir;
|
||||
|
||||
static GOptionEntry option_entries[] = {
|
||||
{ "cache-dir", 0, 0, G_OPTION_ARG_STRING, &opt_cache_dir, "Use custom cache dir", NULL },
|
||||
};
|
||||
|
||||
gboolean
|
||||
|
|
@ -49,6 +52,12 @@ ot_remote_builtin_refs (int argc, char **argv, GCancellable *cancellable, GError
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (opt_cache_dir)
|
||||
{
|
||||
if (!ostree_repo_set_cache_dir (repo, AT_FDCWD, opt_cache_dir, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
remote_name = argv[1];
|
||||
|
||||
if (!ostree_repo_remote_list_refs (repo, remote_name, &refs, cancellable, error))
|
||||
|
|
|
|||
|
|
@ -28,7 +28,10 @@
|
|||
|
||||
static gboolean opt_raw;
|
||||
|
||||
static char* opt_cache_dir;
|
||||
|
||||
static GOptionEntry option_entries[] = {
|
||||
{ "cache-dir", 0, 0, G_OPTION_ARG_STRING, &opt_cache_dir, "Use custom cache dir", NULL },
|
||||
{ "raw", 0, 0, G_OPTION_ARG_NONE, &opt_raw, "Show raw variant data", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
|
@ -59,6 +62,12 @@ ot_remote_builtin_summary (int argc, char **argv, GCancellable *cancellable, GEr
|
|||
|
||||
remote_name = argv[1];
|
||||
|
||||
if (opt_cache_dir)
|
||||
{
|
||||
if (!ostree_repo_set_cache_dir (repo, AT_FDCWD, opt_cache_dir, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (opt_raw)
|
||||
flags |= OSTREE_DUMP_RAW;
|
||||
|
||||
|
|
|
|||
|
|
@ -66,4 +66,3 @@ path_is_on_readonly_fs (char *path)
|
|||
|
||||
return (stvfsbuf.f_flag & ST_RDONLY) != 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
# Copyright (C) 2011,2014 Colin Walters <walters@verbum.org>
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
|
|
@ -21,10 +21,17 @@ set -euo pipefail
|
|||
echo "1..16"
|
||||
|
||||
function validate_bootloader() {
|
||||
(cd ${test_tmpdir};
|
||||
if test -f sysroot/boot/syslinux/syslinux.cfg; then
|
||||
$(dirname $0)/syslinux-entries-crosscheck.py sysroot
|
||||
fi)
|
||||
cd ${test_tmpdir};
|
||||
bootloader=""
|
||||
if test -f sysroot/boot/syslinux/syslinux.cfg; then
|
||||
bootloader="syslinux"
|
||||
elif test -f sysroot/boot/grub2/grub.cfg; then
|
||||
bootloader="grub2"
|
||||
fi
|
||||
if test -n "${bootloader}"; then
|
||||
$(dirname $0)/bootloader-entries-crosscheck.py sysroot ${bootloader}
|
||||
fi
|
||||
cd -
|
||||
}
|
||||
|
||||
orig_mtime=$(stat -c '%.Y' sysroot/ostree/deploy)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
echo "1..50"
|
||||
echo "1..53"
|
||||
|
||||
$OSTREE checkout test2 checkout-test2
|
||||
echo "ok checkout"
|
||||
|
|
@ -96,6 +96,33 @@ assert_file_has_content yet/another/tree/green 'leaf'
|
|||
assert_file_has_content four '4'
|
||||
echo "ok cwd contents"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
$OSTREE commit -b test2-no-parent -s '' $test_tmpdir/checkout-test2-4
|
||||
assert_streq $($OSTREE log test2-no-parent |grep '^commit' | wc -l) "1"
|
||||
$OSTREE commit -b test2-no-parent -s '' --parent=none $test_tmpdir/checkout-test2-4
|
||||
assert_streq $($OSTREE log test2-no-parent |grep '^commit' | wc -l) "1"
|
||||
echo "ok commit no parent"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
$OSTREE commit -b test2-custom-parent -s '' $test_tmpdir/checkout-test2-4
|
||||
$OSTREE commit -b test2-custom-parent -s '' $test_tmpdir/checkout-test2-4
|
||||
$OSTREE commit -b test2-custom-parent -s '' $test_tmpdir/checkout-test2-4
|
||||
assert_streq $($OSTREE log test2-custom-parent |grep '^commit' | wc -l) "3"
|
||||
prevparent=$($OSTREE rev-parse test2-custom-parent^)
|
||||
$OSTREE commit -b test2-custom-parent -s '' --parent=${prevparent} $test_tmpdir/checkout-test2-4
|
||||
assert_streq $($OSTREE log test2-custom-parent |grep '^commit' | wc -l) "3"
|
||||
echo "ok commit custom parent"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
orphaned_rev=$($OSTREE commit --orphan -s "$(date)" $test_tmpdir/checkout-test2-4)
|
||||
$OSTREE ls ${orphaned_rev} >/dev/null
|
||||
$OSTREE prune --refs-only
|
||||
if $OSTREE ls ${orphaned_rev} 2>err.txt; then
|
||||
assert_not_reached "Found orphaned commit"
|
||||
fi
|
||||
assert_file_has_content err.txt "No such metadata object"
|
||||
echo "ok commit orphaned"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
$OSTREE diff test2^ test2 > diff-test2
|
||||
assert_file_has_content diff-test2 'D */a/5'
|
||||
|
|
|
|||
|
|
@ -25,9 +25,14 @@ if len(sys.argv) == 1:
|
|||
else:
|
||||
sysroot = sys.argv[1]
|
||||
|
||||
bootloader = sys.argv[2]
|
||||
loaderpath = sysroot + '/boot/loader/entries'
|
||||
syslinuxpath = sysroot + '/boot/syslinux/syslinux.cfg'
|
||||
|
||||
if bootloader == "grub2":
|
||||
sys.stdout.write('GRUB2 configuration validation not implemented.\n')
|
||||
sys.exit(0)
|
||||
|
||||
def fatal(msg):
|
||||
sys.stderr.write(msg)
|
||||
sys.stderr.write('\n')
|
||||
|
|
@ -17,7 +17,17 @@
|
|||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
SRCDIR=$(dirname $0)
|
||||
if [ -n "${G_TEST_SRCDIR:-}" ]; then
|
||||
test_srcdir="${G_TEST_SRCDIR}/tests"
|
||||
else
|
||||
test_srcdir=$(dirname $0)
|
||||
fi
|
||||
|
||||
if [ -n "${G_TEST_BUILDDIR:-}" ]; then
|
||||
test_builddir="${G_TEST_BUILDDIR}/tests"
|
||||
else
|
||||
test_builddir=$(dirname $0)
|
||||
fi
|
||||
|
||||
assert_not_reached () {
|
||||
echo $@ 1>&2; exit 1
|
||||
|
|
@ -31,8 +41,12 @@ test_tmpdir=$(pwd)
|
|||
if ! test -f .testtmp; then
|
||||
files=$(ls)
|
||||
if test -n "${files}"; then
|
||||
ls -l
|
||||
assert_not_reached "test tmpdir=${test_tmpdir} is not empty; run this test via \`make check TESTS=\`, not directly"
|
||||
fi
|
||||
# Remember that this is an acceptable test $(pwd), for the benefit of
|
||||
# C and JS tests which may source this file again
|
||||
touch .testtmp
|
||||
fi
|
||||
|
||||
export G_DEBUG=fatal-warnings
|
||||
|
|
@ -54,7 +68,7 @@ export TEST_GPG_KEYID_3="DF444D67"
|
|||
# homedir in order to create lockfiles. Work around
|
||||
# this by copying locally.
|
||||
echo "Copying gpghome to ${test_tmpdir}"
|
||||
cp -a ${SRCDIR}/gpghome ${test_tmpdir}
|
||||
cp -a "${test_srcdir}/gpghome" ${test_tmpdir}
|
||||
export TEST_GPG_KEYHOME=${test_tmpdir}/gpghome
|
||||
export OSTREE_GPG_HOME=${test_tmpdir}/gpghome/trusted
|
||||
|
||||
|
|
@ -63,9 +77,9 @@ if test -n "${OT_TESTS_DEBUG:-}"; then
|
|||
fi
|
||||
|
||||
if test -n "${OT_TESTS_VALGRIND:-}"; then
|
||||
CMD_PREFIX="env G_SLICE=always-malloc valgrind -q --leak-check=full --num-callers=30 --suppressions=${SRCDIR}/ostree-valgrind.supp"
|
||||
CMD_PREFIX="env G_SLICE=always-malloc valgrind -q --leak-check=full --num-callers=30 --suppressions=${test_srcdir}/ostree-valgrind.supp"
|
||||
else
|
||||
CMD_PREFIX="env LD_PRELOAD=${SRCDIR}/libreaddir-rand.so"
|
||||
CMD_PREFIX="env LD_PRELOAD=${test_builddir}/libreaddir-rand.so"
|
||||
fi
|
||||
|
||||
assert_streq () {
|
||||
|
|
@ -215,6 +229,20 @@ setup_os_boot_uboot() {
|
|||
ln -s loader/uEnv.txt sysroot/boot/uEnv.txt
|
||||
}
|
||||
|
||||
setup_os_boot_grub2() {
|
||||
grub2_options=$1
|
||||
mkdir -p sysroot/boot/grub2/
|
||||
ln -s ../loader/grub.cfg sysroot/boot/grub2/grub.cfg
|
||||
export OSTREE_BOOT_PARTITION="/boot"
|
||||
case "$grub2_options" in
|
||||
*ostree-grub-generator*)
|
||||
cp ${test_srcdir}/ostree-grub-generator ${test_tmpdir}
|
||||
chmod +x ${test_tmpdir}/ostree-grub-generator
|
||||
export OSTREE_GRUB2_EXEC=${test_tmpdir}/ostree-grub-generator
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
setup_os_repository () {
|
||||
mode=$1
|
||||
bootmode=$2
|
||||
|
|
@ -287,6 +315,9 @@ EOF
|
|||
"uboot")
|
||||
setup_os_boot_uboot
|
||||
;;
|
||||
*grub2*)
|
||||
setup_os_boot_grub2 "${bootmode}"
|
||||
;;
|
||||
esac
|
||||
|
||||
cd ${test_tmpdir}
|
||||
|
|
@ -324,3 +355,32 @@ os_repository_new_commit ()
|
|||
${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit --add-metadata-string "version=${version}" -b testos/buildmaster/x86_64-runtime -s "Build"
|
||||
cd ${test_tmpdir}
|
||||
}
|
||||
|
||||
skip_without_user_xattrs () {
|
||||
touch test-xattrs
|
||||
if ! setfattr -n user.testvalue -v somevalue test-xattrs; then
|
||||
echo "1..0 # SKIP this test requires xattr support"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
skip_without_fuse () {
|
||||
if ! fusermount --version >/dev/null 2>&1; then
|
||||
echo "1..0 # SKIP no fusermount"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! [ -w /dev/fuse ]; then
|
||||
echo "1..0 # SKIP no write access to /dev/fuse"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! [ -e /etc/mtab ]; then
|
||||
echo "1..0 # SKIP no /etc/mtab"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
libtest_cleanup_gpg () {
|
||||
gpg-connect-agent --homedir ${test_tmpdir}/gpghome killagent /bye || true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
../src/boot/grub2/ostree-grub-generator
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo '1..1'
|
||||
|
||||
grep ' ostree_[A-Za-z0-9_]*;' ${G_TEST_SRCDIR}/src/libostree/libostree.sym | sed -e 's,^ *\([A-Za-z0-9_]*\);,\1,' | sort -u > expected-symbols.txt
|
||||
eu-readelf -a ${G_TEST_BUILDDIR}/.libs/libostree-1.so | grep 'FUNC.*GLOBAL.*DEFAULT.*@@LIBOSTREE_' | sed -e 's,^.* \(ostree_[A-Za-z0-9_]*\)@@LIBOSTREE_[0-9_.]*,\1,' |sort -u > found-symbols.txt
|
||||
diff -u expected-symbols.txt found-symbols.txt
|
||||
|
||||
echo 'ok'
|
||||
|
|
@ -21,11 +21,7 @@ set -euo pipefail
|
|||
|
||||
. $(dirname $0)/libtest.sh
|
||||
|
||||
echo "1..1"
|
||||
|
||||
# Exports OSTREE_SYSROOT so --sysroot not needed.
|
||||
setup_os_repository "archive-z2" "grub2"
|
||||
|
||||
echo "ok setup"
|
||||
setup_os_repository "archive-z2" "grub2 ostree-grub-generator"
|
||||
|
||||
. $(dirname $0)/admin-test.sh
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ set -euo pipefail
|
|||
setup_os_repository "archive-z2" "syslinux"
|
||||
|
||||
# If parallel is not installed, skip the test
|
||||
if ! parallel --help >/dev/null 2>&1; then
|
||||
echo "1..0 # SKIP no /usr/bin/parallel"
|
||||
if ! parallel --gnu /bin/true </dev/null >/dev/null 2>&1; then
|
||||
echo "1..0 # SKIP GNU parallel not available"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ echo "rev=${rev}"
|
|||
${CMD_PREFIX} ostree admin deploy --karg=root=LABEL=MOO --karg=quiet --os=testos testos:testos/buildmaster/x86_64-runtime
|
||||
assert_has_dir sysroot/boot/ostree/testos-${bootcsum}
|
||||
|
||||
parallel_cmd=parallel
|
||||
parallel_cmd="parallel --gnu"
|
||||
if parallel --help | grep -q -e --no-notice; then
|
||||
parallel_cmd="${parallel_cmd} --no-notice"
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ echo '1..11'
|
|||
|
||||
setup_test_repository "archive-z2"
|
||||
|
||||
. ${SRCDIR}/archive-test.sh
|
||||
. ${test_srcdir}/archive-test.sh
|
||||
|
||||
cd ${test_tmpdir}
|
||||
mkdir repo2
|
||||
|
|
|
|||
|
|
@ -19,10 +19,12 @@
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
echo "1..1"
|
||||
|
||||
. $(dirname $0)/libtest.sh
|
||||
|
||||
skip_without_user_xattrs
|
||||
|
||||
echo "1..1"
|
||||
|
||||
setup_test_repository "bare-user"
|
||||
echo "ok setup"
|
||||
|
||||
|
|
|
|||
|
|
@ -132,5 +132,6 @@ if ${CMD_PREFIX} ostree --repo=repo show main | grep -o 'Found [[:digit:]] signa
|
|||
fi
|
||||
|
||||
rm -rf repo gnomerepo-files
|
||||
libtest_cleanup_gpg
|
||||
|
||||
echo "ok"
|
||||
|
|
|
|||
|
|
@ -21,10 +21,12 @@ set -euo pipefail
|
|||
|
||||
. $(dirname $0)/libtest.sh
|
||||
|
||||
skip_without_user_xattrs
|
||||
|
||||
bindatafiles="bash true ostree"
|
||||
morebindatafiles="false ls"
|
||||
|
||||
echo '1..7'
|
||||
echo '1..8'
|
||||
|
||||
mkdir repo
|
||||
${CMD_PREFIX} ostree --repo=repo init --mode=archive-z2
|
||||
|
|
@ -128,9 +130,9 @@ assert_streq "${totalsize_orig}" "${totalsize_swapped}"
|
|||
|
||||
echo 'ok generate + show endian swapped'
|
||||
|
||||
tar xf ${SRCDIR}/pre-endian-deltas-repo-big.tar.xz
|
||||
tar xf ${test_srcdir}/pre-endian-deltas-repo-big.tar.xz
|
||||
mv pre-endian-deltas-repo{,-big}
|
||||
tar xf ${SRCDIR}/pre-endian-deltas-repo-little.tar.xz
|
||||
tar xf ${test_srcdir}/pre-endian-deltas-repo-little.tar.xz
|
||||
mv pre-endian-deltas-repo{,-little}
|
||||
legacy_origrev=$(${CMD_PREFIX} ostree --repo=pre-endian-deltas-repo-big rev-parse main^)
|
||||
legacy_newrev=$(${CMD_PREFIX} ostree --repo=pre-endian-deltas-repo-big rev-parse main)
|
||||
|
|
@ -184,3 +186,18 @@ ${CMD_PREFIX} ostree --repo=repo2 fsck
|
|||
${CMD_PREFIX} ostree --repo=repo2 ls ${newrev} >/dev/null
|
||||
|
||||
echo 'ok apply offline inline'
|
||||
|
||||
${CMD_PREFIX} ostree --repo=repo static-delta list | grep ^${origrev}-${newrev}$ || exit 1
|
||||
${CMD_PREFIX} ostree --repo=repo static-delta list | grep ^${origrev}$ || exit 1
|
||||
|
||||
${CMD_PREFIX} ostree --repo=repo static-delta delete ${origrev} || exit 1
|
||||
|
||||
${CMD_PREFIX} ostree --repo=repo static-delta list | grep ^${origrev}-${newrev}$ || exit 1
|
||||
${CMD_PREFIX} ostree --repo=repo static-delta list | grep ^${origrev}$ && exit 1
|
||||
|
||||
${CMD_PREFIX} ostree --repo=repo static-delta delete ${origrev}-${newrev} || exit 1
|
||||
|
||||
${CMD_PREFIX} ostree --repo=repo static-delta list | grep ^${origrev}-${newrev}$ && exit 1
|
||||
${CMD_PREFIX} ostree --repo=repo static-delta list | grep ^${origrev}$ && exit 1
|
||||
|
||||
echo 'ok delete'
|
||||
|
|
|
|||
|
|
@ -19,13 +19,11 @@
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
if ! fusermount --version >/dev/null 2>&1; then
|
||||
echo "1..0 # SKIP no fusermount"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
. $(dirname $0)/libtest.sh
|
||||
|
||||
skip_without_fuse
|
||||
skip_without_user_xattrs
|
||||
|
||||
echo "1..1"
|
||||
|
||||
# Run "triggers" like ldconfig, gtk-update-icon-cache, etc.
|
||||
|
|
@ -44,14 +42,14 @@ exampleos_build_commit_package() {
|
|||
mkdir -p ${pkg}-package/usr/bin/
|
||||
echo "${pkg}-content ${version}" > ${pkg}-package/usr/bin/${pkg}
|
||||
# Use a dummy subject for this.
|
||||
ostree --repo=build-repo commit -b exampleos/x86_64/${pkg} -s '' --tree=dir=${pkg}-package
|
||||
${CMD_PREFIX} ostree --repo=build-repo commit -b exampleos/x86_64/${pkg} -s '' --tree=dir=${pkg}-package
|
||||
rm ${pkg}-package -rf
|
||||
}
|
||||
|
||||
exampleos_recompose() {
|
||||
rm exampleos-build -rf
|
||||
for pkg in ${packages}; do
|
||||
ostree --repo=build-repo checkout -U --union exampleos/x86_64/${pkg} exampleos-build
|
||||
${CMD_PREFIX} ostree --repo=build-repo checkout -U --union exampleos/x86_64/${pkg} exampleos-build
|
||||
done
|
||||
|
||||
# Now that we have our rootfs, run triggers
|
||||
|
|
@ -62,15 +60,15 @@ exampleos_recompose() {
|
|||
# Then we commit it, using --link-checkout-speedup to effectively
|
||||
# only re-checksum the ldconfig file. We also have dummy commit
|
||||
# message here.
|
||||
ostree --repo=build-repo commit -b exampleos/x86_64/standard -s 'exampleos build' --link-checkout-speedup exampleos-build
|
||||
${CMD_PREFIX} ostree --repo=build-repo commit -b exampleos/x86_64/standard -s 'exampleos build' --link-checkout-speedup exampleos-build
|
||||
}
|
||||
|
||||
packages="bash systemd"
|
||||
|
||||
mkdir build-repo
|
||||
ostree --repo=build-repo init --mode=bare-user
|
||||
${CMD_PREFIX} ostree --repo=build-repo init --mode=bare-user
|
||||
mkdir repo
|
||||
ostree --repo=repo init --mode=archive-z2
|
||||
${CMD_PREFIX} ostree --repo=repo init --mode=archive-z2
|
||||
# Our FUSE mount point
|
||||
mkdir mnt
|
||||
|
||||
|
|
@ -83,7 +81,7 @@ exampleos_build_commit_package systemd 224
|
|||
exampleos_recompose
|
||||
|
||||
# This is our first commit - let's publish it.
|
||||
ostree --repo=repo pull-local build-repo exampleos/x86_64/standard
|
||||
${CMD_PREFIX} ostree --repo=repo pull-local build-repo exampleos/x86_64/standard
|
||||
|
||||
# Now, update the bash package - this is a new commit on the branch
|
||||
# exampleos/x86_64/bash.
|
||||
|
|
@ -93,11 +91,11 @@ exampleos_build_commit_package bash 0.5.0
|
|||
exampleos_recompose
|
||||
|
||||
# Publish again:
|
||||
ostree --repo=repo pull-local build-repo exampleos/x86_64/standard
|
||||
${CMD_PREFIX} ostree --repo=repo pull-local build-repo exampleos/x86_64/standard
|
||||
# Optional: Generate a static delta vs the previous build
|
||||
ostree --repo=repo static-delta generate exampleos/x86_64/standard
|
||||
${CMD_PREFIX} ostree --repo=repo static-delta generate exampleos/x86_64/standard
|
||||
# Optional: Regenerate the summary file
|
||||
ostree --repo=repo summary -u
|
||||
${CMD_PREFIX} ostree --repo=repo summary -u
|
||||
|
||||
# Try: ostree --repo=demo-repo ls -R exampleos/x86_64/standard
|
||||
|
||||
|
|
|
|||
|
|
@ -78,4 +78,6 @@ if ${OSTREE} show test2 | grep -o 'Found [[:digit:]] signature'; then
|
|||
assert_not_reached
|
||||
fi
|
||||
|
||||
libtest_cleanup_gpg
|
||||
|
||||
echo "ok"
|
||||
|
|
|
|||
|
|
@ -19,10 +19,15 @@
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
echo "1..1"
|
||||
# We don't want OSTREE_GPG_HOME used for these tests.
|
||||
unset OSTREE_GPG_HOME
|
||||
|
||||
. $(dirname $0)/libtest.sh
|
||||
|
||||
skip_without_user_xattrs
|
||||
|
||||
echo "1..7"
|
||||
|
||||
setup_test_repository "archive-z2"
|
||||
echo "ok setup"
|
||||
|
||||
|
|
@ -55,3 +60,38 @@ find checkout3 -printf '%P %s %#m %u/%g %y %l\n' | sort > checkout3.files
|
|||
cmp checkout1.files checkout2.files
|
||||
cmp checkout1.files checkout3.files
|
||||
echo "ok checkouts same"
|
||||
|
||||
mkdir repo4
|
||||
${CMD_PREFIX} ostree --repo=repo4 init --mode="archive-z2"
|
||||
${CMD_PREFIX} ostree --repo=repo4 remote add --gpg-import ${test_tmpdir}/gpghome/key1.asc origin repo
|
||||
if ${CMD_PREFIX} ostree --repo=repo4 pull-local --remote=origin --gpg-verify repo test2 2>&1; then
|
||||
assert_not_reached "GPG verification unexpectedly succeeded"
|
||||
fi
|
||||
echo "ok --gpg-verify with no signature"
|
||||
|
||||
${OSTREE} gpg-sign --gpg-homedir=${TEST_GPG_KEYHOME} test2 ${TEST_GPG_KEYID_1}
|
||||
|
||||
mkdir repo5
|
||||
${CMD_PREFIX} ostree --repo=repo5 init --mode="archive-z2"
|
||||
${CMD_PREFIX} ostree --repo=repo5 remote add --gpg-import ${test_tmpdir}/gpghome/key1.asc origin repo
|
||||
${CMD_PREFIX} ostree --repo=repo5 pull-local --remote=origin --gpg-verify repo test2
|
||||
echo "ok --gpg-verify"
|
||||
|
||||
mkdir repo6
|
||||
${CMD_PREFIX} ostree --repo=repo6 init --mode="archive-z2"
|
||||
${CMD_PREFIX} ostree --repo=repo6 remote add --gpg-import ${test_tmpdir}/gpghome/key1.asc origin repo
|
||||
if ${CMD_PREFIX} ostree --repo=repo6 pull-local --remote=origin --gpg-verify-summary repo test2 2>&1; then
|
||||
assert_not_reached "GPG summary verification with no summary unexpectedly succeeded"
|
||||
fi
|
||||
|
||||
${OSTREE} summary -u update
|
||||
|
||||
if ${CMD_PREFIX} ostree --repo=repo6 pull-local --remote=origin --gpg-verify-summary repo test2 2>&1; then
|
||||
assert_not_reached "GPG summary verification with signed no summary unexpectedly succeeded"
|
||||
fi
|
||||
|
||||
${OSTREE} summary -u update --gpg-sign=${TEST_GPG_KEYID_1} --gpg-homedir=${TEST_GPG_KEYHOME}
|
||||
|
||||
${CMD_PREFIX} ostree --repo=repo6 pull-local --remote=origin --gpg-verify-summary repo test2 2>&1
|
||||
|
||||
echo "ok --gpg-verify-summary"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright (C) 2016 Alexander Larsson <alexl@redhat.com>
|
||||
#
|
||||
# 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..2'
|
||||
|
||||
setup_test_repository "archive-z2"
|
||||
|
||||
export OSTREE_GPG_SIGN="${OSTREE} gpg-sign --gpg-homedir=${TEST_GPG_KEYHOME}"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
|
||||
# Create a repo
|
||||
${CMD_PREFIX} ostree --repo=repo2 init
|
||||
${CMD_PREFIX} ostree --repo=repo2 remote add --gpg-import=${test_tmpdir}/gpghome/trusted/pubring.gpg --set=gpg-verify=true aremote file://$(pwd)/repo test2
|
||||
|
||||
# Create a repo with repo2 as parent
|
||||
${CMD_PREFIX} ostree init --repo=repo3 --mode=bare-user
|
||||
${CMD_PREFIX} ostree config --repo=repo3 set core.parent `pwd`/repo2
|
||||
|
||||
# Ensure the unsigned pull fails so we know we imported the gpg config correctly
|
||||
if ${CMD_PREFIX} ostree --repo=repo3 pull aremote; then
|
||||
assert_not_reached "GPG verification unexpectedly succeeded"
|
||||
fi
|
||||
echo "ok unsigned pull w/parent"
|
||||
|
||||
# Make a signed commit and ensure we can now pull
|
||||
${OSTREE} commit -b test2 -s "A GPG signed commit" -m "Signed commit body" --gpg-sign=${TEST_GPG_KEYID_1} --gpg-homedir=${TEST_GPG_KEYHOME} --tree=dir=files
|
||||
${CMD_PREFIX} ostree --repo=repo3 pull aremote
|
||||
|
||||
echo "ok signed pull w/parent"
|
||||
|
|
@ -21,6 +21,8 @@ set -euo pipefail
|
|||
|
||||
. $(dirname $0)/libtest.sh
|
||||
|
||||
skip_without_user_xattrs
|
||||
|
||||
setup_fake_remote_repo1 "archive-z2"
|
||||
|
||||
echo '1..2'
|
||||
|
|
@ -128,9 +130,9 @@ assert_file_has_content deltascount "^1$"
|
|||
echo "ok prune"
|
||||
|
||||
rm repo -rf
|
||||
ostree --repo=repo init --mode=bare-user
|
||||
${CMD_PREFIX} ostree --repo=repo init --mode=bare-user
|
||||
${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin $(cat httpd-address)/ostree/gnomerepo
|
||||
${CMD_PREFIX} ostree --repo=repo pull --depth=-1 --commit-metadata-only origin test
|
||||
ostree --repo=repo prune
|
||||
${CMD_PREFIX} ostree --repo=repo prune
|
||||
|
||||
echo "ok prune with partial repo"
|
||||
|
|
|
|||
|
|
@ -23,4 +23,4 @@ set -euo pipefail
|
|||
|
||||
setup_fake_remote_repo1 "archive-z2"
|
||||
|
||||
. ${SRCDIR}/pull-test.sh
|
||||
. ${test_srcdir}/pull-test.sh
|
||||
|
|
|
|||
|
|
@ -121,3 +121,5 @@ echo "ok pull mirror with invalid summary sig and no verification"
|
|||
# assert_file_has_content deltas.txt "${origmain}-${newmain}"
|
||||
|
||||
# echo "ok pull mirror with signed summary covering static deltas"
|
||||
|
||||
libtest_cleanup_gpg
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@ assert_file_has_content err.txt "Couldn't find file object"
|
|||
rev=$(${CMD_PREFIX} ostree --repo=repo rev-parse origin:main)
|
||||
assert_has_file repo/state/${rev}.commitpartial
|
||||
|
||||
# Test pulling a file, not a dir
|
||||
${CMD_PREFIX} ostree --repo=repo pull --subpath=/firstfile origin main
|
||||
${CMD_PREFIX} ostree --repo=repo ls origin:main /firstfile
|
||||
|
||||
${CMD_PREFIX} ostree --repo=repo pull origin main
|
||||
assert_not_has_file repo/state/${rev}.commitpartial
|
||||
${CMD_PREFIX} ostree --repo=repo fsck
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ set -euo pipefail
|
|||
|
||||
. $(dirname $0)/libtest.sh
|
||||
|
||||
echo "1..6"
|
||||
echo "1..7"
|
||||
|
||||
COMMIT_SIGN="--gpg-homedir=${TEST_GPG_KEYHOME} --gpg-sign=${TEST_GPG_KEYID_1}"
|
||||
setup_fake_remote_repo1 "archive-z2" "${COMMIT_SIGN}"
|
||||
|
|
@ -91,6 +91,21 @@ assert_has_file repo/tmp/cache/summaries/origin
|
|||
assert_has_file repo/tmp/cache/summaries/origin.sig
|
||||
echo "ok prune summary cache"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
repo_reinit
|
||||
mkdir cachedir
|
||||
${OSTREE} --repo=repo pull --cache-dir=cachedir origin main
|
||||
assert_not_has_file repo/tmp/cache/summaries/origin
|
||||
assert_not_has_file repo/tmp/cache/summaries/origin.sig
|
||||
assert_has_file cachedir/summaries/origin
|
||||
assert_has_file cachedir/summaries/origin.sig
|
||||
|
||||
rm cachedir/summaries/origin
|
||||
${OSTREE} --repo=repo pull --cache-dir=cachedir origin main
|
||||
assert_not_has_file repo/tmp/cache/summaries/origin
|
||||
assert_has_file cachedir/summaries/origin
|
||||
|
||||
echo "ok pull with signed summary and cachedir"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
repo_reinit
|
||||
|
|
@ -133,3 +148,5 @@ assert_file_has_content summary.txt "Good signature from \"Ostree Tester <test@t
|
|||
grep static-deltas summary.txt > static-deltas.txt
|
||||
assert_file_has_content static-deltas.txt \
|
||||
$(${OSTREE} --repo=repo rev-parse origin:main)
|
||||
|
||||
libtest_cleanup_gpg
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright (C) 2014 Alexander Larsson <alexl@redhat.com>
|
||||
#
|
||||
# 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..3'
|
||||
|
||||
setup_test_repository "bare"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
mkdir repo2
|
||||
${CMD_PREFIX} ostree --repo=repo2 init --mode="bare"
|
||||
|
||||
${CMD_PREFIX} ostree --repo=repo2 --untrusted pull-local repo
|
||||
|
||||
find repo2 -type f -links +1 | while read line; do
|
||||
assert_not_reached "pull-local created hardlinks"
|
||||
done
|
||||
echo "ok pull-local --untrusted didn't hardlink"
|
||||
|
||||
# Corrupt repo
|
||||
for i in ${test_tmpdir}/repo/objects/*/*.file; do
|
||||
|
||||
# make sure it's not a symlink
|
||||
if [ -L $i ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "corrupting $i"
|
||||
echo "broke" >> $i
|
||||
break;
|
||||
done
|
||||
|
||||
rm -rf repo2
|
||||
mkdir repo2
|
||||
${CMD_PREFIX} ostree --repo=repo2 init --mode="bare"
|
||||
if ${CMD_PREFIX} ostree --repo=repo2 pull-local repo; then
|
||||
echo "ok trusted pull with corruption succeeded"
|
||||
else
|
||||
assert_not_reached "corrupted trusted pull unexpectedly succeeded!"
|
||||
fi
|
||||
|
||||
rm -rf repo2
|
||||
mkdir repo2
|
||||
${CMD_PREFIX} ostree --repo=repo2 init --mode="bare"
|
||||
if ${CMD_PREFIX} ostree --repo=repo2 pull-local --untrusted repo; then
|
||||
assert_not_reached "corrupted untrusted pull unexpectedly failed!"
|
||||
else
|
||||
echo "ok untrusted pull with corruption failed"
|
||||
fi
|
||||
|
|
@ -143,4 +143,5 @@ if ${OSTREE} pull R2:main >/dev/null 2>&1; then
|
|||
fi
|
||||
${OSTREE} pull R3:main >/dev/null
|
||||
|
||||
libtest_cleanup_gpg
|
||||
echo "ok"
|
||||
|
|
|
|||
|
|
@ -19,12 +19,11 @@
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
if ! fusermount --version >/dev/null 2>&1; then
|
||||
echo "1..0 # SKIP no fusermount"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
. $(dirname $0)/libtest.sh
|
||||
|
||||
skip_without_fuse
|
||||
skip_without_user_xattrs
|
||||
|
||||
setup_test_repository "bare-user"
|
||||
|
||||
echo "1..5"
|
||||
|
|
|
|||
|
|
@ -19,15 +19,12 @@
|
|||
|
||||
set -euo pipefail
|
||||
|
||||
touch test-xattrs
|
||||
if ! setfattr -n user.testvalue -v somevalue test-xattrs; then
|
||||
exit 77
|
||||
fi
|
||||
. $(dirname $0)/libtest.sh
|
||||
|
||||
skip_without_user_xattrs
|
||||
|
||||
echo "1..2"
|
||||
|
||||
. $(dirname $0)/libtest.sh
|
||||
|
||||
setup_test_repository "archive-z2"
|
||||
|
||||
cd ${test_tmpdir}
|
||||
|
|
|
|||
Loading…
Reference in New Issue