[ostree] ostadmin: Change command line for qemu deploy helper



commit a6c19aa00c05ba6c5900d53600ab2fbfd1dac58f
Author: Colin Walters <walters verbum org>
Date:   Fri Aug 3 08:24:03 2012 -0400

    ostadmin: Change command line for qemu deploy helper
    
    The qemu helper really wants to copy kernel modules, but not
    update the system bootloader.  Allow it to reuse ostadmin for
    this.
    
    Note that our previous path of shelling out to "cp -al" broke because
    it refused to make cross-device links.
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    # On branch master
    # Your branch is ahead of 'origin/master' by 1 commit.
    #
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #	modified:   src/libotutil/ot-gio-utils.c
    #	modified:   src/libotutil/ot-gio-utils.h
    #	modified:   src/ostadmin/ot-admin-builtin-deploy.c
    #
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #	embedded-dependencies/glib/
    #	embedded-dependencies/libsoup/

 src/libotutil/ot-gio-utils.c           |   91 ++++++++++++++++++++++++++++++++
 src/libotutil/ot-gio-utils.h           |    6 ++
 src/ostadmin/ot-admin-builtin-deploy.c |   88 +++++++++++++++++-------------
 3 files changed, 147 insertions(+), 38 deletions(-)
---
diff --git a/src/libotutil/ot-gio-utils.c b/src/libotutil/ot-gio-utils.c
index b3df9a0..e31e47b 100644
--- a/src/libotutil/ot-gio-utils.c
+++ b/src/libotutil/ot-gio-utils.c
@@ -392,5 +392,96 @@ ot_gio_checksum_stream_finish (GInputStream   *in,
 
   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == ot_gio_checksum_stream_async);
   return g_memdup (g_simple_async_result_get_op_res_gpointer (simple), 32);
+}
 
+/**
+ * ot_gio_shutil_cp_al_or_fallback:
+ * @src: Source path
+ * @dest: Destination path
+ * @cancellable:
+ * @error:
+ *
+ * Recursively copy path @src (which must be a directory) to the
+ * target @dest.  If possible, hardlinks are used; if a hardlink is
+ * not possible, a regular copy is created.  Any existing files are
+ * overwritten.
+ *
+ * Returns: %TRUE on success
+ */
+gboolean
+ot_gio_shutil_cp_al_or_fallback (GFile         *src,
+                                 GFile         *dest,
+                                 GCancellable  *cancellable,
+                                 GError       **error)
+{
+  gboolean ret = FALSE;
+  ot_lobj GFileEnumerator *enumerator = NULL;
+  ot_lobj GFileInfo *file_info = NULL;
+  GError *temp_error = NULL;
+
+  enumerator = g_file_enumerate_children (src, OSTREE_GIO_FAST_QUERYINFO,
+                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                                          cancellable, error);
+  if (!enumerator)
+    goto out;
+
+  if (!ot_gfile_ensure_directory (dest, FALSE, error))
+    goto out;
+
+  while ((file_info = g_file_enumerator_next_file (enumerator, cancellable, &temp_error)) != NULL)
+    {
+      const char *name = g_file_info_get_name (file_info);
+      ot_lobj GFile *src_child = g_file_get_child (src, name);
+      ot_lobj GFile *dest_child = g_file_get_child (dest, name);
+
+      if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
+        {
+          if (!ot_gfile_ensure_directory (dest_child, FALSE, error))
+            goto out;
+
+          /* Can't do this even though we'd like to; it fails with an error about
+           * setting standard::type not being supported =/
+           *
+           if (!g_file_set_attributes_from_info (dest_child, file_info, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+           cancellable, error))
+           goto out;
+          */
+          if (chmod (ot_gfile_get_path_cached (dest_child),
+                     g_file_info_get_attribute_uint32 (file_info, "unix::mode")) == -1)
+            {
+              ot_util_set_error_from_errno (error, errno);
+              goto out;
+            }
+
+          if (!ot_gio_shutil_cp_al_or_fallback (src_child, dest_child, cancellable, error))
+            goto out;
+        }
+      else
+        {
+          (void) unlink (ot_gfile_get_path_cached (dest_child));
+          if (link (ot_gfile_get_path_cached (src_child), ot_gfile_get_path_cached (dest_child)) == -1)
+            {
+              if (!(errno == EMLINK || errno == EXDEV))
+                {
+                  ot_util_set_error_from_errno (error, errno);
+                  goto out;
+                }
+              if (!g_file_copy (src_child, dest_child,
+                                G_FILE_COPY_OVERWRITE | G_FILE_COPY_ALL_METADATA | G_FILE_COPY_NOFOLLOW_SYMLINKS,
+                                cancellable, NULL, NULL, error))
+                goto out;
+            }
+        }
+      g_clear_object (&file_info);
+    }
+  if (temp_error)
+    {
+      g_propagate_error (error, temp_error);
+      goto out;
+    }
+
+  ret = TRUE;
+ out:
+  return ret;
 }
+
diff --git a/src/libotutil/ot-gio-utils.h b/src/libotutil/ot-gio-utils.h
index 6440375..5855a97 100644
--- a/src/libotutil/ot-gio-utils.h
+++ b/src/libotutil/ot-gio-utils.h
@@ -96,6 +96,12 @@ guchar * ot_gio_checksum_stream_finish (GInputStream   *in,
                                         GAsyncResult   *result,
                                         GError        **error);
 
+gboolean ot_gio_shutil_cp_al_or_fallback (GFile         *src,
+                                          GFile         *dest,
+                                          GCancellable  *cancellable,
+                                          GError       **error);
+
+
 G_END_DECLS
 
 #endif
diff --git a/src/ostadmin/ot-admin-builtin-deploy.c b/src/ostadmin/ot-admin-builtin-deploy.c
index 6d85f33..e35eeec 100644
--- a/src/ostadmin/ot-admin-builtin-deploy.c
+++ b/src/ostadmin/ot-admin-builtin-deploy.c
@@ -32,49 +32,57 @@ typedef struct {
   OstreeRepo  *repo;
 } OtAdminDeploy;
 
-static gboolean opt_checkout_only;
+static gboolean opt_no_initramfs;
+static gboolean opt_no_bootloader;
 static char *opt_ostree_dir;
 
 static GOptionEntry options[] = {
   { "ostree-dir", 0, 0, G_OPTION_ARG_STRING, &opt_ostree_dir, "Path to OSTree root directory", NULL },
-  { "checkout-only", 0, 0, G_OPTION_ARG_NONE, &opt_checkout_only, "Don't generate initramfs or update bootloader", NULL },
+  { "no-initramfs", 0, 0, G_OPTION_ARG_NONE, &opt_no_initramfs, "Don't generate initramfs", NULL },
+  { "no-bootloader", 0, 0, G_OPTION_ARG_NONE, &opt_no_bootloader, "Don't update bootloader", NULL },
   { NULL }
 };
 
 static gboolean
-update_initramfs (const char       *release,
-                  const char       *deploy_target,
-                  GCancellable     *cancellable,
-                  GError          **error)
+copy_modules (const char    *release,
+              GCancellable  *cancellable,
+              GError       **error)
 {
   gboolean ret = FALSE;
+  ot_lobj GFile *src_modules_file = NULL;
   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;
-
+  
+  src_modules_file = ot_gfile_from_build_path ("/lib/modules", release, NULL);
   dest_modules_file = ot_gfile_from_build_path (opt_ostree_dir, "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))
+  if (!g_file_query_exists (dest_modules_file, cancellable))
+    {
+      if (!ot_gio_shutil_cp_al_or_fallback (src_modules_file, dest_modules_file, cancellable, error))
         goto out;
     }
       
+  ret = TRUE;
+ out:
+  if (error)
+    g_prefix_error (error, "Error copying kernel modules: ");
+  return ret;
+}
+
+static gboolean
+update_initramfs (const char       *release,
+                  const char       *deploy_target,
+                  GCancellable     *cancellable,
+                  GError          **error)
+{
+  gboolean ret = FALSE;
+  ot_lfree char *initramfs_name = NULL;
+  ot_lobj GFile *initramfs_file = NULL;
+  ot_lfree char *last_deploy_path = NULL;
+
   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))
@@ -345,6 +353,8 @@ ot_admin_builtin_deploy (int argc, char **argv, GError **error)
   gboolean ret = FALSE;
   const char *deploy_target = NULL;
   const char *revision = NULL;
+  struct utsname utsname;
+  const char *release;
   __attribute__((unused)) GCancellable *cancellable = NULL;
 
   if (!opt_ostree_dir)
@@ -371,26 +381,28 @@ ot_admin_builtin_deploy (int argc, char **argv, GError **error)
   if (!do_checkout (self, deploy_target, revision, cancellable, error))
     goto out;
 
-  if (!opt_checkout_only)
+  (void) uname (&utsname);
+  
+  if (strcmp (utsname.sysname, "Linux") != 0)
     {
-
-      struct utsname utsname;
-      const char *release;
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Unsupported machine %s", utsname.sysname);
+      goto out;
+    }
   
-      (void) uname (&utsname);
+  release = utsname.release;
   
-      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 (!copy_modules (release, cancellable, error))
+    goto out;
+  
+  if (!opt_no_initramfs)
+    {
       if (!update_initramfs (release, deploy_target, cancellable, error))
         goto out;
-
+    }
+  
+  if (!opt_no_bootloader)
+    {
       if (!update_grub (release, cancellable, error))
         goto out;
     }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]