deploy: Rework kernel arguments, add --karg-append to "admin deploy"
The "ordered hash" code was really just for kernel arguments. And it turns out it needs to be a multihash (for e.g. multiple console= arguments). So turn the OstreeOrderedHash into OstreeKernelArgs, and move the bits to split key=value and such into there. Now we're not making this public API yet - the public OstreeSysroot just takes char **kargs. To facilitate code reuse between ostree/ and libostree/, make it a noinst libtool library. It'll be duplicated in the binary and library, but that's OK for now. We can investigate making OstreeKernelArgs public later. https://bugzilla.gnome.org/show_bug.cgi?id=721136
This commit is contained in:
1 parent
7db2031fa0
commit
b2d0ba7ac1
13 files changed
+425
-306
No files matched your search
@@ -0,0 +1,263 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2013,2014 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-kernel-args.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
struct _OstreeKernelArgs {
|
||||
GPtrArray *order;
|
||||
GHashTable *table;
|
||||
};
|
||||
|
||||
static char *
|
||||
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 "";
|
||||
}
|
||||
}
|
||||
|
||||
OstreeKernelArgs *
|
||||
_ostree_kernel_args_new (void)
|
||||
{
|
||||
OstreeKernelArgs *ret;
|
||||
ret = g_new0 (OstreeKernelArgs, 1);
|
||||
ret->order = g_ptr_array_new_with_free_func (g_free);
|
||||
ret->table = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL, (GDestroyNotify)g_ptr_array_unref);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_free (OstreeKernelArgs *kargs)
|
||||
{
|
||||
if (!kargs)
|
||||
return;
|
||||
g_ptr_array_unref (kargs->order);
|
||||
g_hash_table_unref (kargs->table);
|
||||
g_free (kargs);
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_cleanup (void *loc)
|
||||
{
|
||||
_ostree_kernel_args_free (*((OstreeKernelArgs**)loc));
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_replace_take (OstreeKernelArgs *kargs,
|
||||
char *arg)
|
||||
{
|
||||
gboolean existed;
|
||||
GPtrArray *values = g_ptr_array_new_with_free_func (g_free);
|
||||
const char *value = split_keyeq (arg);
|
||||
|
||||
existed = g_hash_table_remove (kargs->table, arg);
|
||||
if (!existed)
|
||||
g_ptr_array_add (kargs->order, arg);
|
||||
g_ptr_array_add (values, g_strdup (value));
|
||||
g_hash_table_replace (kargs->table, arg, values);
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_replace (OstreeKernelArgs *kargs,
|
||||
const char *arg)
|
||||
{
|
||||
_ostree_kernel_args_replace_take (kargs, g_strdup (arg));
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_append (OstreeKernelArgs *kargs,
|
||||
const char *arg)
|
||||
{
|
||||
gboolean existed = TRUE;
|
||||
GPtrArray *values;
|
||||
char *duped = g_strdup (arg);
|
||||
const char *val = split_keyeq (duped);
|
||||
|
||||
values = g_hash_table_lookup (kargs->table, duped);
|
||||
if (!values)
|
||||
{
|
||||
values = g_ptr_array_new_with_free_func (g_free);
|
||||
existed = FALSE;
|
||||
}
|
||||
|
||||
g_ptr_array_add (values, g_strdup (val));
|
||||
|
||||
if (!existed)
|
||||
{
|
||||
g_hash_table_replace (kargs->table, duped, values);
|
||||
g_ptr_array_add (kargs->order, duped);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (duped);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_replace_argv (OstreeKernelArgs *kargs,
|
||||
char **argv)
|
||||
{
|
||||
char **strviter;
|
||||
|
||||
for (strviter = argv; strviter && *strviter; strviter++)
|
||||
{
|
||||
const char *arg = *strviter;
|
||||
_ostree_kernel_args_replace (kargs, arg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_append_argv (OstreeKernelArgs *kargs,
|
||||
char **argv)
|
||||
{
|
||||
char **strviter;
|
||||
|
||||
for (strviter = argv; strviter && *strviter; strviter++)
|
||||
{
|
||||
const char *arg = *strviter;
|
||||
_ostree_kernel_args_append (kargs, arg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_parse_append (OstreeKernelArgs *kargs,
|
||||
const char *options)
|
||||
{
|
||||
char **args = NULL;
|
||||
char **iter;
|
||||
|
||||
if (!options)
|
||||
return;
|
||||
|
||||
args = g_strsplit (options, " ", -1);
|
||||
for (iter = args; *iter; iter++)
|
||||
{
|
||||
char *arg = *iter;
|
||||
_ostree_kernel_args_append (kargs, arg);
|
||||
}
|
||||
g_strfreev (args);
|
||||
}
|
||||
|
||||
OstreeKernelArgs *
|
||||
_ostree_kernel_args_from_string (const char *options)
|
||||
{
|
||||
OstreeKernelArgs *ret;
|
||||
|
||||
ret = _ostree_kernel_args_new ();
|
||||
_ostree_kernel_args_parse_append (ret, options);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char **
|
||||
_ostree_kernel_args_to_strv (OstreeKernelArgs *kargs)
|
||||
{
|
||||
GPtrArray *strv = g_ptr_array_new ();
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < kargs->order->len; i++)
|
||||
{
|
||||
const char *key = kargs->order->pdata[i];
|
||||
GPtrArray *values = g_hash_table_lookup (kargs->table, key);
|
||||
guint j;
|
||||
|
||||
g_assert (values != NULL);
|
||||
|
||||
for (j = 0; j < values->len; j++)
|
||||
{
|
||||
const char *value = values->pdata[j];
|
||||
|
||||
g_ptr_array_add (strv, g_strconcat (key, "=", value, NULL));
|
||||
}
|
||||
}
|
||||
g_ptr_array_add (strv, NULL);
|
||||
|
||||
return (char**)g_ptr_array_free (strv, FALSE);
|
||||
}
|
||||
|
||||
char *
|
||||
_ostree_kernel_args_to_string (OstreeKernelArgs *kargs)
|
||||
{
|
||||
GString *buf = g_string_new ("");
|
||||
gboolean first = TRUE;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < kargs->order->len; i++)
|
||||
{
|
||||
const char *key = kargs->order->pdata[i];
|
||||
GPtrArray *values = g_hash_table_lookup (kargs->table, key);
|
||||
guint j;
|
||||
|
||||
g_assert (values != NULL);
|
||||
|
||||
for (j = 0; j < values->len; j++)
|
||||
{
|
||||
const char *value = values->pdata[j];
|
||||
|
||||
if (first)
|
||||
first = FALSE;
|
||||
else
|
||||
g_string_append_c (buf, ' ');
|
||||
|
||||
if (value && *value)
|
||||
{
|
||||
g_string_append (buf, key);
|
||||
g_string_append_c (buf, '=');
|
||||
g_string_append (buf, value);
|
||||
}
|
||||
else
|
||||
g_string_append (buf, key);
|
||||
}
|
||||
}
|
||||
|
||||
return g_string_free (buf, FALSE);
|
||||
}
|
||||
|
||||
const char *
|
||||
_ostree_kernel_args_get_last_value (OstreeKernelArgs *kargs, const char *key)
|
||||
{
|
||||
GPtrArray *values = g_hash_table_lookup (kargs->table, key);
|
||||
|
||||
if (!values)
|
||||
return NULL;
|
||||
|
||||
g_assert (values->len > 0);
|
||||
return (char*)values->pdata[values->len-1];
|
||||
}
|
||||
Reference in new issue
Block a user