Example #1
0
gboolean
ot_admin_builtin_diff (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error)
{
  GOptionContext *context;
  gboolean ret = FALSE;
  gs_unref_object OstreeDeployment *deployment = NULL;
  gs_unref_object GFile *deployment_dir = NULL;
  gs_unref_ptrarray GPtrArray *modified = NULL;
  gs_unref_ptrarray GPtrArray *removed = NULL;
  gs_unref_ptrarray GPtrArray *added = NULL;
  gs_unref_object GFile *orig_etc_path = NULL;
  gs_unref_object GFile *new_etc_path = NULL;

  context = g_option_context_new ("Diff current /etc configuration versus default");

  g_option_context_add_main_entries (context, options, NULL);

  if (!g_option_context_parse (context, &argc, &argv, error))
    goto out;
  
  if (!ostree_sysroot_load (sysroot, cancellable, error))
    goto out;

  if (!ot_admin_require_booted_deployment_or_osname (sysroot, opt_osname,
                                                     cancellable, error))
    goto out;
  if (opt_osname != NULL)
    {
      deployment = ostree_sysroot_get_merge_deployment (sysroot, opt_osname);
      if (deployment == NULL)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                       "No deployment for OS '%s'", opt_osname);
          goto out;
        }
    }
  else
    deployment = g_object_ref (ostree_sysroot_get_booted_deployment (sysroot));

  deployment_dir = ostree_sysroot_get_deployment_directory (sysroot, deployment);

  orig_etc_path = g_file_resolve_relative_path (deployment_dir, "usr/etc");
  new_etc_path = g_file_resolve_relative_path (deployment_dir, "etc");
  
  modified = g_ptr_array_new_with_free_func ((GDestroyNotify) ostree_diff_item_unref);
  removed = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
  added = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
  if (!ostree_diff_dirs (OSTREE_DIFF_FLAGS_IGNORE_XATTRS,
                         orig_etc_path, new_etc_path, modified, removed, added,
                         cancellable, error))
    goto out;

  ostree_diff_print (orig_etc_path, new_etc_path, modified, removed, added);

  ret = TRUE;
 out:
  if (context)
    g_option_context_free (context);
  return ret;
}
Example #2
0
gboolean
ostree_builtin_diff (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
{
  gboolean ret = FALSE;
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(OstreeRepo) repo = NULL;
  const char *src;
  const char *target;
  g_autofree char *src_prev = NULL;
  g_autoptr(GFile) srcf = NULL;
  g_autoptr(GFile) targetf = NULL;
  g_autoptr(GPtrArray) modified = NULL;
  g_autoptr(GPtrArray) removed = NULL;
  g_autoptr(GPtrArray) added = NULL;

  context = g_option_context_new ("REV TARGETDIR");

  if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error))
    goto out;

  if (argc < 2)
    {
      gchar *help = g_option_context_get_help (context, TRUE, NULL);
      g_printerr ("%s\n", help);
      g_free (help);
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                               "REV must be specified");
      goto out;
    }

  if (argc == 2)
    {
      src_prev = g_strconcat (argv[1], "^", NULL);
      src = src_prev;
      target = argv[1];
    }
  else
    {
      src = argv[1];
      target = argv[2];
    }

  if (!opt_stats && !opt_fs_diff)
    opt_fs_diff = TRUE;

  if (opt_fs_diff)
    {
      OstreeDiffFlags diff_flags = OSTREE_DIFF_FLAGS_NONE; 

      if (opt_no_xattrs)
        diff_flags |= OSTREE_DIFF_FLAGS_IGNORE_XATTRS;
      
      if (!parse_file_or_commit (repo, src, &srcf, cancellable, error))
        goto out;
      if (!parse_file_or_commit (repo, target, &targetf, cancellable, error))
        goto out;

      modified = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_diff_item_unref);
      removed = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
      added = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);

      OstreeDiffDirsOptions diff_opts = { opt_owner_uid, opt_owner_gid };
      if (!ostree_diff_dirs_with_options (diff_flags, srcf, targetf, modified, removed,
                                          added, &diff_opts, cancellable, error))
        goto out;

      ostree_diff_print (srcf, targetf, modified, removed, added);
    }

  if (opt_stats)
    {
      g_autoptr(GHashTable) reachable_a = NULL;
      g_autoptr(GHashTable) reachable_b = NULL;
      g_autoptr(GHashTable) reachable_intersection = NULL;
      g_autofree char *rev_a = NULL;
      g_autofree char *rev_b = NULL;
      g_autofree char *size = NULL;
      guint a_size;
      guint b_size;
      guint64 total_common;

      if (!ostree_repo_resolve_rev (repo, src, FALSE, &rev_a, error))
        goto out;
      if (!ostree_repo_resolve_rev (repo, target, FALSE, &rev_b, error))
        goto out;

      if (!ostree_repo_traverse_commit (repo, rev_a, 0, &reachable_a, cancellable, error))
        goto out;
      if (!ostree_repo_traverse_commit (repo, rev_b, 0, &reachable_b, cancellable, error))
        goto out;

      a_size = g_hash_table_size (reachable_a);
      b_size = g_hash_table_size (reachable_b);
      g_print ("[A] Object Count: %u\n", a_size);
      g_print ("[B] Object Count: %u\n", b_size);

      reachable_intersection = reachable_set_intersect (reachable_a, reachable_b);

      g_print ("Common Object Count: %u\n", g_hash_table_size (reachable_intersection));

      if (!object_set_total_size (repo, reachable_intersection, &total_common,
                                  cancellable, error))
        goto out;
      size = g_format_size_full (total_common, 0);
      g_print ("Common Object Size: %s\n", size);
    }

  ret = TRUE;
 out:
  return ret;
}
Example #3
0
gboolean
ostree_builtin_diff (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error)
{
  gboolean ret = FALSE;
  GOptionContext *context;
  const char *src;
  const char *target;
  gs_free char *src_prev = NULL;
  gs_unref_object GFile *srcf = NULL;
  gs_unref_object GFile *targetf = NULL;
  gs_unref_ptrarray GPtrArray *modified = NULL;
  gs_unref_ptrarray GPtrArray *removed = NULL;
  gs_unref_ptrarray GPtrArray *added = NULL;

  context = g_option_context_new ("REV TARGETDIR - Compare directory TARGETDIR against revision REV");
  g_option_context_add_main_entries (context, options, NULL);

  if (!g_option_context_parse (context, &argc, &argv, error))
    goto out;

  if (argc < 2)
    {
      gchar *help = g_option_context_get_help (context, TRUE, NULL);
      g_printerr ("%s\n", help);
      g_free (help);
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                               "REV must be specified");
      goto out;
    }

  if (argc == 2)
    {
      src_prev = g_strconcat (argv[1], "^", NULL);
      src = src_prev;
      target = argv[1];
    }
  else
    {
      src = argv[1];
      target = argv[2];
    }

  if (!opt_stats && !opt_fs_diff)
    opt_fs_diff = TRUE;

  if (opt_fs_diff)
    {
      if (!parse_file_or_commit (repo, src, &srcf, cancellable, error))
        goto out;
      if (!parse_file_or_commit (repo, target, &targetf, cancellable, error))
        goto out;

      modified = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_diff_item_unref);
      removed = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
      added = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
      
      if (!ostree_diff_dirs (OSTREE_DIFF_FLAGS_NONE, srcf, targetf, modified, removed, added, cancellable, error))
        goto out;

      ostree_diff_print (srcf, targetf, modified, removed, added);
    }

  if (opt_stats)
    {
      gs_unref_hashtable GHashTable *reachable_a = NULL;
      gs_unref_hashtable GHashTable *reachable_b = NULL;
      gs_unref_hashtable GHashTable *reachable_intersection = NULL;
      gs_free char *rev_a = NULL;
      gs_free char *rev_b = NULL;
      gs_free char *size = NULL;
      guint a_size;
      guint b_size;
      guint64 total_common;

      if (!ostree_repo_resolve_rev (repo, src, FALSE, &rev_a, error))
        goto out;
      if (!ostree_repo_resolve_rev (repo, target, FALSE, &rev_b, error))
        goto out;

      if (!ostree_repo_traverse_commit (repo, rev_a, -1, &reachable_a, cancellable, error))
        goto out;
      if (!ostree_repo_traverse_commit (repo, rev_b, -1, &reachable_b, cancellable, error))
        goto out;

      a_size = g_hash_table_size (reachable_a);
      b_size = g_hash_table_size (reachable_b);
      g_print ("[A] Object Count: %u\n", a_size);
      g_print ("[B] Object Count: %u\n", b_size);

      reachable_intersection = reachable_set_intersect (reachable_a, reachable_b);

      g_print ("Common Object Count: %u\n", g_hash_table_size (reachable_intersection));

      if (!object_set_total_size (repo, reachable_intersection, &total_common,
                                  cancellable, error))
        goto out;
      size = g_format_size_full (total_common, 0);
      g_print ("Common Object Size: %s\n", size);
    }

  ret = TRUE;
 out:
  if (context)
    g_option_context_free (context);
  return ret;
}