From 18b6f5fd0c334ca60a397752ce717138abea739a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 6 May 2012 17:03:50 -0400 Subject: [PATCH] ostadmin: Initial code --- Makefile-ostadmin.am | 29 +++ Makefile-otutil.am | 3 + Makefile.am | 1 + gnomeos/ostree-install.sh | 93 ------- src/libotutil/ot-gio-utils.c | 28 +++ src/libotutil/ot-gio-utils.h | 2 + src/libotutil/ot-spawn-utils.c | 78 ++++++ src/libotutil/ot-spawn-utils.h | 42 ++++ src/libotutil/otutil.c | 41 ++++ src/libotutil/otutil.h | 5 + src/ostadmin/main.c | 43 ++++ src/ostadmin/ot-admin-builtin-deploy.c | 327 +++++++++++++++++++++++++ src/ostadmin/ot-admin-builtin-init.c | 87 +++++++ src/ostadmin/ot-admin-builtins.h | 35 +++ src/ostadmin/ot-admin-main.c | 133 ++++++++++ src/ostadmin/ot-admin-main.h | 32 +++ src/ostree/ot-builtin-checkout.c | 7 +- 17 files changed, 892 insertions(+), 94 deletions(-) create mode 100644 Makefile-ostadmin.am delete mode 100755 gnomeos/ostree-install.sh create mode 100644 src/libotutil/ot-spawn-utils.c create mode 100644 src/libotutil/ot-spawn-utils.h create mode 100644 src/libotutil/otutil.c create mode 100644 src/ostadmin/main.c create mode 100644 src/ostadmin/ot-admin-builtin-deploy.c create mode 100644 src/ostadmin/ot-admin-builtin-init.c create mode 100644 src/ostadmin/ot-admin-builtins.h create mode 100644 src/ostadmin/ot-admin-main.c create mode 100644 src/ostadmin/ot-admin-main.h diff --git a/Makefile-ostadmin.am b/Makefile-ostadmin.am new file mode 100644 index 00000000..d8305dcb --- /dev/null +++ b/Makefile-ostadmin.am @@ -0,0 +1,29 @@ +# Copyright (C) 2012 Colin Walters +# +# 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. + +bin_PROGRAMS += ostadmin + +ostadmin_SOURCES = src/ostadmin/main.c \ + src/ostadmin/ot-admin-builtins.h \ + src/ostadmin/ot-admin-builtin-init.c \ + src/ostadmin/ot-admin-builtin-deploy.c \ + src/ostadmin/ot-admin-main.h \ + src/ostadmin/ot-admin-main.c \ + $(NULL) + +ostadmin_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/ostadmin -DLOCALEDIR=\"$(datadir)/locale\" $(OT_DEP_GIO_UNIX_CFLAGS) +ostadmin_LDADD = libotutil.la $(OT_DEP_GIO_UNIX_LIBS) diff --git a/Makefile-otutil.am b/Makefile-otutil.am index 1bf27649..fec972a3 100644 --- a/Makefile-otutil.am +++ b/Makefile-otutil.am @@ -28,12 +28,15 @@ libotutil_la_SOURCES = \ src/libotutil/ot-opt-utils.h \ src/libotutil/ot-unix-utils.c \ src/libotutil/ot-unix-utils.h \ + src/libotutil/ot-spawn-utils.c \ + src/libotutil/ot-spawn-utils.h \ src/libotutil/ot-variant-utils.c \ src/libotutil/ot-variant-utils.h \ src/libotutil/ot-gio-utils.c \ src/libotutil/ot-gio-utils.h \ src/libotutil/ot-glib-compat.c \ src/libotutil/ot-glib-compat.h \ + src/libotutil/otutil.c \ src/libotutil/otutil.h \ $(NULL) libotutil_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(OT_DEP_GIO_UNIX_CFLAGS) diff --git a/Makefile.am b/Makefile.am index 48951ad2..9d31e098 100644 --- a/Makefile.am +++ b/Makefile.am @@ -37,6 +37,7 @@ include Makefile-daemon.am include Makefile-otutil.am include Makefile-libostree.am include Makefile-ostree.am +include Makefile-ostadmin.am include Makefile-switchroot.am include Makefile-ostbuild.am include Makefile-triggers.am diff --git a/gnomeos/ostree-install.sh b/gnomeos/ostree-install.sh deleted file mode 100755 index ac6f2535..00000000 --- a/gnomeos/ostree-install.sh +++ /dev/null @@ -1,93 +0,0 @@ -#!/bin/bash -# -*- indent-tabs-mode: nil; -*- -# Copyright (C) 2011,2012 Colin Walters -# -# Prepare an empty OSTree setup on system; this presently uses the -# "host" kernel. This has no impact on the host system. -# -# Note also this script is idempotent - you can run it more than -# once, and you should in fact do so right now to update to a newer -# host kernel. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -set -e -set -x - -WORKDIR=`pwd` -cd `dirname $0` -SRCDIR=`pwd` -cd $WORKDIR - -if test $(id -u) != 0; then - cat <pdata); + + return g_file_new_for_path (path); +} + GFile * ot_gfile_get_child_strconcat (GFile *parent, const char *first, diff --git a/src/libotutil/ot-gio-utils.h b/src/libotutil/ot-gio-utils.h index c98e73a5..16b2f123 100644 --- a/src/libotutil/ot-gio-utils.h +++ b/src/libotutil/ot-gio-utils.h @@ -36,6 +36,8 @@ G_BEGIN_DECLS GFileType ot_gfile_type_for_mode (guint32 mode); +GFile *ot_gfile_from_build_path (const char *first, ...) G_GNUC_NULL_TERMINATED; + GFile *ot_gfile_get_child_strconcat (GFile *parent, const char *first, ...) G_GNUC_NULL_TERMINATED; GFile *ot_gfile_new_for_path (const char *path); diff --git a/src/libotutil/ot-spawn-utils.c b/src/libotutil/ot-spawn-utils.c new file mode 100644 index 00000000..1dab0142 --- /dev/null +++ b/src/libotutil/ot-spawn-utils.c @@ -0,0 +1,78 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2011 Colin Walters + * + * 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. + * + * Author: Colin Walters + */ + +#include "config.h" + +#include "otutil.h" + +#include +#include + +gboolean +ot_spawn_sync_checked (const char *cwd, + char **argv, + char **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + char **stdout_data, + char **stderr_data, + GError **error) +{ + gboolean ret = FALSE; + gint exit_status; + char *ret_stdout_data = NULL; + char *ret_stderr_data = NULL; + + if (!g_spawn_sync (cwd, argv, envp, flags, child_setup, user_data, + stdout_data ? &ret_stdout_data : NULL, + stderr_data ? &ret_stderr_data : NULL, + &exit_status, + error)) + goto out; + + if (WIFEXITED (exit_status)) + { + if (WEXITSTATUS (exit_status) != 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Exited with code %d", WEXITSTATUS (exit_status)); + goto out; + } + } + else if (WIFSIGNALED (exit_status)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Killed by signal %d", WTERMSIG (exit_status)); + goto out; + } + else + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Exited abnormally"); + goto out; + } + + ret = TRUE; + out: + return ret; +} diff --git a/src/libotutil/ot-spawn-utils.h b/src/libotutil/ot-spawn-utils.h new file mode 100644 index 00000000..86b4beb0 --- /dev/null +++ b/src/libotutil/ot-spawn-utils.h @@ -0,0 +1,42 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2011 Colin Walters . + * + * 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. + * + * Author: Colin Walters + */ + +#ifndef __OSTREE_SPAWN_UTILS_H__ +#define __OSTREE_SPAWN_UTILS_H__ + +#include + +G_BEGIN_DECLS + +gboolean ot_spawn_sync_checked (const char *cwd, + char **argv, + char **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + char **stdout_data, + char **stderr_data, + GError **error); + +G_END_DECLS + +#endif diff --git a/src/libotutil/otutil.c b/src/libotutil/otutil.c new file mode 100644 index 00000000..ebed1a5e --- /dev/null +++ b/src/libotutil/otutil.c @@ -0,0 +1,41 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2011 Colin Walters + * + * 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. + * + * Author: Colin Walters + */ + +#include "config.h" + +#include "otutil.h" + +#include + +void +ot_ptrarray_add_many (GPtrArray *a, ...) +{ + va_list args; + void *p; + + va_start (args, a); + + while ((p = va_arg (args, void *)) != NULL) + g_ptr_array_add (a, p); + + va_end (args); +} diff --git a/src/libotutil/otutil.h b/src/libotutil/otutil.h index ad276d4d..532cca87 100644 --- a/src/libotutil/otutil.h +++ b/src/libotutil/otutil.h @@ -23,6 +23,8 @@ #ifndef __OSTREE_UTIL_H__ #define __OSTREE_UTIL_H__ +#include + #define ot_gobject_refz(o) (o ? g_object_ref (o) : o) #define ot_clear_checksum(c) G_STMT_START { \ typeof(c) __tmp_chksum = c; \ @@ -47,6 +49,9 @@ #include #include #include +#include #include +void ot_ptrarray_add_many (GPtrArray *a, ...) G_GNUC_NULL_TERMINATED; + #endif diff --git a/src/ostadmin/main.c b/src/ostadmin/main.c new file mode 100644 index 00000000..42d6f214 --- /dev/null +++ b/src/ostadmin/main.c @@ -0,0 +1,43 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2012 Colin Walters + * + * 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. + * + * Author: Colin Walters + */ + +#include "config.h" + +#include + +#include + +#include "ot-admin-main.h" +#include "ot-admin-builtins.h" + +static OtAdminBuiltin builtins[] = { + { "deploy", ot_admin_builtin_deploy, 0 }, + { "init", ot_admin_builtin_init, 0 }, + { NULL } +}; + +int +main (int argc, + char **argv) +{ + return ot_admin_main (argc, argv, builtins); +} diff --git a/src/ostadmin/ot-admin-builtin-deploy.c b/src/ostadmin/ot-admin-builtin-deploy.c new file mode 100644 index 00000000..d935c2d6 --- /dev/null +++ b/src/ostadmin/ot-admin-builtin-deploy.c @@ -0,0 +1,327 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2012 Colin Walters + * + * 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. + * + * Author: Colin Walters + */ + +#include "config.h" + +#include "ot-admin-builtins.h" +#include "otutil.h" + +#include +#include + +static gboolean opt_checkout_only; + +static GOptionEntry options[] = { + { "checkout-only", 0, 0, G_OPTION_ARG_NONE, &opt_checkout_only, "Don't generate initramfs or update bootloader", NULL }, + { NULL } +}; + +static gboolean +update_initramfs (const char *release, + const char *last_deploy_target, + GCancellable *cancellable, + GError **error) +{ + gboolean ret = FALSE; + ot_lobj GFile *dest_modules_parent = NULL; + ot_lobj GFile *dest_modules_file = NULL; + ot_lfree char *initramfs_name = NULL; + ot_lobj GFile *initramfs_file = NULL; + ot_lfree char *last_deploy_path = NULL; + + dest_modules_file = ot_gfile_from_build_path ("/ostree/modules", release, NULL); + dest_modules_parent = g_file_get_parent (dest_modules_file); + if (!ot_gfile_ensure_directory (dest_modules_parent, FALSE, error)) + goto out; + if (!g_file_query_exists (dest_modules_file, NULL)) + { + ot_lptrarray GPtrArray *cp_args = NULL; + ot_lobj GFile *src_modules_file = ot_gfile_from_build_path ("/lib/modules", release, NULL); + + cp_args = g_ptr_array_new (); + ot_ptrarray_add_many (cp_args, "cp", "-al", ot_gfile_get_path_cached (src_modules_file), + ot_gfile_get_path_cached (dest_modules_file), NULL); + g_ptr_array_add (cp_args, NULL); + + g_print ("Copying kernel modules from %s\n", ot_gfile_get_path_cached (src_modules_file)); + if (!ot_spawn_sync_checked (NULL, (char**)cp_args->pdata, NULL, + G_SPAWN_SEARCH_PATH, + NULL, NULL, NULL, NULL, error)) + goto out; + } + + initramfs_name = g_strconcat ("initramfs-ostree-", release, ".img", NULL); + initramfs_file = ot_gfile_from_build_path ("/boot", initramfs_name, NULL); + if (!g_file_query_exists (initramfs_file, NULL)) + { + ot_lptrarray GPtrArray *mkinitramfs_args = NULL; + ot_lfree char *tmpdir = NULL; + ot_lfree char *initramfs_tmp_path = NULL; + ot_lobj GFile *initramfs_tmp_file = NULL; + ot_lobj GFileInfo *initramfs_tmp_info = NULL; + + if ((tmpdir = g_dir_make_tmp ("ostree-initramfs.XXXXXX", error)) == NULL) + goto out; + + last_deploy_path = g_build_filename ("/ostree", last_deploy_target, NULL); + + mkinitramfs_args = g_ptr_array_new (); + /* Note: the hardcoded /tmp path below is not actually a + * security flaw, because we've bind-mounted dracut's view + * of /tmp to the securely-created tmpdir above. + */ + ot_ptrarray_add_many (mkinitramfs_args, + "linux-user-chroot", + "--mount-readonly", "/", + "--mount-proc", "/proc", + "--mount-bind", "/dev", "/dev", + "--mount-bind", "/ostree/var", "/var", + "--mount-bind", tmpdir, "/tmp", + "--mount-bind", "/ostree/modules", "/lib/modules", + last_deploy_path, + "dracut", "-f", "/tmp/initramfs-ostree.img", release, + NULL); + g_ptr_array_add (mkinitramfs_args, NULL); + + g_print ("Generating initramfs using %s...\n", last_deploy_path); + if (!ot_spawn_sync_checked (NULL, (char**)mkinitramfs_args->pdata, NULL, + G_SPAWN_SEARCH_PATH, + NULL, NULL, NULL, NULL, error)) + { + (void) unlink (initramfs_tmp_path); + goto out; + } + + initramfs_tmp_path = g_build_filename (tmpdir, "initramfs-ostree.img", NULL); + initramfs_tmp_file = g_file_new_for_path (initramfs_tmp_path); + initramfs_tmp_info = g_file_query_info (initramfs_tmp_file, OSTREE_GIO_FAST_QUERYINFO, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + cancellable, error); + if (!initramfs_tmp_info) + goto out; + + if (g_file_info_get_size (initramfs_tmp_info) == 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Initramfs generation failed, check dracut.log"); + goto out; + } + + if (!g_file_copy (initramfs_tmp_file, initramfs_file, 0, cancellable, NULL, NULL, error)) + goto out; + + g_print ("Created: %s\n", ot_gfile_get_path_cached (initramfs_file)); + + (void) unlink (initramfs_tmp_path); + (void) rmdir (tmpdir); + } + + ret = TRUE; + out: + return ret; +} + +static gboolean +grep_literal (GFile *f, + const char *string, + gboolean *out_matches, + GCancellable *cancellable, + GError **error) +{ + gboolean ret = FALSE; + gboolean ret_matches = FALSE; + ot_lobj GInputStream *in = NULL; + ot_lobj GDataInputStream *datain = NULL; + ot_lfree char *line = NULL; + + in = (GInputStream*)g_file_read (f, cancellable, error); + if (!in) + goto out; + datain = (GDataInputStream*)g_data_input_stream_new (in); + if (!in) + goto out; + + while ((line = g_data_input_stream_read_line (datain, NULL, cancellable, error)) != NULL) + { + if (strstr (line, string)) + { + ret_matches = TRUE; + break; + } + + g_free (line); + } + + ret = TRUE; + if (out_matches) + *out_matches = ret_matches; + out: + return ret; +} + +static gboolean +get_kernel_path_from_release (const char *release, + GFile **out_path, + GCancellable *cancellable, + GError **error) +{ + gboolean ret = FALSE; + ot_lfree char *name = NULL; + ot_lobj GFile *possible_path = NULL; + + /* TODO - replace this with grubby code */ + + name = g_strconcat ("vmlinuz-", release, NULL); + possible_path = ot_gfile_from_build_path ("/boot", name, NULL); + if (!g_file_query_exists (possible_path, cancellable)) + g_clear_object (&possible_path); + + ret = TRUE; + ot_transfer_out_value (out_path, &possible_path); + /* out: */ + return ret; +} + +static gboolean +update_grub (const char *release, + GCancellable *cancellable, + GError **error) +{ + gboolean ret = FALSE; + ot_lobj GFile *grub_path = g_file_new_for_path ("/boot/grub/grub.conf"); + + if (g_file_query_exists (grub_path, cancellable)) + { + gboolean have_grub_entry; + if (!grep_literal (grub_path, "OSTree", &have_grub_entry, + cancellable, error)) + goto out; + + if (!have_grub_entry) + { + ot_lptrarray GPtrArray *grubby_args = NULL; + ot_lfree char *add_kernel_arg = NULL; + ot_lfree char *initramfs_arg = NULL; + ot_lobj GFile *kernel_path = NULL; + + if (!get_kernel_path_from_release (release, &kernel_path, cancellable, error)) + goto out; + + if (kernel_path == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Couldn't find kernel for release %s", release); + goto out; + } + + grubby_args = g_ptr_array_new (); + add_kernel_arg = g_strconcat ("--add-kernel=", ot_gfile_get_path_cached (kernel_path), NULL); + initramfs_arg = g_strconcat ("--initrd=", "/boot/initramfs-ostree-", release, ".img", NULL); + ot_ptrarray_add_many (grubby_args, "grubby", "--grub", add_kernel_arg, initramfs_arg, + "--copy-default", "--title=OSTree", NULL); + g_ptr_array_add (grubby_args, NULL); + + g_print ("Adding OSTree grub entry...\n"); + if (!ot_spawn_sync_checked (NULL, (char**)grubby_args->pdata, NULL, G_SPAWN_SEARCH_PATH, + NULL, NULL, NULL, NULL, error)) + goto out; + } + else + g_print ("Already have OSTree entry in grub config\n"); + } + else + { + g_print ("/boot/grub/grub.conf not found, assuming you have GRUB 2\n"); + } + + ret = TRUE; + out: + return ret; +} + +gboolean +ot_admin_builtin_deploy (int argc, char **argv, GError **error) +{ + GOptionContext *context; + gboolean ret = FALSE; + int i; + const char *last_deploy_target = NULL; + __attribute__((unused)) GCancellable *cancellable = NULL; + + context = g_option_context_new ("- Perform checkouts, ensure initramfs is generated"); + g_option_context_add_main_entries (context, options, NULL); + + if (!g_option_context_parse (context, &argc, &argv, error)) + goto out; + + if (argc < 3) + { + ot_util_usage_error (context, "At least one REV must be specified", error); + goto out; + } + + for (i = 2; i < argc; i++) + { + const char *deploy_target = argv[i]; + ot_lptrarray GPtrArray *checkout_args = NULL; + + checkout_args = g_ptr_array_new (); + ot_ptrarray_add_many (checkout_args, "ostree", "--repo=/ostree/repo", + "checkout", "--atomic-retarget", deploy_target, NULL); + g_ptr_array_add (checkout_args, NULL); + + if (!ot_spawn_sync_checked (NULL, (char**)checkout_args->pdata, NULL, G_SPAWN_SEARCH_PATH, + NULL, NULL, NULL, NULL, error)) + goto out; + + last_deploy_target = deploy_target; + } + + if (!opt_checkout_only) + { + struct utsname utsname; + const char *release; + + (void) uname (&utsname); + + if (strcmp (utsname.sysname, "Linux") != 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Unsupported machine %s", utsname.sysname); + goto out; + } + + release = utsname.release; + + if (!update_initramfs (release, last_deploy_target, cancellable, error)) + goto out; + + if (!update_grub (release, cancellable, error)) + goto out; + } + + ret = TRUE; + out: + if (context) + g_option_context_free (context); + return ret; +} diff --git a/src/ostadmin/ot-admin-builtin-init.c b/src/ostadmin/ot-admin-builtin-init.c new file mode 100644 index 00000000..fdf61d6b --- /dev/null +++ b/src/ostadmin/ot-admin-builtin-init.c @@ -0,0 +1,87 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2012 Colin Walters + * + * 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. + * + * Author: Colin Walters + */ + +#include "config.h" + +#include "ot-admin-builtins.h" +#include "otutil.h" + +#include + +static GOptionEntry options[] = { +}; + + +gboolean +ot_admin_builtin_init (int argc, char **argv, GError **error) +{ + GOptionContext *context; + gboolean ret = FALSE; + ot_lobj GFile *dir = NULL; + __attribute__((unused)) GCancellable *cancellable = NULL; + + context = g_option_context_new ("- Initialize /ostree directory"); + g_option_context_add_main_entries (context, options, NULL); + + if (!g_option_context_parse (context, &argc, &argv, error)) + goto out; + + g_clear_object (&dir); + dir = g_file_new_for_path ("/ostree/repo"); + if (!ot_gfile_ensure_directory (dir, TRUE, error)) + goto out; + g_clear_object (&dir); + dir = g_file_new_for_path ("/ostree/repo/objects"); + if (!g_file_query_exists (dir, NULL)) + { + const char *child_argv[] = { "ostree", "--repo=/ostree/repo", "init", NULL }; + + if (!ot_spawn_sync_checked (NULL, (char**)child_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, + NULL, NULL, error)) + { + g_prefix_error (error, "Failed to initialize repository: "); + goto out; + } + } + + /* Ensure a few subdirectories of /var exist, since we need them for + dracut generation */ + g_clear_object (&dir); + dir = g_file_new_for_path ("/ostree/var/log"); + if (!ot_gfile_ensure_directory (dir, TRUE, error)) + goto out; + g_clear_object (&dir); + dir = g_file_new_for_path ("/ostree/var/tmp"); + if (!ot_gfile_ensure_directory (dir, TRUE, error)) + goto out; + if (chmod ("/ostree/var/tmp", 01777) < 0) + { + ot_util_set_error_from_errno (error, errno); + goto out; + } + + ret = TRUE; + out: + if (context) + g_option_context_free (context); + return ret; +} diff --git a/src/ostadmin/ot-admin-builtins.h b/src/ostadmin/ot-admin-builtins.h new file mode 100644 index 00000000..44c22099 --- /dev/null +++ b/src/ostadmin/ot-admin-builtins.h @@ -0,0 +1,35 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2011 Colin Walters + * + * 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. + * + * Author: Colin Walters + */ + +#ifndef __OT_ADMIN_BUILTINS__ +#define __OT_ADMIN_BUILTINS__ + +#include + +G_BEGIN_DECLS + +gboolean ot_admin_builtin_init (int argc, char **argv, GError **error); +gboolean ot_admin_builtin_deploy (int argc, char **argv, GError **error); + +G_END_DECLS + +#endif diff --git a/src/ostadmin/ot-admin-main.c b/src/ostadmin/ot-admin-main.c new file mode 100644 index 00000000..b416ec96 --- /dev/null +++ b/src/ostadmin/ot-admin-main.c @@ -0,0 +1,133 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2011 Colin Walters + * + * 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. + * + * Author: Colin Walters + */ + +#include "config.h" + +#include + +#include + +#include "ot-admin-main.h" +#include "otutil.h" + +static int +usage (char **argv, OtAdminBuiltin *builtins, gboolean is_error) +{ + OtAdminBuiltin *builtin = builtins; + void (*print_func) (const gchar *format, ...); + + if (is_error) + print_func = g_printerr; + else + print_func = g_print; + + print_func ("usage: %s COMMAND [options]\n", + argv[0]); + print_func ("Builtin commands:\n"); + + while (builtin->name) + { + print_func (" %s\n", builtin->name); + builtin++; + } + return (is_error ? 1 : 0); +} + +static void +prep_builtin_argv (const char *builtin, + int argc, + char **argv, + int *out_argc, + char ***out_argv) +{ + int i; + char **cmd_argv; + + cmd_argv = g_new0 (char *, argc + 2); + + cmd_argv[0] = (char*)builtin; + for (i = 0; i < argc; i++) + cmd_argv[i+1] = argv[i]; + cmd_argv[i+1] = NULL; + *out_argc = argc+1; + *out_argv = cmd_argv; +} + +static void +set_error_print_usage (GError **error, OtAdminBuiltin *builtins, const char *msg, char **argv) +{ + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, msg); + usage (argv, builtins, TRUE); +} + +int +ot_admin_main (int argc, + char **argv, + OtAdminBuiltin *builtins) +{ + OtAdminBuiltin *builtin; + GError *error = NULL; + int cmd_argc; + char **cmd_argv = NULL; + const char *cmd = NULL; + + /* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */ + g_setenv ("GIO_USE_VFS", "local", TRUE); + + g_type_init (); + + g_set_prgname (argv[0]); + + if (argc < 2) + return usage (argv, builtins, 1); + + cmd = argv[1]; + + builtin = builtins; + while (builtin->name) + { + if (g_strcmp0 (cmd, builtin->name) == 0) + break; + builtin++; + } + + if (!builtin->name) + { + set_error_print_usage (&error, builtins, "Unknown command", argv); + goto out; + } + + prep_builtin_argv (cmd, argc-1, argv+1, &cmd_argc, &cmd_argv); + + if (!builtin->fn (cmd_argc, cmd_argv, &error)) + goto out; + + out: + g_free (cmd_argv); + if (error) + { + g_printerr ("%s\n", error->message); + g_clear_error (&error); + return 1; + } + return 0; +} diff --git a/src/ostadmin/ot-admin-main.h b/src/ostadmin/ot-admin-main.h new file mode 100644 index 00000000..8f0e6378 --- /dev/null +++ b/src/ostadmin/ot-admin-main.h @@ -0,0 +1,32 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2011 Colin Walters + * + * 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. + * + * Author: Colin Walters + */ + +#include + +typedef struct { + const char *name; + gboolean (*fn) (int argc, char **argv, GError **error); + int flags; +} OtAdminBuiltin; + +int ot_admin_main (int argc, char **argv, OtAdminBuiltin *builtins); + diff --git a/src/ostree/ot-builtin-checkout.c b/src/ostree/ot-builtin-checkout.c index 4ac817ac..ceb6d7e4 100644 --- a/src/ostree/ot-builtin-checkout.c +++ b/src/ostree/ot-builtin-checkout.c @@ -338,7 +338,11 @@ ostree_builtin_checkout (int argc, char **argv, GFile *repo_path, GError **error skip_checkout = FALSE; } - if (!skip_checkout) + if (skip_checkout) + { + g_print ("ostree-checkout: Rev %s is already checked out as %s\n", commit, resolved_commit); + } + else { if (!process_one_checkout (repo, resolved_commit, opt_subpath, checkout_target_tmp ? checkout_target_tmp : checkout_target, @@ -360,6 +364,7 @@ ostree_builtin_checkout (int argc, char **argv, GFile *repo_path, GError **error ot_gfile_get_basename_cached (checkout_target), cancellable, error)) goto out; + g_print ("ostree-checkout: Rev %s checked out as %s\n", commit, resolved_commit); } } }