static gboolean
print_rpmdb_diff (GFile          *oldroot,
                  GFile          *newroot,
                  GCancellable   *cancellable,
                  GError        **error)
{
  gboolean ret = FALSE;
  _cleanup_hysack_ HySack old_sack = NULL;
  _cleanup_hypackagelist_ HyPackageList old_pkglist = NULL;
  _cleanup_hysack_ HySack new_sack = NULL;
  _cleanup_hypackagelist_ HyPackageList new_pkglist = NULL;
  guint i;
  HyPackage pkg;
  gboolean printed_header = FALSE;

  if (!rpmostree_get_pkglist_for_root (oldroot, &old_sack, &old_pkglist,
                                       cancellable, error))
    goto out;

  if (!rpmostree_get_pkglist_for_root (newroot, &new_sack, &new_pkglist,
                                       cancellable, error))
    goto out;
  
  printed_header = FALSE;
  FOR_PACKAGELIST(pkg, new_pkglist, i)
    {
      _cleanup_hyquery_ HyQuery query = NULL;
      _cleanup_hypackagelist_ HyPackageList pkglist = NULL;
      
      query = hy_query_create (old_sack);
      hy_query_filter (query, HY_PKG_NAME, HY_EQ, hy_package_get_name (pkg));
      hy_query_filter (query, HY_PKG_EVR, HY_NEQ, hy_package_get_evr (pkg));
      hy_query_filter (query, HY_PKG_REPONAME, HY_EQ, HY_SYSTEM_REPO_NAME);
      pkglist = hy_query_run (query);
      if (hy_packagelist_count (pkglist) > 0)
        {
          gs_free char *nevra = hy_package_get_nevra (pkg);
          if (!printed_header)
            {
              g_print ("Changed:\n");
              printed_header = TRUE;
            }
          g_print ("  %s\n", nevra);
        }
    }
Exemplo n.º 2
0
gboolean
rpmostree_treefile_postprocessing (GFile         *yumroot,
                                   GFile         *context_directory,
                                   GBytes        *serialized_treefile,
                                   JsonObject    *treefile,
                                   GCancellable  *cancellable,
                                   GError       **error)
{
    gboolean ret = FALSE;
    guint i, len;
    JsonArray *units = NULL;
    JsonArray *remove = NULL;
    const char *default_target = NULL;
    const char *postprocess_script = NULL;

    if (json_object_has_member (treefile, "units"))
        units = json_object_get_array_member (treefile, "units");

    if (units)
        len = json_array_get_length (units);
    else
        len = 0;

    {
        gs_unref_object GFile *multiuser_wants_dir =
            g_file_resolve_relative_path (yumroot, "etc/systemd/system/multi-user.target.wants");

        if (!gs_file_ensure_directory (multiuser_wants_dir, TRUE, cancellable, error))
            goto out;

        for (i = 0; i < len; i++)
        {
            const char *unitname = _rpmostree_jsonutil_array_require_string_element (units, i, error);
            gs_unref_object GFile *unit_link_target = NULL;
            gs_free char *symlink_target = NULL;

            if (!unitname)
                goto out;

            symlink_target = g_strconcat ("/usr/lib/systemd/system/", unitname, NULL);
            unit_link_target = g_file_get_child (multiuser_wants_dir, unitname);

            if (g_file_query_file_type (unit_link_target, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL) == G_FILE_TYPE_SYMBOLIC_LINK)
                continue;

            g_print ("Adding %s to multi-user.target.wants\n", unitname);

            if (!g_file_make_symbolic_link (unit_link_target, symlink_target,
                                            cancellable, error))
                goto out;
        }
    }

    {
        gs_unref_object GFile *target_treefile_dir_path =
            g_file_resolve_relative_path (yumroot, "usr/share/rpm-ostree");
        gs_unref_object GFile *target_treefile_path =
            g_file_get_child (target_treefile_dir_path, "treefile.json");
        const guint8 *buf;
        gsize len;

        if (!gs_file_ensure_directory (target_treefile_dir_path, TRUE,
                                       cancellable, error))
            goto out;

        g_print ("Writing '%s'\n", gs_file_get_path_cached (target_treefile_path));
        buf = g_bytes_get_data (serialized_treefile, &len);

        if (!g_file_replace_contents (target_treefile_path, (char*)buf, len,
                                      NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION,
                                      NULL, cancellable, error))
            goto out;
    }

    if (!_rpmostree_jsonutil_object_get_optional_string_member (treefile, "default_target",
            &default_target, error))
        goto out;

    if (default_target != NULL)
    {
        gs_unref_object GFile *default_target_path =
            g_file_resolve_relative_path (yumroot, "etc/systemd/system/default.target");
        gs_free char *dest_default_target_path =
            g_strconcat ("/usr/lib/systemd/system/", default_target, NULL);

        (void) gs_file_unlink (default_target_path, NULL, NULL);

        if (!g_file_make_symbolic_link (default_target_path, dest_default_target_path,
                                        cancellable, error))
            goto out;
    }

    if (json_object_has_member (treefile, "remove-files"))
    {
        remove = json_object_get_array_member (treefile, "remove-files");
        len = json_array_get_length (remove);
    }
    else
        len = 0;

    for (i = 0; i < len; i++)
    {
        const char *val = _rpmostree_jsonutil_array_require_string_element (remove, i, error);
        gs_unref_object GFile *child = NULL;

        if (!val)
            return FALSE;
        if (g_path_is_absolute (val))
        {
            g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                         "'remove' elements must be relative");
            goto out;
        }

        child = g_file_resolve_relative_path (yumroot, val);

        if (g_file_query_exists (child, NULL))
        {
            g_print ("Removing '%s'\n", val);
            if (!gs_shutil_rm_rf (child, cancellable, error))
                goto out;
        }
        else
        {
            g_printerr ("warning: Targeted path for remove-files does not exist: %s\n",
                        gs_file_get_path_cached (child));
        }
    }

    if (json_object_has_member (treefile, "remove-from-packages"))
    {
        g_autoptr(RpmOstreeRefSack) refsack = NULL;
        _cleanup_hypackagelist_ HyPackageList pkglist = NULL;
        guint i;

        remove = json_object_get_array_member (treefile, "remove-from-packages");
        len = json_array_get_length (remove);

        if (!rpmostree_get_pkglist_for_root (AT_FDCWD, gs_file_get_path_cached (yumroot),
                                             &refsack, &pkglist,
                                             cancellable, error))
        {
            g_prefix_error (error, "Reading package set: ");
            goto out;
        }

        for (i = 0; i < len; i++)
        {
            JsonArray *elt = json_array_get_array_element (remove, i);
            if (!handle_remove_files_from_package (yumroot, refsack, elt, cancellable, error))
                goto out;
        }
    }

    if (!_rpmostree_jsonutil_object_get_optional_string_member (treefile, "postprocess-script",
            &postprocess_script, error))
        goto out;

    if (postprocess_script)
    {
        const char *yumroot_path = gs_file_get_path_cached (yumroot);
        gs_unref_object GFile *src = g_file_resolve_relative_path (context_directory, postprocess_script);
        const char *bn = gs_file_get_basename_cached (src);
        gs_free char *binpath = g_strconcat ("/usr/bin/rpmostree-postprocess-", bn, NULL);
        gs_free char *destpath = g_strconcat (yumroot_path, binpath, NULL);
        gs_unref_object GFile *dest = g_file_new_for_path (destpath);
        /* Clone all the things */

        if (!g_file_copy (src, dest, 0, cancellable, NULL, NULL, error))
        {
            g_prefix_error (error, "Copying postprocess-script '%s' into target: ", bn);
            goto out;
        }

        g_print ("Executing postprocessing script '%s'\n", bn);

        {
            char *child_argv[] = { binpath, NULL };
            if (!run_sync_in_root (yumroot, binpath, child_argv, error))
            {
                g_prefix_error (error, "While executing postprocessing script '%s': ", bn);
                goto out;
            }
        }

        g_print ("Finished postprocessing script '%s'\n", bn);
    }

    ret = TRUE;
out:
    return ret;
}