libostree: Nearly complete move of API into OstreeSysroot
Move the deployment code too.
This commit is contained in:
1 parent
95f07d486a
commit
c6292942ff
17 files changed
+399
-542
No files matched your search
@@ -0,0 +1,83 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2013 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This program 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 licence or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "ostree-ordered-hash.h"
|
||||
#include "libgsystem.h"
|
||||
|
||||
OstreeOrderedHash *
|
||||
_ostree_ordered_hash_new (void)
|
||||
{
|
||||
OstreeOrderedHash *ret;
|
||||
ret = g_new0 (OstreeOrderedHash, 1);
|
||||
ret->order = g_ptr_array_new_with_free_func (g_free);
|
||||
ret->table = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_ordered_hash_free (OstreeOrderedHash *ohash)
|
||||
{
|
||||
if (!ohash)
|
||||
return;
|
||||
g_ptr_array_unref (ohash->order);
|
||||
g_hash_table_unref (ohash->table);
|
||||
g_free (ohash);
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_ordered_hash_cleanup (void *loc)
|
||||
{
|
||||
_ostree_ordered_hash_free (*((OstreeOrderedHash**)loc));
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_ordered_hash_replace_key_take (OstreeOrderedHash *ohash,
|
||||
char *key,
|
||||
const char *value)
|
||||
{
|
||||
gboolean existed;
|
||||
|
||||
existed = g_hash_table_remove (ohash->table, key);
|
||||
if (!existed)
|
||||
g_ptr_array_add (ohash->order, key);
|
||||
g_hash_table_insert (ohash->table, key, (char*)value);
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_ordered_hash_replace_key (OstreeOrderedHash *ohash,
|
||||
const char *key,
|
||||
const char *val)
|
||||
{
|
||||
GString *buf;
|
||||
gsize keylen;
|
||||
char *valp;
|
||||
char *valblock;
|
||||
|
||||
buf = g_string_new (key);
|
||||
keylen = buf->len;
|
||||
g_string_append_c (buf, '\0');
|
||||
g_string_append (buf, val);
|
||||
valblock = g_string_free (buf, FALSE);
|
||||
valp = valblock + keylen + 1;
|
||||
|
||||
_ostree_ordered_hash_replace_key_take (ohash, valblock, valp);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2013 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This program 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 licence or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct {
|
||||
GPtrArray *order;
|
||||
GHashTable *table;
|
||||
} OstreeOrderedHash;
|
||||
|
||||
OstreeOrderedHash *_ostree_ordered_hash_new (void);
|
||||
void _ostree_ordered_hash_free (OstreeOrderedHash *ohash);
|
||||
void _ostree_ordered_hash_cleanup (void *loc);
|
||||
void _ostree_ordered_hash_replace_key_take (OstreeOrderedHash *ohash,
|
||||
char *key,
|
||||
const char *value);
|
||||
void _ostree_ordered_hash_replace_key (OstreeOrderedHash *ohash,
|
||||
const char *key,
|
||||
const char *val);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -21,6 +21,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "ostree.h"
|
||||
#include "ostree-ordered-hash.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -53,5 +54,11 @@ _ostree_sysroot_get_devino (GFile *path,
|
||||
|
||||
char *_ostree_sysroot_join_lines (GPtrArray *lines);
|
||||
|
||||
char *_ostree_sysroot_split_keyeq (char *str);
|
||||
|
||||
OstreeOrderedHash *_ostree_sysroot_parse_kernel_args (const char *options);
|
||||
|
||||
char * _ostree_sysroot_kernel_arg_string_serialize (OstreeOrderedHash *ohash);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -839,3 +839,243 @@ _ostree_sysroot_join_lines (GPtrArray *lines)
|
||||
}
|
||||
return g_string_free (buf, FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_kernel_commandline (OstreeOrderedHash **out_args,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gs_unref_object GFile *proc_cmdline = g_file_new_for_path ("/proc/cmdline");
|
||||
gs_free char *contents = NULL;
|
||||
gsize len;
|
||||
|
||||
if (!g_file_load_contents (proc_cmdline, cancellable, &contents, &len, NULL,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
*out_args = _ostree_sysroot_parse_kernel_args (contents);;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_sysroot_find_booted_deployment:
|
||||
* @target_sysroot: Root directory
|
||||
* @deployments: (element-type OstreeDeployment): Loaded deployments
|
||||
* @out_deployment: (out): The currently booted deployment
|
||||
* @cancellable:
|
||||
* @error:
|
||||
*
|
||||
* If the system is currently booted into a deployment in
|
||||
* @deployments, set @out_deployment. Note that if @target_sysroot is
|
||||
* not equal to "/", @out_deployment will always be set to %NULL.
|
||||
*/
|
||||
gboolean
|
||||
ostree_sysroot_find_booted_deployment (OstreeSysroot *self,
|
||||
GPtrArray *deployments,
|
||||
OstreeDeployment **out_deployment,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gs_unref_object GFile *active_root = g_file_new_for_path ("/");
|
||||
gs_unref_object OstreeSysroot *active_deployment_root = ostree_sysroot_new_default ();
|
||||
gs_unref_object OstreeDeployment *ret_deployment = NULL;
|
||||
|
||||
if (g_file_equal (active_root, self->path))
|
||||
{
|
||||
guint i;
|
||||
const char *bootlink_arg;
|
||||
__attribute__((cleanup(_ostree_ordered_hash_cleanup))) OstreeOrderedHash *kernel_args = NULL;
|
||||
guint32 root_device;
|
||||
guint64 root_inode;
|
||||
|
||||
if (!_ostree_sysroot_get_devino (active_root, &root_device, &root_inode,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!parse_kernel_commandline (&kernel_args, cancellable, error))
|
||||
goto out;
|
||||
|
||||
bootlink_arg = g_hash_table_lookup (kernel_args->table, "ostree");
|
||||
if (bootlink_arg)
|
||||
{
|
||||
for (i = 0; i < deployments->len; i++)
|
||||
{
|
||||
OstreeDeployment *deployment = deployments->pdata[i];
|
||||
gs_unref_object GFile *deployment_path = ostree_sysroot_get_deployment_directory (active_deployment_root, deployment);
|
||||
guint32 device;
|
||||
guint64 inode;
|
||||
|
||||
if (!_ostree_sysroot_get_devino (deployment_path, &device, &inode,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (device == root_device && inode == root_inode)
|
||||
{
|
||||
ret_deployment = g_object_ref (deployment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret_deployment == NULL)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Unexpected state: ostree= kernel argument found, but / is not a deployment root");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not an ostree system */
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
ot_transfer_out_value (out_deployment, &ret_deployment);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_sysroot_require_deployment_or_osname (OstreeSysroot *sysroot,
|
||||
GPtrArray *deployments,
|
||||
const char *osname,
|
||||
OstreeDeployment **out_deployment,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gs_unref_object OstreeDeployment *ret_deployment = NULL;
|
||||
|
||||
if (!ostree_sysroot_find_booted_deployment (sysroot, deployments, &ret_deployment,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (ret_deployment == NULL && osname == NULL)
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Not currently booted into an OSTree system and no --os= argument given");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
ot_transfer_out_value (out_deployment, &ret_deployment);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
OstreeOrderedHash *
|
||||
_ostree_sysroot_parse_kernel_args (const char *options)
|
||||
{
|
||||
OstreeOrderedHash *ret;
|
||||
char **args;
|
||||
char **iter;
|
||||
|
||||
ret = _ostree_ordered_hash_new ();
|
||||
|
||||
if (!options)
|
||||
return ret;
|
||||
|
||||
args = g_strsplit (options, " ", -1);
|
||||
for (iter = args; *iter; iter++)
|
||||
{
|
||||
char *arg = *iter;
|
||||
char *val;
|
||||
|
||||
val = _ostree_sysroot_split_keyeq (arg);
|
||||
|
||||
g_ptr_array_add (ret->order, arg);
|
||||
g_hash_table_insert (ret->table, arg, val);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Modify @arg which should be of the form key=value to make @arg just
|
||||
* contain key. Return a pointer to the start of value.
|
||||
*/
|
||||
char *
|
||||
_ostree_sysroot_split_keyeq (char *arg)
|
||||
{
|
||||
char *eq;
|
||||
|
||||
eq = strchr (arg, '=');
|
||||
if (eq)
|
||||
{
|
||||
/* Note key/val are in one malloc block,
|
||||
* so we don't free val...
|
||||
*/
|
||||
*eq = '\0';
|
||||
return eq+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ...and this allows us to insert a constant
|
||||
* string.
|
||||
*/
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
_ostree_sysroot_kernel_arg_string_serialize (OstreeOrderedHash *ohash)
|
||||
{
|
||||
guint i;
|
||||
GString *buf = g_string_new ("");
|
||||
gboolean first = TRUE;
|
||||
|
||||
for (i = 0; i < ohash->order->len; i++)
|
||||
{
|
||||
const char *key = ohash->order->pdata[i];
|
||||
const char *val = g_hash_table_lookup (ohash->table, key);
|
||||
|
||||
g_assert (val != NULL);
|
||||
|
||||
if (first)
|
||||
first = FALSE;
|
||||
else
|
||||
g_string_append_c (buf, ' ');
|
||||
|
||||
if (*val)
|
||||
g_string_append_printf (buf, "%s=%s", key, val);
|
||||
else
|
||||
g_string_append (buf, key);
|
||||
}
|
||||
|
||||
return g_string_free (buf, FALSE);
|
||||
}
|
||||
|
||||
OstreeDeployment *
|
||||
ostree_sysroot_get_merge_deployment (GPtrArray *deployments,
|
||||
const char *osname,
|
||||
OstreeDeployment *booted_deployment)
|
||||
{
|
||||
g_return_val_if_fail (osname != NULL || booted_deployment != NULL, NULL);
|
||||
|
||||
if (osname == NULL)
|
||||
osname = ostree_deployment_get_osname (booted_deployment);
|
||||
|
||||
if (booted_deployment &&
|
||||
g_strcmp0 (ostree_deployment_get_osname (booted_deployment), osname) == 0)
|
||||
{
|
||||
return g_object_ref (booted_deployment);
|
||||
}
|
||||
else
|
||||
{
|
||||
guint i;
|
||||
for (i = 0; i < deployments->len; i++)
|
||||
{
|
||||
OstreeDeployment *deployment = deployments->pdata[i];
|
||||
|
||||
if (strcmp (ostree_deployment_get_osname (deployment), osname) != 0)
|
||||
continue;
|
||||
|
||||
return g_object_ref (deployment);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -73,5 +73,46 @@ gboolean ostree_sysroot_get_repo (OstreeSysroot *self,
|
||||
OstreeBootloader *ostree_sysroot_query_bootloader (OstreeSysroot *sysroot);
|
||||
|
||||
|
||||
gboolean ostree_sysroot_find_booted_deployment (OstreeSysroot *sysroot,
|
||||
GPtrArray *deployments,
|
||||
OstreeDeployment **out_deployment,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_sysroot_require_deployment_or_osname (OstreeSysroot *sysroot,
|
||||
GPtrArray *deployment_list,
|
||||
const char *osname,
|
||||
OstreeDeployment **out_deployment,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_sysroot_write_deployments (OstreeSysroot *sysroot,
|
||||
int current_bootversion,
|
||||
int new_bootversion,
|
||||
GPtrArray *new_deployments,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_sysroot_deploy (OstreeSysroot *sysroot,
|
||||
int current_bootversion,
|
||||
GPtrArray *current_deployments,
|
||||
const char *osname,
|
||||
const char *revision,
|
||||
GKeyFile *origin,
|
||||
char **add_kernel_argv,
|
||||
gboolean retain,
|
||||
OstreeDeployment *booted_deployment,
|
||||
OstreeDeployment *merge_deployment,
|
||||
OstreeDeployment **out_new_deployment,
|
||||
int *out_new_bootversion,
|
||||
GPtrArray **out_new_deployments,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
|
||||
OstreeDeployment *ostree_sysroot_get_merge_deployment (GPtrArray *deployment_list,
|
||||
const char *osname,
|
||||
OstreeDeployment *booted_deployment);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
Reference in new issue
Block a user