示例#1
0
static void
do_countBools (SoupMessage *msg, SoupXMLRPCParams *params)
{
	GVariant *args;
	GVariant *child;
	GVariantIter iter;
	gboolean val;
	int trues = 0, falses = 0;
	GVariantDict dict;

	if (!(args = parse_params (msg, params, "(ab)")))
		return;

	child = g_variant_get_child_value (args, 0);

	g_variant_iter_init (&iter, child);
	while (g_variant_iter_loop (&iter, "b", &val)) {
		if (val)
			trues++;
		else
			falses++;
	}

	g_variant_dict_init (&dict, NULL);
	g_variant_dict_insert (&dict, "true", "i", trues);
	g_variant_dict_insert (&dict, "false", "i", falses);

	soup_xmlrpc_message_set_response (msg, g_variant_dict_end (&dict), NULL);

	g_variant_unref (args);
	g_variant_unref (child);
}
GVariant *
rpmostreed_commit_generate_cached_details_variant (OstreeDeployment *deployment,
                                                   OstreeRepo *repo,
                                                   const gchar *refspec,
						   GError **error)
{
  g_autoptr(GVariant) commit = NULL;
  g_autofree gchar *origin_refspec = NULL;
  g_autofree gchar *head = NULL;
  gboolean gpg_enabled;
  const gchar *osname;
  GVariant *sigs = NULL; /* floating variant */
  GVariantDict dict;

  osname = ostree_deployment_get_osname (deployment);

  if (refspec)
    origin_refspec = g_strdup (refspec);
  else
    {
      g_autoptr(RpmOstreeOrigin) origin = NULL;
  
      origin = rpmostree_origin_parse_deployment (deployment, error);
      if (!origin)
        return NULL;
      origin_refspec = g_strdup (rpmostree_origin_get_refspec (origin));
    }

  g_assert (origin_refspec);

  /* allow_noent=TRUE since the ref may have been deleted for a
   * rebase.
   */
  if (!ostree_repo_resolve_rev (repo, origin_refspec,
                                TRUE, &head, error))
    return NULL;

  if (head == NULL)
    head = g_strdup (ostree_deployment_get_csum (deployment));

  if (!ostree_repo_load_variant (repo,
				 OSTREE_OBJECT_TYPE_COMMIT,
				 head,
				 &commit,
				 error))
    return NULL;

  sigs = rpmostreed_deployment_gpg_results (repo, origin_refspec, head, &gpg_enabled);

  g_variant_dict_init (&dict, NULL);
  if (osname != NULL)
    g_variant_dict_insert (&dict, "osname", "s", osname);
  g_variant_dict_insert (&dict, "checksum", "s", head);
  variant_add_commit_details (&dict, commit);
  g_variant_dict_insert (&dict, "origin", "s", origin_refspec);
  if (sigs != NULL)
    g_variant_dict_insert_value (&dict, "signatures", sigs);
  g_variant_dict_insert (&dict, "gpg-enabled", "b", gpg_enabled);
  return g_variant_dict_end (&dict);
}
GVariant *
rpmostreed_deployment_generate_blank_variant (void)
{
  GVariantDict dict;

  g_variant_dict_init (&dict, NULL);

  return g_variant_dict_end (&dict);
}
示例#4
0
文件: autoptr.c 项目: Babelz/SaNi
static void
test_g_variant_dict (void)
{
  g_autoptr(GVariant) data = g_variant_new_from_data (G_VARIANT_TYPE ("a{sv}"), "", 0, FALSE, NULL, NULL);
  g_auto(GVariantDict) stackval;
  g_autoptr(GVariantDict) val = g_variant_dict_new (data);

  g_variant_dict_init (&stackval, data);
  g_assert (val != NULL);
}
static GVariant *
get_args_variant (void)
{
  GVariantDict dict;

  g_variant_dict_init (&dict, NULL);
  g_variant_dict_insert (&dict, "reboot", "b", opt_reboot);

  return g_variant_dict_end (&dict);
}
示例#6
0
void abrt_p2_task_add_detail(AbrtP2Task *task,
            const char *key,
            GVariant *value)
{
    GVariantDict dict;
    g_variant_dict_init(&dict, task->pv->p2t_details);
    g_variant_dict_insert(&dict, key, "v", value);

    if (task->pv->p2t_details)
        g_variant_unref(task->pv->p2t_details);

    task->pv->p2t_details = g_variant_dict_end(&dict);
}
static GVariant *
artist_album_cursor_to_variant_dict (TrackerSparqlCursor *const cursor)
{

  GVariantDict dict;
  g_variant_dict_init (&dict, NULL);

  insert_string_value (cursor, &dict, "urn", 0);
  insert_integer_value (cursor, &dict, "id", 1);
  insert_string_value (cursor, &dict, "title", 2);

  return g_variant_dict_end (&dict);

}
static GVariant *
get_args_variant (const char *revision)
{
  GVariantDict dict;

  g_variant_dict_init (&dict, NULL);
  g_variant_dict_insert (&dict, "skip-purge", "b", opt_skip_purge);
  g_variant_dict_insert (&dict, "reboot", "b", opt_reboot);

  if (revision != NULL)
    g_variant_dict_insert (&dict, "revision", "s", revision);

  return g_variant_dict_end (&dict);
}
static GVariant *
get_args_variant (void)
{
  GVariantDict dict;
  g_variant_dict_init (&dict, NULL);
  g_variant_dict_insert (&dict, "reboot", "b", opt_reboot);
  g_variant_dict_insert (&dict, "dry-run", "b", opt_dry_run);
#if 0
  if (opt_no_scripts)
      g_variant_dict_insert (&dict, "noscripts", "b", TRUE);
  if (opt_ignore_script)
    g_variant_dict_insert (&dict, "ignore-scripts", "^as", opt_ignore_script);
#endif
  return g_variant_dict_end (&dict);
}
static RpmOstreeTransactionLiveFsFlags
livefs_flags_from_options (GVariant *options)
{
  RpmOstreeTransactionLiveFsFlags ret = 0;
  GVariantDict options_dict;
  gboolean opt = FALSE;

  g_variant_dict_init (&options_dict, options);
  if (g_variant_dict_lookup (&options_dict, "dry-run", "b", &opt) && opt)
    ret |= RPMOSTREE_TRANSACTION_LIVEFS_FLAG_DRY_RUN;
  if (g_variant_dict_lookup (&options_dict, "replace", "b", &opt) && opt)
    ret |= RPMOSTREE_TRANSACTION_LIVEFS_FLAG_REPLACE;

  g_variant_dict_clear (&options_dict);

  return ret;
}
static GVariant *
track_cursor_to_variant_dict (TrackerSparqlCursor *const cursor)
{

  GVariantDict dict;
  g_variant_dict_init (&dict, NULL);

  insert_string_value (cursor, &dict, "urn", 0);
  insert_integer_value (cursor, &dict, "id", 1);
  insert_string_value (cursor, &dict, "url", 2);
  insert_string_value (cursor, &dict, "title", 3);
  insert_integer_value (cursor, &dict, "track-number", 4);
  insert_integer_value (cursor, &dict, "disc-number", 5);

  return g_variant_dict_end (&dict);

}
示例#12
0
GVariant*
rpmostree_get_options_variant (gboolean reboot,
                               gboolean allow_downgrade,
                               gboolean skip_purge,
                               gboolean no_pull_base,
                               gboolean dry_run,
                               gboolean no_overrides)
{
  GVariantDict dict;
  g_variant_dict_init (&dict, NULL);
  g_variant_dict_insert (&dict, "reboot", "b", reboot);
  g_variant_dict_insert (&dict, "allow-downgrade", "b", allow_downgrade);
  g_variant_dict_insert (&dict, "skip-purge", "b", skip_purge);
  g_variant_dict_insert (&dict, "no-pull-base", "b", no_pull_base);
  g_variant_dict_insert (&dict, "dry-run", "b", dry_run);
  g_variant_dict_insert (&dict, "no-overrides", "b", no_overrides);
  return g_variant_ref_sink (g_variant_dict_end (&dict));
}
示例#13
0
static gboolean
get_modifiers_variant (const char   *set_refspec,
                       const char   *set_revision,
                       const char *const* install_pkgs,
                       const char *const* uninstall_pkgs,
                       const char *const* override_replace_pkgs,
                       const char *const* override_remove_pkgs,
                       const char *const* override_reset_pkgs,
                       GVariant    **out_modifiers,
                       GUnixFDList **out_fd_list,
                       GError      **error)
{
  GVariantDict dict;
  g_variant_dict_init (&dict, NULL);
  g_autoptr(GUnixFDList) fd_list = g_unix_fd_list_new ();

  if (install_pkgs)
    {
      if (!vardict_sort_and_insert_pkgs (&dict, "install", fd_list,
                                         install_pkgs, error))
        return FALSE;
    }

  if (override_replace_pkgs)
    {
      if (!vardict_sort_and_insert_pkgs (&dict, "override-replace", fd_list,
                                         override_replace_pkgs, error))
        return FALSE;
    }

  if (set_refspec)
    g_variant_dict_insert (&dict, "set-refspec", "s", set_refspec);
  if (set_revision)
    g_variant_dict_insert (&dict, "set-revision", "s", set_revision);

  vardict_insert_strv (&dict, "uninstall-packages", uninstall_pkgs);
  vardict_insert_strv (&dict, "override-remove-packages", override_remove_pkgs);
  vardict_insert_strv (&dict, "override-reset-packages", override_reset_pkgs);

  *out_fd_list = g_steal_pointer (&fd_list);
  *out_modifiers = g_variant_ref_sink (g_variant_dict_end (&dict));
  return TRUE;
}
static void
properties_changed (GDBusProxy *proxy,
		    GVariant   *changed_properties,
		    GStrv       invalidated_properties,
		    gpointer    user_data)
{
	GVariant *v;
	GVariantDict dict;

	g_variant_dict_init (&dict, changed_properties);

	if (g_variant_dict_contains (&dict, "HasAccelerometer")) {
		v = g_dbus_proxy_get_cached_property (iio_proxy, "HasAccelerometer");
		g_message ("Accelerometer %s", g_variant_get_boolean (v) ? "appeared" : "disappeared");
		g_variant_unref (v);
	}
	if (g_variant_dict_contains (&dict, "AccelerometerOrientation")) {
		v = g_dbus_proxy_get_cached_property (iio_proxy, "AccelerometerOrientation");
		g_message ("Accelerometer orientation changed: %s", g_variant_get_string (v, NULL));
		g_variant_unref (v);
	}
	if (g_variant_dict_contains (&dict, "HasAmbientLight")) {
		v = g_dbus_proxy_get_cached_property (iio_proxy, "HasAmbientLight");
		g_message ("Light sensor %s", g_variant_get_boolean (v) ? "appeared" : "disappeared");
		g_variant_unref (v);
	}
	if (g_variant_dict_contains (&dict, "LightLevel")) {
		GVariant *unit;

		v = g_dbus_proxy_get_cached_property (iio_proxy, "LightLevel");
		unit = g_dbus_proxy_get_cached_property (iio_proxy, "LightLevelUnit");
		g_message ("Light changed: %lf (%s)", g_variant_get_double (v), g_variant_get_string (unit, NULL));
		g_variant_unref (v);
		g_variant_unref (unit);
	}
}
static gboolean
pkg_change (RpmOstreeCommandInvocation *invocation,
            RPMOSTreeSysroot *sysroot_proxy,
            const char *const* packages_to_add,
            const char *const* packages_to_remove,
            GCancellable  *cancellable,
            GError       **error)
{
  const char *const strv_empty[] = { NULL };

  if (!packages_to_add)
    packages_to_add = strv_empty;
  if (!packages_to_remove)
    packages_to_remove = strv_empty;

  glnx_unref_object RPMOSTreeOS *os_proxy = NULL;
  if (!rpmostree_load_os_proxy (sysroot_proxy, opt_osname,
                                cancellable, &os_proxy, error))
    return FALSE;

  g_autoptr(GVariant) previous_deployment = rpmostree_os_dup_default_deployment (os_proxy);

  GVariantDict dict;
  g_variant_dict_init (&dict, NULL);
  g_variant_dict_insert (&dict, "reboot", "b", opt_reboot);
  g_variant_dict_insert (&dict, "cache-only", "b", opt_cache_only);
  g_variant_dict_insert (&dict, "download-only", "b", opt_download_only);
  g_variant_dict_insert (&dict, "no-pull-base", "b", TRUE);
  g_variant_dict_insert (&dict, "dry-run", "b", opt_dry_run);
  g_variant_dict_insert (&dict, "allow-inactive", "b", opt_allow_inactive);
  g_variant_dict_insert (&dict, "no-layering", "b", opt_uninstall_all);
  g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_dict_end (&dict));

  gboolean met_local_pkg = FALSE;
  for (const char *const* it = packages_to_add; it && *it; it++)
    met_local_pkg = met_local_pkg || g_str_has_suffix (*it, ".rpm");

  /* Use newer D-Bus API only if we have to. */
  g_autofree char *transaction_address = NULL;
  if (met_local_pkg)
    {
      if (!rpmostree_update_deployment (os_proxy,
                                        NULL, /* refspec */
                                        NULL, /* revision */
                                        packages_to_add,
                                        packages_to_remove,
                                        NULL, /* override replace */
                                        NULL, /* override remove */
                                        NULL, /* override reset */
                                        options,
                                        &transaction_address,
                                        cancellable,
                                        error))
        return FALSE;
    }
  else
    {
      if (!rpmostree_os_call_pkg_change_sync (os_proxy,
                                              options,
                                              packages_to_add,
                                              packages_to_remove,
                                              NULL,
                                              &transaction_address,
                                              NULL,
                                              cancellable,
                                              error))
        return FALSE;
    }

  return rpmostree_transaction_client_run (invocation, sysroot_proxy, os_proxy,
                                           options, FALSE,
                                           transaction_address,
                                           previous_deployment,
                                           cancellable, error);
}
示例#16
0
gboolean
rpmostree_builtin_upgrade (int             argc,
                           char          **argv,
                           GCancellable   *cancellable,
                           GError        **error)
{
  gboolean ret = FALSE;

  GOptionContext *context = g_option_context_new ("- Perform a system upgrade");
  glnx_unref_object RPMOSTreeOS *os_proxy = NULL;
  glnx_unref_object RPMOSTreeSysroot *sysroot_proxy = NULL;
  g_autoptr(GVariant) default_deployment = NULL;
  g_autofree char *transaction_address = NULL;

  if (!rpmostree_option_context_parse (context,
                                       option_entries,
                                       &argc, &argv,
                                       RPM_OSTREE_BUILTIN_FLAG_NONE,
                                       cancellable,
                                       &sysroot_proxy,
                                       error))
    goto out;

  if (opt_check_diff && opt_reboot)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "cannot specify both --reboot and --check-diff");
      goto out;
    }

  if (!rpmostree_load_os_proxy (sysroot_proxy, opt_osname,
                                cancellable, &os_proxy, error))
    goto out;

  if (opt_check_diff)
    {
      if (!rpmostree_os_call_download_update_rpm_diff_sync (os_proxy,
                                                            &transaction_address,
                                                            cancellable,
                                                            error))
        goto out;
    }
  else
    {
      g_signal_connect (os_proxy, "notify::default-deployment",
                        G_CALLBACK (default_changed_callback),
                        &default_deployment);

      if (!rpmostree_os_call_upgrade_sync (os_proxy,
                                           get_args_variant (),
                                           &transaction_address,
                                           cancellable,
                                           error))
        goto out;
    }

  if (!rpmostree_transaction_get_response_sync (sysroot_proxy,
                                                transaction_address,
                                                cancellable,
                                                error))
    goto out;

  if (opt_check_diff)
    {
      /* yes, doing this without using dbus */
      gs_unref_object OstreeSysroot *sysroot = NULL;
      gs_unref_object OstreeRepo *repo = NULL;
      gs_unref_object GFile *rpmdbdir = NULL;
      gs_unref_object GFile *sysroot_file = NULL;
      g_autofree char *origin_description = NULL;
      g_autoptr(GVariant) cached_update = NULL;
      const char *sysroot_path;
      GVariantDict upgrade_dict;

      _cleanup_rpmrev_ struct RpmRevisionData *rpmrev1 = NULL;
      _cleanup_rpmrev_ struct RpmRevisionData *rpmrev2 = NULL;

      gs_free char *ref = NULL; /* location of this rev */
      gs_free char *remote = NULL;

      if (!rpmostree_os_get_has_cached_update_rpm_diff (os_proxy))
        goto out;

      sysroot_path = rpmostree_sysroot_get_path (sysroot_proxy);
      sysroot_file = g_file_new_for_path (sysroot_path);
      sysroot = ostree_sysroot_new (sysroot_file);

      if (!ostree_sysroot_load (sysroot, cancellable, error))
        goto out;

      if (!ostree_sysroot_get_repo (sysroot, &repo, cancellable, error))
        goto out;

      cached_update = rpmostree_os_dup_cached_update(os_proxy);
      g_variant_dict_init (&upgrade_dict, cached_update);
      if (!g_variant_dict_lookup (&upgrade_dict, "origin", "s", &origin_description))
        goto out;

      if (!ostree_parse_refspec (origin_description, &remote, &ref, error))
         goto out;

      if (rpmReadConfigFiles (NULL, NULL))
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "rpm failed to init: %s", rpmlogMessage ());
          goto out;
        }

      if (!(rpmrev1 = rpmrev_new (repo,
                                  ostree_deployment_get_csum (ostree_sysroot_get_booted_deployment (sysroot)),
                                  NULL, cancellable, error)))
        goto out;

      if (!(rpmrev2 = rpmrev_new (repo, ref,
                                  NULL, cancellable, error)))
        goto out;

      rpmhdrs_diff_prnt_diff (rpmhdrs_diff (rpmrev_get_headers (rpmrev1),
                                            rpmrev_get_headers (rpmrev2)));
    }
  else
    {
      /* nothing changed */
      if (default_deployment == NULL)
        {
          goto out;
        }
      if (!opt_reboot)
        {
          const char *sysroot_path;

          sysroot_path = rpmostree_sysroot_get_path (sysroot_proxy);

          if (!rpmostree_print_treepkg_diff_from_sysroot_path (sysroot_path,
                                                               cancellable,
                                                               error))
            goto out;

          g_print ("Run \"systemctl reboot\" to start a reboot\n");
        }
    }

  ret = TRUE;

out:
  /* Does nothing if using the message bus. */
  rpmostree_cleanup_peer ();

  return ret;
}
GVariant *
rpmostreed_deployment_generate_variant (OstreeDeployment *deployment,
                                        OstreeRepo *repo)
{
  g_autoptr(GVariant) commit = NULL;

  g_autofree gchar *origin_refspec = NULL;
  g_autofree gchar *version_commit = NULL;
  g_autofree gchar *id = NULL;

  GVariant *sigs = NULL; /* floating variant */
  GError *error = NULL;

  GVariantDict dict;
  guint64 timestamp = 0;

  const gchar *osname = ostree_deployment_get_osname (deployment);
  const gchar *csum = ostree_deployment_get_csum (deployment);
  gint serial = ostree_deployment_get_deployserial (deployment);
  id = rpmostreed_deployment_generate_id (deployment);

  if (ostree_repo_load_variant (repo,
                                OSTREE_OBJECT_TYPE_COMMIT,
                                csum,
                                &commit,
                                &error))
    {
      g_autoptr(GVariant) metadata = NULL;
      timestamp = ostree_commit_get_timestamp (commit);
      metadata = g_variant_get_child_value (commit, 0);
      if (metadata != NULL)
          g_variant_lookup (metadata, "version", "s", &version_commit);
    }
  else
    {
      g_warning ("Error loading commit %s", error->message);
    }
  g_clear_error (&error);

  origin_refspec = rpmostreed_deployment_get_refspec (deployment);
  if (origin_refspec)
    sigs = rpmostreed_deployment_gpg_results (repo, origin_refspec, csum);

  g_variant_dict_init (&dict, NULL);

  g_variant_dict_insert (&dict, "id", "s", id);
  if (osname != NULL)
    g_variant_dict_insert (&dict, "osname", "s", osname);
  g_variant_dict_insert (&dict, "serial", "i", serial);
  g_variant_dict_insert (&dict, "checksum", "s", csum);
  if (version_commit != NULL)
    g_variant_dict_insert (&dict, "version", "s", version_commit);
  if (timestamp > 0)
    g_variant_dict_insert (&dict, "timestamp", "t", timestamp);
  if (origin_refspec != NULL)
    g_variant_dict_insert (&dict, "origin", "s", origin_refspec);
  if (sigs != NULL)
    g_variant_dict_insert_value (&dict, "signatures", sigs);

  return g_variant_dict_end (&dict);
}
示例#18
0
static void abrt_p2_task_finish_gtask(GObject *source_object,
           GAsyncResult *result,
           gpointer user_data)
{
    AbrtP2Task *task = ABRT_P2_TASK(source_object);

    if (!g_task_is_valid(result, task))
    {
        error_msg("BUG:%s:%s: invalid GTask", __FILE__, __func__);
        return;
    }

    GError *error = NULL;
    const gint32 code = g_task_propagate_int(G_TASK(result), &error);

    if (code == ABRT_P2_TASK_CODE_STOP)
    {
        log_debug("Task stopped");

        abrt_p2_task_change_status(task, ABRT_P2_TASK_STATUS_STOPPED);
    }
    else if (code >= ABRT_P2_TASK_CODE_DONE)
    {
        log_debug("Task done");

        task->pv->p2t_code = code - ABRT_P2_TASK_CODE_DONE;
        abrt_p2_task_change_status(task, ABRT_P2_TASK_STATUS_DONE);
    }
    else if (abrt_p2_task_is_cancelled(task))
    {
        if (error != NULL)
        {
            log_debug("Task canceled with error: %s", error->message);

            g_error_free(error);
            error = NULL;
        }
        else
            log_debug("Task canceled");

        ABRT_P2_TASK_VIRTUAL_CANCEL(task, &error);
        abrt_p2_task_change_status(task, ABRT_P2_TASK_STATUS_CANCELED);
    }
    else
    {
        GVariantDict response;
        g_variant_dict_init(&response, NULL);

        if (error != NULL)
        {
            log_debug("Task failed with error: %s", error->message);

            g_variant_dict_insert(&response,
                                  "Error.Message",
                                  "s",
                                  error->message);

            g_error_free(error);
        }
        else if (code == ABRT_P2_TASK_CODE_ERROR)
        {
            log_debug("Task failed without error message");

            g_variant_dict_insert(&response,
                                  "Error.Message",
                                  "s",
                                  "Task failed");
        }
        else
        {
            error_msg("BUG:%s:%s: unknown Task return code: %d",
                      __FILE__,
                      __func__,
                      code);

            g_variant_dict_insert(&response,
                                  "Error.Message",
                                  "s",
                                  "Internal error: Invalid Task return code");
        }

        abrt_p2_task_set_response(task, g_variant_dict_end(&response));
        abrt_p2_task_change_status(task, ABRT_P2_TASK_STATUS_FAILED);
    }

    g_object_unref(task->pv->p2t_cancellable);
    task->pv->p2t_cancellable = NULL;
}
GVariant *
rpmostreed_deployment_generate_variant (OstreeDeployment *deployment,
                                        const char *booted_id,
                                        OstreeRepo *repo,
					GError **error)
{
  g_autoptr(GVariant) commit = NULL;
  g_autoptr(RpmOstreeOrigin) origin = NULL;
  g_autofree gchar *id = NULL;

  GVariant *sigs = NULL; /* floating variant */

  GVariantDict dict;

  const gchar *osname = ostree_deployment_get_osname (deployment);
  const gchar *csum = ostree_deployment_get_csum (deployment);
  gint serial = ostree_deployment_get_deployserial (deployment);
  gboolean gpg_enabled = FALSE;

  if (!ostree_repo_load_variant (repo,
				 OSTREE_OBJECT_TYPE_COMMIT,
				 csum,
				 &commit,
				 error))
    return NULL;
  
  id = rpmostreed_deployment_generate_id (deployment);

  origin = rpmostree_origin_parse_deployment (deployment, error);
  if (!origin)
    return NULL;

  g_variant_dict_init (&dict, NULL);

  g_variant_dict_insert (&dict, "id", "s", id);
  if (osname != NULL)
    g_variant_dict_insert (&dict, "osname", "s", osname);
  g_variant_dict_insert (&dict, "serial", "i", serial);
  g_variant_dict_insert (&dict, "checksum", "s", csum);
  if (rpmostree_origin_is_locally_assembled (origin))
    {
      const char *parent = ostree_commit_get_parent (commit);
      g_assert (parent);
      g_variant_dict_insert (&dict, "base-checksum", "s", parent);
      sigs = rpmostreed_deployment_gpg_results (repo, rpmostree_origin_get_refspec (origin),
                                                parent, &gpg_enabled);
    }
  else
    sigs = rpmostreed_deployment_gpg_results (repo, rpmostree_origin_get_refspec (origin),
                                              csum, &gpg_enabled);

  variant_add_commit_details (&dict, commit);
  g_variant_dict_insert (&dict, "origin", "s", rpmostree_origin_get_refspec (origin));
  if (rpmostree_origin_get_packages (origin) != NULL)
    g_variant_dict_insert (&dict, "packages", "^as", rpmostree_origin_get_packages (origin));
  if (sigs != NULL)
    g_variant_dict_insert_value (&dict, "signatures", sigs);
  g_variant_dict_insert (&dict, "gpg-enabled", "b", gpg_enabled);

  g_variant_dict_insert (&dict, "unlocked", "s",
			 ostree_deployment_unlocked_state_to_string (ostree_deployment_get_unlocked (deployment)));

  if (booted_id != NULL)
    g_variant_dict_insert (&dict, "booted", "b", g_strcmp0 (booted_id, id) == 0);

  return g_variant_dict_end (&dict);
}
示例#20
0
int
rpmostree_builtin_status (int             argc,
                          char          **argv,
                          GCancellable   *cancellable,
                          GError        **error)
{
  int exit_status = EXIT_FAILURE;
  GOptionContext *context = g_option_context_new ("- Get the version of the booted system");
  glnx_unref_object RPMOSTreeOS *os_proxy = NULL;
  glnx_unref_object RPMOSTreeSysroot *sysroot_proxy = NULL;
  g_autoptr(GVariant) booted_deployment = NULL;
  g_autoptr(GVariant) deployments = NULL;
  g_autoptr(GVariant) booted_signatures = NULL;
  g_autoptr(GPtrArray) deployment_dicts = NULL;
  GVariantIter iter;
  GVariant *child;
  g_autofree gchar *booted_id = NULL;

  const guint CSUM_DISP_LEN = 10; /* number of checksum characters to display */
  guint i, n;
  guint max_timestamp_len = 19; /* length of timestamp "YYYY-MM-DD HH:MM:SS" */
  guint max_id_len = CSUM_DISP_LEN; /* length of checksum ID */
  guint max_osname_len = 0; /* maximum length of osname - determined in code */
  guint max_refspec_len = 0; /* maximum length of refspec - determined in code */
  guint max_version_len = 0; /* maximum length of version - determined in code */
  guint buffer = 5; /* minimum space between end of one entry and new column */


  if (!rpmostree_option_context_parse (context,
                                       option_entries,
                                       &argc, &argv,
                                       RPM_OSTREE_BUILTIN_FLAG_NONE,
                                       cancellable,
                                       &sysroot_proxy,
                                       error))
    goto out;

  if (!rpmostree_load_os_proxy (sysroot_proxy, NULL,
                                cancellable, &os_proxy, error))
    goto out;

  booted_deployment = rpmostree_os_dup_booted_deployment (os_proxy);
  if (booted_deployment)
    {
      GVariantDict dict;
      g_variant_dict_init (&dict, booted_deployment);
      g_variant_dict_lookup (&dict, "id", "s", &booted_id);
      booted_signatures = g_variant_dict_lookup_value (&dict, "signatures",
                                                       G_VARIANT_TYPE ("av"));
      g_variant_dict_clear (&dict);
    }

  deployment_dicts = g_ptr_array_new_with_free_func ((GDestroyNotify) g_variant_dict_unref);

  deployments = rpmostree_sysroot_dup_deployments (sysroot_proxy);

  g_variant_iter_init (&iter, deployments);

  while ((child = g_variant_iter_next_value (&iter)) != NULL)
    {
      GVariantDict *dict = g_variant_dict_new (child);

      /* Takes ownership of the dictionary */
      g_ptr_array_add (deployment_dicts, dict);

      /* find lengths for use in column output */
      if (!opt_pretty)
        {
          gchar *origin_refspec = NULL; /* borrowed */
          gchar *os_name = NULL; /* borrowed */
          gchar *version_string = NULL; /* borrowed */

          /* osname should always be present. */
          if (g_variant_dict_lookup (dict, "osname", "&s", &os_name))
            max_osname_len = MAX (max_osname_len, strlen (os_name));
          else
            {
              const char *id = NULL;
              g_variant_dict_lookup (dict, "id", "&s", &id);
              g_critical ("Deployment '%s' missing osname", id != NULL ? id : "?");
            }

          if (g_variant_dict_lookup (dict, "version", "&s", &version_string))
            max_version_len = MAX (max_version_len, strlen (version_string));

          if (g_variant_dict_lookup (dict, "origin", "&s", &origin_refspec))
            max_refspec_len = MAX (max_refspec_len, strlen (origin_refspec));
        }

      g_variant_unref (child);
    }

  if (!opt_pretty)
    {
      /* print column headers */
      g_print ("  %-*s", max_timestamp_len+buffer,"TIMESTAMP (UTC)");
      if (max_version_len)
        g_print ("%-*s", max_version_len+buffer,"VERSION");
      g_print ("%-*s%-*s%-*s\n",
               max_id_len+buffer, "ID",
               max_osname_len+buffer, "OSNAME",
               max_refspec_len+buffer, "REFSPEC");
    }
  /* header for "pretty" row output */
  else
    printchar ("=", 60);

  n = deployment_dicts->len;

  /* print entries for each deployment */
  for (i = 0; i < n; i++)
    {
      GVariantDict *dict;
      g_autoptr(GDateTime) timestamp = NULL;
      g_autofree char *timestamp_string = NULL;
      g_autofree gchar *truncated_csum = NULL;
      g_autoptr(GVariant) signatures = NULL;

      gchar *id = NULL; /* borrowed */
      gchar *origin_refspec = NULL; /* borrowed */
      gchar *os_name = NULL; /* borrowed */
      gchar *version_string = NULL; /* borrowed */
      gchar *checksum = NULL; /* borrowed */

      guint64 t = 0;
      gint serial;
      gboolean is_booted = FALSE;

      dict = g_ptr_array_index (deployment_dicts, i);

      g_variant_dict_lookup (dict, "id", "&s", &id);
      g_variant_dict_lookup (dict, "osname", "&s", &os_name);
      g_variant_dict_lookup (dict, "serial", "i", &serial);
      g_variant_dict_lookup (dict, "checksum", "s", &checksum);
      g_variant_dict_lookup (dict, "version", "s", &version_string);
      g_variant_dict_lookup (dict, "timestamp", "t", &t);
      g_variant_dict_lookup (dict, "origin", "s", &origin_refspec);
      signatures = g_variant_dict_lookup_value (dict, "signatures",
                                                G_VARIANT_TYPE ("av"));

      is_booted = g_strcmp0 (booted_id, id) == 0;

      timestamp = g_date_time_new_from_unix_utc (t);
      if (timestamp != NULL)
        timestamp_string = g_date_time_format (timestamp, "%Y-%m-%d %T");
      else
        timestamp_string = g_strdup_printf ("(invalid)");

      /* truncate checksum */
      truncated_csum = g_strndup (checksum, CSUM_DISP_LEN);

      /* print deployment info column */
      if (!opt_pretty)
        {
          g_print ("%c %-*s",
                   is_booted ? '*' : ' ',
                   max_timestamp_len+buffer, timestamp_string);

          if (max_version_len)
            g_print ("%-*s",
                     max_version_len+buffer, version_string ? version_string : "");
          g_print ("%-*s%-*s%-*s\n",
                   max_id_len+buffer, truncated_csum,
                   max_osname_len+buffer, os_name,
                   max_refspec_len+buffer, origin_refspec);
        }

      /* print "pretty" row info */
      else
        {
          guint tab = 11;
          char *title = NULL;
          if (i==0)
            title = "DEFAULT ON BOOT";
          else if (is_booted || n <= 2)
            title = "NON-DEFAULT ROLLBACK TARGET";
          else
            title = "NON-DEFAULT DEPLOYMENT";
          g_print ("  %c %s\n",
                  is_booted ? '*' : ' ',
                  title);

          printchar ("-", 40);
          if (version_string)
            g_print ("  %-*s%-*s\n", tab, "version", tab, version_string);

          g_print ("  %-*s%-*s\n  %-*s%-*s.%d\n  %-*s%-*s\n  %-*s%-*s\n",
                  tab, "timestamp", tab, timestamp_string,
                  tab, "id", tab, checksum, serial,
                  tab, "osname", tab, os_name,
                  tab, "refspec", tab, origin_refspec);

          if (signatures != NULL)
            rpmostree_print_signatures (signatures, "  GPG: ");

          printchar ("=", 60);
        }
    }

  /* Print any signatures for the booted deployment, but only in NON-pretty
   * mode.  We save this for the end to preserve the tabular formatting for
   * deployments. */
  if (!opt_pretty && booted_signatures != NULL)
    {
      guint n_sigs = g_variant_n_children (booted_signatures);
      if (n_sigs > 0)
        {
          /* XXX If we ever add internationalization, use ngettext() here. */
          g_print ("\nGPG: Found %u signature%s on the booted deployment (*):\n",
                   n_sigs, n_sigs == 1 ? "" : "s");
          rpmostree_print_signatures (booted_signatures, "  ");
        }
    }

  exit_status = EXIT_SUCCESS;

out:
  /* Does nothing if using the message bus. */
  rpmostree_cleanup_peer ();

  return exit_status;
}
static gboolean
rewrite_delta (OstreeRepo *src_repo,
               const char *src_commit,
               OstreeRepo *dst_repo,
               const char *dst_commit,
               GVariant   *dst_commitv,
               const char *from,
               GError    **error)
{
  g_autoptr(GFile) src_delta_file = NULL;
  g_autoptr(GFile) dst_delta_file = NULL;
  g_autofree char *src_detached_key = _ostree_get_relative_static_delta_path (from, src_commit, "commitmeta");
  g_autofree char *dst_detached_key = _ostree_get_relative_static_delta_path (from, dst_commit, "commitmeta");
  g_autofree char *src_delta_dir = _ostree_get_relative_static_delta_path (from, src_commit, NULL);
  g_autofree char *dst_delta_dir = _ostree_get_relative_static_delta_path (from, dst_commit, NULL);
  g_autofree char *src_superblock_path = _ostree_get_relative_static_delta_path (from, src_commit, "superblock");
  g_autofree char *dst_superblock_path = _ostree_get_relative_static_delta_path (from, dst_commit, "superblock");
  GMappedFile *mfile = NULL;
  g_auto(GVariantBuilder) superblock_builder = FLATPAK_VARIANT_BUILDER_INITIALIZER;
  g_autoptr(GVariant) src_superblock = NULL;
  g_autoptr(GVariant) dst_superblock = NULL;
  g_autoptr(GBytes) bytes = NULL;
  g_autoptr(GVariant) dst_detached = NULL;
  g_autoptr(GVariant) src_metadata = NULL;
  g_autoptr(GVariant) src_recurse = NULL;
  g_autoptr(GVariant) src_parts = NULL;
  g_auto(GVariantDict) dst_metadata_dict = FLATPAK_VARIANT_DICT_INITIALIZER;
  int i;

  src_delta_file = g_file_resolve_relative_path (ostree_repo_get_path (src_repo), src_superblock_path);
  mfile = g_mapped_file_new (flatpak_file_get_path_cached (src_delta_file), FALSE, NULL);
  if (mfile == NULL)
    return TRUE; /* No superblock, not an error */

  bytes = g_mapped_file_get_bytes (mfile);
  g_mapped_file_unref (mfile);

  src_superblock = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT), bytes, FALSE));

  src_metadata = g_variant_get_child_value (src_superblock, 0);
  src_recurse = g_variant_get_child_value (src_superblock, 5);
  src_parts = g_variant_get_child_value (src_superblock, 6);

  if (g_variant_n_children (src_recurse) != 0)
    return flatpak_fail (error, "Recursive deltas not supported, ignoring");

  g_variant_builder_init (&superblock_builder, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT));

  g_variant_dict_init (&dst_metadata_dict, src_metadata);
  g_variant_dict_remove (&dst_metadata_dict, src_detached_key);
  if (ostree_repo_read_commit_detached_metadata (dst_repo, dst_commit, &dst_detached, NULL, NULL) &&
      dst_detached != NULL)
    g_variant_dict_insert_value (&dst_metadata_dict, dst_detached_key, dst_detached);

  g_variant_builder_add_value (&superblock_builder, g_variant_dict_end (&dst_metadata_dict));
  g_variant_builder_add_value (&superblock_builder, g_variant_get_child_value (src_superblock, 1)); /* timestamp */
  g_variant_builder_add_value (&superblock_builder, from ? ostree_checksum_to_bytes_v (from) : new_bytearray ((guchar *) "", 0));
  g_variant_builder_add_value (&superblock_builder, ostree_checksum_to_bytes_v (dst_commit));
  g_variant_builder_add_value (&superblock_builder, dst_commitv);
  g_variant_builder_add_value (&superblock_builder, src_recurse);
  g_variant_builder_add_value (&superblock_builder, src_parts);
  g_variant_builder_add_value (&superblock_builder, g_variant_get_child_value (src_superblock, 7)); /* fallback */

  dst_superblock = g_variant_ref_sink (g_variant_builder_end (&superblock_builder));

  if (!glnx_shutil_mkdir_p_at (ostree_repo_get_dfd (dst_repo), dst_delta_dir, 0755, NULL, error))
    return FALSE;

  for (i = 0; i < g_variant_n_children (src_parts); i++)
    {
      g_autofree char *src_part_path = g_strdup_printf ("%s/%d", src_delta_dir, i);
      g_autofree char *dst_part_path = g_strdup_printf ("%s/%d", dst_delta_dir, i);

      if (!glnx_file_copy_at (ostree_repo_get_dfd (src_repo),
                              src_part_path,
                              NULL,
                              ostree_repo_get_dfd (dst_repo),
                              dst_part_path,
                              GLNX_FILE_COPY_OVERWRITE | GLNX_FILE_COPY_NOXATTRS,
                              NULL, error))
        return FALSE;
    }

  dst_delta_file = g_file_resolve_relative_path (ostree_repo_get_path (dst_repo), dst_superblock_path);
  if (!flatpak_variant_save (dst_delta_file, dst_superblock, NULL, error))
    return FALSE;

  return TRUE;
}
示例#22
0
/**
 * rpmostreed_repo_pull_ancestry:
 * @repo: Repo
 * @refspec: Repository branch
 * @visitor: (allow-none): Visitor function to call on each commit
 * @visitor_data: (allow-none): User data for @visitor
 * @progress: (allow-none): Progress
 * @cancellable: Cancellable
 * @error: Error
 *
 * Downloads an ancestry of commit objects starting from @refspec.
 *
 * If a @visitor function pointer is given, commit objects are downloaded
 * in batches and the @visitor function is called for each commit object.
 * The @visitor function can stop the recursion, such as when looking for
 * a particular commit.
 *
 * Returns: %TRUE on success, %FALSE on failure
 */
gboolean
rpmostreed_repo_pull_ancestry (OstreeRepo               *repo,
                               const char               *refspec,
                               RpmostreedCommitVisitor   visitor,
                               gpointer                  visitor_data,
                               OstreeAsyncProgress      *progress,
                               GCancellable             *cancellable,
                               GError                  **error)
{
  OstreeRepoPullFlags flags;
  GVariantDict options;
  GVariant *refs_value;
  const char *refs_array[] = { NULL, NULL };
  g_autofree char *remote = NULL;
  g_autofree char *ref = NULL;
  g_autofree char *checksum = NULL;
  int depth, ii;
  gboolean ret = FALSE;

  g_return_val_if_fail (OSTREE_IS_REPO (repo), FALSE);
  g_return_val_if_fail (refspec != NULL, FALSE);

  if (!ostree_parse_refspec (refspec, &remote, &ref, error))
    goto out;

  /* If no visitor function was provided then we won't be short-circuiting
   * the recursion, so pull everything in one shot. Otherwise pull commits
   * in increasingly large batches. */
  depth = (visitor != NULL) ? 10 : -1;

  flags = OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY;

  /* It's important to use the ref name instead of a checksum on the first
   * pass because we want to search from the latest available commit on the
   * remote server, which is not necessarily what the ref name is currently
   * pointing at in our local repo. */
  refs_array[0] = ref;

  while (TRUE)
    {
      /* Floating reference, transferred to dictionary. */
      refs_value = g_variant_new_strv ((const char * const *) refs_array, -1);

      g_variant_dict_init (&options, NULL);
      g_variant_dict_insert (&options, "depth", "i", depth);
      g_variant_dict_insert (&options, "flags", "i", flags);
      g_variant_dict_insert_value (&options, "refs", refs_value);

      if (!ostree_repo_pull_with_options (repo, remote,
                                          g_variant_dict_end (&options),
                                          progress, cancellable, error))
        goto out;

      /* First pass only.  Now we can resolve the ref to a checksum. */
      if (checksum == NULL)
        {
          if (!ostree_repo_resolve_rev (repo, ref, FALSE, &checksum, error))
            goto out;
        }

      /* If depth is negative (no visitor), this loop is skipped. */
      for (ii = 0; ii < depth && checksum != NULL; ii++)
        {
          g_autoptr(GVariant) commit = NULL;
          gboolean stop = FALSE;

          if (!ostree_repo_load_commit (repo, checksum, &commit, NULL, error))
            goto out;

          if (!visitor (repo, checksum, commit, visitor_data, &stop, error))
            goto out;

          g_clear_pointer (&checksum, g_free);

          if (!stop)
            checksum = ostree_commit_get_parent (commit);
        }

      /* Break if no visitor, or visitor told us to stop. */
      if (depth < 0 || checksum == NULL)
        break;

      /* Pull the next batch of commits, twice as many. */
      refs_array[0] = checksum;
      depth = depth * 2;
    }

  ret = TRUE;

out:
  return ret;
}