New upstream version 2017.12

This commit is contained in:
Simon McVittie committed 2017-10-03 18:51:37 +01:00
commit d5964d6850
283 files changed
+4566 -2286

No files matched your search

+34 -9
View File
@@ -19,11 +19,7 @@
set -euo pipefail
echo "1..$((72 + ${extra_basic_tests:-0}))"
$CMD_PREFIX ostree --version > version.yaml
python -c 'import yaml; yaml.safe_load(open("version.yaml"))'
echo "ok yaml version"
echo "1..$((73 + ${extra_basic_tests:-0}))"
CHECKOUT_U_ARG=""
CHECKOUT_H_ARGS="-H"
@@ -282,7 +278,8 @@ if ! skip_one_without_user_xattrs; then
opposite_mode=archive
fi
ostree_repo_init repo2 --mode=$opposite_mode
${CMD_PREFIX} ostree --repo=repo2 pull-local repo
${CMD_PREFIX} ostree --repo=repo2 pull-local repo >out.txt
assert_file_has_content out.txt "[1-9][0-9]* metadata, [1-9][0-9]* content objects imported"
test2_commitid=$(${CMD_PREFIX} ostree --repo=repo rev-parse test2)
test2_commit_relpath=/objects/${test2_commitid:0:2}/${test2_commitid:2}.commit
assert_files_hardlinked repo/${test2_commit_relpath} repo2/${test2_commit_relpath}
@@ -314,7 +311,7 @@ $CMD_PREFIX ostree --repo=repo-input commit -b content-with-suid --statoverride=
if $CMD_PREFIX ostree pull-local --repo=repo --bareuseronly-files repo-input content-with-suid 2>err.txt; then
assert_not_reached "copying suid file with --bareuseronly-files worked?"
fi
assert_file_has_content err.txt 'object.*\.file: invalid mode.*with bits 040.*'
assert_file_has_content err.txt 'Content object.*: invalid mode.*with bits 040.*'
echo "ok pull-local (bareuseronly files)"
if ! skip_one_without_user_xattrs; then
@@ -605,6 +602,24 @@ $OSTREE checkout test2 test2-checkout
(cd test2-checkout && $OSTREE commit ${COMMIT_ARGS} --link-checkout-speedup -b test2 -s "tmp")
echo "ok commit with link speedup"
cd ${test_tmpdir}
rm -rf test2-checkout
$OSTREE checkout test2 test2-checkout
# set cow to different perms, but re-set cowro to the same perms
cat > statoverride.txt <<EOF
=$((0600)) /baz/cow
=$((0600)) /baz/cowro
EOF
$OSTREE commit ${COMMIT_ARGS} --statoverride=statoverride.txt \
--table-output --link-checkout-speedup -b test2-tmp test2-checkout > stats.txt
$OSTREE diff test2 test2-tmp > diff-test2
assert_file_has_content diff-test2 'M */baz/cow$'
assert_not_file_has_content diff-test2 'M */baz/cowro$'
assert_not_file_has_content diff-test2 'baz/saucer'
# only /baz/cow is a cache miss
assert_file_has_content stats.txt '^Content Written: 1$'
echo "ok commit with link speedup and modifier"
cd ${test_tmpdir}
$OSTREE ls test2
echo "ok ls with no argument"
@@ -809,8 +824,18 @@ cd ${test_tmpdir}
rm -rf test2-checkout
mkdir -p test2-checkout
cd test2-checkout
touch should-not-be-fsynced
$OSTREE commit ${COMMIT_ARGS} -b test2 -s "Unfsynced commit" --fsync=false
echo 'should not be fsynced' > should-not-be-fsynced
if ! skip_one_without_strace_fault_injection; then
# Test that --fsync=false doesn't fsync
fsync_inject_error_ostree="strace -o /dev/null -f -e inject=syncfs,fsync,sync:error=EPERM ostree"
${fsync_inject_error_ostree} --repo=${test_tmpdir}/repo commit ${COMMIT_ARGS} -b test2-no-fsync --fsync=false
# And test that we get EPERM if we inject an error
if ${fsync_inject_error_ostree} --repo=${test_tmpdir}/repo commit ${COMMIT_ARGS} -b test2-no-fsync 2>err.txt; then
fatal "fsync error injection failed"
fi
assert_file_has_content err.txt 'sync.*Operation not permitted'
echo "ok fsync disabled"
fi
# Run this test only as non-root user. When run as root, the chmod
# won't have any effect.
-1
View File
@@ -47,7 +47,6 @@ function listObjectChecksumsRecurse(dir, allObjects) {
e.close(null);
}
let [,commit] = repo.resolve_rev(refToCorrupt, false);
let [,root,commit] = repo.read_commit(refToCorrupt, null);
let allObjects = {};
allObjects[commit + '.commit'] = true;
+76 -18
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -73,6 +72,68 @@ ot_test_setup_repo (GCancellable *cancellable,
return g_steal_pointer (&ret_repo);
}
/* Determine whether we're able to relabel files. Needed for bare tests. */
gboolean
ot_check_relabeling (gboolean *can_relabel,
GError **error)
{
g_auto(GLnxTmpfile) tmpf = { 0, };
if (!glnx_open_tmpfile_linkable_at (AT_FDCWD, ".", O_RDWR | O_CLOEXEC, &tmpf, error))
return FALSE;
g_autoptr(GError) local_error = NULL;
g_autoptr(GBytes) bytes = glnx_fgetxattr_bytes (tmpf.fd, "security.selinux", &local_error);
if (!bytes)
{
/* libglnx preserves errno */
if (G_IN_SET (errno, ENOTSUP, ENODATA))
{
*can_relabel = FALSE;
return TRUE;
}
g_propagate_error (error, g_steal_pointer (&local_error));
return FALSE;
}
gsize data_len;
const guint8 *data = g_bytes_get_data (bytes, &data_len);
if (fsetxattr (tmpf.fd, "security.selinux", data, data_len, 0) < 0)
{
if (errno == ENOTSUP)
{
*can_relabel = FALSE;
return TRUE;
}
return glnx_throw_errno_prefix (error, "fsetxattr");
}
*can_relabel = TRUE;
return TRUE;
}
/* Determine whether the filesystem supports getting/setting user xattrs. */
gboolean
ot_check_user_xattrs (gboolean *has_user_xattrs,
GError **error)
{
g_auto(GLnxTmpfile) tmpf = { 0, };
if (!glnx_open_tmpfile_linkable_at (AT_FDCWD, ".", O_RDWR | O_CLOEXEC, &tmpf, error))
return FALSE;
if (fsetxattr (tmpf.fd, "user.test", "novalue", strlen ("novalue"), 0) < 0)
{
if (errno == ENOTSUP)
{
*has_user_xattrs = FALSE;
return TRUE;
}
return glnx_throw_errno_prefix (error, "fsetxattr");
}
*has_user_xattrs = TRUE;
return TRUE;
}
OstreeSysroot *
ot_test_setup_sysroot (GCancellable *cancellable,
GError **error)
@@ -80,22 +141,19 @@ ot_test_setup_sysroot (GCancellable *cancellable,
if (!ot_test_run_libtest ("setup_os_repository \"archive\" \"syslinux\"", error))
return FALSE;
struct statfs stbuf;
{ g_autoptr(GString) buf = g_string_new ("mutable-deployments");
if (statfs ("/", &stbuf) < 0)
return glnx_null_throw_errno (error);
/* Keep this in sync with the overlayfs bits in libtest.sh */
#ifndef OVERLAYFS_SUPER_MAGIC
#define OVERLAYFS_SUPER_MAGIC 0x794c7630
#endif
if (stbuf.f_type == OVERLAYFS_SUPER_MAGIC)
{
g_print ("libostreetest: detected overlayfs\n");
g_string_append (buf, ",no-xattrs");
}
/* Make sure deployments are mutable */
g_setenv ("OSTREE_SYSROOT_DEBUG", buf->str, TRUE);
}
g_autoptr(GString) buf = g_string_new ("mutable-deployments");
gboolean can_relabel;
if (!ot_check_relabeling (&can_relabel, error))
return FALSE;
if (!can_relabel)
{
g_print ("libostreetest: can't relabel, turning off xattrs\n");
g_string_append (buf, ",no-xattrs");
}
/* Make sure deployments are mutable */
g_setenv ("OSTREE_SYSROOT_DEBUG", buf->str, TRUE);
g_autoptr(GFile) sysroot_path = g_file_new_for_path ("sysroot");
return ostree_sysroot_new (sysroot_path);
+7 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2016 Colin Walters <walters@verbum.org>
*
* This library is free software; you can redistribute it and/or
@@ -32,6 +31,12 @@ gboolean ot_test_run_libtest (const char *cmd, GError **error);
OstreeRepo *ot_test_setup_repo (GCancellable *cancellable,
GError **error);
gboolean ot_check_relabeling (gboolean *can_relabel,
GError **error);
gboolean ot_check_user_xattrs (gboolean *has_user_xattrs,
GError **error);
OstreeSysroot *ot_test_setup_sysroot (GCancellable *cancellable,
GError **error);
+2
View File
@@ -40,6 +40,8 @@ if locale -a | grep C.UTF-8 >/dev/null; then
else
export LC_ALL=C
fi
# A GNU extension, used whenever LC_ALL is not C
unset LANGUAGE
# This should really be the default IMO
export G_DEBUG=fatal-warnings
+107 -14
View File
@@ -70,16 +70,50 @@ chmod -R u+w "${test_tmpdir}"
export TEST_GPG_KEYHOME=${test_tmpdir}/gpghome
export OSTREE_GPG_HOME=${test_tmpdir}/gpghome/trusted
# See comment in ot-builtin-commit.c and https://github.com/ostreedev/ostree/issues/758
# Also keep this in sync with the bits in libostreetest.c
echo evaluating for overlayfs...
case $(stat -f --printf '%T' /) in
overlayfs)
echo "overlayfs found; enabling OSTREE_NO_XATTRS"
export OSTREE_SYSROOT_DEBUG="${OSTREE_SYSROOT_DEBUG},no-xattrs"
export OSTREE_NO_XATTRS=1 ;;
*) ;;
esac
assert_has_setfattr() {
if ! which setfattr 2>/dev/null; then
fatal "no setfattr available to determine xattr support"
fi
}
_have_selinux_relabel=''
have_selinux_relabel() {
assert_has_setfattr
if test "${_have_selinux_relabel}" = ''; then
pushd ${test_tmpdir}
echo testlabel > testlabel.txt
selinux_xattr=security.selinux
if getfattr --encoding=base64 -n ${selinux_xattr} testlabel.txt >label.txt 2>err.txt; then
label=$(grep -E -e "^${selinux_xattr}=" < label.txt |sed -e "s,${selinux_xattr}=,,")
if setfattr -n ${selinux_xattr} -v ${label} testlabel.txt 2>err.txt; then
echo "SELinux enabled in $(pwd), and have privileges to relabel"
_have_selinux_relabel=yes
else
sed -e 's/^/# /' < err.txt >&2
echo "Found SELinux label, but unable to set (Unprivileged Docker?)"
_have_selinux_relabel=no
fi
else
sed -e 's/^/# /' < err.txt >&2
echo "Unable to retrieve SELinux label, assuming disabled"
_have_selinux_relabel=no
fi
popd
fi
test ${_have_selinux_relabel} = yes
}
# just globally turn off xattrs if we can't manipulate security xattrs; this is
# the case for overlayfs -- really, we should only enforce this for tests that
# use bare repos; separate from other tests that should check for user xattrs
# support
# see https://github.com/ostreedev/ostree/issues/758
# and https://github.com/ostreedev/ostree/pull/1217
echo -n checking for xattrs...
if ! have_selinux_relabel; then
export OSTREE_SYSROOT_DEBUG="${OSTREE_SYSROOT_DEBUG},no-xattrs"
export OSTREE_NO_XATTRS=1
fi
echo done
if test -n "${OT_TESTS_DEBUG:-}"; then
@@ -141,6 +175,7 @@ setup_test_repository () {
fi
cd ${test_tmpdir}
rm -rf repo
if test -n "${mode}"; then
ostree_repo_init repo --mode=${mode}
else
@@ -150,6 +185,9 @@ setup_test_repository () {
export OSTREE="${CMD_PREFIX} ostree ${ot_repo}"
cd ${test_tmpdir}
local oldumask="$(umask)"
umask 022
rm -rf files
mkdir files
cd files
ot_files=`pwd`
@@ -172,6 +210,7 @@ setup_test_repository () {
ln -s nonexistent baz/alink
mkdir baz/another/
echo x > baz/another/y
umask "${oldumask}"
cd ${test_tmpdir}/files
$OSTREE commit ${COMMIT_ARGS} -b test2 -s "Test Commit 2" -m "Commit body second"
@@ -511,10 +550,24 @@ os_repository_new_commit ()
cd ${test_tmpdir}
}
_have_user_xattrs=''
have_user_xattrs() {
assert_has_setfattr
if test "${_have_user_xattrs}" = ''; then
touch test-xattrs
if setfattr -n user.testvalue -v somevalue test-xattrs 2>/dev/null; then
_have_user_xattrs=yes
else
_have_user_xattrs=no
fi
rm -f test-xattrs
fi
test ${_have_user_xattrs} = yes
}
# Usage: if ! skip_one_without_user_xattrs; then ... more tests ...; fi
skip_one_without_user_xattrs () {
touch test-xattrs
if ! setfattr -n user.testvalue -v somevalue test-xattrs; then
if ! have_user_xattrs; then
echo "ok # SKIP - this test requires xattr support"
return 0
else
@@ -523,9 +576,43 @@ skip_one_without_user_xattrs () {
}
skip_without_user_xattrs () {
touch test-xattrs
setfattr -n user.testvalue -v somevalue test-xattrs || \
if ! have_user_xattrs; then
skip "this test requires xattr support"
fi
}
# Skip unless SELinux is disabled, or we can relabel.
# Default Docker has security.selinux xattrs, but returns
# EOPNOTSUPP when trying to set them, even to the existing value.
# https://github.com/ostreedev/ostree/pull/759
# https://github.com/ostreedev/ostree/pull/1217
skip_without_no_selinux_or_relabel () {
if ! have_selinux_relabel; then
skip "this test requires xattr support"
fi
}
# https://brokenpi.pe/tools/strace-fault-injection
_have_strace_fault_injection=''
have_strace_fault_injection() {
if test "${_have_strace_fault_injection}" = ''; then
if strace -P ${test_srcdir}/libtest-core.sh -e inject=read:retval=0 cat ${test_srcdir}/libtest-core.sh >out.txt &&
test '!' -s out.txt; then
_have_strace_fault_injection=yes
else
_have_strace_fault_injection=no
fi
rm -f out.txt
fi
test ${_have_strace_fault_injection} = yes
}
skip_one_without_strace_fault_injection() {
if ! have_strace_fault_injection; then
echo "ok # SKIP this test requires strace fault injection"
return 0
fi
return 1
}
skip_without_fuse () {
@@ -538,6 +625,12 @@ skip_without_fuse () {
[ -e /etc/mtab ] || skip "no /etc/mtab"
}
skip_without_experimental () {
if ! ostree --version | grep -q -e '- experimental'; then
skip "No experimental API is compiled in"
fi
}
has_gpgme () {
${CMD_PREFIX} ostree --version > version.txt
assert_file_has_content version.txt '- gpgme'
+72 -5
View File
@@ -35,14 +35,14 @@ function verify_initial_contents() {
assert_file_has_content baz/cow '^moo$'
}
echo "1..29"
echo "1..31"
# Try both syntaxes
repo_init --no-gpg-verify
${CMD_PREFIX} ostree --repo=repo pull origin main >out.txt
assert_file_has_content out.txt "[1-9][0-9]* metadata, [1-9][0-9]* content objects fetched"
${CMD_PREFIX} ostree --repo=repo pull origin:main > out.txt
assert_not_file_has_content out.txt "content objects fetched"
assert_not_file_has_content out.txt "[1-9][0-9]* content objects fetched"
${CMD_PREFIX} ostree --repo=repo fsck
echo "ok pull"
@@ -127,7 +127,7 @@ for flag in "" "--mirror"; do
if ${CMD_PREFIX} ostree --repo=mirrorrepo pull ${flag} --bareuseronly-files origin content-with-suid 2>err.txt; then
assert_not_reached "pulled unsafe bareuseronly"
fi
assert_file_has_content err.txt 'object.*\.file: invalid mode.*with bits 040.*'
assert_file_has_content err.txt 'Content object.*: invalid mode.*with bits 040.*'
done
echo "ok pull (bareuseronly, unsafe)"
@@ -137,6 +137,63 @@ ${CMD_PREFIX} ostree --repo=mirrorrepo prune --refs-only
${CMD_PREFIX} ostree --repo=mirrorrepo pull --mirror --bareuseronly-files origin main
echo "ok pull (bareuseronly mirror)"
# Corruption tests <https://github.com/ostreedev/ostree/issues/1211>
cd ${test_tmpdir}
repo_init --no-gpg-verify
if ! is_bare_user_only_repo repo && ! skip_one_without_user_xattrs; then
if is_bare_user_only_repo repo; then
cacherepomode=bare-user-only
else
cacherepomode=bare-user
fi
rm cacherepo -rf
ostree_repo_init cacherepo --mode=${cacherepomode}
${CMD_PREFIX} ostree --repo=cacherepo pull-local ostree-srv/gnomerepo main
rev=$(ostree --repo=cacherepo rev-parse main)
${CMD_PREFIX} ostree --repo=cacherepo ls -R -C main > ls.txt
regfile_hash=$(grep -E -e '^-0' ls.txt | head -1 | awk '{ print $5 }')
${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false corruptrepo $(cat httpd-address)/ostree/corruptrepo
# Make this a loop so in the future we can add more object types like commit etc.
for object in ${regfile_hash}.file; do
checksum=$(echo ${object} | sed -e 's,\(.*\)\.[a-z]*$,\1,')
path=cacherepo/objects/${object:0:2}/${object:2}
# Preserve user.ostreemeta xattr
cp -a ${path}{,.new}
(dd if=${path} conv=swab) > ${path}.new
mv ${path}{.new,}
if ${CMD_PREFIX} ostree --repo=cacherepo fsck 2>err.txt; then
fatal "corrupt repo fsck?"
fi
assert_file_has_content err.txt "corrupted.*${checksum}"
rm ostree-srv/corruptrepo -rf
ostree_repo_init ostree-srv/corruptrepo --mode=archive
${CMD_PREFIX} ostree --repo=ostree-srv/corruptrepo pull-local cacherepo main
# Pulling via HTTP into a non-archive should fail, even with
# --http-trusted.
if ${CMD_PREFIX} ostree --repo=repo pull --http-trusted corruptrepo main 2>err.txt; then
fatal "Pulled from corrupt repo?"
fi
assert_file_has_content err.txt "Corrupted.*${checksum}"
if ${CMD_PREFIX} ostree --repo=repo show corruptrepo:main >/dev/null; then
fatal "Pulled from corrupt repo?"
fi
${CMD_PREFIX} ostree --repo=repo prune --refs-only
rm repo/tmp/* -rf
ostree_repo_init corruptmirrorrepo --mode=archive
# Pulling via http-trusted should not verify the checksum
${CMD_PREFIX} ostree --repo=corruptmirrorrepo remote add --set=gpg-verify=false corruptrepo $(cat httpd-address)/ostree/corruptrepo
${CMD_PREFIX} ostree --repo=corruptmirrorrepo pull --mirror --http-trusted corruptrepo main
# But it should fail to fsck
if ${CMD_PREFIX} ostree --repo=corruptmirrorrepo fsck 2>err.txt; then
fatal "corrupt mirror repo fsck?"
fi
done
# And ensure the repo is reinitialized
repo_init --no-gpg-verify
echo "ok corruption"
fi
cd ${test_tmpdir}
rm mirrorrepo/refs/remotes/* -rf
${CMD_PREFIX} ostree --repo=mirrorrepo prune --refs-only
@@ -158,7 +215,7 @@ ostree_repo_init mirrorrepo-local --mode=archive
${CMD_PREFIX} ostree --repo=mirrorrepo-local remote add --set=gpg-verify=false origin file://$(pwd)/ostree-srv/gnomerepo
${CMD_PREFIX} ostree --repo=mirrorrepo-local pull --mirror origin main
${CMD_PREFIX} ostree --repo=mirrorrepo-local fsck
$OSTREE show main >/dev/null
${CMD_PREFIX} ostree --repo=mirrorrepo show main >/dev/null
echo "ok pull local mirror"
cd ${test_tmpdir}
@@ -419,6 +476,16 @@ fi
assert_file_has_content err.txt "GPG verification enabled, but no signatures found"
echo "ok pull repo 404 (gpg)"
cd ${test_tmpdir}
find ostree-srv/gnomerepo/objects -name '*.dirtree' | while read f; do mv ${f}{,.orig}; done
repo_init --set=gpg-verify=false
if ${CMD_PREFIX} ostree --repo=repo --depth=0 pull origin main 2>err.txt; then
assert_not_reached "pull repo 404 succeeded?"
fi
assert_file_has_content err.txt "404"
find ostree-srv/gnomerepo/objects -name '*.dirtree.orig' | while read f; do mv ${f} $(dirname $f)/$(basename ${f} .orig); done
echo "ok pull repo 404 on dirtree object"
cd ${test_tmpdir}
repo_init --set=gpg-verify=true
${CMD_PREFIX} ostree --repo=ostree-srv/gnomerepo commit \
@@ -451,5 +518,5 @@ rm ostree-srv/gnomerepo/summary
if ${CMD_PREFIX} ostree --repo=repo pull origin main 2>err.txt; then
fatal "pull of invalid ref succeeded"
fi
assert_file_has_content_literal err.txt 'error: Fetching refs/heads/main: Invalid rev lots of html here lots of html here lots of html here lots of'
assert_file_has_content_literal err.txt 'error: Fetching checksum for ref ((empty), main): Invalid rev lots of html here lots of html here lots of html here lots of'
echo "ok pull got HTML for a ref"
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2015 Colin Walters <walters@verbum.org>.
*
* This library is free software; you can redistribute it and/or
+126
View File
@@ -0,0 +1,126 @@
/*
* Copyright © 2017 Endless Mobile, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Authors:
* - Philip Withnall <withnall@endlessm.com>
*/
#include "config.h"
#include <gio/gio.h>
#include <glib.h>
#include <glib-object.h>
#include <locale.h>
#include "ostree-autocleanups.h"
#include "ostree-remote-private.h"
#include "ostree-repo-finder.h"
#include "ostree-repo-finder-mount.h"
#include "ostree-types.h"
#include "test-mock-gio.h"
static void
result_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
GAsyncResult **result_out = user_data;
*result_out = g_object_ref (result);
}
static void
collection_ref_free0 (OstreeCollectionRef *ref)
{
g_clear_pointer (&ref, (GDestroyNotify) ostree_collection_ref_free);
}
int
main (int argc, char **argv)
{
g_autoptr(GError) error = NULL;
setlocale (LC_ALL, "");
if (argc < 5 || (argc % 2) != 1)
{
g_printerr ("Usage: %s REPO MOUNT-ROOT COLLECTION-ID REF-NAME [COLLECTION-ID REF-NAME …]\n", argv[0]);
return 1;
}
g_autoptr(GMainContext) context = g_main_context_new ();
g_main_context_push_thread_default (context);
g_autoptr(OstreeRepo) parent_repo = ostree_repo_open_at (AT_FDCWD, argv[1], NULL, &error);
g_assert_no_error (error);
/* Set up a mock volume. */
g_autoptr(GFile) mount_root = g_file_new_for_commandline_arg (argv[2]);
g_autoptr(GMount) mount = G_MOUNT (ostree_mock_mount_new ("mount", mount_root));
g_autoptr(GList) mounts = g_list_prepend (NULL, mount);
g_autoptr(GVolumeMonitor) monitor = ostree_mock_volume_monitor_new (mounts, NULL);
g_autoptr(OstreeRepoFinderMount) finder = ostree_repo_finder_mount_new (monitor);
/* Resolve the refs. */
g_autoptr(GPtrArray) refs = g_ptr_array_new_with_free_func ((GDestroyNotify) collection_ref_free0);
for (gsize i = 3; i < argc; i += 2)
{
const char *collection_id = argv[i];
const char *ref_name = argv[i + 1];
g_ptr_array_add (refs, ostree_collection_ref_new (collection_id, ref_name));
}
g_ptr_array_add (refs, NULL); /* NULL terminator */
g_autoptr(GAsyncResult) result = NULL;
ostree_repo_finder_resolve_async (OSTREE_REPO_FINDER (finder),
(const OstreeCollectionRef * const *) refs->pdata,
parent_repo, NULL, result_cb, &result);
while (result == NULL)
g_main_context_iteration (context, TRUE);
g_autoptr(GPtrArray) results = ostree_repo_finder_resolve_finish (OSTREE_REPO_FINDER (finder),
result, &error);
g_assert_no_error (error);
/* Check that the results are correct: the invalid refs should have been
* ignored, and the valid results canonicalised and deduplicated. */
for (gsize i = 0; i < results->len; i++)
{
const OstreeRepoFinderResult *result = g_ptr_array_index (results, i);
GHashTableIter iter;
OstreeCollectionRef *ref;
const gchar *checksum;
g_hash_table_iter_init (&iter, result->ref_to_checksum);
while (g_hash_table_iter_next (&iter, (gpointer *) &ref, (gpointer *) &checksum))
g_print ("%" G_GSIZE_FORMAT " %s %s %s %s\n",
i, ostree_remote_get_name (result->remote),
ref->collection_id, ref->ref_name,
checksum);
}
g_main_context_pop_thread_default (context);
return 0;
}
+128 -3
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2016 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -237,6 +236,131 @@ test_object_writes (gconstpointer data)
}
}
static GVariant*
xattr_cb (OstreeRepo *repo,
const char *path,
GFileInfo *file_info,
gpointer user_data)
{
GVariant *xattr = user_data;
if (g_str_equal (path, "/baz/cow"))
return g_variant_ref (xattr);
return NULL;
}
/* check that using a devino cache doesn't cause us to ignore xattr callbacks */
static void
test_devino_cache_xattrs (void)
{
g_autoptr(GError) error = NULL;
gboolean ret = FALSE;
g_autoptr(GFile) repo_path = g_file_new_for_path ("repo");
/* re-initialize as bare */
ret = ot_test_run_libtest ("setup_test_repository bare", &error);
g_assert_no_error (error);
g_assert (ret);
gboolean can_relabel;
ret = ot_check_relabeling (&can_relabel, &error);
g_assert_no_error (error);
g_assert (ret);
gboolean has_user_xattrs;
ret = ot_check_user_xattrs (&has_user_xattrs, &error);
g_assert_no_error (error);
g_assert (ret);
/* we need both because we're bare and our tests target user xattrs */
if (!can_relabel || !has_user_xattrs)
{
g_test_skip ("this test requires full xattr support");
return;
}
g_autoptr(OstreeRepo) repo = ostree_repo_new (repo_path);
ret = ostree_repo_open (repo, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_autofree char *csum = NULL;
ret = ostree_repo_resolve_rev (repo, "test2", FALSE, &csum, &error);
g_assert_no_error (error);
g_assert (ret);
g_autoptr(OstreeRepoDevInoCache) cache = ostree_repo_devino_cache_new ();
OstreeRepoCheckoutAtOptions options = {0,};
options.no_copy_fallback = TRUE;
options.devino_to_csum_cache = cache;
ret = ostree_repo_checkout_at (repo, &options, AT_FDCWD, "checkout", csum, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_autoptr(OstreeMutableTree) mtree = ostree_mutable_tree_new ();
g_autoptr(OstreeRepoCommitModifier) modifier =
ostree_repo_commit_modifier_new (0, NULL, NULL, NULL);
ostree_repo_commit_modifier_set_devino_cache (modifier, cache);
g_auto(GVariantBuilder) builder;
g_variant_builder_init (&builder, (GVariantType*)"a(ayay)");
g_variant_builder_add (&builder, "(@ay@ay)",
g_variant_new_bytestring ("user.myattr"),
g_variant_new_bytestring ("data"));
g_autoptr(GVariant) orig_xattrs = g_variant_ref_sink (g_variant_builder_end (&builder));
ret = ostree_repo_prepare_transaction (repo, NULL, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
ostree_repo_commit_modifier_set_xattr_callback (modifier, xattr_cb, NULL, orig_xattrs);
ret = ostree_repo_write_dfd_to_mtree (repo, AT_FDCWD, "checkout",
mtree, modifier, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_autoptr(GFile) root = NULL;
ret = ostree_repo_write_mtree (repo, mtree, &root, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
/* now check that the final xattr matches */
g_autoptr(GFile) baz_child = g_file_get_child (root, "baz");
g_autoptr(GFile) cow_child = g_file_get_child (baz_child, "cow");
g_autoptr(GVariant) xattrs = NULL;
ret = ostree_repo_file_get_xattrs (OSTREE_REPO_FILE (cow_child), &xattrs, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
gboolean found_xattr = FALSE;
gsize n = g_variant_n_children (xattrs);
for (gsize i = 0; i < n; i++)
{
const guint8* name;
const guint8* value;
g_variant_get_child (xattrs, i, "(^&ay^&ay)", &name, &value);
if (g_str_equal ((const char*)name, "user.myattr"))
{
g_assert_cmpstr ((const char*)value, ==, "data");
found_xattr = TRUE;
break;
}
}
g_assert (found_xattr);
OstreeRepoTransactionStats stats;
ret = ostree_repo_commit_transaction (repo, &stats, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
/* we should only have had to checksum /baz/cow */
g_assert_cmpint (stats.content_objects_written, ==, 1);
}
int main (int argc, char **argv)
{
g_autoptr(GError) error = NULL;
@@ -244,13 +368,14 @@ int main (int argc, char **argv)
g_test_init (&argc, &argv, NULL);
repo = ot_test_setup_repo (NULL, &error);
repo = ot_test_setup_repo (NULL, &error);
if (!repo)
goto out;
g_test_add_data_func ("/repo-not-system", repo, test_repo_is_not_system);
g_test_add_data_func ("/raw-file-to-archive-stream", repo, test_raw_file_to_archive_stream);
g_test_add_data_func ("/objectwrites", repo, test_object_writes);
g_test_add_func ("/xattrs-devino-cache", test_devino_cache_xattrs);
g_test_add_func ("/remotename", test_validate_remotename);
return g_test_run();
+6 -2
View File
@@ -22,9 +22,13 @@ set -euo pipefail
. $(dirname $0)/libtest.sh
setup_test_repository "bare-user-only"
extra_basic_tests=4
extra_basic_tests=5
. $(dirname $0)/basic-test.sh
$CMD_PREFIX ostree --version > version.yaml
python -c 'import yaml; yaml.safe_load(open("version.yaml"))'
echo "ok yaml version"
# Reset things so we don't inherit a lot of state from earlier tests
cd ${test_tmpdir}
rm repo files -rf
@@ -45,7 +49,7 @@ $CMD_PREFIX ostree --repo=repo-input commit -b content-with-suid --statoverride=
if $CMD_PREFIX ostree pull-local --repo=repo repo-input 2>err.txt; then
assert_not_reached "copying suid file into bare-user worked?"
fi
assert_file_has_content err.txt "Invalid mode.*with bits 040.*in bare-user-only"
assert_file_has_content err.txt "Content object.*invalid mode.*with bits 040.*"
echo "ok failed to commit suid"
cd ${test_tmpdir}
+2 -6
View File
@@ -34,11 +34,7 @@ setup_test_repository "bare-user"
cd ${test_tmpdir}
objpath_nonexec=$(ostree_file_path_to_object_path repo test2 baz/cow)
# Sigh, umask
touch testfile
default_mode=$(stat -c '%a' testfile)
rm testfile
assert_file_has_mode ${objpath_nonexec} ${default_mode}
assert_file_has_mode ${objpath_nonexec} 644
objpath_ro=$(ostree_file_path_to_object_path repo test2 baz/cowro)
assert_file_has_mode ${objpath_ro} 600
objpath_exec=$(ostree_file_path_to_object_path repo test2 baz/deeper/ohyeahx)
@@ -48,7 +44,7 @@ echo "ok bare-user committed modes"
rm test2-checkout -rf
$OSTREE checkout -U -H test2 test2-checkout
cd test2-checkout
assert_file_has_mode baz/cow ${default_mode}
assert_file_has_mode baz/cow 644
assert_file_has_mode baz/cowro 600
assert_file_has_mode baz/deeper/ohyeahx 755
echo "ok bare-user checkout modes"
+2 -1
View File
@@ -21,6 +21,7 @@ set -euo pipefail
. $(dirname $0)/libtest.sh
setup_test_repository "bare"
skip_without_no_selinux_or_relabel
setup_test_repository "bare"
. $(dirname $0)/basic-test.sh
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright © 2017 Endless Mobile, Inc.
*
* This library is free software; you can redistribute it and/or
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
+15 -13
View File
@@ -26,7 +26,7 @@ if ! has_gpgme; then
exit 0
fi
echo "1..1"
echo "1..6"
keyid="472CDAFA"
oldpwd=`pwd`
@@ -73,6 +73,7 @@ if env OSTREE_GPG_HOME=${test_tmpdir} ${CMD_PREFIX} ostree --repo=repo pull orig
assert_not_reached "pull with no trusted GPG keys unexpectedly succeeded!"
fi
rm repo -rf
echo "ok pull no trusted GPG"
# And a test case with valid signature
cd ${test_tmpdir}
@@ -80,9 +81,10 @@ mkdir repo
ostree_repo_init repo
${CMD_PREFIX} ostree --repo=repo remote add origin $(cat httpd-address)/ostree/gnomerepo
${CMD_PREFIX} ostree --repo=repo pull origin main
${CMD_PREFIX} ostree --repo=repo show --gpg-verify-remote=origin main | grep -o 'Found [[:digit:]] signature' > show-verify-remote
assert_file_has_content show-verify-remote 'Found 1 signature'
${CMD_PREFIX} ostree --repo=repo show --gpg-verify-remote=origin main > show.txt
assert_file_has_content_literal show.txt 'Found 1 signature'
rm repo -rf
echo "ok pull verify"
# A test with corrupted detached signature
cd ${test_tmpdir}
@@ -96,6 +98,7 @@ if ${CMD_PREFIX} ostree --repo=repo pull origin main; then
assert_not_reached "pull with corrupted signature unexpectedly succeeded!"
fi
rm repo -rf
echo "ok pull corrupted sig"
# And now attempt to pull the same corrupted commit, but with GPG
# verification off
@@ -105,6 +108,7 @@ ostree_repo_init repo
${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin $(cat httpd-address)/ostree/gnomerepo
${CMD_PREFIX} ostree --repo=repo pull origin main
rm repo -rf
echo "ok repull corrupted"
# Add an unsigned commit to the repo, then pull, then sign the commit,
# then pull again. Make sure we get the expected number of signatures
@@ -117,23 +121,21 @@ mkdir repo
ostree_repo_init repo
${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin $(cat httpd-address)/ostree/gnomerepo
${CMD_PREFIX} ostree --repo=repo pull origin main
if ${CMD_PREFIX} ostree --repo=repo show main | grep -o 'Found [[:digit:]] signature'; then
assert_not_reached
fi
${CMD_PREFIX} ostree --repo=repo show main > show.txt
assert_not_file_has_content show.txt 'Found.*signature'
${CMD_PREFIX} ostree --repo=${test_tmpdir}/ostree-srv/gnomerepo gpg-sign --gpg-homedir=${test_tmpdir}/gpghome main $keyid
${CMD_PREFIX} ostree --repo=repo pull origin main
${CMD_PREFIX} ostree --repo=repo show main | grep -o 'Found [[:digit:]] signature' > show
assert_file_has_content show 'Found 1 signature'
${CMD_PREFIX} ostree --repo=repo show main > show.txt
assert_file_has_content_literal show.txt 'Found 1 signature'
echo "ok pull unsigned, then sign"
# Delete the signature from the commit so the detached metadata is empty,
# then pull and verify the signature is also deleted on the client side.
${CMD_PREFIX} ostree --repo=${test_tmpdir}/ostree-srv/gnomerepo gpg-sign --gpg-homedir=${test_tmpdir}/gpghome --delete main $keyid
${CMD_PREFIX} ostree --repo=repo pull origin main
if ${CMD_PREFIX} ostree --repo=repo show main | grep -o 'Found [[:digit:]] signature'; then
assert_not_reached
fi
${CMD_PREFIX} ostree --repo=repo show main >show.txt
assert_not_file_has_content show.txt 'Found.*signature'
echo "ok pull sig deleted"
rm -rf repo gnomerepo-files
libtest_cleanup_gpg
echo "ok"
+110
View File
@@ -0,0 +1,110 @@
#!/bin/bash
#
# Copyright © 2017 Endless Mobile, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#
# Authors:
# - Philip Withnall <withnall@endlessm.com>
set -euo pipefail
. $(dirname $0)/libtest.sh
echo "1..5"
cd ${test_tmpdir}
mkdir repo
ostree_repo_init repo --collection-id org.example.Collection1
mkdir -p tree/root
touch tree/root/a
# Add a few commits
seq 5 | while read i; do
echo a >> tree/root/a
${CMD_PREFIX} ostree --repo=repo commit --branch=test-$i -m test -s test --gpg-homedir="${TEST_GPG_KEYHOME}" --gpg-sign="${TEST_GPG_KEYID_1}" tree
done
${CMD_PREFIX} ostree --repo=repo summary --update --gpg-homedir="${TEST_GPG_KEYHOME}" --gpg-sign="${TEST_GPG_KEYID_1}"
# Pull into a ‘local’ repository, to more accurately represent the situation of
# creating a USB stick from your local machine.
mkdir local-repo
${CMD_PREFIX} ostree --repo=local-repo init
${CMD_PREFIX} ostree --repo=local-repo remote add remote1 file://$(pwd)/repo --collection-id org.example.Collection1 --gpg-import="${test_tmpdir}/gpghome/key1.asc"
${CMD_PREFIX} ostree --repo=local-repo pull remote1 test-1 test-2 test-3 test-4 test-5
# Simple test to put two refs onto a USB stick.
mkdir dest-mount1
${CMD_PREFIX} ostree --repo=local-repo create-usb dest-mount1 org.example.Collection1 test-1 org.example.Collection1 test-2
assert_has_dir dest-mount1/.ostree/repo
${CMD_PREFIX} ostree --repo=dest-mount1/.ostree/repo refs --collections > dest-refs
assert_file_has_content dest-refs "^(org.example.Collection1, test-1)$"
assert_file_has_content dest-refs "^(org.example.Collection1, test-2)$"
assert_not_file_has_content dest-refs "^(org.example.Collection1, test-3)$"
assert_has_file dest-mount1/.ostree/repo/summary
echo "ok 1 simple usb"
# Test that the repository can be placed in another standard location on the USB stick.
for dest in ostree/repo .ostree/repo; do
rm -rf dest-mount2
mkdir dest-mount2
${CMD_PREFIX} ostree --repo=local-repo create-usb --destination-repo "$dest" dest-mount2 org.example.Collection1 test-1
assert_has_dir "dest-mount2/$dest"
if [ -d dest-mount2/.ostree/repos.d ]; then
ls dest-mount2/.ostree/repos.d | wc -l > repo-links
assert_file_has_content repo-links "^0$"
fi
done
echo "ok 2 usb in standard location"
# Test that the repository can be placed in a non-standard location and gets a symlink to it.
mkdir dest-mount3
${CMD_PREFIX} ostree --repo=local-repo create-usb --destination-repo some-dest dest-mount3 org.example.Collection1 test-1
assert_has_dir "dest-mount3/some-dest"
assert_symlink_has_content "dest-mount3/.ostree/repos.d/00-generated" "/some-dest$"
${CMD_PREFIX} ostree --repo=dest-mount3/.ostree/repos.d/00-generated refs --collections > dest-refs
assert_file_has_content dest-refs "^(org.example.Collection1, test-1)$"
assert_has_file dest-mount3/.ostree/repos.d/00-generated/summary
echo "ok 3 usb in non-standard location"
# Test that adding an additional ref to an existing USB repository works.
${CMD_PREFIX} ostree --repo=local-repo create-usb --destination-repo some-dest dest-mount3 org.example.Collection1 test-2 org.example.Collection1 test-3
assert_has_dir "dest-mount3/some-dest"
assert_symlink_has_content "dest-mount3/.ostree/repos.d/00-generated" "/some-dest$"
${CMD_PREFIX} ostree --repo=dest-mount3/.ostree/repos.d/00-generated refs --collections > dest-refs
assert_file_has_content dest-refs "^(org.example.Collection1, test-1)$"
assert_file_has_content dest-refs "^(org.example.Collection1, test-1)$"
assert_file_has_content dest-refs "^(org.example.Collection1, test-3)$"
assert_has_file dest-mount3/.ostree/repos.d/00-generated/summary
echo "ok 4 adding ref to an existing usb"
# Check that #OstreeRepoFinderMount works from a volume initialised uing create-usb.
mkdir finder-repo
ostree_repo_init finder-repo
${CMD_PREFIX} ostree --repo=finder-repo remote add remote1 file://$(pwd)/just-needed-for-the-keyring --collection-id org.example.Collection1 --gpg-import="${test_tmpdir}/gpghome/key1.asc"
${test_builddir}/repo-finder-mount finder-repo dest-mount1 org.example.Collection1 test-1 org.example.Collection1 test-2 &> out
assert_file_has_content out "^0 .*_2Fdest-mount1_2F.ostree_2Frepo_remote1.trustedkeys.gpg org.example.Collection1 test-1 $(ostree --repo=repo show test-1)$"
assert_file_has_content out "^0 .*_2Fdest-mount1_2F.ostree_2Frepo_remote1.trustedkeys.gpg org.example.Collection1 test-2 $(ostree --repo=repo show test-2)$"
echo "ok 5 find from usb repo"
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
+10 -1
View File
@@ -75,7 +75,16 @@ test_recursive() {
assert_file_empty out
for subcmd in $builtins; do
test_recursive "$cmd $subcmd"
case "$subcmd" in
(trivial-httpd)
# Skip trivial-httpd if enabled, it doesn't work
# uninstalled (and also doesn't produce the output
# we expect).
;;
(*)
test_recursive "$cmd $subcmd"
;;
esac
done
fi
}
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright © 2017 Endless Mobile, Inc.
*
* This library is free software; you can redistribute it and/or
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright © 2017 Endless Mobile, Inc.
*
* This library is free software; you can redistribute it and/or
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
+72 -29
View File
@@ -25,7 +25,7 @@ skip_without_user_xattrs
setup_fake_remote_repo1 "archive"
echo '1..5'
echo '1..12'
cd ${test_tmpdir}
mkdir repo
@@ -44,16 +44,20 @@ done
${CMD_PREFIX} ostree --repo=repo pull --depth=-1 origin test
assert_repo_has_n_commits() {
repo=$1
count=$2
assert_streq "$(find ${repo}/objects -name '*.commit' | wc -l)" "${count}"
}
${CMD_PREFIX} ostree prune --repo=repo --refs-only --depth=2 -v
find repo | grep \.commit$ | wc -l > commitcount
assert_file_has_content commitcount "^3$"
assert_repo_has_n_commits repo 3
find repo/objects -name '*.tombstone-commit' | wc -l > tombstonecommitcount
assert_file_has_content tombstonecommitcount "^0$"
$OSTREE fsck
${CMD_PREFIX} ostree prune --repo=repo --refs-only --depth=1 -v
find repo | grep \.commit$ | wc -l > commitcount
assert_file_has_content commitcount "^2$"
assert_repo_has_n_commits repo 2
find repo/objects -name '*.tombstone-commit' | wc -l > tombstonecommitcount
assert_file_has_content tombstonecommitcount "^0$"
@@ -70,8 +74,7 @@ find repo/objects -name '*.tombstone-commit' | wc -l > tombstonecommitcount
assert_file_has_content tombstonecommitcount "^0$"
${CMD_PREFIX} ostree prune --repo=repo --refs-only --depth=0 -v
find repo/objects -name '*.commit' | wc -l > commitcount
assert_file_has_content commitcount "^1$"
assert_repo_has_n_commits repo 1
find repo/objects -name '*.tombstone-commit' | wc -l > tombstonecommitcount
assert_not_file_has_content tombstonecommitcount "^0$"
$OSTREE fsck
@@ -88,28 +91,22 @@ assert_file_has_content tombstonecommitcount "^1$"
$OSTREE fsck
${CMD_PREFIX} ostree prune --repo=repo --refs-only --depth=0 -v
find repo/objects -name '*.commit' | wc -l > commitcount
assert_file_has_content commitcount "^1$"
assert_repo_has_n_commits repo 1
${CMD_PREFIX} ostree --repo=repo commit --branch=test -m test -s test tree --timestamp="2005-10-29 12:43:29 +0000"
${CMD_PREFIX} ostree --repo=repo commit --branch=test -m test -s test tree --timestamp="2010-10-29 12:43:29 +0000"
find repo/objects -name '*.commit' | wc -l > commitcount
assert_file_has_content commitcount "^3$"
assert_repo_has_n_commits repo 3
${CMD_PREFIX} ostree --repo=repo prune --keep-younger-than="2015-10-29 12:43:29 +0000"
find repo/objects -name '*.commit' | wc -l > commitcount
assert_file_has_content commitcount "^2$"
assert_repo_has_n_commits repo 2
$OSTREE fsck
${CMD_PREFIX} ostree prune --repo=repo --refs-only --depth=0 -v
find repo/objects -name '*.commit' | wc -l > commitcount
assert_file_has_content commitcount "^2$"
assert_repo_has_n_commits repo 2
${CMD_PREFIX} ostree --repo=repo commit --branch=test -m test -s test tree --timestamp="October 25 1985"
${CMD_PREFIX} ostree --repo=repo commit --branch=test -m test -s test tree --timestamp="October 21 2015"
find repo/objects -name '*.commit' | wc -l > commitcount
assert_file_has_content commitcount "^4$"
assert_repo_has_n_commits repo 4
${CMD_PREFIX} ostree --repo=repo prune --keep-younger-than="1 week ago"
find repo/objects -name '*.commit' | wc -l > commitcount
assert_file_has_content commitcount "^2$"
assert_repo_has_n_commits repo 2
${CMD_PREFIX} ostree --repo=repo commit --branch=oldcommit tree --timestamp="2005-10-29 12:43:29 +0000"
oldcommit_rev=$($OSTREE --repo=repo rev-parse oldcommit)
@@ -200,8 +197,7 @@ for x in $(seq 3); do
${CMD_PREFIX} ostree --repo=datetest-snapshot-repo commit --branch=stable -m test -s "new stable build $x" tree
${CMD_PREFIX} ostree --repo=datetest-snapshot-repo commit --branch=dev -m test -s "new dev build $x" tree
done
find datetest-snapshot-repo/objects -name '*.commit' | wc -l > commitcount
assert_file_has_content commitcount "^16$"
assert_repo_has_n_commits datetest-snapshot-repo 16
# Snapshot the above
reinitialize_datesnap_repo() {
@@ -219,18 +215,15 @@ if ${CMD_PREFIX} ostree --repo=repo prune --keep-younger-than="1 week ago" --ret
fi
assert_file_has_content err.txt 'Invalid depth BACON'
${CMD_PREFIX} ostree --repo=repo prune --keep-younger-than="1 week ago" --retain-branch-depth=stable=-1
find repo/objects -name '*.commit' | wc -l > commitcount
assert_file_has_content commitcount "^11$"
assert_repo_has_n_commits repo 11
# Double check our backup is unchanged
find datetest-snapshot-repo/objects -name '*.commit' | wc -l > commitcount
assert_file_has_content commitcount "^16$"
assert_repo_has_n_commits datetest-snapshot-repo 16
$OSTREE fsck
# Again but this time only retain 6 (5+1) commits on stable. This should drop
# out 8 - 6 = 2 commits (so the 11 above minus 2 = 9)
${CMD_PREFIX} ostree --repo=repo prune --keep-younger-than="1 week ago" --retain-branch-depth=stable=5
find repo/objects -name '*.commit' | wc -l > commitcount
assert_file_has_content commitcount "^9$"
assert_repo_has_n_commits repo 9
$OSTREE fsck
echo "ok retain branch depth and keep-younger-than"
@@ -238,8 +231,58 @@ echo "ok retain branch depth and keep-younger-than"
# so 8 stable + 1 dev = 9
reinitialize_datesnap_repo
${CMD_PREFIX} ostree --repo=repo prune --depth=0 --retain-branch-depth=stable=-1
find repo/objects -name '*.commit' | wc -l > commitcount
assert_file_has_content commitcount "^9$"
assert_repo_has_n_commits repo 9
$OSTREE fsck
echo "ok retain branch depth (alone)"
# Test --only-branch with --depth=0; this should be exactly identical to the
# above with a result of 9.
reinitialize_datesnap_repo
${CMD_PREFIX} ostree --repo=repo prune --only-branch=dev --depth=0
assert_repo_has_n_commits repo 9
$OSTREE fsck
echo "ok --only-branch --depth=0"
# Test --only-branch with --depth=1; should just add 1 to the above, for 10.
reinitialize_datesnap_repo
${CMD_PREFIX} ostree --repo=repo prune --only-branch=dev --depth=1
assert_repo_has_n_commits repo 10
echo "ok --only-branch --depth=1"
# Test --only-branch with all branches
reinitialize_datesnap_repo
${CMD_PREFIX} ostree --repo=repo prune --only-branch=dev --only-branch=stable --depth=0
assert_repo_has_n_commits repo 2
reinitialize_datesnap_repo
${CMD_PREFIX} ostree --repo=repo prune --only-branch=dev --only-branch=stable --depth=1
assert_repo_has_n_commits repo 4
echo "ok --only-branch (all) --depth=1"
# Test --only-branch and --retain-branch-depth overlap
reinitialize_datesnap_repo
${CMD_PREFIX} ostree --repo=repo prune --only-branch=dev --only-branch=stable --depth=0 \
--retain-branch-depth=stable=2
assert_repo_has_n_commits repo 4
echo "ok --only-branch and --retain-branch-depth overlap"
# Test --only-branch and --retain-branch-depth together
reinitialize_datesnap_repo
${CMD_PREFIX} ostree --repo=repo prune --only-branch=dev --depth=0 --retain-branch-depth=stable=2
assert_repo_has_n_commits repo 4
echo "ok --only-branch and --retain-branch-depth together"
# Test --only-branch with --keep-younger-than; this should be identical to the test
# above for --retain-branch-depth=stable=-1
reinitialize_datesnap_repo
${CMD_PREFIX} ostree --repo=repo prune --only-branch=stable --keep-younger-than="1 week ago"
assert_repo_has_n_commits repo 11
echo "ok --only-branch --keep-younger-than"
# Test --only-branch with a nonexistent ref
reinitialize_datesnap_repo
if ${CMD_PREFIX} ostree --repo=repo prune --only-branch=BACON 2>err.txt; then
fatal "we pruned BACON?"
fi
assert_file_has_content err.txt "Refspec.*BACON.*not found"
echo "ok --only-branch=BACON"
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2016 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright © 2017 Endless Mobile, Inc.
*
* This library is free software; you can redistribute it and/or
+9 -16
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright © 2017 Endless Mobile, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -39,7 +38,7 @@
typedef struct
{
OstreeRepo *parent_repo; /* owned */
int working_dfd; /* owned */
GLnxTmpDir tmpdir; /* owned */
GFile *working_dir; /* owned */
} Fixture;
@@ -47,20 +46,17 @@ static void
setup (Fixture *fixture,
gconstpointer test_data)
{
g_autofree gchar *tmp_name = NULL;
g_autoptr(GError) error = NULL;
tmp_name = g_strdup ("test-repo-finder-config-XXXXXX");
glnx_mkdtempat_open_in_system (tmp_name, 0700, &fixture->working_dfd, &error);
(void)glnx_mkdtemp ("test-repo-finder-config-XXXXXX", 0700, &fixture->tmpdir, &error);
g_assert_no_error (error);
g_test_message ("Using temporary directory: %s", tmp_name);
g_test_message ("Using temporary directory: %s", fixture->tmpdir.path);
glnx_shutil_mkdir_p_at (fixture->working_dfd, "repo", 0700, NULL, &error);
glnx_shutil_mkdir_p_at (fixture->tmpdir.fd, "repo", 0700, NULL, &error);
g_assert_no_error (error);
g_autoptr(GFile) tmp_dir = g_file_new_for_path (g_get_tmp_dir ());
fixture->working_dir = g_file_get_child (tmp_dir, tmp_name);
fixture->working_dir = g_file_new_for_path (fixture->tmpdir.path);
fixture->parent_repo = ot_test_setup_repo (NULL, &error);
g_assert_no_error (error);
@@ -73,10 +69,7 @@ teardown (Fixture *fixture,
g_autoptr(GError) error = NULL;
/* Recursively remove the temporary directory. */
glnx_shutil_rm_rf_at (fixture->working_dfd, ".", NULL, NULL);
close (fixture->working_dfd);
fixture->working_dfd = -1;
(void)glnx_tmpdir_delete (&fixture->tmpdir, NULL, NULL);
/* The repo also needs its source files to be removed. This is the inverse
* of setup_test_repository() in libtest.sh. */
@@ -177,14 +170,14 @@ assert_create_remote (Fixture *fixture,
g_autoptr(GError) error = NULL;
const gchar *repo_name = (collection_id != NULL) ? collection_id : "no-collection";
glnx_shutil_mkdir_p_at (fixture->working_dfd, repo_name, 0700, NULL, &error);
glnx_shutil_mkdir_p_at (fixture->tmpdir.fd, repo_name, 0700, NULL, &error);
g_assert_no_error (error);
g_autoptr(GFile) repo_path = g_file_get_child (fixture->working_dir, repo_name);
g_autoptr(OstreeRepo) repo = ostree_repo_new (repo_path);
ostree_repo_set_collection_id (repo, collection_id, &error);
g_assert_no_error (error);
ostree_repo_create (repo, OSTREE_REPO_MODE_ARCHIVE_Z2, NULL, &error);
ostree_repo_create (repo, OSTREE_REPO_MODE_ARCHIVE, NULL, &error);
g_assert_no_error (error);
/* Set up the refs from @.... */
+131
View File
@@ -0,0 +1,131 @@
#!/bin/bash
#
# Copyright © 2017 Endless Mobile, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#
# Authors:
# - Philip Withnall <withnall@endlessm.com>
set -euo pipefail
. $(dirname $0)/libtest.sh
SUDO="sudo --non-interactive"
# Skip the test if a well-known USB stick is not available.
# To run the test, you must have a throwaway partition on a USB stick (doesn’t
# matter how it’s formatted, as the test will reformat it), and must set
# MOUNT_INTEGRATION_DEV to that partition. For example,
# MOUNT_INTEGRATION_DEV=/dev/sdb1. For safety, the test will be skipped if the
# partition is already mounted.
#
# FIXME: We could potentially automate this in future if there’s a way to trick
# GIO into treating an arbitrary partition (such as a loopback device of our
# creation) as removable.
if ! [ -b "${MOUNT_INTEGRATION_DEV:-}" ]; then
skip "Test needs a disposable USB stick passed in as MOUNT_INTEGRATION_DEV"
fi
# Sanity check that the given device is not already mounted, to try and avoid
# hosing the system.
if mount | grep -q "${MOUNT_INTEGRATION_DEV}"; then
skip "${MOUNT_INTEGRATION_DEV} must not be mounted already"
fi
_mount_cleanup () {
${SUDO} umount "${MOUNT_INTEGRATION_DEV}" || true
}
case "${TEST_SKIP_CLEANUP:-}" in
no|"")
trap _mount_cleanup EXIT
;;
err)
trap _mount_cleanup ERR
;;
esac
echo "1..3"
cd ${test_tmpdir}
mkdir repo
ostree_repo_init repo --collection-id org.example.Collection1
mkdir -p tree/root
touch tree/root/a
# Add a few commits
seq 5 | while read i; do
echo a >> tree/root/a
${CMD_PREFIX} ostree --repo=repo commit --branch=test-$i -m test -s test --gpg-homedir="${TEST_GPG_KEYHOME}" --gpg-sign="${TEST_GPG_KEYID_1}" tree
done
${CMD_PREFIX} ostree --repo=repo summary --update --gpg-homedir="${TEST_GPG_KEYHOME}" --gpg-sign="${TEST_GPG_KEYID_1}"
${CMD_PREFIX} ostree --repo=repo rev-parse test-1 > ref1-checksum
# Pull into a ‘local’ repository, to more accurately represent the situation of
# creating a USB stick from your local machine.
mkdir local-repo
ostree_repo_init local-repo
${CMD_PREFIX} ostree --repo=local-repo remote add remote1 file://$(pwd)/repo --collection-id org.example.Collection1 --gpg-import="${test_tmpdir}/gpghome/key1.asc"
${CMD_PREFIX} ostree --repo=local-repo pull remote1 test-1 test-2 test-3 test-4 test-5
for fs_type in ext4 vfat; do
# Prepare a USB stick containing some of the refs on the given file system.
if [ "$fs_type" = "ext4" ]; then
fs_options="-F -E root_owner=$(id -u):$(id -g)"
else
fs_options=
fi
${SUDO} mkfs.$fs_type $fs_options "${MOUNT_INTEGRATION_DEV}" > /dev/null
usb_mount=$(udisksctl mount --block-device "${MOUNT_INTEGRATION_DEV}" --filesystem-type $fs_type | sed -n "s/^Mounted .* at \(.*\)\.$/\1/p")
${CMD_PREFIX} ostree --repo=local-repo create-usb "${usb_mount}" org.example.Collection1 test-1 org.example.Collection1 test-2
assert_has_dir "${usb_mount}"/.ostree/repo
${CMD_PREFIX} ostree --repo="${usb_mount}"/.ostree/repo refs --collections > dest-refs
assert_file_has_content dest-refs "^(org.example.Collection1, test-1)$"
assert_file_has_content dest-refs "^(org.example.Collection1, test-2)$"
assert_not_file_has_content dest-refs "^(org.example.Collection1, test-3)$"
assert_has_file "${usb_mount}"/.ostree/repo/summary
# Pull into a second local repository (theoretically, a separate computer).
mkdir peer-repo_$fs_type
ostree_repo_init peer-repo_$fs_type
${CMD_PREFIX} ostree --repo=peer-repo_$fs_type remote add remote1 file://just-here-for-the-keyring --collection-id org.example.Collection1 --gpg-import="${test_tmpdir}/gpghome/key1.asc"
${CMD_PREFIX} ostree --repo=peer-repo_$fs_type find-remotes org.example.Collection1 test-1 > find-results
assert_not_file_has_content find-results "^No results.$"
assert_file_has_content find-results "^Result 0: file://${usb_mount}"
assert_file_has_content find-results "(org.example.Collection1, test-1) = $(cat ref1-checksum)$"
${CMD_PREFIX} ostree --repo=peer-repo_$fs_type find-remotes --pull org.example.Collection1 test-1 > pull-results
assert_file_has_content pull-results "^Pulled 1/1 refs successfully.$"
${CMD_PREFIX} ostree --repo=peer-repo_$fs_type refs --collections > refs
assert_file_has_content refs "^(org.example.Collection1, test-1)$"
${SUDO} umount "${MOUNT_INTEGRATION_DEV}"
echo "ok end-to-end USB on ${fs_type}"
done
# Check the two repositories are identical.
diff -ur peer-repo_ext4 peer-repo_vfat
echo "ok end-to-end USB repositories are identical"
+145 -75
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright © 2017 Endless Mobile, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -40,30 +39,27 @@
typedef struct
{
OstreeRepo *parent_repo;
int working_dfd; /* owned */
GFile *working_dir; /* owned */
GLnxTmpDir tmpdir; /* owned */
GFile *working_dir; /* Points at tmpdir */
} Fixture;
static void
setup (Fixture *fixture,
gconstpointer test_data)
{
g_autofree gchar *tmp_name = NULL;
g_autoptr(GError) error = NULL;
tmp_name = g_strdup ("test-repo-finder-mount-XXXXXX");
glnx_mkdtempat_open_in_system (tmp_name, 0700, &fixture->working_dfd, &error);
(void)glnx_mkdtemp ("test-repo-finder-mount-XXXXXX", 0700, &fixture->tmpdir, &error);
g_assert_no_error (error);
g_test_message ("Using temporary directory: %s", tmp_name);
g_test_message ("Using temporary directory: %s", fixture->tmpdir.path);
glnx_shutil_mkdir_p_at (fixture->working_dfd, "repo", 0700, NULL, &error);
glnx_shutil_mkdir_p_at (fixture->tmpdir.fd, "repo", 0700, NULL, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
g_clear_error (&error);
g_assert_no_error (error);
g_autoptr(GFile) tmp_dir = g_file_new_for_path (g_get_tmp_dir ());
fixture->working_dir = g_file_get_child (tmp_dir, tmp_name);
fixture->working_dir = g_file_new_for_path (fixture->tmpdir.path);
fixture->parent_repo = ot_test_setup_repo (NULL, &error);
g_assert_no_error (error);
@@ -73,13 +69,8 @@ static void
teardown (Fixture *fixture,
gconstpointer test_data)
{
g_autoptr(GError) error = NULL;
/* Recursively remove the temporary directory. */
glnx_shutil_rm_rf_at (fixture->working_dfd, ".", NULL, NULL);
close (fixture->working_dfd);
fixture->working_dfd = -1;
(void)glnx_tmpdir_delete (&fixture->tmpdir, NULL, NULL);
/* The repo also needs its source files to be removed. This is the inverse
* of setup_test_repository() in libtest.sh. */
@@ -156,7 +147,7 @@ test_repo_finder_mount_no_mounts (Fixture *fixture,
g_main_context_pop_thread_default (context);
}
/* Create a .ostree/repos directory under the given @mount_root, or abort. */
/* Create a .ostree/repos.d directory under the given @mount_root, or abort. */
static gboolean
assert_create_repos_dir (Fixture *fixture,
const gchar *mount_root_name,
@@ -166,8 +157,8 @@ assert_create_repos_dir (Fixture *fixture,
glnx_fd_close int repos_dfd = -1;
g_autoptr(GError) error = NULL;
g_autofree gchar *path = g_build_filename (mount_root_name, ".ostree", "repos", NULL);
glnx_shutil_mkdir_p_at_open (fixture->working_dfd, path, 0700, &repos_dfd, NULL, &error);
g_autofree gchar *path = g_build_filename (mount_root_name, ".ostree", "repos.d", NULL);
glnx_shutil_mkdir_p_at_open (fixture->tmpdir.fd, path, 0700, &repos_dfd, NULL, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
g_clear_error (&error);
g_assert_no_error (error);
@@ -191,7 +182,7 @@ assert_create_remote_va (Fixture *fixture,
g_autoptr(GError) error = NULL;
g_autoptr(OstreeRepo) repo = ostree_repo_new (repo_dir);
ostree_repo_create (repo, OSTREE_REPO_MODE_ARCHIVE_Z2, NULL, &error);
ostree_repo_create (repo, OSTREE_REPO_MODE_ARCHIVE, NULL, &error);
g_assert_no_error (error);
/* Set up the refs from @.... */
@@ -233,22 +224,22 @@ assert_create_remote_va (Fixture *fixture,
}
static OstreeRepo *
assert_create_repo_dir (Fixture *fixture,
int repos_dfd,
GMount *repos_mount,
const OstreeCollectionRef *ref,
gchar **out_uri,
assert_create_repo_dir (Fixture *fixture,
int repos_dfd,
GMount *repos_mount,
const char *repo_name,
gchar **out_uri,
...) G_GNUC_NULL_TERMINATED;
/* Create a @ref directory under the given @repos_dfd, or abort. Create a new
* repository in it with the refs given in @..., as per assert_create_remote_va().
* Return the URI of the repository. */
/* Create a @repo_name directory under the given @repos_dfd, or abort. Create a
* new repository in it with the refs given in @..., as per
* assert_create_remote_va(). Return the URI of the repository. */
static OstreeRepo *
assert_create_repo_dir (Fixture *fixture,
int repos_dfd,
GMount *repos_mount,
const OstreeCollectionRef *ref,
gchar **out_uri,
assert_create_repo_dir (Fixture *fixture,
int repos_dfd,
GMount *repos_mount,
const char *repo_name,
gchar **out_uri,
...)
{
glnx_fd_close int ref_dfd = -1;
@@ -256,15 +247,14 @@ assert_create_repo_dir (Fixture *fixture,
g_autoptr(GError) error = NULL;
va_list args;
g_autofree gchar *path = g_build_filename (ref->collection_id, ref->ref_name, NULL);
glnx_shutil_mkdir_p_at_open (repos_dfd, path, 0700, &ref_dfd, NULL, &error);
glnx_shutil_mkdir_p_at_open (repos_dfd, repo_name, 0700, &ref_dfd, NULL, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
g_clear_error (&error);
g_assert_no_error (error);
g_autoptr(GFile) mount_root = g_mount_get_root (repos_mount);
g_autoptr(GFile) repos_dir = g_file_get_child (mount_root, ".ostree/repos");
g_autoptr(GFile) repo_dir = g_file_get_child (repos_dir, path);
g_autoptr(GFile) repos_dir = g_file_get_child (mount_root, ".ostree/repos.d");
g_autoptr(GFile) repo_dir = g_file_get_child (repos_dir, repo_name);
va_start (args, out_uri);
repo = assert_create_remote_va (fixture, repo_dir, args);
@@ -275,38 +265,19 @@ assert_create_repo_dir (Fixture *fixture,
return g_steal_pointer (&repo);
}
/* Create a @ref symlink under the given @repos_dfd, pointing to
* @symlink_target, or abort. */
static int
assert_create_repo_symlink (int repos_dfd,
const OstreeCollectionRef *ref,
const gchar *symlink_target_path)
/* Create a @repo_name symlink under the given @repos_dfd, pointing to
* @symlink_target_path, or abort. */
static void
assert_create_repo_symlink (int repos_dfd,
const char *repo_name,
const char *symlink_target_path)
{
glnx_fd_close int symlink_target_dfd = -1;
g_autoptr(GError) error = NULL;
/* The @ref_parent_dir is not necessarily @collection_dir, since @ref may
* contain slashes. */
g_autofree gchar *path = g_build_filename (ref->collection_id, ref->ref_name, NULL);
g_autofree gchar *path_parent = g_path_get_dirname (path);
glnx_shutil_mkdir_p_at (repos_dfd, path_parent, 0700, NULL, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
g_clear_error (&error);
g_assert_no_error (error);
if (TEMP_FAILURE_RETRY (symlinkat (symlink_target_path, repos_dfd, path)) != 0)
if (TEMP_FAILURE_RETRY (symlinkat (symlink_target_path, repos_dfd, repo_name)) != 0)
{
g_autoptr(GError) error = NULL;
glnx_throw_errno_prefix (&error, "symlinkat");
g_assert_no_error (error);
}
/* Return a dir FD for the symlink target. */
glnx_opendirat (repos_dfd, path, TRUE, &symlink_target_dfd, &error);
g_assert_no_error (error);
return glnx_steal_fd (&symlink_target_dfd);
}
/* Add configuration for a remote named @remote_name, at @remote_uri, with a
@@ -356,7 +327,7 @@ test_repo_finder_mount_mixed_mounts (Fixture *fixture,
g_autofree gchar *repo2_repo_a_uri = NULL;
g_autofree gchar *repo1_ref0_checksum = NULL, *repo1_ref1_checksum = NULL, *repo1_ref2_checksum = NULL;
g_autofree gchar *repo2_ref0_checksum = NULL, *repo2_ref1_checksum = NULL, *repo2_ref2_checksum = NULL;
g_autofree gchar *repo1_ref5_checksum = NULL;
g_autofree gchar *repo1_ref5_checksum = NULL, *repo2_ref3_checksum = NULL;
gsize i;
const OstreeCollectionRef ref0 = { "org.example.Collection1", "exampleos/x86_64/ref0" };
const OstreeCollectionRef ref1 = { "org.example.Collection1", "exampleos/x86_64/ref1" };
@@ -379,27 +350,26 @@ test_repo_finder_mount_mixed_mounts (Fixture *fixture,
assert_create_repos_dir (fixture, "no-repos-mount", &no_repos_repos, &no_repos_mount);
assert_create_repos_dir (fixture, "repo1-mount", &repo1_repos, &repo1_mount);
repo1_repo_a = assert_create_repo_dir (fixture, repo1_repos, repo1_mount, refs[0], &repo1_repo_a_uri,
repo1_repo_a = assert_create_repo_dir (fixture, repo1_repos, repo1_mount, "repo1-repo-a", &repo1_repo_a_uri,
refs[0], &repo1_ref0_checksum,
refs[2], &repo1_ref2_checksum,
refs[5], &repo1_ref5_checksum,
NULL);
repo1_repo_b = assert_create_repo_dir (fixture, repo1_repos, repo1_mount, refs[1], &repo1_repo_b_uri,
repo1_repo_b = assert_create_repo_dir (fixture, repo1_repos, repo1_mount, "repo1-repo-b", &repo1_repo_b_uri,
refs[1], &repo1_ref1_checksum,
NULL);
assert_create_repo_symlink (repo1_repos, refs[2], "ref0"); /* repo1_repo_a */
assert_create_repo_symlink (repo1_repos, refs[5], "../../../org.example.Collection1/exampleos/x86_64/ref0"); /* repo1_repo_a */
assert_create_repo_symlink (repo1_repos, "repo1-repo-a-alias", "repo1-repo-a");
assert_create_repos_dir (fixture, "repo2-mount", &repo2_repos, &repo2_mount);
repo2_repo_a = assert_create_repo_dir (fixture, repo2_repos, repo2_mount, refs[0], &repo2_repo_a_uri,
repo2_repo_a = assert_create_repo_dir (fixture, repo2_repos, repo2_mount, "repo2-repo-a", &repo2_repo_a_uri,
refs[0], &repo2_ref0_checksum,
refs[1], &repo2_ref1_checksum,
refs[2], &repo2_ref2_checksum,
refs[3], NULL,
refs[3], &repo2_ref3_checksum,
NULL);
assert_create_repo_symlink (repo2_repos, refs[1], "ref0"); /* repo2_repo_a */
assert_create_repo_symlink (repo2_repos, refs[2], "ref1"); /* repo2_repo_b */
assert_create_repo_symlink (repo2_repos, refs[3], "/");
assert_create_repo_symlink (repo2_repos, "repo2-repo-a-alias", "repo2-repo-a");
assert_create_repo_symlink (repo2_repos, "dangling-symlink", "repo2-repo-b");
assert_create_repo_symlink (repo2_repos, "root", "/");
mounts = g_list_prepend (mounts, non_removable_mount);
mounts = g_list_prepend (mounts, no_repos_mount);
@@ -462,10 +432,108 @@ test_repo_finder_mount_mixed_mounts (Fixture *fixture,
else if (g_strcmp0 (uri, repo2_repo_a_uri) == 0 &&
g_strcmp0 (keyring, "remote1.trustedkeys.gpg") == 0)
{
g_assert_cmpuint (g_hash_table_size (result->ref_to_checksum), ==, 3);
g_assert_cmpuint (g_hash_table_size (result->ref_to_checksum), ==, 4);
g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[0]), ==, repo2_ref0_checksum);
g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[1]), ==, repo2_ref1_checksum);
g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[2]), ==, repo2_ref2_checksum);
g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, refs[3]), ==, repo2_ref3_checksum);
}
else
{
g_test_message ("Unknown result ‘%s’ with keyring ‘%s’.",
result->remote->name, result->remote->keyring);
g_assert_not_reached ();
}
}
g_main_context_pop_thread_default (context);
}
/* Test resolving the refs against a mock volume which contains two repositories
* in the default repository paths ostree/repo and .ostree/repo, to check that
* those paths are read */
static void
test_repo_finder_mount_well_known (Fixture *fixture,
gconstpointer test_data)
{
g_autoptr(OstreeRepoFinderMount) finder = NULL;
g_autoptr(GVolumeMonitor) monitor = NULL;
g_autoptr(GMainContext) context = NULL;
g_autoptr(GAsyncResult) result = NULL;
g_autoptr(GPtrArray) results = NULL; /* (element-type OstreeRepoFinderResult) */
g_autoptr(GError) error = NULL;
g_autoptr(GList) mounts = NULL; /* (element-type OstreeMockMount) */
g_autoptr(GMount) mount = NULL;
glnx_fd_close int repos = -1;
g_autoptr(OstreeRepo) repo_a = NULL, repo_b = NULL;
g_autofree gchar *repo_a_uri = NULL, *repo_b_uri = NULL;
g_autofree gchar *ref_a_checksum = NULL, *ref_b_checksum = NULL;
gsize i;
const OstreeCollectionRef ref_a = { "org.example.Collection1", "refA" };
const OstreeCollectionRef ref_b = { "org.example.Collection2", "refB" };
const OstreeCollectionRef * const refs[] = { &ref_a, &ref_b, NULL };
context = g_main_context_new ();
g_main_context_push_thread_default (context);
/* Build the various mock drives/volumes/mounts, and some repositories with
* refs within them. We use "/" under the assumption that it’s on a separate
* file system from /tmp, so it’s an example of a symlink pointing outside
* its mount point. */
assert_create_repos_dir (fixture, "mount", &repos, &mount);
repo_a = assert_create_repo_dir (fixture, repos, mount, "../../ostree/repo", &repo_a_uri,
&ref_a, &ref_a_checksum,
NULL);
repo_b = assert_create_repo_dir (fixture, repos, mount, "../../.ostree/repo", &repo_b_uri,
&ref_b, &ref_b_checksum,
NULL);
assert_create_repo_symlink (repos, "repo-a-alias", "../../ostree/repo");
mounts = g_list_prepend (mounts, mount);
monitor = ostree_mock_volume_monitor_new (mounts, NULL);
finder = ostree_repo_finder_mount_new (monitor);
assert_create_remote_config (fixture->parent_repo, "remote1", "https://nope1", "org.example.Collection1");
assert_create_remote_config (fixture->parent_repo, "remote2", "https://nope2", "org.example.Collection2");
/* Resolve the refs. */
ostree_repo_finder_resolve_async (OSTREE_REPO_FINDER (finder), refs,
fixture->parent_repo,
NULL, result_cb, &result);
while (result == NULL)
g_main_context_iteration (context, TRUE);
results = ostree_repo_finder_resolve_finish (OSTREE_REPO_FINDER (finder),
result, &error);
g_assert_no_error (error);
g_assert_nonnull (results);
g_assert_cmpuint (results->len, ==, 2);
/* Check that the results are correct: the valid results canonicalised and
* deduplicated. */
for (i = 0; i < results->len; i++)
{
g_autofree gchar *uri = NULL;
const gchar *keyring;
const OstreeRepoFinderResult *result = g_ptr_array_index (results, i);
uri = g_key_file_get_string (result->remote->options, result->remote->group, "url", &error);
g_assert_no_error (error);
keyring = result->remote->keyring;
if (g_strcmp0 (uri, repo_a_uri) == 0 &&
g_strcmp0 (keyring, "remote1.trustedkeys.gpg") == 0)
{
g_assert_cmpuint (g_hash_table_size (result->ref_to_checksum), ==, 1);
g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, &ref_a), ==, ref_a_checksum);
}
else if (g_strcmp0 (uri, repo_b_uri) == 0 &&
g_strcmp0 (keyring, "remote2.trustedkeys.gpg") == 0)
{
g_assert_cmpuint (g_hash_table_size (result->ref_to_checksum), ==, 1);
g_assert_cmpstr (g_hash_table_lookup (result->ref_to_checksum, &ref_b), ==, ref_b_checksum);
}
else
{
@@ -488,6 +556,8 @@ int main (int argc, char **argv)
test_repo_finder_mount_no_mounts, teardown);
g_test_add ("/repo-finder-mount/mixed-mounts", Fixture, NULL, setup,
test_repo_finder_mount_mixed_mounts, teardown);
g_test_add ("/repo-finder-mount/well-known", Fixture, NULL, setup,
test_repo_finder_mount_well_known, teardown);
return g_test_run();
}
+167
View File
@@ -0,0 +1,167 @@
/*
* Copyright © 2017 Endless Mobile, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Authors:
* - Philip Withnall <withnall@endlessm.com>
*/
#include "config.h"
#include <gio/gio.h>
#include <glib.h>
#include <glib-object.h>
#include <libglnx.h>
#include <locale.h>
#include "ostree-autocleanups.h"
#include "ostree-types.h"
/* Test fixture. Creates a temporary directory. */
typedef struct
{
GLnxTmpDir tmpdir; /* (owned) */
} Fixture;
static void
setup (Fixture *fixture,
gconstpointer test_data)
{
g_autoptr(GError) error = NULL;
(void) glnx_mkdtemp ("test-repo-XXXXXX", 0700, &fixture->tmpdir, &error);
g_assert_no_error (error);
g_test_message ("Using temporary directory: %s", fixture->tmpdir.path);
}
static void
teardown (Fixture *fixture,
gconstpointer test_data)
{
/* Recursively remove the temporary directory. */
(void) glnx_tmpdir_delete (&fixture->tmpdir, NULL, NULL);
}
/* Test that the hash values for two #OstreeRepo instances pointing at the same
* repository are equal. We can’t test anything else, since hash collisions are
* always a possibility. */
static void
test_repo_hash (Fixture *fixture,
gconstpointer test_data)
{
g_autoptr(GError) error = NULL;
g_autoptr(OstreeRepo) repo1 = ostree_repo_create_at (fixture->tmpdir.fd, ".",
OSTREE_REPO_MODE_ARCHIVE,
NULL,
NULL, &error);
g_assert_no_error (error);
g_autoptr(OstreeRepo) repo2 = ostree_repo_open_at (fixture->tmpdir.fd, ".",
NULL, &error);
g_assert_no_error (error);
g_assert_cmpuint (ostree_repo_hash (repo1), ==, ostree_repo_hash (repo2));
}
/* Test that trying to hash a closed repo results in an assertion failure. */
static void
test_repo_hash_closed (Fixture *fixture,
gconstpointer test_data)
{
if (g_test_subprocess ())
{
g_autoptr(GFile) repo_path = g_file_new_for_path (fixture->tmpdir.path);
g_autoptr(OstreeRepo) repo = ostree_repo_new (repo_path);
ostree_repo_hash (repo);
return;
}
g_test_trap_subprocess (NULL, 0, 0);
g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*ERROR*ostree_repo_hash: assertion failed:*");
}
/* Test that various repositories test equal (or not) with each other. */
static void
test_repo_equal (Fixture *fixture,
gconstpointer test_data)
{
g_autoptr(GError) error = NULL;
/* Create a few separate repos and some #OstreeRepo objects for them. */
glnx_ensure_dir (fixture->tmpdir.fd, "repo1", 0755, &error);
g_assert_no_error (error);
glnx_ensure_dir (fixture->tmpdir.fd, "repo2", 0755, &error);
g_assert_no_error (error);
g_autoptr(OstreeRepo) repo1 = ostree_repo_create_at (fixture->tmpdir.fd, "repo1",
OSTREE_REPO_MODE_ARCHIVE,
NULL,
NULL, &error);
g_assert_no_error (error);
g_autoptr(OstreeRepo) repo1_alias = ostree_repo_open_at (fixture->tmpdir.fd, "repo1",
NULL, &error);
g_assert_no_error (error);
g_autoptr(OstreeRepo) repo2 = ostree_repo_create_at (fixture->tmpdir.fd, "repo2",
OSTREE_REPO_MODE_ARCHIVE,
NULL,
NULL, &error);
g_assert_no_error (error);
g_autoptr(GFile) closed_repo_path = g_file_new_for_path (fixture->tmpdir.path);
g_autoptr(OstreeRepo) closed_repo = ostree_repo_new (closed_repo_path);
/* Test various equalities. */
g_assert_true (ostree_repo_equal (repo1, repo1));
g_assert_true (ostree_repo_equal (repo1_alias, repo1_alias));
g_assert_true (ostree_repo_equal (repo1, repo1_alias));
g_assert_true (ostree_repo_equal (repo1_alias, repo1));
g_assert_true (ostree_repo_equal (repo2, repo2));
g_assert_false (ostree_repo_equal (repo1, repo2));
g_assert_false (ostree_repo_equal (repo1_alias, repo2));
g_assert_false (ostree_repo_equal (repo2, repo1));
g_assert_false (ostree_repo_equal (repo2, repo1_alias));
g_assert_false (ostree_repo_equal (repo1, closed_repo));
g_assert_false (ostree_repo_equal (repo1_alias, closed_repo));
g_assert_false (ostree_repo_equal (closed_repo, repo1));
g_assert_false (ostree_repo_equal (closed_repo, repo1_alias));
g_assert_false (ostree_repo_equal (repo2, closed_repo));
g_assert_false (ostree_repo_equal (closed_repo, repo2));
g_assert_false (ostree_repo_equal (closed_repo, closed_repo));
}
int
main (int argc,
char **argv)
{
setlocale (LC_ALL, "");
g_test_init (&argc, &argv, NULL);
g_test_add ("/repo/hash", Fixture, NULL, setup,
test_repo_hash, teardown);
g_test_add ("/repo/hash/closed", Fixture, NULL, setup,
test_repo_hash_closed, teardown);
g_test_add ("/repo/equal", Fixture, NULL, setup,
test_repo_equal, teardown);
return g_test_run ();
}
+4 -1
View File
@@ -26,7 +26,7 @@ skip_without_user_xattrs
setup_test_repository "bare"
echo "1..7"
echo "1..8"
cd ${test_tmpdir}
mkdir mnt
@@ -114,3 +114,6 @@ fi
assert_file_has_content err.txt "Unable to do hardlink checkout across devices"
echo "ok checkout copy fallback"
# check that O_RDONLY|O_CREAT is handled correctly; used by flock(1) at least
flock mnt/nonexistent-file echo "ok create file in ro mode"
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2013 Colin Walters <walters@verbum.org>
*
* This library is free software; you can redistribute it and/or
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
+19
View File
@@ -91,4 +91,23 @@ ${CMD_PREFIX} ostree --repo=repo summary --update --add-metadata=map='@a{sv} {}'
${CMD_PREFIX} ostree --repo=repo summary --view > summary
assert_file_has_content summary "^map: {}$"
# Check the ostree-metadata ref has also been created with the same content and appropriate bindings.
${CMD_PREFIX} ostree --repo=repo refs --collections > refs
assert_file_has_content refs "^(org.example.Collection1, ostree-metadata)$"
${CMD_PREFIX} ostree --repo=repo show ostree-metadata --raw > metadata
assert_file_has_content metadata "'map': <@a{sv} {}>"
assert_file_has_content metadata "'ostree.ref-binding': <\['ostree-metadata'\]>"
assert_file_has_content metadata "'ostree.collection-binding': <'org.example.Collection1'>"
# There should be 5 commits in the ostree-metadata branch, since we’ve updated the summary 5 times.
${CMD_PREFIX} ostree --repo=repo log ostree-metadata | grep 'commit ' | wc -l > commit-count
assert_file_has_content commit-count "^5$"
# The ostree-metadata commits should not contain any files
${CMD_PREFIX} ostree --repo=repo ls ostree-metadata > files
assert_file_has_content files " /$"
cat files | wc -l > files-count
assert_file_has_content files-count "^1$"
echo "ok 2 update summary with collections"
+1 -1
View File
@@ -52,7 +52,7 @@ echo 'ok documented symbols'
# ONLY update this checksum in release commits!
cat > released-sha256.txt <<EOF
b486764b32fbf3d8b7d16114a206cb0789281fe663a1d3d3c13cc48171be4fd7 ${released_syms}
809b49ee0c3a7c230213a00d8c021c3a0ebb91988e39225ded83ef500b9c5eba ${released_syms}
EOF
sha256sum -c released-sha256.txt
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2016 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
+3 -3
View File
@@ -97,9 +97,9 @@ assertEquals(deploymentPath.query_exists(null), false);
//// Ok, redeploy, then add a new revision upstream and pull it
let [,deployment] = sysroot.deploy_tree('testos', rev, origin,
mergeDeployment, null,
null);
[,deployment] = sysroot.deploy_tree('testos', rev, origin,
mergeDeployment, null,
null);
newDeployments = deployments;
deployments = null;
newDeployments.unshift(deployment);
+1 -2
View File
@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
/*
* Copyright (C) 2013 Colin Walters <walters@verbum.org>
*
* This library is free software; you can redistribute it and/or