Exemple #1
0
/* Used by the remote builtins which are special in taking --sysroot or --repo */
gboolean
ostree_parse_sysroot_or_repo_option (GOptionContext *context,
                                     const char *sysroot_path,
                                     const char *repo_path,
                                     OstreeSysroot **out_sysroot,
                                     OstreeRepo **out_repo,
                                     GCancellable *cancellable,
                                     GError **error)
{
  g_autoptr(OstreeSysroot) sysroot = NULL;
  g_autoptr(OstreeRepo) repo = NULL;
  if (sysroot_path)
    {
      g_autoptr(GFile) sysroot_file = g_file_new_for_path (sysroot_path);
      sysroot = ostree_sysroot_new (sysroot_file);
      if (!ostree_sysroot_load (sysroot, cancellable, error))
        return FALSE;
      if (!ostree_sysroot_get_repo (sysroot, &repo, cancellable, error))
        return FALSE;
    }
  else
    {
      repo = parse_repo_option (context, repo_path, FALSE, cancellable, error);
      if (!repo)
        return FALSE;
    }

  ot_transfer_out_value (out_sysroot, &sysroot);
  ot_transfer_out_value (out_repo, &repo);
  return TRUE;
}
gboolean
ot_admin_builtin_init_fs (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error)
{
  GOptionContext *context;
  gboolean ret = FALSE;
  gs_unref_object GFile *dir = NULL;
  gs_unref_object GFile *child = NULL;
  gs_unref_object OstreeSysroot *target_sysroot = NULL;
  guint i;
  const char *normal_toplevels[] = {"boot", "dev", "home", "proc", "run", "sys"};

  context = g_option_context_new ("PATH - Initialize a root filesystem");
  g_option_context_add_main_entries (context, options, NULL);

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

  if (argc < 2)
    {
      ot_util_usage_error (context, "PATH must be specified", error);
      goto out;
    }

  dir = g_file_new_for_path (argv[1]);
  target_sysroot = ostree_sysroot_new (dir);

  for (i = 0; i < G_N_ELEMENTS(normal_toplevels); i++)
    {
      child = g_file_get_child (dir, normal_toplevels[i]);
      if (!gs_file_ensure_directory_mode (child, 0755, cancellable, error))
        goto out;
      g_clear_object (&child);
    }

  child = g_file_get_child (dir, "root");
  if (!gs_file_ensure_directory_mode (child, 0700, cancellable, error))
    goto out;
  g_clear_object (&child);

  child = g_file_get_child (dir, "tmp");
  if (!gs_file_ensure_directory_mode (child, 01777, cancellable, error))
    goto out;
  g_clear_object (&child);

  if (!ostree_sysroot_ensure_initialized (target_sysroot, cancellable, error))
    goto out;

  ret = TRUE;
 out:
  if (context)
    g_option_context_free (context);
  return ret;
}
/**
 * rpmostreed_sysroot_populate :
 *
 * loads internals and starts monitoring
 *
 * Returns: True on success
 */
gboolean
rpmostreed_sysroot_populate (RpmostreedSysroot *self,
			     GCancellable *cancellable,
                             GError **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFile) sysroot_file = NULL;
  const char *sysroot_path;

  g_return_val_if_fail (self != NULL, FALSE);

  sysroot_path = rpmostree_sysroot_get_path (RPMOSTREE_SYSROOT (self));
  sysroot_file = g_file_new_for_path (sysroot_path);
  self->ot_sysroot = ostree_sysroot_new (sysroot_file);

  /* This creates and caches an OstreeRepo instance inside
   * OstreeSysroot to ensure subsequent ostree_sysroot_get_repo()
   * calls won't fail.
   */
  if (!ostree_sysroot_get_repo (self->ot_sysroot, &self->repo, cancellable, error))
    goto out;

  if (!sysroot_populate_deployments_unlocked (self, NULL, error))
    goto out;

  if (self->monitor == NULL)
    {
      const char *sysroot_path = gs_file_get_path_cached (ostree_sysroot_get_path (self->ot_sysroot));
      g_autofree char *sysroot_deploy_path = g_build_filename (sysroot_path, "ostree/deploy", NULL);
      g_autoptr(GFile) sysroot_deploy = g_file_new_for_path (sysroot_deploy_path);
      
      self->monitor = g_file_monitor (sysroot_deploy, 0, NULL, error);

      if (self->monitor == NULL)
        goto out;

      self->sig_changed = g_signal_connect (self->monitor,
                                            "changed",
                                            G_CALLBACK (on_deploy_changed),
                                            self);
    }

  ret = TRUE;
out:
  return ret;
}
/* Called by ostree-finalize-staged.service, and in turn
 * invokes a cmdprivate function inside the shared library.
 */
gboolean
ot_admin_builtin_finalize_staged (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
{
  /* Just a sanity check; we shouldn't be called outside of the service though.
   */
  struct stat stbuf;
  if (fstatat (AT_FDCWD, "/run/ostree-booted", &stbuf, 0) < 0)
    return TRUE;

  g_autoptr(GFile) sysroot_file = g_file_new_for_path ("/");
  g_autoptr(OstreeSysroot) sysroot = ostree_sysroot_new (sysroot_file);

  if (!ostree_sysroot_load (sysroot, cancellable, error))
    return FALSE;
  if (!ostree_cmd__private__()->ostree_finalize_staged (sysroot, cancellable, error))
    return FALSE;

  return TRUE;
}
Exemple #5
0
OstreeSysroot *
ot_test_setup_sysroot (GCancellable *cancellable,
                       GError **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFile) sysroot_path = g_file_new_for_path ("sysroot");
  glnx_unref_object OstreeSysroot *ret_sysroot = NULL;

  if (!ot_test_run_libtest ("setup_os_repository \"archive-z2\" \"syslinux\"", error))
    goto out;

  /* Make sure deployments are mutable */
  g_setenv ("OSTREE_SYSROOT_DEBUG", "mutable-deployments", TRUE);

  ret_sysroot = ostree_sysroot_new (sysroot_path);

  ret = TRUE;
 out:
  if (ret)
    return g_steal_pointer (&ret_sysroot);
  return NULL;
}
Exemple #6
0
OstreeSysroot *
ot_test_setup_sysroot (GCancellable *cancellable,
                       GError **error)
{
  gboolean ret = FALSE;
  g_autoptr(GFile) sysroot_path = g_file_new_for_path ("sysroot");
  glnx_unref_object OstreeSysroot *ret_sysroot = NULL;
  struct statfs stbuf;

  if (!ot_test_run_libtest ("setup_os_repository \"archive-z2\" \"syslinux\"", error))
    goto out;

  { g_autoptr(GString) buf = g_string_new ("mutable-deployments");
    if (statfs ("/", &stbuf) < 0)
      return glnx_null_throw_errno (error);
    /* Keep this in sync with the overlayfs bits in libtest.sh */
#ifndef OVERLAYFS_SUPER_MAGIC
#define OVERLAYFS_SUPER_MAGIC 0x794c7630
#endif
    if (stbuf.f_type == OVERLAYFS_SUPER_MAGIC)
      {
        g_print ("libostreetest: detected overlayfs\n");
        g_string_append (buf, ",no-xattrs");
      }
    /* Make sure deployments are mutable */
    g_setenv ("OSTREE_SYSROOT_DEBUG", buf->str, TRUE);
  }

  ret_sysroot = ostree_sysroot_new (sysroot_path);

  ret = TRUE;
 out:
  if (ret)
    return g_steal_pointer (&ret_sysroot);
  return NULL;
}
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;
}
Exemple #8
0
gboolean
ostree_admin_option_context_parse (GOptionContext *context,
                                   const GOptionEntry *main_entries,
                                   int *argc,
                                   char ***argv,
                                   OstreeAdminBuiltinFlags flags,
                                   OstreeSysroot **out_sysroot,
                                   GCancellable *cancellable,
                                   GError **error)
{
  g_autoptr(GFile) sysroot_path = NULL;
  glnx_unref_object OstreeSysroot *sysroot = NULL;
  gboolean success = FALSE;

  /* Entries are listed in --help output in the order added.  We add the
   * main entries ourselves so that we can add the --sysroot entry first. */

  g_option_context_add_main_entries (context, global_admin_entries, NULL);

  if (!ostree_option_context_parse (context, main_entries, argc, argv, OSTREE_BUILTIN_FLAG_NO_REPO, NULL, cancellable, error))
    goto out;

  if (opt_sysroot != NULL)
    sysroot_path = g_file_new_for_path (opt_sysroot);

  sysroot = ostree_sysroot_new (sysroot_path);

  if (flags & OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER)
    {
      GFile *path = ostree_sysroot_get_path (sysroot);

      /* If sysroot path is "/" then user must be root. */
      if (!g_file_has_parent (path, NULL) && getuid () != 0)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
                       "You must be root to perform this command");
          goto out;
        }
    }

  if (opt_print_current_dir)
    {
      g_autoptr(GPtrArray) deployments = NULL;
      OstreeDeployment *first_deployment;
      g_autoptr(GFile) deployment_file = NULL;
      g_autofree char *deployment_path = NULL;

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

      deployments = ostree_sysroot_get_deployments (sysroot);
      if (deployments->len == 0)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Unable to find a deployment in sysroot");
          goto out;
        }
      first_deployment = deployments->pdata[0];
      deployment_file = ostree_sysroot_get_deployment_directory (sysroot, first_deployment);
      deployment_path = g_file_get_path (deployment_file);

      g_print ("%s\n", deployment_path);

      /* The g_autoptr, g_autofree etc. don't happen when we explicitly
       * exit, making valgrind complain about leaks */
      g_clear_object (&sysroot);
      g_clear_object (&sysroot_path);
      g_clear_object (&deployment_file);
      g_clear_pointer (&deployments, g_ptr_array_unref);
      g_clear_pointer (&deployment_path, g_free);
      exit (EXIT_SUCCESS);
    }

  if ((flags & OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED) == 0)
    {
      /* Released when sysroot is finalized, or on process exit */
      if (!ot_admin_sysroot_lock (sysroot, error))
        goto out;
    }

  if (out_sysroot)
    *out_sysroot = g_steal_pointer (&sysroot);

  success = TRUE;

out:
  return success;
}
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");
  gs_unref_object GFile *sysroot_path = NULL;
  gs_unref_object OstreeSysroot *sysroot = NULL;
  gs_unref_object OstreeSysrootUpgrader *upgrader = NULL;
  gs_unref_object OstreeAsyncProgress *progress = NULL;
  GSConsole *console = NULL;
  gboolean changed;
  OstreeSysrootUpgraderPullFlags upgraderpullflags = 0;

  gs_free char *origin_description = NULL;
  gs_unref_object OstreeRepo *repo = NULL; 

  g_option_context_add_main_entries (context, option_entries, NULL);

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

  sysroot_path = g_file_new_for_path (opt_sysroot);
  sysroot = ostree_sysroot_new (sysroot_path);
  if (!ostree_sysroot_load (sysroot, cancellable, error))
    goto out;

  upgrader = ostree_sysroot_upgrader_new_for_os (sysroot, opt_osname,
                                                 cancellable, error);
  if (!upgrader)
    goto out;

  origin_description = ostree_sysroot_upgrader_get_origin_description (upgrader);
  if (origin_description)
    g_print ("Updating from: %s\n", origin_description);

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

  console = gs_console_get ();
  if (console)
    {
      gs_console_begin_status_line (console, "", NULL, NULL);
      progress = ostree_async_progress_new_and_connect (_rpmostree_pull_progress, console);
    }

  if (opt_allow_downgrade)  
    upgraderpullflags |= OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_ALLOW_OLDER;

  if (opt_check_diff)
    {
      if (!ostree_sysroot_upgrader_pull_one_dir (upgrader, "/usr/share/rpm", 0, 0, progress, &changed,
                                     cancellable, error))
        goto out;
    }

  else
    {
      if (!ostree_sysroot_upgrader_pull (upgrader, 0, 0, progress, &changed,
                                       cancellable, error))
        goto out;
    }

  if (console)
    {
      if (!gs_console_end_status_line (console, cancellable, error))
        {
          console = NULL;
          goto out;
        }
      console = NULL;
    }

  if (!changed)
    {
      g_print ("No updates available.\n");
    }
  else
    {
      if (!opt_check_diff)
        {
          if (!ostree_sysroot_upgrader_deploy (upgrader, cancellable, error))
                goto out;
        
          if (opt_reboot)
            gs_subprocess_simple_run_sync (NULL, GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT,
                                           cancellable, error,
                                           "systemctl", "reboot", NULL);
          else
            {
#ifdef HAVE_PATCHED_HAWKEY_AND_LIBSOLV
              if (!rpmostree_print_treepkg_diff (sysroot, cancellable, error))
                goto out;
#endif

              g_print ("Updates prepared for next boot; run \"systemctl reboot\" to start a reboot\n");
            }
        }


      else
        {
          gs_unref_object GFile *rpmdbdir = NULL;
          _cleanup_rpmrev_ struct RpmRevisionData *rpmrev1 = NULL;
          _cleanup_rpmrev_ struct RpmRevisionData *rpmrev2 = NULL;

          gs_free char *tmpd = g_mkdtemp (g_strdup ("/tmp/rpm-ostree.XXXXXX"));

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

          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;
            }

          rpmdbdir = g_file_new_for_path (tmpd);

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

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

          rpmhdrs_diff_prnt_diff (rpmrev1->root, rpmrev2->root,
                            rpmhdrs_diff (rpmrev1->rpmdb, rpmrev2->rpmdb),
                            cancellable, error);
        }
    }
  
  ret = TRUE;
 out:
  if (console)
    (void) gs_console_end_status_line (console, NULL, NULL);

  return ret;
}
gboolean
rpmostree_builtin_rebase (int             argc,
                          char          **argv,
                          GCancellable   *cancellable,
                          GError        **error)
{
  gboolean ret = FALSE;
  GOptionContext *context = g_option_context_new ("REFSPEC - Switch to a different tree");
  const char *new_provided_refspec;
  gs_unref_object OstreeSysroot *sysroot = NULL;
  gs_unref_object OstreeRepo *repo = NULL;
  gs_free char *origin_refspec = NULL;
  gs_free char *origin_remote = NULL;
  gs_free char *origin_ref = NULL;
  gs_free char *new_remote = NULL;
  gs_free char *new_ref = NULL;
  gs_free char *new_refspec = NULL;
  gs_unref_object GFile *sysroot_path = NULL;
  gs_unref_object OstreeSysrootUpgrader *upgrader = NULL;
  gs_unref_object OstreeAsyncProgress *progress = NULL;
  gboolean changed;
  GSConsole *console = NULL;
  gs_unref_keyfile GKeyFile *old_origin = NULL;
  gs_unref_keyfile GKeyFile *new_origin = NULL;
  
  if (!rpmostree_option_context_parse (context, option_entries, &argc, &argv, error))
    goto out;

  if (argc < 2)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "REFSPEC must be specified");
      goto out;
    }

  new_provided_refspec = argv[1];

  sysroot_path = g_file_new_for_path (opt_sysroot);
  sysroot = ostree_sysroot_new (sysroot_path);
  if (!ostree_sysroot_load (sysroot, cancellable, error))
    goto out;

  upgrader = ostree_sysroot_upgrader_new_for_os_with_flags (sysroot, opt_osname,
                                                            OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED,
                                                            cancellable, error);
  if (!upgrader)
    goto out;

  old_origin = ostree_sysroot_upgrader_get_origin (upgrader);
  origin_refspec = g_key_file_get_string (old_origin, "origin", "refspec", NULL);
  
  if (!ostree_parse_refspec (origin_refspec, &origin_remote, &origin_ref, error))
    goto out;

  /* Allow just switching remotes */
  if (g_str_has_suffix (new_provided_refspec, ":"))
    {
      new_remote = g_strdup (new_provided_refspec);
      new_remote[strlen(new_remote)-1] = '\0';
      new_ref = g_strdup (origin_ref);
    }
  else
    {
      if (!ostree_parse_refspec (new_provided_refspec, &new_remote, &new_ref, error))
        goto out;
    }
  
  if (!new_remote)
    new_refspec = g_strconcat (origin_remote, ":", new_ref, NULL);
  else
    new_refspec = g_strconcat (new_remote, ":", new_ref, NULL);
  
  if (strcmp (origin_refspec, new_refspec) == 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Old and new refs are equal: %s", new_refspec);
      goto out;
    }

  new_origin = ostree_sysroot_origin_new_from_refspec (sysroot, new_refspec);
  if (!ostree_sysroot_upgrader_set_origin (upgrader, new_origin, cancellable, error))
    goto out;

  console = gs_console_get ();
  if (console)
    {
      gs_console_begin_status_line (console, "", NULL, NULL);
      progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, console);
    }

  /* Always allow older...there's not going to be a chronological
   * relationship necessarily.
   */
  if (!ostree_sysroot_upgrader_pull (upgrader, 0,
                                     OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_ALLOW_OLDER,
                                     progress, &changed,
                                     cancellable, error))
    goto out;

  if (console)
    {
      if (!gs_console_end_status_line (console, cancellable, error))
        {
          console = NULL;
          goto out;
        }
      console = NULL;
    }

  if (!ostree_sysroot_upgrader_deploy (upgrader, cancellable, error))
    goto out;

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

  if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
    goto out;

  g_print ("Deleting ref '%s:%s'\n", origin_remote, origin_ref);
  ostree_repo_transaction_set_ref (repo, origin_remote, origin_ref, NULL);
  
  if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
    goto out;
  
  if (!rpmostree_print_treepkg_diff (sysroot, cancellable, error))
    goto out;
  
  ret = TRUE;
 out:
  if (console)
    (void) gs_console_end_status_line (console, NULL, NULL);
  return ret;
}
Exemple #11
0
/**
 * ostree_sysroot_new_default:
 *
 * Returns: (transfer full): An accessor for the current visible root / filesystem
 */
OstreeSysroot*
ostree_sysroot_new_default (void)
{
  g_autoptr(GFile) rootfs = g_file_new_for_path ("/");
  return ostree_sysroot_new (rootfs);
}
gboolean
rpmostree_builtin_rollback (int             argc,
                            char          **argv,
                            GCancellable   *cancellable,
                            GError        **error)
{
  gboolean ret = FALSE;
  GOptionContext *context = g_option_context_new ("- Revert to the previously booted tree");
  gs_unref_object GFile *sysroot_path = NULL;
  gs_unref_object OstreeSysroot *sysroot = NULL;
  gs_free char *origin_description = NULL;
  gs_unref_ptrarray GPtrArray *deployments = NULL;
  gs_unref_ptrarray GPtrArray *new_deployments =
    g_ptr_array_new_with_free_func (g_object_unref);
  OstreeDeployment *booted_deployment = NULL;
  guint i;
  guint booted_index;
  guint index_to_prepend;
  
  if (!rpmostree_option_context_parse (context, option_entries, &argc, &argv, error))
    goto out;

  sysroot_path = g_file_new_for_path (opt_sysroot);
  sysroot = ostree_sysroot_new (sysroot_path);
  if (!ostree_sysroot_load (sysroot, cancellable, error))
    goto out;

  booted_deployment = ostree_sysroot_get_booted_deployment (sysroot);
  if (booted_deployment == NULL)
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           "Not currently booted into an OSTree system");
      goto out;
    }

  deployments = ostree_sysroot_get_deployments (sysroot);
  if (deployments->len < 2)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Found %u deployments, at least 2 required for rollback",
                   deployments->len);
      goto out;
    }

  g_assert (booted_deployment != NULL);
  for (booted_index = 0; booted_index < deployments->len; booted_index++)
    {
      if (deployments->pdata[booted_index] == booted_deployment)
        break;
    }
  g_assert (booted_index < deployments->len);
  g_assert (deployments->pdata[booted_index] == booted_deployment);
  
  if (booted_index != 0)
    {
      /* There is an earlier deployment, let's assume we want to just
       * insert the current one in front.
       */

       /*
       What this does is, if we're NOT in the default boot index, it plans to prepend
       our current index (1, since we can't have more than two trees) so that it becomes index 0 
       (default) and the current default becomes index 1
       */
      index_to_prepend = booted_index;
    }
  else
    {
      /* We're booted into the first, let's roll back to the previous */
      index_to_prepend = 1;
    }
  
  g_ptr_array_add (new_deployments, g_object_ref (deployments->pdata[index_to_prepend]));
  for (i = 0; i < deployments->len; i++)
    {
      if (i == index_to_prepend)
        continue;
      g_ptr_array_add (new_deployments, g_object_ref (deployments->pdata[i]));
    }

  g_print ("Moving '%s.%d' to be first deployment\n",
           ostree_deployment_get_csum (deployments->pdata[index_to_prepend]),
           ostree_deployment_get_deployserial (deployments->pdata[index_to_prepend]));

  if (!ostree_sysroot_write_deployments (sysroot, new_deployments, cancellable,
                                         error))
    goto out;

  if (opt_reboot)
    gs_subprocess_simple_run_sync (NULL, GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT,
                                   cancellable, error,
                                   "systemctl", "reboot", NULL);
  else
    {
      if (!rpmostree_print_treepkg_diff (sysroot, cancellable, error))
        goto out;

      g_print ("Successfully reset deployment order; run \"systemctl reboot\" to start a reboot\n");
    }

  if (opt_reboot)
  ret = TRUE;
 out:
  return ret;
}
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");
  gs_unref_object GFile *sysroot_path = NULL;
  gs_unref_object OstreeSysroot *sysroot = NULL;
  gs_unref_object OstreeSysrootUpgrader *upgrader = NULL;
  gs_unref_object OstreeAsyncProgress *progress = NULL;
  GSConsole *console = NULL;
  gboolean changed;
  OstreeSysrootUpgraderPullFlags upgraderpullflags = 0;
  gs_free char *origin_description = NULL;
  
  g_option_context_add_main_entries (context, option_entries, NULL);

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

  sysroot_path = g_file_new_for_path (opt_sysroot);
  sysroot = ostree_sysroot_new (sysroot_path);
  if (!ostree_sysroot_load (sysroot, cancellable, error))
    goto out;

  upgrader = ostree_sysroot_upgrader_new_for_os (sysroot, opt_osname,
                                                 cancellable, error);
  if (!upgrader)
    goto out;

  origin_description = ostree_sysroot_upgrader_get_origin_description (upgrader);
  if (origin_description)
    g_print ("Updating from: %s\n", origin_description);

  console = gs_console_get ();
  if (console)
    {
      gs_console_begin_status_line (console, "", NULL, NULL);
      progress = ostree_async_progress_new_and_connect (_rpmostree_pull_progress, console);
    }

  if (opt_allow_downgrade)
    upgraderpullflags |= OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_ALLOW_OLDER;

  if (!ostree_sysroot_upgrader_pull (upgrader, 0, 0, progress, &changed,
                                     cancellable, error))
    goto out;

  if (console)
    {
      if (!gs_console_end_status_line (console, cancellable, error))
        {
          console = NULL;
          goto out;
        }
      console = NULL;
    }

  if (!changed)
    {
      g_print ("No updates available.\n");
    }
  else
    {
      if (!ostree_sysroot_upgrader_deploy (upgrader, cancellable, error))
        goto out;

      if (opt_reboot)
        gs_subprocess_simple_run_sync (NULL, GS_SUBPROCESS_STREAM_DISPOSITION_INHERIT,
                                       cancellable, error,
                                       "systemctl", "reboot", NULL);
      else
        {
#ifdef HAVE_PATCHED_HAWKEY_AND_LIBSOLV
          if (!rpmostree_print_treepkg_diff (sysroot, cancellable, error))
            goto out;
#endif

          g_print ("Updates prepared for next boot; run \"systemctl reboot\" to start a reboot\n");
        }
    }
  
  ret = TRUE;
 out:
  if (console)
    (void) gs_console_end_status_line (console, NULL, NULL);

  return ret;
}
Exemple #14
0
/**
 * ostree_sysroot_new_default:
 *
 * Returns: (transfer full): An accessor for the current visible root / filesystem
 */
OstreeSysroot*
ostree_sysroot_new_default (void)
{
  return ostree_sysroot_new (NULL);
}