package layering: major rework
- Move the package layering logic away from pkg-add and into the upgrader - Add pkg-delete - Add dry-run option Closes: #289 Approved by: cgwalters
This commit is contained in:
parent
a25cdde25c
commit
ead1ecdd23
@ -42,6 +42,7 @@ librpmostreed_la_SOURCES = \
|
||||
src/daemon/rpmostreed-transaction-types.h \
|
||||
src/daemon/rpmostreed-transaction-types.c \
|
||||
src/daemon/rpmostreed-transaction-pkg-add.c \
|
||||
src/daemon/rpmostreed-transaction-pkg-delete.c \
|
||||
src/daemon/rpmostree-package-variants.h \
|
||||
src/daemon/rpmostree-package-variants.c \
|
||||
src/daemon/rpmostreed-os.h \
|
||||
|
@ -28,6 +28,7 @@ rpm_ostree_SOURCES = src/app/main.c \
|
||||
src/app/rpmostree-builtin-deploy.c \
|
||||
src/app/rpmostree-builtin-rebase.c \
|
||||
src/app/rpmostree-builtin-pkgadd.c \
|
||||
src/app/rpmostree-builtin-pkgdelete.c \
|
||||
src/app/rpmostree-builtin-status.c \
|
||||
src/app/rpmostree-builtin-internals.c \
|
||||
src/app/rpmostree-builtin-container.c \
|
||||
|
14
TODO
14
TODO
@ -25,3 +25,17 @@ Autobuilder
|
||||
* Write an intelligent scheduler
|
||||
- Task with same name of newer version wait until old one is done
|
||||
- Walk infinite test matrix
|
||||
|
||||
Package layering
|
||||
----------------
|
||||
|
||||
* Provide a mechanism for updating packages (& pruning older versions)
|
||||
* Support pkgs which bring their own pps
|
||||
https://github.com/projectatomic/rpm-ostree/pull/107#issuecomment-205082381
|
||||
* Support local RPMs installation (though `ostree admin unlock` makes this
|
||||
easier now, but it's not carried over)
|
||||
* Add a way to mark commits as valid for multiple policies rather than creating
|
||||
a new commit everytime we relabel
|
||||
* Related to the above: store the header metadata in the tree itself rather than
|
||||
in the commit to avoid duplication across relabeling commits
|
||||
* Add a --onto option?
|
||||
|
2
libglnx
2
libglnx
@ -1 +1 @@
|
||||
Subproject commit 08ae6639e522e9b11765245fbecdbbe474ccde98
|
||||
Subproject commit 40ef5f7400d4f8eed6a8f834917008b33ad4fb4e
|
@ -40,6 +40,7 @@ static RpmOstreeCommand commands[] = {
|
||||
{ "db", rpmostree_builtin_db },
|
||||
{ "deploy", rpmostree_builtin_deploy },
|
||||
{ "pkg-add", rpmostree_builtin_pkg_add },
|
||||
{ "pkg-delete", rpmostree_builtin_pkg_delete },
|
||||
{ "rebase", rpmostree_builtin_rebase },
|
||||
{ "rollback", rpmostree_builtin_rollback },
|
||||
{ "status", rpmostree_builtin_status },
|
||||
|
@ -29,10 +29,12 @@
|
||||
|
||||
static char *opt_osname;
|
||||
static gboolean opt_reboot;
|
||||
static gboolean opt_dry_run;
|
||||
|
||||
static GOptionEntry option_entries[] = {
|
||||
{ "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Operate on provided OSNAME", "OSNAME" },
|
||||
{ "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Initiate a reboot after upgrade is prepared", NULL },
|
||||
{ "dry-run", 'n', 0, G_OPTION_ARG_NONE, &opt_dry_run, "Exit after printing the transaction", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@ -42,6 +44,7 @@ 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);
|
||||
return g_variant_dict_end (&dict);
|
||||
}
|
||||
|
||||
@ -99,7 +102,11 @@ rpmostree_builtin_pkg_add (int argc,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
if (!opt_reboot)
|
||||
if (opt_dry_run)
|
||||
{
|
||||
g_print ("Exiting because of '--dry-run' option\n");
|
||||
}
|
||||
else if (!opt_reboot)
|
||||
{
|
||||
const char *sysroot_path;
|
||||
|
||||
|
128
src/app/rpmostree-builtin-pkgdelete.c
Normal file
128
src/app/rpmostree-builtin-pkgdelete.c
Normal file
@ -0,0 +1,128 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2015 Colin Walters <walters@verbum.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation; either version 2 of the licence or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "rpmostree-builtins.h"
|
||||
#include "rpmostree-libbuiltin.h"
|
||||
#include "rpmostree-rpm-util.h"
|
||||
#include "rpmostree-dbus-helpers.h"
|
||||
|
||||
#include <libglnx.h>
|
||||
|
||||
static char *opt_osname;
|
||||
static gboolean opt_reboot;
|
||||
static gboolean opt_dry_run;
|
||||
|
||||
static GOptionEntry option_entries[] = {
|
||||
{ "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Operate on provided OSNAME", "OSNAME" },
|
||||
{ "reboot", 'r', 0, G_OPTION_ARG_NONE, &opt_reboot, "Initiate a reboot after upgrade is prepared", NULL },
|
||||
{ "dry-run", 'n', 0, G_OPTION_ARG_NONE, &opt_dry_run, "Exit after printing the transaction", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
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);
|
||||
return g_variant_dict_end (&dict);
|
||||
}
|
||||
|
||||
int
|
||||
rpmostree_builtin_pkg_delete (int argc,
|
||||
char **argv,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
int exit_status = EXIT_FAILURE;
|
||||
GOptionContext *context;
|
||||
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;
|
||||
int i;
|
||||
g_autoptr(GPtrArray) argv_and_null = g_ptr_array_new ();
|
||||
|
||||
context = g_option_context_new ("PACKAGE [PACKAGE...] - Remove previously layered RPM packages");
|
||||
|
||||
if (!rpmostree_option_context_parse (context,
|
||||
option_entries,
|
||||
&argc, &argv,
|
||||
RPM_OSTREE_BUILTIN_FLAG_NONE,
|
||||
cancellable,
|
||||
&sysroot_proxy,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
rpmostree_usage_error (context, "At least one PACKAGE must be specified", error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
g_ptr_array_add (argv_and_null, argv[i]);
|
||||
g_ptr_array_add (argv_and_null, NULL);
|
||||
|
||||
if (!rpmostree_load_os_proxy (sysroot_proxy, opt_osname,
|
||||
cancellable, &os_proxy, error))
|
||||
goto out;
|
||||
|
||||
if (!rpmostree_os_call_pkg_delete_sync (os_proxy,
|
||||
get_args_variant (),
|
||||
(const char * const*)argv_and_null->pdata,
|
||||
&transaction_address,
|
||||
cancellable,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
if (!rpmostree_transaction_get_response_sync (sysroot_proxy,
|
||||
transaction_address,
|
||||
cancellable,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
if (opt_dry_run)
|
||||
{
|
||||
g_print ("Exiting because of '--dry-run' option\n");
|
||||
}
|
||||
else if (!opt_reboot)
|
||||
{
|
||||
const char *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");
|
||||
}
|
||||
|
||||
exit_status = EXIT_SUCCESS;
|
||||
|
||||
out:
|
||||
/* Does nothing if using the message bus. */
|
||||
rpmostree_cleanup_peer ();
|
||||
|
||||
return exit_status;
|
||||
}
|
@ -51,6 +51,7 @@ BUILTINPROTO(db);
|
||||
BUILTINPROTO(internals);
|
||||
BUILTINPROTO(container);
|
||||
BUILTINPROTO(pkg_add);
|
||||
BUILTINPROTO(pkg_delete);
|
||||
|
||||
#undef BUILTINPROTO
|
||||
|
||||
|
@ -178,6 +178,12 @@
|
||||
<arg type="s" name="transaction_address" direction="out"/>
|
||||
</method>
|
||||
|
||||
<method name="PkgDelete">
|
||||
<arg type="a{sv}" name="options" direction="in"/>
|
||||
<arg type="as" name="packages"/>
|
||||
<arg type="s" name="transaction_address" direction="out"/>
|
||||
</method>
|
||||
|
||||
</interface>
|
||||
|
||||
<interface name="org.projectatomic.rpmostree1.Transaction">
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -36,13 +36,18 @@ typedef struct RpmOstreeSysrootUpgrader RpmOstreeSysrootUpgrader;
|
||||
* RpmOstreeSysrootUpgraderFlags:
|
||||
* @RPMOSTREE_SYSROOT_UPGRADER_FLAGS_NONE: No options
|
||||
* @RPMOSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED: Do not error if the origin has an unconfigured-state key
|
||||
* @RPMOSTREE_SYSROOT_UPGRADER_FLAGS_ALLOW_OLDER: Do not error if the new deployment was composed earlier than the current deployment
|
||||
* @RPMOSTREE_SYSROOT_UPGRADER_FLAGS_REDEPLOY: Use the same revision as the current deployment
|
||||
* @RPMOSTREE_SYSROOT_UPGRADER_FLAGS_PKGOVERLAY_DRY_RUN: If layering packages, only print the transaction
|
||||
*
|
||||
* Flags controlling operation of an #RpmOstreeSysrootUpgrader.
|
||||
*/
|
||||
typedef enum {
|
||||
RPMOSTREE_SYSROOT_UPGRADER_FLAGS_NONE = (1 << 0),
|
||||
RPMOSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED = (1 << 1),
|
||||
RPMOSTREE_SYSROOT_UPGRADER_FLAGS_ALLOW_OLDER = (1 << 2)
|
||||
RPMOSTREE_SYSROOT_UPGRADER_FLAGS_ALLOW_OLDER = (1 << 2),
|
||||
RPMOSTREE_SYSROOT_UPGRADER_FLAGS_REDEPLOY = (1 << 3),
|
||||
RPMOSTREE_SYSROOT_UPGRADER_FLAGS_PKGOVERLAY_DRY_RUN = (1 << 4)
|
||||
} RpmOstreeSysrootUpgraderFlags;
|
||||
|
||||
GType rpmostree_sysroot_upgrader_get_type (void);
|
||||
@ -55,6 +60,7 @@ RpmOstreeSysrootUpgrader *rpmostree_sysroot_upgrader_new (OstreeSysroot
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
OstreeDeployment* rpmostree_sysroot_upgrader_get_merge_deployment (RpmOstreeSysrootUpgrader *self);
|
||||
const char *rpmostree_sysroot_upgrader_get_refspec (RpmOstreeSysrootUpgrader *self);
|
||||
const char *const*rpmostree_sysroot_upgrader_get_packages (RpmOstreeSysrootUpgrader *self);
|
||||
|
||||
@ -65,6 +71,25 @@ GKeyFile *rpmostree_sysroot_upgrader_dup_origin (RpmOstreeSysrootUpgrader *self)
|
||||
gboolean rpmostree_sysroot_upgrader_set_origin (RpmOstreeSysrootUpgrader *self, GKeyFile *origin,
|
||||
GCancellable *cancellable, GError **error);
|
||||
|
||||
gboolean rpmostree_sysroot_upgrader_set_origin_rebase (RpmOstreeSysrootUpgrader *self,
|
||||
const char *new_refspec,
|
||||
GError **error);
|
||||
|
||||
void rpmostree_sysroot_upgrader_set_origin_override (RpmOstreeSysrootUpgrader *self,
|
||||
const char *override_commit);
|
||||
|
||||
gboolean
|
||||
rpmostree_sysroot_upgrader_add_packages (RpmOstreeSysrootUpgrader *self,
|
||||
char **new_packages,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
rpmostree_sysroot_upgrader_delete_packages (RpmOstreeSysrootUpgrader *self,
|
||||
char **packages,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
rpmostree_sysroot_upgrader_pull (RpmOstreeSysrootUpgrader *self,
|
||||
const char *dir_to_pull,
|
||||
@ -79,9 +104,4 @@ rpmostree_sysroot_upgrader_deploy (RpmOstreeSysrootUpgrader *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean rpmostree_sysroot_upgrader_set_origin_rebase (RpmOstreeSysrootUpgrader *self, const char *new_refspec, GError **error);
|
||||
void rpmostree_sysroot_upgrader_set_origin_override (RpmOstreeSysrootUpgrader *self, const char *override_commit);
|
||||
void rpmostree_sysroot_upgrader_set_origin_baseref_local (RpmOstreeSysrootUpgrader *self, const char *local_commit);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -711,7 +711,6 @@ os_handle_pkg_add (RPMOSTreeOS *interface,
|
||||
GVariant *arg_options,
|
||||
const char * const *arg_packages)
|
||||
{
|
||||
/* TODO: Totally ignoring arg_packages for now */
|
||||
RpmostreedOS *self = RPMOSTREED_OS (interface);
|
||||
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
||||
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
||||
@ -719,6 +718,7 @@ os_handle_pkg_add (RPMOSTreeOS *interface,
|
||||
GVariantDict options_dict;
|
||||
const char *osname;
|
||||
gboolean opt_reboot = FALSE;
|
||||
gboolean opt_dry_run = FALSE;
|
||||
GError *local_error = NULL;
|
||||
|
||||
/* If a compatible transaction is in progress, share its bus address. */
|
||||
@ -748,6 +748,9 @@ os_handle_pkg_add (RPMOSTreeOS *interface,
|
||||
g_variant_dict_lookup (&options_dict,
|
||||
"reboot", "b",
|
||||
&opt_reboot);
|
||||
g_variant_dict_lookup (&options_dict,
|
||||
"dry-run", "b",
|
||||
&opt_dry_run);
|
||||
g_variant_dict_clear (&options_dict);
|
||||
|
||||
transaction = rpmostreed_transaction_new_pkg_add (invocation,
|
||||
@ -755,6 +758,7 @@ os_handle_pkg_add (RPMOSTreeOS *interface,
|
||||
osname,
|
||||
arg_packages,
|
||||
opt_reboot,
|
||||
opt_dry_run,
|
||||
cancellable,
|
||||
&local_error);
|
||||
|
||||
@ -778,6 +782,83 @@ out:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
os_handle_pkg_delete (RPMOSTreeOS *interface,
|
||||
GDBusMethodInvocation *invocation,
|
||||
GVariant *arg_options,
|
||||
const char * const *arg_packages)
|
||||
{
|
||||
RpmostreedOS *self = RPMOSTREED_OS (interface);
|
||||
glnx_unref_object RpmostreedTransaction *transaction = NULL;
|
||||
glnx_unref_object OstreeSysroot *ot_sysroot = NULL;
|
||||
glnx_unref_object GCancellable *cancellable = NULL;
|
||||
GVariantDict options_dict;
|
||||
const char *osname;
|
||||
gboolean opt_reboot = FALSE;
|
||||
gboolean opt_dry_run = FALSE;
|
||||
GError *local_error = NULL;
|
||||
|
||||
/* If a compatible transaction is in progress, share its bus address. */
|
||||
transaction = rpmostreed_transaction_monitor_ref_active_transaction (self->transaction_monitor);
|
||||
if (transaction != NULL)
|
||||
{
|
||||
if (rpmostreed_transaction_is_compatible (transaction, invocation))
|
||||
goto out;
|
||||
|
||||
g_clear_object (&transaction);
|
||||
}
|
||||
|
||||
cancellable = g_cancellable_new ();
|
||||
|
||||
if (!rpmostreed_sysroot_load_state (rpmostreed_sysroot_get (),
|
||||
cancellable,
|
||||
&ot_sysroot,
|
||||
NULL,
|
||||
&local_error))
|
||||
goto out;
|
||||
|
||||
osname = rpmostree_os_get_name (interface);
|
||||
|
||||
/* XXX Fail if option type is wrong? */
|
||||
|
||||
g_variant_dict_init (&options_dict, arg_options);
|
||||
g_variant_dict_lookup (&options_dict,
|
||||
"reboot", "b",
|
||||
&opt_reboot);
|
||||
g_variant_dict_lookup (&options_dict,
|
||||
"dry-run", "b",
|
||||
&opt_dry_run);
|
||||
g_variant_dict_clear (&options_dict);
|
||||
|
||||
transaction = rpmostreed_transaction_new_pkg_delete (invocation,
|
||||
ot_sysroot,
|
||||
osname,
|
||||
arg_packages,
|
||||
opt_reboot,
|
||||
opt_dry_run,
|
||||
cancellable,
|
||||
&local_error);
|
||||
|
||||
if (transaction == NULL)
|
||||
goto out;
|
||||
|
||||
rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);
|
||||
|
||||
out:
|
||||
if (local_error != NULL)
|
||||
{
|
||||
g_dbus_method_invocation_take_error (invocation, local_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *client_address;
|
||||
client_address = rpmostreed_transaction_get_client_address (transaction);
|
||||
rpmostree_os_complete_pkg_delete (interface, invocation, client_address);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
os_handle_get_cached_rebase_rpm_diff (RPMOSTreeOS *interface,
|
||||
GDBusMethodInvocation *invocation,
|
||||
@ -1152,6 +1233,7 @@ rpmostreed_os_iface_init (RPMOSTreeOSIface *iface)
|
||||
iface->handle_clear_rollback_target = os_handle_clear_rollback_target;
|
||||
iface->handle_rebase = os_handle_rebase;
|
||||
iface->handle_pkg_add = os_handle_pkg_add;
|
||||
iface->handle_pkg_delete = os_handle_pkg_delete;
|
||||
iface->handle_get_cached_rebase_rpm_diff = os_handle_get_cached_rebase_rpm_diff;
|
||||
iface->handle_download_rebase_rpm_diff = os_handle_download_rebase_rpm_diff;
|
||||
iface->handle_get_cached_deploy_rpm_diff = os_handle_get_cached_deploy_rpm_diff;
|
||||
|
@ -43,6 +43,7 @@ typedef struct {
|
||||
char *osname;
|
||||
char **packages;
|
||||
gboolean reboot;
|
||||
gboolean dry_run;
|
||||
} PkgAddTransaction;
|
||||
|
||||
typedef RpmostreedTransactionClass PkgAddTransactionClass;
|
||||
@ -65,407 +66,37 @@ pkg_add_transaction_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (pkg_add_transaction_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
copy_dir_contents_nonrecurse_at (int src_dfd,
|
||||
const char *srcpath,
|
||||
int dest_dfd,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
g_auto(GLnxDirFdIterator) dfd_iter = { FALSE, };
|
||||
struct dirent *dent = NULL;
|
||||
|
||||
if (!glnx_dirfd_iterator_init_at (src_dfd, srcpath, TRUE,
|
||||
&dfd_iter, error))
|
||||
goto out;
|
||||
|
||||
while (glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error))
|
||||
{
|
||||
if (dent == NULL)
|
||||
break;
|
||||
if (!glnx_file_copy_at (dfd_iter.fd, dent->d_name, NULL, dest_dfd, dent->d_name, 0,
|
||||
cancellable, error))
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Given a directory referred to by @dfd and @dirpath, ensure that
|
||||
* physical (or reflink'd) copies of all files are done.
|
||||
*/
|
||||
static gboolean
|
||||
break_hardlinks_at (int dfd,
|
||||
const char *dirpath,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
glnx_fd_close int dest_dfd = -1;
|
||||
g_autofree char *dirpath_tmp = g_strconcat (dirpath, ".tmp", NULL);
|
||||
|
||||
if (TEMP_FAILURE_RETRY (renameat (dfd, dirpath, dfd, dirpath_tmp)) != 0)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* We're not accurately copying the mode, but in reality modes don't
|
||||
* matter since it's all immutable anyways.
|
||||
*/
|
||||
if (TEMP_FAILURE_RETRY (mkdirat (dfd, dirpath, 0755)) != 0)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!glnx_opendirat (dfd, dirpath, TRUE, &dest_dfd, error))
|
||||
goto out;
|
||||
|
||||
if (!copy_dir_contents_nonrecurse_at (dfd, dirpath_tmp, dest_dfd, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!glnx_shutil_rm_rf_at (dfd, dirpath_tmp, cancellable, error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
on_hifstate_percentage_changed (HifState *hifstate,
|
||||
guint percentage,
|
||||
gpointer user_data)
|
||||
{
|
||||
const char *text = user_data;
|
||||
glnx_console_progress_text_percent (text, percentage);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
overlay_packages_in_deploydir (HifContext *hifctx,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
|
||||
/* --- Run transaction --- */
|
||||
{ g_auto(GLnxConsoleRef) console = { 0, };
|
||||
glnx_unref_object HifState *hifstate = hif_state_new ();
|
||||
guint progress_sigid;
|
||||
|
||||
progress_sigid = g_signal_connect (hifstate, "percentage-changed",
|
||||
G_CALLBACK (on_hifstate_percentage_changed),
|
||||
"Installing: ");
|
||||
|
||||
glnx_console_lock (&console);
|
||||
|
||||
if (!hif_context_commit (hifctx, hifstate, error))
|
||||
goto out;
|
||||
|
||||
g_signal_handler_disconnect (hifstate, progress_sigid);
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pkg_add_transaction_execute (RpmostreedTransaction *transaction,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
PkgAddTransaction *self;
|
||||
OstreeSysroot *sysroot;
|
||||
int sysroot_fd; /* Borrowed */
|
||||
OstreeRepoCheckoutOptions checkout_options = { 0, };
|
||||
|
||||
PkgAddTransaction *self = NULL;
|
||||
OstreeSysroot *sysroot = NULL;
|
||||
glnx_unref_object RpmOstreeSysrootUpgrader *upgrader = NULL;
|
||||
glnx_unref_object OstreeRepo *repo = NULL;
|
||||
glnx_unref_object OstreeAsyncProgress *progress = NULL;
|
||||
glnx_unref_object OstreeDeployment *merge_deployment = NULL;
|
||||
glnx_unref_object OstreeDeployment *new_deployment = NULL;
|
||||
g_autofree char *merge_deployment_dirpath = NULL;
|
||||
g_autofree char *tmp_deploy_workdir_name = NULL;
|
||||
gboolean tmp_deploy_workdir_created = FALSE;
|
||||
g_autofree char *tmp_deploy_root_path = NULL;
|
||||
g_autofree char *new_revision = NULL;
|
||||
glnx_fd_close int merge_deployment_dirfd = -1;
|
||||
glnx_fd_close int ostree_repo_tmp_dirfd = -1;
|
||||
glnx_fd_close int deploy_tmp_dirfd = -1;
|
||||
g_autoptr(GKeyFile) origin = NULL;
|
||||
HifContext *hifctx = NULL;
|
||||
g_autoptr(RpmOstreeContext) ctx = NULL;
|
||||
g_autoptr(GHashTable) cur_origin_pkgrequests = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
g_autoptr(GHashTable) new_pkgrequests = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
g_autoptr(GHashTable) layer_new_packages = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
int flags = RPMOSTREE_SYSROOT_UPGRADER_FLAGS_REDEPLOY;
|
||||
|
||||
self = (PkgAddTransaction *) transaction;
|
||||
|
||||
sysroot = rpmostreed_transaction_get_sysroot (transaction);
|
||||
sysroot_fd = ostree_sysroot_get_fd (sysroot);
|
||||
|
||||
merge_deployment = ostree_sysroot_get_merge_deployment (sysroot, self->osname);
|
||||
if (merge_deployment == NULL)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"No deployments found for osname %s", self->osname);
|
||||
goto out;
|
||||
}
|
||||
if (self->dry_run)
|
||||
flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_PKGOVERLAY_DRY_RUN;
|
||||
|
||||
merge_deployment_dirpath = ostree_sysroot_get_deployment_dirpath (sysroot, merge_deployment);
|
||||
|
||||
if (!glnx_opendirat (sysroot_fd, merge_deployment_dirpath, TRUE,
|
||||
&merge_deployment_dirfd, error))
|
||||
goto out;
|
||||
|
||||
if (!glnx_opendirat (sysroot_fd, "ostree/repo/tmp", TRUE,
|
||||
&ostree_repo_tmp_dirfd, error))
|
||||
goto out;
|
||||
|
||||
upgrader = rpmostree_sysroot_upgrader_new (sysroot, self->osname, 0,
|
||||
upgrader = rpmostree_sysroot_upgrader_new (sysroot, self->osname, flags,
|
||||
cancellable, error);
|
||||
if (upgrader == NULL)
|
||||
goto out;
|
||||
|
||||
if (!ostree_sysroot_get_repo (sysroot, &repo, cancellable, error))
|
||||
goto out;
|
||||
|
||||
origin = rpmostree_sysroot_upgrader_dup_origin (upgrader);
|
||||
if (origin == NULL)
|
||||
{
|
||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Merge deployment has no origin");
|
||||
goto out;
|
||||
}
|
||||
|
||||
{
|
||||
const char *cur_origin_refspec =
|
||||
rpmostree_sysroot_upgrader_get_refspec (upgrader);
|
||||
const char *const *cur_origin_packages =
|
||||
rpmostree_sysroot_upgrader_get_packages (upgrader);
|
||||
const char *const*strviter;
|
||||
|
||||
g_assert (cur_origin_refspec);
|
||||
|
||||
for (strviter = cur_origin_packages; strviter && *strviter; strviter++)
|
||||
{
|
||||
const char *pkg = *strviter;
|
||||
g_hash_table_add (cur_origin_pkgrequests, (char*)pkg);
|
||||
g_hash_table_add (new_pkgrequests, (char*)pkg);
|
||||
}
|
||||
|
||||
(void) g_key_file_remove_key (origin, "origin", "refspec", NULL);
|
||||
g_key_file_set_value (origin, "origin", "baserefspec", cur_origin_refspec);
|
||||
}
|
||||
|
||||
if (!rpmostree_sysroot_upgrader_set_origin (upgrader, origin, cancellable, error))
|
||||
goto out;
|
||||
|
||||
{
|
||||
char **iter = self->packages;
|
||||
g_autoptr(RpmOstreeRefSack) rsack = NULL;
|
||||
|
||||
rsack = rpmostree_get_refsack_for_root (sysroot_fd,
|
||||
merge_deployment_dirpath,
|
||||
cancellable, error);
|
||||
if (!rsack)
|
||||
goto out;
|
||||
|
||||
for (; iter && *iter; iter++)
|
||||
{
|
||||
const char *desired_pkg = *iter;
|
||||
HyQuery query = NULL;
|
||||
g_autoptr(GPtrArray) pkglist = NULL;
|
||||
|
||||
if (g_hash_table_contains (cur_origin_pkgrequests, desired_pkg))
|
||||
{
|
||||
if (error && *error == NULL)
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Package '%s' is already requested", desired_pkg);
|
||||
"Could not create sysroot upgrader");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* It's now requested */
|
||||
g_hash_table_add (new_pkgrequests, (char*)desired_pkg);
|
||||
|
||||
query = hy_query_create (rsack->sack);
|
||||
hy_query_filter (query, HY_PKG_NAME, HY_EQ, desired_pkg);
|
||||
hy_query_filter (query, HY_PKG_REPONAME, HY_EQ, HY_SYSTEM_REPO_NAME);
|
||||
pkglist = hy_query_run (query);
|
||||
|
||||
/* This one tracks whether it actually needs to be installed */
|
||||
if (pkglist->len == 0)
|
||||
g_hash_table_add (layer_new_packages, (char*)desired_pkg);
|
||||
|
||||
if (query)
|
||||
hy_query_free (query);
|
||||
}
|
||||
}
|
||||
|
||||
ctx = rpmostree_context_new_system (cancellable, error);
|
||||
if (!ctx)
|
||||
goto out;
|
||||
|
||||
hifctx = rpmostree_context_get_hif (ctx);
|
||||
{
|
||||
g_autofree char *reposdir =
|
||||
g_build_filename (merge_deployment_dirpath, "etc/yum.repos.d", NULL);
|
||||
hif_context_set_repo_dir (hifctx, reposdir);
|
||||
}
|
||||
|
||||
tmp_deploy_workdir_name = g_strdup ("rpmostree-deploy-XXXXXX");
|
||||
if (!glnx_mkdtempat (ostree_repo_tmp_dirfd, tmp_deploy_workdir_name, 0755, error))
|
||||
goto out;
|
||||
tmp_deploy_workdir_created = TRUE;
|
||||
|
||||
tmp_deploy_root_path = g_strconcat (tmp_deploy_workdir_name, "root", NULL);
|
||||
|
||||
checkout_options.devino_to_csum_cache = ostree_repo_devino_cache_new ();
|
||||
|
||||
if (!ostree_repo_checkout_tree_at (repo, &checkout_options, ostree_repo_tmp_dirfd, tmp_deploy_root_path,
|
||||
ostree_deployment_get_csum (merge_deployment),
|
||||
if (!rpmostree_sysroot_upgrader_add_packages (upgrader, self->packages,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!glnx_opendirat (ostree_repo_tmp_dirfd, tmp_deploy_root_path, TRUE,
|
||||
&deploy_tmp_dirfd, error))
|
||||
goto out;
|
||||
|
||||
/* Convert usr/share/rpm into physical copies, as librpm mutates it in place */
|
||||
if (!break_hardlinks_at (deploy_tmp_dirfd, "usr/share/rpm", cancellable, error))
|
||||
goto out;
|
||||
|
||||
/* Temporarily rename /usr/etc to /etc so that RPMs can drop new files there */
|
||||
if (TEMP_FAILURE_RETRY (renameat (deploy_tmp_dirfd, "usr/etc",
|
||||
deploy_tmp_dirfd, "etc")) != 0)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
{ g_autofree char *tmp_deploy_abspath = glnx_fdrel_abspath (deploy_tmp_dirfd, ".");
|
||||
hif_context_set_install_root (hifctx, tmp_deploy_abspath);
|
||||
}
|
||||
|
||||
/* Note this path is relative to the install root */
|
||||
hif_context_set_rpm_macro (hifctx, "_dbpath", "/usr/share/rpm");
|
||||
|
||||
if (!hif_context_setup (hifctx, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (g_hash_table_size (layer_new_packages) > 0)
|
||||
{
|
||||
HifTransaction *hiftx;
|
||||
HyGoal goal;
|
||||
GHashTableIter hashiter;
|
||||
gpointer hkey, hvalue;
|
||||
|
||||
/* --- Downloading metadata --- */
|
||||
{ g_auto(GLnxConsoleRef) console = { 0, };
|
||||
glnx_unref_object HifState *hifstate = hif_state_new ();
|
||||
guint progress_sigid;
|
||||
|
||||
progress_sigid = g_signal_connect (hifstate, "percentage-changed",
|
||||
G_CALLBACK (on_hifstate_percentage_changed),
|
||||
"Downloading metadata: ");
|
||||
|
||||
glnx_console_lock (&console);
|
||||
|
||||
if (!hif_context_setup_sack (hifctx, hifstate, error))
|
||||
goto out;
|
||||
|
||||
g_signal_handler_disconnect (hifstate, progress_sigid);
|
||||
}
|
||||
|
||||
hiftx = hif_context_get_transaction (hifctx);
|
||||
|
||||
g_hash_table_iter_init (&hashiter, layer_new_packages);
|
||||
while (g_hash_table_iter_next (&hashiter, &hkey, &hvalue))
|
||||
{
|
||||
const char *pkg = hkey;
|
||||
|
||||
if (!hif_context_install (hifctx, pkg, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
goal = hif_context_get_goal (hifctx);
|
||||
|
||||
if (!hif_transaction_depsolve (hiftx, goal, NULL, error))
|
||||
goto out;
|
||||
|
||||
/* --- Downloading packages --- */
|
||||
{ g_auto(GLnxConsoleRef) console = { 0, };
|
||||
glnx_unref_object HifState *hifstate = hif_state_new ();
|
||||
guint progress_sigid;
|
||||
|
||||
progress_sigid = g_signal_connect (hifstate, "percentage-changed",
|
||||
G_CALLBACK (on_hifstate_percentage_changed),
|
||||
"Downloading: ");
|
||||
|
||||
glnx_console_lock (&console);
|
||||
|
||||
if (!hif_transaction_download (hiftx, hifstate, error))
|
||||
goto out;
|
||||
|
||||
g_signal_handler_disconnect (hifstate, progress_sigid);
|
||||
}
|
||||
|
||||
/* find any packages without valid GPG signatures */
|
||||
#if 0
|
||||
if (!hif_transaction_check_untrusted (hiftx, goal, error))
|
||||
goto out;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Add previous package requests with newly requested packages */
|
||||
{ gs_unref_ptrarray GPtrArray *new_requested_pkglist = g_ptr_array_new ();
|
||||
GHashTableIter hashiter;
|
||||
gpointer hkey, hvalue;
|
||||
|
||||
g_hash_table_iter_init (&hashiter, cur_origin_pkgrequests);
|
||||
while (g_hash_table_iter_next (&hashiter, &hkey, &hvalue))
|
||||
g_ptr_array_add (new_requested_pkglist, hkey);
|
||||
|
||||
g_hash_table_iter_init (&hashiter, layer_new_packages);
|
||||
while (g_hash_table_iter_next (&hashiter, &hkey, &hvalue))
|
||||
g_ptr_array_add (new_requested_pkglist, hkey);
|
||||
|
||||
g_key_file_set_string_list (origin, "packages", "requested",
|
||||
(const char*const*)new_requested_pkglist->pdata,
|
||||
new_requested_pkglist->len);
|
||||
}
|
||||
|
||||
if (!overlay_packages_in_deploydir (hifctx, cancellable, error))
|
||||
goto out;
|
||||
|
||||
/* Rename /usr/etc back to /etc */
|
||||
if (TEMP_FAILURE_RETRY (renameat (deploy_tmp_dirfd, "etc", deploy_tmp_dirfd, "usr/etc")) != 0)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!rpmostree_commit (deploy_tmp_dirfd, repo, NULL, NULL, NULL, TRUE,
|
||||
checkout_options.devino_to_csum_cache,
|
||||
&new_revision, cancellable, error))
|
||||
goto out;
|
||||
|
||||
(void) close (deploy_tmp_dirfd);
|
||||
deploy_tmp_dirfd = -1;
|
||||
|
||||
if (!glnx_shutil_rm_rf_at (ostree_repo_tmp_dirfd, tmp_deploy_workdir_name, cancellable, error))
|
||||
goto out;
|
||||
tmp_deploy_workdir_created = FALSE;
|
||||
|
||||
rpmostree_sysroot_upgrader_set_origin_baseref_local (upgrader, new_revision);
|
||||
|
||||
if (!rpmostree_sysroot_upgrader_deploy (upgrader, cancellable, error))
|
||||
goto out;
|
||||
|
||||
@ -474,10 +105,6 @@ pkg_add_transaction_execute (RpmostreedTransaction *transaction,
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
if (tmp_deploy_workdir_created)
|
||||
(void) glnx_shutil_rm_rf_at (ostree_repo_tmp_dirfd, tmp_deploy_workdir_name, NULL, NULL);
|
||||
if (checkout_options.devino_to_csum_cache)
|
||||
ostree_repo_devino_cache_unref (checkout_options.devino_to_csum_cache);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -503,6 +130,7 @@ rpmostreed_transaction_new_pkg_add (GDBusMethodInvocation *invocation,
|
||||
const char *osname,
|
||||
const char * const *packages,
|
||||
gboolean reboot,
|
||||
gboolean dry_run,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
@ -524,6 +152,7 @@ rpmostreed_transaction_new_pkg_add (GDBusMethodInvocation *invocation,
|
||||
self->osname = g_strdup (osname);
|
||||
self->packages = g_strdupv ((char**)packages);
|
||||
self->reboot = reboot;
|
||||
self->dry_run = dry_run;
|
||||
}
|
||||
|
||||
return (RpmostreedTransaction *) self;
|
||||
|
159
src/daemon/rpmostreed-transaction-pkg-delete.c
Normal file
159
src/daemon/rpmostreed-transaction-pkg-delete.c
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ostree.h"
|
||||
|
||||
#include <libglnx.h>
|
||||
#include <rpm/rpmlib.h>
|
||||
#include <rpm/rpmlog.h>
|
||||
#include <rpm/rpmdb.h>
|
||||
#include <libhif.h>
|
||||
#include <libhif/hif-utils.h>
|
||||
#include <libgsystem.h>
|
||||
|
||||
#include "rpmostreed-transaction-types.h"
|
||||
#include "rpmostreed-transaction-types.h"
|
||||
#include "rpmostreed-transaction.h"
|
||||
#include "rpmostreed-deployment-utils.h"
|
||||
#include "rpmostreed-sysroot.h"
|
||||
#include "rpmostree-sysroot-upgrader.h"
|
||||
#include "rpmostreed-utils.h"
|
||||
#include "rpmostree-postprocess.h"
|
||||
#include "rpmostree-rpm-util.h"
|
||||
#include "rpmostree-core.h"
|
||||
|
||||
typedef struct {
|
||||
RpmostreedTransaction parent;
|
||||
char *osname;
|
||||
char **packages;
|
||||
gboolean reboot;
|
||||
gboolean dry_run;
|
||||
} PkgDeleteTransaction;
|
||||
|
||||
typedef RpmostreedTransactionClass PkgDeleteTransactionClass;
|
||||
|
||||
GType pkg_delete_transaction_get_type (void);
|
||||
|
||||
G_DEFINE_TYPE (PkgDeleteTransaction,
|
||||
pkg_delete_transaction,
|
||||
RPMOSTREED_TYPE_TRANSACTION)
|
||||
|
||||
static void
|
||||
pkg_delete_transaction_finalize (GObject *object)
|
||||
{
|
||||
PkgDeleteTransaction *self;
|
||||
|
||||
self = (PkgDeleteTransaction *) object;
|
||||
g_free (self->osname);
|
||||
g_strfreev (self->packages);
|
||||
|
||||
G_OBJECT_CLASS (pkg_delete_transaction_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pkg_delete_transaction_execute (RpmostreedTransaction *transaction,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
PkgDeleteTransaction *self = NULL;
|
||||
OstreeSysroot *sysroot = NULL;
|
||||
glnx_unref_object RpmOstreeSysrootUpgrader *upgrader = NULL;
|
||||
int flags = RPMOSTREE_SYSROOT_UPGRADER_FLAGS_REDEPLOY;
|
||||
|
||||
self = (PkgDeleteTransaction *) transaction;
|
||||
sysroot = rpmostreed_transaction_get_sysroot (transaction);
|
||||
|
||||
if (self->dry_run)
|
||||
flags |= RPMOSTREE_SYSROOT_UPGRADER_FLAGS_PKGOVERLAY_DRY_RUN;
|
||||
|
||||
upgrader = rpmostree_sysroot_upgrader_new (sysroot, self->osname, flags,
|
||||
cancellable, error);
|
||||
if (upgrader == NULL)
|
||||
{
|
||||
if (error && *error == NULL)
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Could not create sysroot upgrader");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!rpmostree_sysroot_upgrader_delete_packages (upgrader, self->packages,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!rpmostree_sysroot_upgrader_deploy (upgrader, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (self->reboot)
|
||||
rpmostreed_reboot (cancellable, error);
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
pkg_delete_transaction_class_init (PkgDeleteTransactionClass *class)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
|
||||
object_class = G_OBJECT_CLASS (class);
|
||||
object_class->finalize = pkg_delete_transaction_finalize;
|
||||
|
||||
class->execute = pkg_delete_transaction_execute;
|
||||
}
|
||||
|
||||
static void
|
||||
pkg_delete_transaction_init (PkgDeleteTransaction *self)
|
||||
{
|
||||
}
|
||||
|
||||
RpmostreedTransaction *
|
||||
rpmostreed_transaction_new_pkg_delete (GDBusMethodInvocation *invocation,
|
||||
OstreeSysroot *sysroot,
|
||||
const char *osname,
|
||||
const char * const *packages,
|
||||
gboolean reboot,
|
||||
gboolean dry_run,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
PkgDeleteTransaction *self;
|
||||
|
||||
g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
|
||||
g_return_val_if_fail (OSTREE_IS_SYSROOT (sysroot), NULL);
|
||||
g_return_val_if_fail (osname != NULL, NULL);
|
||||
g_return_val_if_fail (packages != NULL, NULL);
|
||||
|
||||
self = g_initable_new (pkg_delete_transaction_get_type (),
|
||||
cancellable, error,
|
||||
"invocation", invocation,
|
||||
"sysroot-path", gs_file_get_path_cached (ostree_sysroot_get_path (sysroot)),
|
||||
NULL);
|
||||
|
||||
if (self != NULL)
|
||||
{
|
||||
self->osname = g_strdup (osname);
|
||||
self->packages = g_strdupv ((char**)packages);
|
||||
self->reboot = reboot;
|
||||
self->dry_run = dry_run;
|
||||
}
|
||||
|
||||
return (RpmostreedTransaction *) self;
|
||||
}
|
@ -79,5 +79,16 @@ RpmostreedTransaction *
|
||||
const char *osname,
|
||||
const char *const *packages,
|
||||
gboolean reboot,
|
||||
gboolean dry_run,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
RpmostreedTransaction *
|
||||
rpmostreed_transaction_new_pkg_delete (GDBusMethodInvocation *invocation,
|
||||
OstreeSysroot *sysroot,
|
||||
const char *osname,
|
||||
const char *const *packages,
|
||||
gboolean reboot,
|
||||
gboolean dry_run,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
@ -708,7 +708,7 @@ workaround_selinux_cross_labeling_recurse (int dfd,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gboolean
|
||||
rpmostree_prepare_rootfs_get_sepolicy (int dfd,
|
||||
const char *path,
|
||||
OstreeSePolicy **out_sepolicy,
|
||||
|
@ -36,6 +36,13 @@ rpmostree_rootfs_postprocess_common (int rootfs_fd,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
rpmostree_prepare_rootfs_get_sepolicy (int dfd,
|
||||
const char *path,
|
||||
OstreeSePolicy **out_sepolicy,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
rpmostree_prepare_rootfs_for_commit (GFile *rootfs,
|
||||
JsonObject *treefile,
|
||||
|
@ -703,6 +703,7 @@ rpmrev_free (struct RpmRevisionData *ptr)
|
||||
gboolean
|
||||
rpmostree_checkout_only_rpmdb_tempdir (OstreeRepo *repo,
|
||||
const char *ref,
|
||||
const char *template,
|
||||
char **out_tempdir,
|
||||
int *out_tempdir_dfd,
|
||||
GCancellable *cancellable,
|
||||
@ -716,7 +717,7 @@ rpmostree_checkout_only_rpmdb_tempdir (OstreeRepo *repo,
|
||||
|
||||
g_return_val_if_fail (out_tempdir != NULL, FALSE);
|
||||
|
||||
if (!rpmostree_mkdtemp ("/tmp/rpmostree-dbquery-XXXXXX", &tempdir, &tempdir_dfd, error))
|
||||
if (!rpmostree_mkdtemp (template, &tempdir, &tempdir_dfd, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_repo_resolve_rev (repo, ref, FALSE, &commit, error))
|
||||
@ -772,6 +773,8 @@ get_sack_for_root (int dfd,
|
||||
g_return_val_if_fail (out_sack != NULL, FALSE);
|
||||
|
||||
sack = hif_sack_new ();
|
||||
hif_sack_set_rootdir (sack, fullpath);
|
||||
|
||||
if (!hif_sack_setup (sack, HIF_SACK_LOAD_FLAG_BUILD_CACHE, error))
|
||||
goto out;
|
||||
|
||||
@ -814,7 +817,9 @@ rpmostree_get_refsack_for_commit (OstreeRepo *repo,
|
||||
glnx_fd_close int tempdir_dfd = -1;
|
||||
HifSack *hsack;
|
||||
|
||||
if (!rpmostree_checkout_only_rpmdb_tempdir (repo, ref, &tempdir, &tempdir_dfd,
|
||||
if (!rpmostree_checkout_only_rpmdb_tempdir (repo, ref,
|
||||
"/tmp/rpmostree-dbquery-XXXXXX",
|
||||
&tempdir, &tempdir_dfd,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
@ -842,7 +847,9 @@ rpmostree_get_refts_for_commit (OstreeRepo *repo,
|
||||
rpmts ts;
|
||||
int r;
|
||||
|
||||
if (!rpmostree_checkout_only_rpmdb_tempdir (repo, ref, &tempdir, NULL,
|
||||
if (!rpmostree_checkout_only_rpmdb_tempdir (repo, ref,
|
||||
"/tmp/rpmostree-dbquery-XXXXXX",
|
||||
&tempdir, NULL,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
|
@ -85,6 +85,7 @@ GS_DEFINE_CLEANUP_FUNCTION0(struct RpmRevisionData *, _cleanup_rpmrev_free, rpmr
|
||||
gboolean
|
||||
rpmostree_checkout_only_rpmdb_tempdir (OstreeRepo *repo,
|
||||
const char *ref,
|
||||
const char *template,
|
||||
char **out_tempdir,
|
||||
int *out_tempdir_dfd,
|
||||
GCancellable *cancellable,
|
||||
|
@ -427,7 +427,6 @@ _rpmostree_util_parse_origin (GKeyFile *origin,
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
g_autofree char *origin_refspec = NULL;
|
||||
g_auto(GStrv) origin_packages = NULL;
|
||||
gboolean origin_is_bare_refspec = TRUE;
|
||||
|
||||
origin_refspec = g_key_file_get_string (origin, "origin", "refspec", NULL);
|
||||
@ -443,13 +442,74 @@ _rpmostree_util_parse_origin (GKeyFile *origin,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (out_refspec)
|
||||
*out_refspec = g_steal_pointer (&origin_refspec);
|
||||
|
||||
if (out_packages)
|
||||
{
|
||||
if (origin_is_bare_refspec)
|
||||
*out_packages = NULL;
|
||||
else
|
||||
*out_packages = g_key_file_get_string_list (origin, "packages", "requested", NULL, NULL);
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
rpmostree_split_path_ptrarray_validate (const char *path,
|
||||
GPtrArray **out_components,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
g_autoptr(GPtrArray) ret_components = NULL;
|
||||
|
||||
if (strlen (path) > PATH_MAX)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Path '%s' is too long", path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret_components = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
do
|
||||
{
|
||||
const char *p = strchr (path, '/');
|
||||
g_autofree char *component = NULL;
|
||||
|
||||
if (!p)
|
||||
{
|
||||
component = g_strdup (path);
|
||||
path = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
component = g_strndup (path, p - path);
|
||||
path = p + 1;
|
||||
}
|
||||
|
||||
if (!component[0])
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Invalid empty component in path '%s'", path);
|
||||
goto out;
|
||||
}
|
||||
if (g_str_equal (component, ".") ||
|
||||
g_str_equal (component, ".."))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Invalid special element '.' or '..' in path %s", path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_ptr_array_add (ret_components, (char*)g_steal_pointer (&component));
|
||||
} while (path && *path);
|
||||
|
||||
ret = TRUE;
|
||||
*out_components = g_steal_pointer (&ret_components);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
@ -95,3 +95,8 @@ _rpmostree_util_parse_origin (GKeyFile *origin,
|
||||
char **out_refspec,
|
||||
char ***out_packages,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
rpmostree_split_path_ptrarray_validate (const char *path,
|
||||
GPtrArray **out_components,
|
||||
GError **error);
|
||||
|
Loading…
Reference in New Issue
Block a user