mirror of
https://github.com/ostreedev/ostree.git
synced 2024-12-22 17:35:55 +03:00
Add a notion of "physical" sysroot, use for remote writing
(Note this PR was reverted in <https://github.com/ostreedev/ostree/pull/902>; this version should be better) Using `${sysroot}` to mean the physical storage root: We don't want to write to `${sysroot}/etc/ostree/remotes.d`, since nothing will read it, and really `${sysroot}` should just have `/ostree` (ideally). Today the Anaconda rpmostree code ends up writing there. Fix this by adding a notion of "physical" sysroot. We determine whether the path is physical by checking for `/sysroot`, which exists in deployment roots (and there shouldn't be a `${sysroot}/sysroot`). In order to unit test this, I added a `--sysroot` argument to `remote add`. However, doing this better would require reworking the command line parsing for the `remote` argument to support specifying `--repo` or `--sysroot`, and I didn't quite want to do that yet in this patch. This second iteration of this patch fixes the bug we hit the first time; embarassingly enough I broke `ostree remote list` finding system remotes. The fix is to have `ostree_repo_open()` figure out whether it's the same as `/ostree/repo` for now. Down the line...we might consider having the `ostree remote` command line itself instatiate an `OstreeSysroot` by default, but this maximizes compatibility; we just have to pay a small cost that `ostree` usage outside of that case like `ostree static-delta` in a releng Jenkins job or whatever will do this `stat()` too. Closes: https://github.com/ostreedev/ostree/issues/892 Closes: #1008 Approved by: mbarnes
This commit is contained in:
parent
8b1f1c4428
commit
e0346c1494
@ -80,6 +80,13 @@ struct OstreeRepoCommitModifier {
|
||||
GHashTable *devino_cache;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
OSTREE_REPO_SYSROOT_KIND_UNKNOWN,
|
||||
OSTREE_REPO_SYSROOT_KIND_NO, /* Not a system repo */
|
||||
OSTREE_REPO_SYSROOT_KIND_VIA_SYSROOT, /* Constructed via ostree_sysroot_get_repo() */
|
||||
OSTREE_REPO_SYSROOT_KIND_IS_SYSROOT_OSTREE, /* We match /ostree/repo */
|
||||
} OstreeRepoSysrootKind;
|
||||
|
||||
/**
|
||||
* OstreeRepo:
|
||||
*
|
||||
@ -101,6 +108,7 @@ struct OstreeRepo {
|
||||
int objects_dir_fd;
|
||||
int uncompressed_objects_dir_fd;
|
||||
GFile *sysroot_dir;
|
||||
GWeakRef sysroot; /* Weak to avoid a circular ref; see also `is_system` */
|
||||
char *remotes_config_dir;
|
||||
|
||||
GHashTable *txn_refs; /* (element-type utf8 utf8) */
|
||||
@ -118,7 +126,7 @@ struct OstreeRepo {
|
||||
|
||||
gboolean inited;
|
||||
gboolean writable;
|
||||
gboolean is_system; /* Was this repo created via ostree_sysroot_get_repo() ? */
|
||||
OstreeRepoSysrootKind sysroot_kind;
|
||||
GError *writable_error;
|
||||
gboolean in_transaction;
|
||||
gboolean disable_fsync;
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <glnx-console.h>
|
||||
|
||||
#include "ostree-core-private.h"
|
||||
#include "ostree-sysroot-private.h"
|
||||
#include "ostree-remote-private.h"
|
||||
#include "ostree-repo-private.h"
|
||||
#include "ostree-repo-file.h"
|
||||
@ -125,6 +126,10 @@ G_DEFINE_TYPE (OstreeRepo, ostree_repo, G_TYPE_OBJECT)
|
||||
|
||||
#define SYSCONF_REMOTES SHORTENED_SYSCONFDIR "/ostree/remotes.d"
|
||||
|
||||
static GFile *
|
||||
get_remotes_d_dir (OstreeRepo *self,
|
||||
GFile *sysroot);
|
||||
|
||||
OstreeRemote *
|
||||
_ostree_repo_get_remote (OstreeRepo *self,
|
||||
const char *name,
|
||||
@ -467,6 +472,7 @@ ostree_repo_finalize (GObject *object)
|
||||
if (self->uncompressed_objects_dir_fd != -1)
|
||||
(void) close (self->uncompressed_objects_dir_fd);
|
||||
g_clear_object (&self->sysroot_dir);
|
||||
g_weak_ref_clear (&self->sysroot);
|
||||
g_free (self->remotes_config_dir);
|
||||
|
||||
if (self->loose_object_devino_hash)
|
||||
@ -547,10 +553,6 @@ ostree_repo_constructed (GObject *object)
|
||||
|
||||
g_assert (self->repodir != NULL);
|
||||
|
||||
/* Ensure the "sysroot-path" property is set. */
|
||||
if (self->sysroot_dir == NULL)
|
||||
self->sysroot_dir = g_object_ref (_ostree_get_default_sysroot_path ());
|
||||
|
||||
G_OBJECT_CLASS (ostree_repo_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
@ -645,6 +647,7 @@ ostree_repo_init (OstreeRepo *self)
|
||||
self->objects_dir_fd = -1;
|
||||
self->uncompressed_objects_dir_fd = -1;
|
||||
self->commit_stagedir_lock = empty_lockfile;
|
||||
self->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -728,18 +731,20 @@ ostree_repo_new_default (void)
|
||||
gboolean
|
||||
ostree_repo_is_system (OstreeRepo *repo)
|
||||
{
|
||||
g_autoptr(GFile) default_repo_path = NULL;
|
||||
|
||||
g_return_val_if_fail (OSTREE_IS_REPO (repo), FALSE);
|
||||
|
||||
/* If we were created via ostree_sysroot_get_repo(), we know the answer is yes
|
||||
* without having to compare file paths.
|
||||
*/
|
||||
if (repo->is_system)
|
||||
if (repo->sysroot_kind == OSTREE_REPO_SYSROOT_KIND_VIA_SYSROOT ||
|
||||
repo->sysroot_kind == OSTREE_REPO_SYSROOT_KIND_IS_SYSROOT_OSTREE)
|
||||
return TRUE;
|
||||
|
||||
default_repo_path = get_default_repo_path (repo->sysroot_dir);
|
||||
/* No sysroot_dir set? Not a system repo then. */
|
||||
if (!repo->sysroot_dir)
|
||||
return FALSE;
|
||||
|
||||
g_autoptr(GFile) default_repo_path = get_default_repo_path (repo->sysroot_dir);
|
||||
return g_file_equal (repo->repodir, default_repo_path);
|
||||
}
|
||||
|
||||
@ -916,24 +921,11 @@ impl_repo_remote_add (OstreeRepo *self,
|
||||
|
||||
remote = ostree_remote_new (name);
|
||||
|
||||
/* The OstreeRepo maintains its own internal system root path,
|
||||
* so we need to not only check if a "sysroot" argument was given
|
||||
* but also whether it's actually different from OstreeRepo's.
|
||||
*
|
||||
* XXX Having API regret about the "sysroot" argument now.
|
||||
*/
|
||||
gboolean different_sysroot = FALSE;
|
||||
if (sysroot != NULL)
|
||||
different_sysroot = !g_file_equal (sysroot, self->sysroot_dir);
|
||||
|
||||
if (different_sysroot || ostree_repo_is_system (self))
|
||||
g_autoptr(GFile) etc_ostree_remotes_d = get_remotes_d_dir (self, sysroot);
|
||||
if (etc_ostree_remotes_d)
|
||||
{
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
|
||||
if (sysroot == NULL)
|
||||
sysroot = self->sysroot_dir;
|
||||
|
||||
g_autoptr(GFile) etc_ostree_remotes_d = g_file_resolve_relative_path (sysroot, SYSCONF_REMOTES);
|
||||
if (!g_file_make_directory_with_parents (etc_ostree_remotes_d,
|
||||
cancellable, &local_error))
|
||||
{
|
||||
@ -1874,14 +1866,55 @@ append_one_remote_config (OstreeRepo *self,
|
||||
}
|
||||
|
||||
static GFile *
|
||||
get_remotes_d_dir (OstreeRepo *self)
|
||||
get_remotes_d_dir (OstreeRepo *self,
|
||||
GFile *sysroot)
|
||||
{
|
||||
if (self->remotes_config_dir != NULL)
|
||||
/* Support explicit override */
|
||||
if (self->sysroot_dir != NULL && 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;
|
||||
g_autoptr(GFile) sysroot_owned = NULL;
|
||||
/* Very complicated sysroot logic; this bit breaks the otherwise mostly clean
|
||||
* layering between OstreeRepo and OstreeSysroot. First, If a sysroot was
|
||||
* provided, use it. Otherwise, check to see whether we reference
|
||||
* /ostree/repo, or if not that, see if we have a ref to a sysroot (and it's
|
||||
* physical).
|
||||
*/
|
||||
g_autoptr(OstreeSysroot) sysroot_ref = NULL;
|
||||
if (sysroot == NULL)
|
||||
{
|
||||
/* No explicit sysroot? Let's see if we have a kind */
|
||||
switch (self->sysroot_kind)
|
||||
{
|
||||
case OSTREE_REPO_SYSROOT_KIND_UNKNOWN:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
case OSTREE_REPO_SYSROOT_KIND_NO:
|
||||
break;
|
||||
case OSTREE_REPO_SYSROOT_KIND_IS_SYSROOT_OSTREE:
|
||||
sysroot = sysroot_owned = g_file_new_for_path ("/");
|
||||
break;
|
||||
case OSTREE_REPO_SYSROOT_KIND_VIA_SYSROOT:
|
||||
sysroot_ref = (OstreeSysroot*)g_weak_ref_get (&self->sysroot);
|
||||
/* Only write to /etc/ostree/remotes.d if we are pointed at a deployment */
|
||||
if (sysroot_ref != NULL && !sysroot_ref->is_physical)
|
||||
sysroot = ostree_sysroot_get_path (sysroot_ref);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* For backwards compat, also fall back to the sysroot-path variable, which we
|
||||
* don't set anymore internally, and I hope no one else uses.
|
||||
*/
|
||||
if (sysroot == NULL && sysroot_ref == NULL)
|
||||
sysroot = self->sysroot_dir;
|
||||
|
||||
/* Did we find a sysroot? If not, NULL means use the repo config, otherwise
|
||||
* return the path in /etc.
|
||||
*/
|
||||
if (sysroot == NULL)
|
||||
return NULL;
|
||||
else
|
||||
return g_file_resolve_relative_path (sysroot, SYSCONF_REMOTES);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -2036,7 +2069,7 @@ reload_remote_config (OstreeRepo *self,
|
||||
if (!add_remotes_from_keyfile (self, self->config, NULL, error))
|
||||
return FALSE;
|
||||
|
||||
g_autoptr(GFile) remotes_d = get_remotes_d_dir (self);
|
||||
g_autoptr(GFile) remotes_d = get_remotes_d_dir (self, NULL);
|
||||
if (remotes_d == NULL)
|
||||
return TRUE;
|
||||
|
||||
@ -2101,6 +2134,7 @@ ostree_repo_open (OstreeRepo *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
struct stat self_stbuf;
|
||||
struct stat stbuf;
|
||||
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
@ -2137,6 +2171,9 @@ ostree_repo_open (OstreeRepo *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!glnx_fstat (self->repo_dir_fd, &self_stbuf, error))
|
||||
return FALSE;
|
||||
|
||||
if (!glnx_opendirat (self->repo_dir_fd, "objects", TRUE,
|
||||
&self->objects_dir_fd, error))
|
||||
{
|
||||
@ -2178,6 +2215,27 @@ ostree_repo_open (OstreeRepo *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If we weren't created via ostree_sysroot_get_repo(), for backwards
|
||||
* compatibility we need to figure out now whether or not we refer to the
|
||||
* system repo. See also ostree-sysroot.c.
|
||||
*/
|
||||
if (self->sysroot_kind == OSTREE_REPO_SYSROOT_KIND_UNKNOWN)
|
||||
{
|
||||
struct stat system_stbuf;
|
||||
/* Ignore any errors if we can't access /ostree/repo */
|
||||
if (fstatat (AT_FDCWD, "/ostree/repo", &system_stbuf, 0) == 0)
|
||||
{
|
||||
/* Are we the same as /ostree/repo? */
|
||||
if (self_stbuf.st_dev == system_stbuf.st_dev &&
|
||||
self_stbuf.st_ino == system_stbuf.st_ino)
|
||||
self->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_IS_SYSROOT_OSTREE;
|
||||
else
|
||||
self->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_NO;
|
||||
}
|
||||
else
|
||||
self->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_NO;
|
||||
}
|
||||
|
||||
if (!ostree_repo_reload_config (self, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
@ -4144,7 +4202,7 @@ find_keyring (OstreeRepo *self,
|
||||
return g_steal_pointer (&file);
|
||||
}
|
||||
|
||||
g_autoptr(GFile) remotes_d = get_remotes_d_dir (self);
|
||||
g_autoptr(GFile) remotes_d = get_remotes_d_dir (self, NULL);
|
||||
if (remotes_d)
|
||||
{
|
||||
g_autoptr(GFile) file2 = g_file_get_child (remotes_d, remote->keyring);
|
||||
|
@ -49,6 +49,7 @@ struct OstreeSysroot {
|
||||
|
||||
gboolean loaded;
|
||||
|
||||
gboolean is_physical; /* TRUE if we're pointed at physical storage root and not a deployment */
|
||||
GPtrArray *deployments;
|
||||
int bootversion;
|
||||
int subbootversion;
|
||||
|
@ -134,7 +134,9 @@ ostree_sysroot_constructed (GObject *object)
|
||||
|
||||
repo_path = g_file_resolve_relative_path (self->path, "ostree/repo");
|
||||
self->repo = ostree_repo_new_for_sysroot_path (repo_path, self->path);
|
||||
self->repo->is_system = TRUE;
|
||||
self->repo->sysroot_kind = OSTREE_REPO_SYSROOT_KIND_VIA_SYSROOT;
|
||||
/* Hold a weak ref for the remote-add handling */
|
||||
g_weak_ref_init (&self->repo->sysroot, object);
|
||||
|
||||
G_OBJECT_CLASS (ostree_sysroot_parent_class)->constructed (object);
|
||||
}
|
||||
@ -813,6 +815,26 @@ ostree_sysroot_load_if_changed (OstreeSysroot *self,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
/* Determine whether we're "physical" or not, the first time we initialize */
|
||||
if (!self->loaded)
|
||||
{
|
||||
/* If we have a booted deployment, the sysroot is / and we're definitely
|
||||
* not physical.
|
||||
*/
|
||||
if (self->booted_deployment)
|
||||
self->is_physical = FALSE; /* (the default, but explicit for clarity) */
|
||||
/* Otherwise - check for /sysroot which should only exist in a deployment,
|
||||
* not in ${sysroot} (a metavariable for the real physical root).
|
||||
*/
|
||||
else if (fstatat (self->sysroot_fd, "sysroot", &stbuf, 0) < 0)
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
return glnx_throw_errno_prefix (error, "fstatat");
|
||||
self->is_physical = TRUE;
|
||||
}
|
||||
/* Otherwise, the default is FALSE */
|
||||
}
|
||||
|
||||
self->bootversion = bootversion;
|
||||
self->subbootversion = subbootversion;
|
||||
self->deployments = deployments;
|
||||
|
@ -207,6 +207,88 @@ ostree_run (int argc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Process a --repo arg; used below, and for the remote builtins */
|
||||
static OstreeRepo *
|
||||
parse_repo_option (GOptionContext *context,
|
||||
const char *repo_path,
|
||||
gboolean skip_repo_open,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(OstreeRepo) repo = NULL;
|
||||
|
||||
if (repo_path == NULL)
|
||||
{
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
|
||||
repo = ostree_repo_new_default ();
|
||||
if (!ostree_repo_open (repo, cancellable, &local_error))
|
||||
{
|
||||
if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||||
{
|
||||
g_autofree char *help = NULL;
|
||||
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Command requires a --repo argument");
|
||||
|
||||
help = g_option_context_get_help (context, FALSE, NULL);
|
||||
g_printerr ("%s", help);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_propagate_error (error, g_steal_pointer (&local_error));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_autoptr(GFile) repo_file = g_file_new_for_path (repo_path);
|
||||
|
||||
repo = ostree_repo_new (repo_file);
|
||||
if (!skip_repo_open)
|
||||
{
|
||||
if (!ostree_repo_open (repo, cancellable, error))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return g_steal_pointer (&repo);
|
||||
}
|
||||
|
||||
/* Used by the remote builtins which are special in taking --sysroot or --repo */
|
||||
gboolean
|
||||
ostree_parse_sysroot_or_repo_option (GOptionContext *context,
|
||||
const char *sysroot_path,
|
||||
const char *repo_path,
|
||||
OstreeSysroot **out_sysroot,
|
||||
OstreeRepo **out_repo,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(OstreeSysroot) sysroot = NULL;
|
||||
g_autoptr(OstreeRepo) repo = NULL;
|
||||
if (sysroot_path)
|
||||
{
|
||||
g_autoptr(GFile) sysroot_file = g_file_new_for_path (sysroot_path);
|
||||
sysroot = ostree_sysroot_new (sysroot_file);
|
||||
if (!ostree_sysroot_load (sysroot, cancellable, error))
|
||||
return FALSE;
|
||||
if (!ostree_sysroot_get_repo (sysroot, &repo, cancellable, error))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
repo = parse_repo_option (context, repo_path, FALSE, cancellable, error);
|
||||
if (!repo)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ot_transfer_out_value (out_sysroot, &sysroot);
|
||||
ot_transfer_out_value (out_repo, &repo);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_option_context_parse (GOptionContext *context,
|
||||
const GOptionEntry *main_entries,
|
||||
@ -217,7 +299,7 @@ ostree_option_context_parse (GOptionContext *context,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
glnx_unref_object OstreeRepo *repo = NULL;
|
||||
g_autoptr(OstreeRepo) repo = NULL;
|
||||
|
||||
/* Entries are listed in --help output in the order added. We add the
|
||||
* main entries ourselves so that we can add the --repo entry first. */
|
||||
@ -254,40 +336,12 @@ ostree_option_context_parse (GOptionContext *context,
|
||||
if (opt_verbose)
|
||||
g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, message_handler, NULL);
|
||||
|
||||
if (opt_repo == NULL && !(flags & OSTREE_BUILTIN_FLAG_NO_REPO))
|
||||
if (!(flags & OSTREE_BUILTIN_FLAG_NO_REPO))
|
||||
{
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
|
||||
repo = ostree_repo_new_default ();
|
||||
if (!ostree_repo_open (repo, cancellable, &local_error))
|
||||
{
|
||||
if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||||
{
|
||||
g_autofree char *help = NULL;
|
||||
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Command requires a --repo argument");
|
||||
|
||||
help = g_option_context_get_help (context, FALSE, NULL);
|
||||
g_printerr ("%s", help);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_propagate_error (error, g_steal_pointer (&local_error));
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (opt_repo != NULL)
|
||||
{
|
||||
g_autoptr(GFile) repo_file = g_file_new_for_path (opt_repo);
|
||||
|
||||
repo = ostree_repo_new (repo_file);
|
||||
if (!(flags & OSTREE_BUILTIN_FLAG_NO_CHECK))
|
||||
{
|
||||
if (!ostree_repo_open (repo, cancellable, error))
|
||||
return FALSE;
|
||||
}
|
||||
repo = parse_repo_option (context, opt_repo, (flags & OSTREE_BUILTIN_FLAG_NO_CHECK) > 0,
|
||||
cancellable, error);
|
||||
if (!repo)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (out_repo)
|
||||
|
@ -46,6 +46,14 @@ int ostree_run (int argc, char **argv, OstreeCommand *commands, GError **error);
|
||||
|
||||
int ostree_usage (OstreeCommand *commands, gboolean is_error);
|
||||
|
||||
gboolean ostree_parse_sysroot_or_repo_option (GOptionContext *context,
|
||||
const char *sysroot_path,
|
||||
const char *repo_path,
|
||||
OstreeSysroot **out_sysroot,
|
||||
OstreeRepo **out_repo,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_option_context_parse (GOptionContext *context,
|
||||
const GOptionEntry *main_entries,
|
||||
int *argc, char ***argv,
|
||||
|
@ -34,6 +34,8 @@ static char *opt_contenturl;
|
||||
#ifdef OSTREE_ENABLE_EXPERIMENTAL_API
|
||||
static char *opt_collection_id;
|
||||
#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */
|
||||
static char *opt_sysroot;
|
||||
static char *opt_repo;
|
||||
|
||||
static GOptionEntry option_entries[] = {
|
||||
{ "set", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_set, "Set config option KEY=VALUE for remote", "KEY=VALUE" },
|
||||
@ -45,6 +47,8 @@ static GOptionEntry option_entries[] = {
|
||||
{ "collection-id", 0, 0, G_OPTION_ARG_STRING, &opt_collection_id,
|
||||
"Globally unique ID for this repository as an collection of refs for redistribution to other repositories", "COLLECTION-ID" },
|
||||
#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */
|
||||
{ "repo", 0, 0, G_OPTION_ARG_FILENAME, &opt_repo, "Path to OSTree repository (defaults to /sysroot/ostree/repo)", "PATH" },
|
||||
{ "sysroot", 0, 0, G_OPTION_ARG_FILENAME, &opt_sysroot, "Use sysroot at PATH (overrides --repo)", "PATH" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@ -52,6 +56,7 @@ gboolean
|
||||
ot_remote_builtin_add (int argc, char **argv, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
g_autoptr(GOptionContext) context = NULL;
|
||||
g_autoptr(OstreeSysroot) sysroot = NULL;
|
||||
g_autoptr(OstreeRepo) repo = NULL;
|
||||
const char *remote_name;
|
||||
const char *remote_url;
|
||||
@ -63,7 +68,12 @@ ot_remote_builtin_add (int argc, char **argv, GCancellable *cancellable, GError
|
||||
context = g_option_context_new ("NAME [metalink=|mirrorlist=]URL [BRANCH...] - Add a remote repository");
|
||||
|
||||
if (!ostree_option_context_parse (context, option_entries, &argc, &argv,
|
||||
OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
|
||||
OSTREE_BUILTIN_FLAG_NO_REPO, NULL, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_parse_sysroot_or_repo_option (context, opt_sysroot, opt_repo,
|
||||
&sysroot, &repo,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (argc < 3)
|
||||
|
@ -25,43 +25,48 @@
|
||||
#include "ot-main.h"
|
||||
#include "ot-remote-builtins.h"
|
||||
|
||||
gboolean opt_if_exists = FALSE;
|
||||
static gboolean opt_if_exists = FALSE;
|
||||
static char *opt_sysroot;
|
||||
static char *opt_repo;
|
||||
|
||||
static GOptionEntry option_entries[] = {
|
||||
{ "if-exists", 0, 0, G_OPTION_ARG_NONE, &opt_if_exists, "Do nothing if the provided remote does not exist", NULL },
|
||||
{ "repo", 0, 0, G_OPTION_ARG_FILENAME, &opt_repo, "Path to OSTree repository (defaults to /sysroot/ostree/repo)", "PATH" },
|
||||
{ "sysroot", 0, 0, G_OPTION_ARG_FILENAME, &opt_sysroot, "Use sysroot at PATH (overrides --repo)", "PATH" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
gboolean
|
||||
ot_remote_builtin_delete (int argc, char **argv, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
g_autoptr(GOptionContext) context = NULL;
|
||||
g_autoptr(OstreeRepo) repo = NULL;
|
||||
const char *remote_name;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
context = g_option_context_new ("NAME - Delete a remote repository");
|
||||
g_autoptr(GOptionContext) context = g_option_context_new ("NAME - Delete a remote repository");
|
||||
|
||||
if (!ostree_option_context_parse (context, option_entries, &argc, &argv,
|
||||
OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
|
||||
goto out;
|
||||
OSTREE_BUILTIN_FLAG_NO_REPO, NULL, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
g_autoptr(OstreeSysroot) sysroot = NULL;
|
||||
g_autoptr(OstreeRepo) repo = NULL;
|
||||
if (!ostree_parse_sysroot_or_repo_option (context, opt_sysroot, opt_repo,
|
||||
&sysroot, &repo,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
ot_util_usage_error (context, "NAME must be specified", error);
|
||||
goto out;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
remote_name = argv[1];
|
||||
const char *remote_name = argv[1];
|
||||
|
||||
if (!ostree_repo_remote_change (repo, NULL,
|
||||
opt_if_exists ? OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS :
|
||||
OSTREE_REPO_REMOTE_CHANGE_DELETE,
|
||||
remote_name, NULL, NULL,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
return FALSE;
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -234,3 +234,18 @@ curr_rev=$(${CMD_PREFIX} ostree rev-parse --repo=sysroot/ostree/repo testos/buil
|
||||
assert_streq ${curr_rev} ${head_rev}
|
||||
|
||||
echo "ok upgrade with and without override-commit"
|
||||
|
||||
deployment=$(${CMD_PREFIX} ostree admin --sysroot=sysroot --print-current-dir)
|
||||
${CMD_PREFIX} ostree --sysroot=sysroot remote add --set=gpg-verify=false remote-test-physical file://$(pwd)/testos-repo
|
||||
assert_not_has_file ${deployment}/etc/ostree/remotes.d/remote-test-physical.conf testos-repo
|
||||
assert_file_has_content sysroot/ostree/repo/config remote-test-physical
|
||||
echo "ok remote add physical sysroot"
|
||||
|
||||
# Now a hack...symlink ${deployment}/sysroot to the sysroot in lieu of a bind
|
||||
# mount which we can't do in unit tests.
|
||||
ln -sr sysroot ${deployment}/sysroot
|
||||
ln -s sysroot/ostree ${deployment}/ostree
|
||||
${CMD_PREFIX} ostree --sysroot=${deployment} remote add --set=gpg-verify=false remote-test-nonphysical file://$(pwd)/testos-repo
|
||||
assert_not_file_has_content sysroot/ostree/repo/config remote-test-nonphysical
|
||||
assert_file_has_content ${deployment}/etc/ostree/remotes.d/remote-test-nonphysical.conf testos-repo
|
||||
echo "ok remote add nonphysical sysroot"
|
||||
|
16
tests/installed/itest-remotes.sh
Executable file
16
tests/installed/itest-remotes.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Test that we didn't regress /etc/ostree/remotes.d handling
|
||||
|
||||
set -xeuo pipefail
|
||||
|
||||
dn=$(dirname $0)
|
||||
. ${dn}/libinsttest.sh
|
||||
|
||||
test_tmpdir=$(prepare_tmpdir)
|
||||
trap _tmpdir_cleanup EXIT
|
||||
|
||||
ostree remote list > remotes.txt
|
||||
if ! test -s remotes.txt; then
|
||||
assert_not_reached "no ostree remotes"
|
||||
fi
|
@ -19,7 +19,7 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "1..16"
|
||||
echo "1..18"
|
||||
|
||||
. $(dirname $0)/libtest.sh
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "1..16"
|
||||
echo "1..18"
|
||||
|
||||
. $(dirname $0)/libtest.sh
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "1..17"
|
||||
echo "1..19"
|
||||
|
||||
. $(dirname $0)/libtest.sh
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user