Skip to content

Commit

Permalink
Add register-driver option to UpdateDeployment D-Bus API
Browse files Browse the repository at this point in the history
Record the agent id and agent systemd unit and serialize it into a
JSON file at `/run/rpmostree/update-driver.json`.

Also add the companion `--register-driver` option to the `deploy`
CLI argument.

Closes coreos#1747.
  • Loading branch information
kelvinfan001 committed Jan 21, 2021
1 parent 7586503 commit d6ced1a
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/app/rpmostree-builtin-deploy.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ static gboolean opt_download_only;
static gboolean opt_lock_finalization;
static gboolean opt_disallow_downgrade;
static gboolean opt_unchanged_exit_77;
static gboolean opt_register_driver;

static GOptionEntry option_entries[] = {
{ "os", 0, 0, G_OPTION_ARG_STRING, &opt_osname, "Operate on provided OSNAME", "OSNAME" },
Expand All @@ -49,6 +50,7 @@ static GOptionEntry option_entries[] = {
{ "lock-finalization", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_lock_finalization, "Prevent automatic deployment finalization on shutdown", NULL },
{ "disallow-downgrade", 0, 0, G_OPTION_ARG_NONE, &opt_disallow_downgrade, "Forbid deployment of chronologically older trees", NULL },
{ "unchanged-exit-77", 0, 0, G_OPTION_ARG_NONE, &opt_unchanged_exit_77, "If no new deployment made, exit 77", NULL },
{ "register-driver", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_register_driver, "Register the calling agent as the driver for updates", NULL },
{ NULL }
};

Expand Down Expand Up @@ -125,6 +127,7 @@ rpmostree_builtin_deploy (int argc,
g_variant_dict_insert (&dict, "download-only", "b", opt_download_only);
g_variant_dict_insert (&dict, "lock-finalization", "b", opt_lock_finalization);
g_variant_dict_insert (&dict, "initiating-command-line", "s", invocation->command_line);
g_variant_dict_insert (&dict, "register-driver", "b", opt_register_driver);
g_autoptr(GVariant) options = g_variant_ref_sink (g_variant_dict_end (&dict));

/* Use newer D-Bus API only if we have to so we maintain coverage. */
Expand Down
2 changes: 2 additions & 0 deletions src/daemon/org.projectatomic.rpmostree1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,8 @@
Stop short of deploying the new tree. If layering packages,
the pkg diff is printed but packages are not downloaded or
imported.
"register-driver" (type 'b')
Register the caller as the update driver.
"no-layering" (type 'b')
Remove all package requests. Requests in "install-packages"
are still subsequently processed if specified.
Expand Down
6 changes: 6 additions & 0 deletions src/daemon/rpmostreed-daemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ G_BEGIN_DECLS
#define DBUS_NAME "org.projectatomic.rpmostree1"
#define BASE_DBUS_PATH "/org/projectatomic/rpmostree1"

/* Update driver info */
#define RPMOSTREE_RUN_DIR "/run/rpm-ostree/"
#define RPMOSTREE_DRIVER_STATE RPMOSTREE_RUN_DIR "update-driver.gv"
#define RPMOSTREE_DRIVER_AGENT_SD_UNIT "agent-sd-unit"
#define RPMOSTREE_DRIVER_AGENT_ID "agent-id"

GType rpmostreed_daemon_get_type (void) G_GNUC_CONST;
RpmostreedDaemon * rpmostreed_daemon_get (void);
gboolean rpmostreed_get_client_uid (RpmostreedDaemon *self,
Expand Down
80 changes: 80 additions & 0 deletions src/daemon/rpmostreed-transaction-types.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@
#include "config.h"
#include "ostree.h"

#include <json-glib/json-glib.h>
#include <gio/gunixoutputstream.h>
#include <libglnx.h>
#include <systemd/sd-journal.h>

#include "rpmostreed-transaction-types.h"
#include "rpmostreed-transaction.h"
#include "rpmostreed-deployment-utils.h"
#include "rpmostreed-sysroot.h"
#include "rpmostreed-daemon.h"
#include "rpmostree-sysroot-upgrader.h"
#include "rpmostree-sysroot-core.h"
#include "rpmostree-rpm-util.h"
Expand Down Expand Up @@ -787,6 +790,74 @@ deploy_has_bool_option (DeployTransaction *self,
return vardict_lookup_bool (self->options, option, FALSE);
}

/* Write a state file which records information about the agent that is "driving" updates */
static gboolean
record_driver_info (const char *id,
const char *sd_unit,
GCancellable *cancellable,
GError **error)
{
g_auto(GVariantBuilder) caller_info_builder;
g_variant_builder_init (&caller_info_builder, G_VARIANT_TYPE ("a{sv}"));

if (id)
g_variant_builder_add (&caller_info_builder, "{sv}", RPMOSTREE_DRIVER_AGENT_ID,
g_variant_new_string (id));
if (sd_unit)
g_variant_builder_add (&caller_info_builder, "{sv}", RPMOSTREE_DRIVER_AGENT_SD_UNIT,
g_variant_new_string (sd_unit));

g_autoptr(GVariant) driver_info =
g_variant_ref_sink (g_variant_builder_end (&caller_info_builder));

if (!glnx_shutil_mkdir_p_at (AT_FDCWD, RPMOSTREE_RUN_DIR, 0755, cancellable, error))
return FALSE;
if (!glnx_file_replace_contents_at (AT_FDCWD, RPMOSTREE_DRIVER_STATE,
static_cast<const guint8*>(g_variant_get_data (driver_info)),
g_variant_get_size (driver_info),
static_cast<GLnxFileReplaceFlags>(0), cancellable, error))
return FALSE;

return TRUE;
}

/* Read from state file that records information about the agent that is "driving" updates */
gboolean
get_driver_info (char **id,
char **sd_unit,
GError **error)
{
glnx_autofd int fd = -1;
g_autoptr(GError) local_error = NULL;
if (!glnx_openat_rdonly (AT_FDCWD, RPMOSTREE_DRIVER_STATE, TRUE, &fd,
&local_error))
{
if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
return g_propagate_error (error, util::move_nullify (local_error)), FALSE;
return TRUE;
}

g_autoptr(GBytes) data = glnx_fd_readall_bytes (fd, NULL, error);
if (!data)
return FALSE;

g_autoptr(GVariant) driver_info =
g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE_VARDICT, data, FALSE));

g_auto(GVariantDict) driver_info_dict;
g_variant_dict_init (&driver_info_dict, driver_info);
auto v = static_cast<char*>(vardict_lookup_ptr (&driver_info_dict,
RPMOSTREE_DRIVER_AGENT_ID, "s"));
if (v)
*id = v;
v = static_cast<char*>(vardict_lookup_ptr (&driver_info_dict,
RPMOSTREE_DRIVER_AGENT_SD_UNIT, "s"));
if (v)
*sd_unit = v;

return TRUE;
}

static gboolean
deploy_transaction_execute (RpmostreedTransaction *transaction,
GCancellable *cancellable,
Expand All @@ -797,6 +868,7 @@ deploy_transaction_execute (RpmostreedTransaction *transaction,

const gboolean dry_run =
((self->flags & RPMOSTREE_TRANSACTION_DEPLOY_FLAG_DRY_RUN) > 0);
const gboolean register_driver = deploy_has_bool_option (self, "register-driver");
const gboolean no_overrides = deploy_has_bool_option (self, "no-overrides");
const gboolean no_layering = deploy_has_bool_option (self, "no-layering");
const gboolean no_initramfs = deploy_has_bool_option (self, "no-initramfs");
Expand Down Expand Up @@ -1332,6 +1404,14 @@ deploy_transaction_execute (RpmostreedTransaction *transaction,
return FALSE;
changed = changed || layering_changed;

if (register_driver)
{
if (!record_driver_info (rpmostreed_transaction_get_agent_id (transaction),
rpmostreed_transaction_get_sd_unit (transaction),
cancellable, error))
return FALSE;
}

if (dry_run)
/* Note early return here; we printed the transaction already */
return TRUE;
Expand Down
5 changes: 5 additions & 0 deletions src/daemon/rpmostreed-transaction-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,8 @@ rpmostreed_transaction_new_kernel_arg (GDBusMethodInvocation *invocation,
GError **error);

G_END_DECLS

gboolean
get_driver_info (char **id,
char **sd_unit,
GError **error);

0 comments on commit d6ced1a

Please sign in to comment.