[ostree] static-delta: Add `show` subcommand



commit 98d5f6e3db376ca0a7ab5f505474a0105bee19a7
Author: Colin Walters <walters verbum org>
Date:   Wed Jan 27 22:02:36 2016 -0500

    static-delta: Add `show` subcommand
    
    Right now though, almost all of the details of deltas are private, so
    we can't do the "honest thing" and have the command line just use the
    shared library.
    
    Eventually some of this should appear in the API, but for now add
    command line which is useful for debugging.

 src/libostree/ostree-cmdprivate.c                |    4 +-
 src/libostree/ostree-cmdprivate.h                |    1 +
 src/libostree/ostree-repo-static-delta-core.c    |   93 ++++++++++++++++++++++
 src/libostree/ostree-repo-static-delta-private.h |   11 +++
 src/libotutil/ot-variant-utils.c                 |   22 +++++
 src/libotutil/ot-variant-utils.h                 |    7 ++
 src/ostree/ot-builtin-static-delta.c             |   35 ++++++++
 7 files changed, 172 insertions(+), 1 deletions(-)
---
diff --git a/src/libostree/ostree-cmdprivate.c b/src/libostree/ostree-cmdprivate.c
index 9983493..74c32a3 100644
--- a/src/libostree/ostree-cmdprivate.c
+++ b/src/libostree/ostree-cmdprivate.c
@@ -23,6 +23,7 @@
 #include "ostree-cmdprivate.h"
 #include "ostree-repo-private.h"
 #include "ostree-core-private.h"
+#include "ostree-repo-static-delta-private.h"
 #include "ostree-sysroot.h"
 #include "ostree-bootloader-grub2.h"
 
@@ -44,7 +45,8 @@ const OstreeCmdPrivateVTable *
 ostree_cmd__private__ (void)
 {
   static OstreeCmdPrivateVTable table = {
-    impl_ostree_generate_grub2_config
+    impl_ostree_generate_grub2_config,
+    _ostree_repo_static_delta_dump
   };
 
   return &table;
diff --git a/src/libostree/ostree-cmdprivate.h b/src/libostree/ostree-cmdprivate.h
index 317a759..7746406 100644
--- a/src/libostree/ostree-cmdprivate.h
+++ b/src/libostree/ostree-cmdprivate.h
@@ -26,6 +26,7 @@ G_BEGIN_DECLS
 
 typedef struct {
   gboolean (* ostree_generate_grub2_config) (OstreeSysroot *sysroot, int bootversion, int target_fd, 
GCancellable *cancellable, GError **error);
+  gboolean (* ostree_static_delta_dump) (OstreeRepo *repo, const char *delta_id, GCancellable *cancellable, 
GError **error);
 } OstreeCmdPrivateVTable;
 
 const OstreeCmdPrivateVTable *
diff --git a/src/libostree/ostree-repo-static-delta-core.c b/src/libostree/ostree-repo-static-delta-core.c
index b2ffddc..bc1b460 100644
--- a/src/libostree/ostree-repo-static-delta-core.c
+++ b/src/libostree/ostree-repo-static-delta-core.c
@@ -22,6 +22,7 @@
 
 #include "ostree-core-private.h"
 #include "ostree-repo-private.h"
+#include "ostree-cmdprivate.h"
 #include "ostree-repo-static-delta-private.h"
 #include "otutil.h"
 
@@ -404,3 +405,95 @@ ostree_repo_static_delta_execute_offline (OstreeRepo                    *self,
  out:
   return ret;
 }
+
+gboolean
+_ostree_repo_static_delta_dump (OstreeRepo                    *self,
+                                const char                    *delta_id,
+                                GCancellable                  *cancellable,
+                                GError                      **error)
+{
+  gboolean ret = FALSE;
+  g_autofree char *from = NULL; 
+  g_autofree char *to = NULL;
+  g_autofree char *superblock_path = NULL;
+  glnx_fd_close int superblock_fd = -1;
+  g_autoptr(GVariant) delta_superblock = NULL;
+  guint64 total_size = 0, total_usize = 0;
+  guint64 total_fallback_size = 0, total_fallback_usize = 0;
+  guint i;
+
+  _ostree_parse_delta_name (delta_id, &from, &to);
+  superblock_path = _ostree_get_relative_static_delta_superblock_path (from, to);
+
+  if (!ot_util_variant_map_at (self->repo_dir_fd, superblock_path,
+                               (GVariantType*)OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT,
+                               TRUE, &delta_superblock, error))
+    goto out;
+
+  g_print ("Delta: %s\n", delta_id);
+  { guint64 ts;
+    g_variant_get_child (delta_superblock, 1, "t", &ts);
+    g_print ("Timestamp: %" G_GUINT64_FORMAT "\n", GUINT64_FROM_BE (ts));
+  }
+  { g_autoptr(GVariant) recurse = NULL;
+    g_variant_get_child (delta_superblock, 5, "@ay", &recurse);
+    g_print ("Number of parents: %u\n", (guint)(g_variant_get_size (recurse) / (OSTREE_SHA256_DIGEST_LEN * 
2)));
+  }
+  { g_autoptr(GVariant) fallback = NULL;
+    guint n_fallback;
+
+    g_variant_get_child (delta_superblock, 7, "@a" OSTREE_STATIC_DELTA_FALLBACK_FORMAT, &fallback);
+    n_fallback = g_variant_n_children (fallback);
+
+    g_print ("Number of fallback entries: %u\n", n_fallback);
+
+    for (i = 0; i < n_fallback; i++)
+      {
+        guint64 size, usize;
+        g_variant_get_child (fallback, i, "(y aytt)", NULL, NULL, &size, &usize);
+        total_fallback_size += size;
+        total_fallback_usize += usize;
+      }
+    { g_autofree char *sizestr = g_format_size (total_fallback_size);
+      g_autofree char *usizestr = g_format_size (total_fallback_usize);
+      g_print ("Total Fallback Size: %" G_GUINT64_FORMAT " (%s)\n", total_fallback_size, sizestr);
+      g_print ("Total Fallback Uncompressed Size: %" G_GUINT64_FORMAT " (%s)\n", total_fallback_usize, 
usizestr);
+    }
+  }
+  { g_autoptr(GVariant) meta_entries = NULL;
+    guint n_parts;
+
+    g_variant_get_child (delta_superblock, 6, "@a" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT, &meta_entries);
+    n_parts = g_variant_n_children (meta_entries);
+    g_print ("Number of parts: %u\n", n_parts);
+
+    for (i = 0; i < n_parts; i++)
+      {
+        guint32 version;
+        guint64 size, usize;
+        g_autoptr(GVariant) objects = NULL;
+        g_variant_get_child (meta_entries, i, "(u aytt@ay)", &version, NULL, &size, &usize, &objects);
+        total_size += size;
+        total_usize += usize;
+        g_print ("Part%u: nobjects=%u size=%" G_GUINT64_FORMAT " usize=%" G_GUINT64_FORMAT "\n",
+                 i, (guint)(g_variant_get_size (objects) / OSTREE_STATIC_DELTA_OBJTYPE_CSUM_LEN), size, 
usize);
+      }
+  }
+
+  { g_autofree char *sizestr = g_format_size (total_size);
+    g_autofree char *usizestr = g_format_size (total_usize);
+    g_print ("Total Part Size: %" G_GUINT64_FORMAT " (%s)\n", total_size, sizestr);
+    g_print ("Total Part Uncompressed Size: %" G_GUINT64_FORMAT " (%s)\n", total_usize, usizestr);
+  }
+  { guint64 overall_size = total_size + total_fallback_size;
+    guint64 overall_usize = total_usize + total_fallback_usize;
+    g_autofree char *sizestr = g_format_size (overall_size);
+    g_autofree char *usizestr = g_format_size (overall_usize);
+    g_print ("Total Size: %" G_GUINT64_FORMAT " (%s)\n", overall_size, sizestr);
+    g_print ("Total Uncompressed Size: %" G_GUINT64_FORMAT " (%s)\n", overall_usize, usizestr);
+  }
+
+  ret = TRUE;
+ out:
+  return ret;
+}
diff --git a/src/libostree/ostree-repo-static-delta-private.h 
b/src/libostree/ostree-repo-static-delta-private.h
index de32ec6..b0e82ad 100644
--- a/src/libostree/ostree-repo-static-delta-private.h
+++ b/src/libostree/ostree-repo-static-delta-private.h
@@ -103,6 +103,11 @@ G_BEGIN_DECLS
  */ 
 #define OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT "(a{sv}tayay" OSTREE_COMMIT_GVARIANT_STRING "aya" 
OSTREE_STATIC_DELTA_META_ENTRY_FORMAT "a" OSTREE_STATIC_DELTA_FALLBACK_FORMAT ")"
 
+gboolean _ostree_static_delta_dump (OstreeRepo     *repo,
+                                    const char *delta_id,
+                                    GCancellable   *cancellable,
+                                    GError        **error);
+
 gboolean _ostree_static_delta_part_validate (OstreeRepo     *repo,
                                              GInputStream   *in,
                                              guint           part_offset,
@@ -177,4 +182,10 @@ _ostree_delta_compute_similar_objects (OstreeRepo                 *repo,
                                        GCancellable               *cancellable,
                                        GError                    **error);
 
+gboolean
+_ostree_repo_static_delta_dump (OstreeRepo                 *repo,
+                                const char                 *delta_id,
+                                GCancellable               *cancellable,
+                                GError                    **error);
+
 G_END_DECLS
diff --git a/src/libotutil/ot-variant-utils.c b/src/libotutil/ot-variant-utils.c
index 1210a78..ed65026 100644
--- a/src/libotutil/ot-variant-utils.c
+++ b/src/libotutil/ot-variant-utils.c
@@ -154,6 +154,28 @@ ot_util_variant_map (GFile              *src,
   return ret;
 }
 
+gboolean
+ot_util_variant_map_at (int dfd,
+                        const char *path,
+                        const GVariantType *type,
+                        gboolean trusted,
+                        GVariant **out_variant,
+                        GError  **error)
+{
+  glnx_fd_close int fd = -1;
+  g_autoptr(GVariant) ret_variant = NULL;
+
+  fd = openat (dfd, path, O_RDONLY | O_CLOEXEC);
+  if (fd < 0)
+    {
+      glnx_set_error_from_errno (error);
+      g_prefix_error (error, "Opening %s: ", path);
+      return FALSE;
+    }
+
+  return ot_util_variant_map_fd (fd, 0, type, trusted, out_variant, error);
+}
+
 typedef struct {
   gpointer addr;
   gsize len;
diff --git a/src/libotutil/ot-variant-utils.h b/src/libotutil/ot-variant-utils.h
index 34b6eb5..1a7abe0 100644
--- a/src/libotutil/ot-variant-utils.h
+++ b/src/libotutil/ot-variant-utils.h
@@ -48,6 +48,13 @@ gboolean ot_util_variant_map (GFile *src,
                               GVariant **out_variant,
                               GError  **error);
 
+gboolean ot_util_variant_map_at (int dfd,
+                                 const char *path,
+                                 const GVariantType *type,
+                                 gboolean trusted,
+                                 GVariant **out_variant,
+                                 GError  **error);
+
 gboolean ot_util_variant_map_fd (int                  fd,
                                  goffset              offset,
                                  const GVariantType  *type,
diff --git a/src/ostree/ot-builtin-static-delta.c b/src/ostree/ot-builtin-static-delta.c
index 903e5fd..c3c99ba 100644
--- a/src/ostree/ot-builtin-static-delta.c
+++ b/src/ostree/ot-builtin-static-delta.c
@@ -23,6 +23,7 @@
 #include "ot-main.h"
 #include "ot-builtins.h"
 #include "ostree.h"
+#include "ostree-cmdprivate.h"
 #include "ot-main.h"
 #include "otutil.h"
 
@@ -38,6 +39,7 @@ static gboolean opt_disable_bsdiff;
 #define BUILTINPROTO(name) static gboolean ot_static_delta_builtin_ ## name (int argc, char **argv, 
GCancellable *cancellable, GError **error)
 
 BUILTINPROTO(list);
+BUILTINPROTO(show);
 BUILTINPROTO(generate);
 BUILTINPROTO(apply_offline);
 
@@ -45,6 +47,7 @@ BUILTINPROTO(apply_offline);
 
 static OstreeCommand static_delta_subcommands[] = {
   { "list", ot_static_delta_builtin_list },
+  { "show", ot_static_delta_builtin_show },
   { "generate", ot_static_delta_builtin_generate },
   { "apply-offline", ot_static_delta_builtin_apply_offline },
   { NULL, NULL }
@@ -130,6 +133,38 @@ ot_static_delta_builtin_list (int argc, char **argv, GCancellable *cancellable,
 }
 
 static gboolean
+ot_static_delta_builtin_show (int argc, char **argv, GCancellable *cancellable, GError **error)
+{
+  gboolean ret = FALSE;
+  GOptionContext *context;
+  glnx_unref_object OstreeRepo *repo = NULL;
+  const char *delta_id = NULL;
+
+  context = g_option_context_new ("SHOW - Dump information on a delta");
+
+  if (!ostree_option_context_parse (context, list_options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, 
cancellable, error))
+    goto out;
+
+  if (argc < 3)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                           "DELTA must be specified");
+      goto out;
+    }
+
+  delta_id = argv[2];
+
+  if (!ostree_cmd__private__ ()->ostree_static_delta_dump (repo, delta_id, cancellable, error))
+    goto out;
+      
+  ret = TRUE;
+ out:
+  if (context)
+    g_option_context_free (context);
+  return ret;
+}
+
+static gboolean
 ot_static_delta_builtin_generate (int argc, char **argv, GCancellable *cancellable, GError **error)
 {
   gboolean ret = FALSE;


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