Skip to content

Commit

Permalink
Merge pull request coreos#3526 from lucab/ups/daemon-dbus-deployment-…
Browse files Browse the repository at this point in the history
…lookup-rust
  • Loading branch information
jlebon authored Mar 22, 2022
2 parents 7a8f637 + 17aafc6 commit 56f2dcf
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 62 deletions.
18 changes: 1 addition & 17 deletions rust/src/daemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,6 @@ pub(crate) fn daemon_sanitycheck_environment(
Ok(())
}

/// Get a currently unique (for this host) identifier for the
/// deployment; TODO - adding the deployment timestamp would make it
/// persistently unique, needs API in libostree.
pub(crate) fn deployment_generate_id(
mut deployment: Pin<&mut crate::FFIOstreeDeployment>,
) -> String {
let deployment = deployment.gobj_wrap();
// unwrap safety: These can't actually return NULL
format!(
"{}-{}.{}",
deployment.osname().unwrap(),
deployment.csum().unwrap(),
deployment.deployserial()
)
}

/// Insert values from `v` into the target `dict` with key `k`.
fn vdict_insert_strv<'a>(dict: &glib::VariantDict, k: &str, v: impl IntoIterator<Item = &'a str>) {
// TODO: drive this into variant_utils in ostree-rs-ext so we don't need
Expand Down Expand Up @@ -150,7 +134,7 @@ pub(crate) fn deployment_populate_variant(
let deployment = &deployment.gobj_wrap();
let dict = dict.gobj_wrap();

let id = deployment_generate_id(deployment.gobj_rewrap());
let id = crate::deployment_generate_id_impl(deployment);
// First, basic values from ostree
dict.insert("id", &id);

Expand Down
98 changes: 98 additions & 0 deletions rust/src/deployment_utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//! Helper logic for handling deployments.
// SPDX-License-Identifier: Apache-2.0 OR MIT

use crate::cxxrsutil::*;
use anyhow::{anyhow, format_err, Result};
use ostree_ext::glib::translate::*;
use ostree_ext::ostree;
use std::pin::Pin;

/// Get a currently unique (for this host) identifier for the deployment.
// TODO - adding the deployment timestamp would make it
// persistently unique, needs API in libostree.
pub fn deployment_generate_id(mut deployment: Pin<&mut crate::FFIOstreeDeployment>) -> String {
let deployment = deployment.gobj_wrap();
deployment_generate_id_impl(&deployment)
}

pub(crate) fn deployment_generate_id_impl(deployment: &ostree::Deployment) -> String {
// SAFETY: the results of these are not-nullable in the C API.
format!(
"{}-{}.{}",
deployment.osname().unwrap(),
deployment.csum().unwrap(),
deployment.deployserial()
)
}

pub fn deployment_for_id(
mut ffi_sysroot: Pin<&mut crate::ffi::OstreeSysroot>,
deploy_id: &str,
) -> CxxResult<*mut crate::FFIOstreeDeployment> {
let sysroot = &ffi_sysroot.gobj_wrap();

let deployment = deployment_for_id_impl(sysroot, deploy_id)?;

let depl_ptr: *mut ostree::ffi::OstreeDeployment = deployment.to_glib_full();
Ok(depl_ptr as *mut _)
}

fn deployment_for_id_impl(
sysroot: &ostree::Sysroot,
deploy_id: &str,
) -> Result<ostree::Deployment> {
if deploy_id.is_empty() {
return Err(anyhow!("empty deployment ID"));
}

for depl_entry in sysroot.deployments() {
let id = deployment_generate_id_impl(&depl_entry);
if deploy_id == id {
return Ok(depl_entry);
}
}

Err(anyhow!("Deployment with id '{}' not found", deploy_id))
}

pub fn deployment_checksum_for_id(
mut ffi_sysroot: Pin<&mut crate::ffi::OstreeSysroot>,
deploy_id: &str,
) -> CxxResult<String> {
let sysroot = &ffi_sysroot.gobj_wrap();

let deployment = deployment_for_id_impl(&sysroot, deploy_id)?;
// SAFETY: result is not-nullable in the C API.
let csum = deployment.csum().unwrap();
Ok(csum.to_string())
}

pub fn deployment_get_base(
mut ffi_sysroot: Pin<&mut crate::ffi::OstreeSysroot>,
opt_deploy_id: &str,
opt_os_name: &str,
) -> CxxResult<*mut crate::FFIOstreeDeployment> {
let sysroot = &ffi_sysroot.gobj_wrap();
let deploy_id = opt_string(opt_deploy_id);
let os_name = opt_string(opt_os_name);

let deployment = deployment_get_base_impl(&sysroot, deploy_id, os_name)?;

let depl_ptr: *mut ostree::ffi::OstreeDeployment = deployment.to_glib_full();
Ok(depl_ptr as *mut _)
}

fn deployment_get_base_impl(
sysroot: &ostree::Sysroot,
deploy_id: Option<&str>,
os_name: Option<&str>,
) -> Result<ostree::Deployment> {
match deploy_id {
Some(id) => deployment_for_id_impl(sysroot, id),
None => sysroot.merge_deployment(os_name).ok_or_else(|| {
let name = os_name.unwrap_or_default();
format_err!("No deployments found for os '{}'", name)
}),
}
}
22 changes: 21 additions & 1 deletion rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,24 @@ pub mod ffi {
fn directory_size(dfd: i32, mut cancellable: Pin<&mut GCancellable>) -> Result<u64>;
}

// deployment_utils.rs
extern "Rust" {
fn deployment_for_id(
sysroot: Pin<&mut OstreeSysroot>,
deploy_id: &str,
) -> Result<*mut OstreeDeployment>;
fn deployment_checksum_for_id(
sysroot: Pin<&mut OstreeSysroot>,
deploy_id: &str,
) -> Result<String>;
fn deployment_get_base(
sysroot: Pin<&mut OstreeSysroot>,
opt_deploy_id: &str,
opt_os_name: &str,
) -> Result<*mut OstreeDeployment>;

}

// A grab-bag of metadata from the deployment's ostree commit
// around layering/derivation
#[derive(Debug, Default)]
Expand Down Expand Up @@ -718,9 +736,11 @@ mod core;
use crate::core::*;
mod capstdext;
mod daemon;
pub(crate) use daemon::*;
mod deployment_utils;
pub(crate) use deployment_utils::*;
mod dirdiff;
pub mod failpoint_bridge;
pub(crate) use daemon::*;
use failpoint_bridge::*;
mod extensions;
pub(crate) use extensions::*;
Expand Down
19 changes: 0 additions & 19 deletions src/daemon/rpmostreed-deployment-utils.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,6 @@
#include "rpmostreed-errors.h"
#include "rpmostreed-utils.h"

gboolean
rpmostreed_deployment_get_for_id (OstreeSysroot *sysroot, const gchar *deploy_id,
OstreeDeployment **out_deployment, GError **error)
{
g_autoptr (GPtrArray) deployments = ostree_sysroot_get_deployments (sysroot);
for (guint i = 0; i < deployments->len; i++)
{
auto deployment = static_cast<OstreeDeployment *> (deployments->pdata[i]);
auto id = rpmostreecxx::deployment_generate_id (*deployment);
if (g_strcmp0 (deploy_id, id.c_str ()) == 0)
{
*out_deployment = (OstreeDeployment *)g_object_ref (deployment);
return TRUE;
}
}

return glnx_throw (error, "Deployment with id '%s' not found", deploy_id);
}

/* rpmostreed_deployment_get_for_index:
*
* sysroot: A #OstreeSysroot instance
Expand Down
3 changes: 0 additions & 3 deletions src/daemon/rpmostreed-deployment-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ G_BEGIN_DECLS

char *rpmostreed_deployment_generate_id (OstreeDeployment *deployment);

gboolean rpmostreed_deployment_get_for_id (OstreeSysroot *sysroot, const gchar *deploy_id,
OstreeDeployment **out_deployment, GError **error);

OstreeDeployment *rpmostreed_deployment_get_for_index (OstreeSysroot *sysroot, const gchar *index,
GError **error);

Expand Down
31 changes: 9 additions & 22 deletions src/daemon/rpmostreed-os.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -339,28 +339,23 @@ get_deployments_rpm_diff (const char *arg_deployid0, const char *arg_deployid1,
{
g_autoptr (GCancellable) cancellable = NULL;
RpmostreedSysroot *global_sysroot;
glnx_unref_object OstreeDeployment *deployment0 = NULL;
glnx_unref_object OstreeDeployment *deployment1 = NULL;
OstreeSysroot *ot_sysroot = NULL;
OstreeRepo *ot_repo = NULL;
g_autoptr (GVariant) value = NULL;
const gchar *ref0;
const gchar *ref1;

global_sysroot = rpmostreed_sysroot_get ();

ot_sysroot = rpmostreed_sysroot_get_root (global_sysroot);
ot_repo = rpmostreed_sysroot_get_repo (global_sysroot);

if (!rpmostreed_deployment_get_for_id (ot_sysroot, arg_deployid0, &deployment0, error))
return FALSE;
ref0 = ostree_deployment_get_csum (deployment0);
rust::Str deploy_id0 (arg_deployid0 ?: "");
auto ref0 = ROSCXX_TRY_VAL (deployment_checksum_for_id (*ot_sysroot, deploy_id0), error);

if (!rpmostreed_deployment_get_for_id (ot_sysroot, arg_deployid1, &deployment1, error))
return FALSE;
ref1 = ostree_deployment_get_csum (deployment1);
rust::Str deploy_id1 (arg_deployid1 ?: "");
auto ref1 = ROSCXX_TRY_VAL (deployment_checksum_for_id (*ot_sysroot, deploy_id1), error);

if (!rpm_ostree_db_diff_variant (ot_repo, ref0, ref1, FALSE, &value, cancellable, error))
if (!rpm_ostree_db_diff_variant (ot_repo, ref0.c_str (), ref1.c_str (), FALSE, &value,
cancellable, error))
return FALSE;

*out_value = util::move_nullify (value);
Expand Down Expand Up @@ -406,17 +401,9 @@ get_cached_update_rpm_diff (const gchar *name, const char *arg_deployid, GVarian
ot_sysroot = rpmostreed_sysroot_get_root (global_sysroot);
ot_repo = rpmostreed_sysroot_get_repo (global_sysroot);

if (arg_deployid == NULL || arg_deployid[0] == '\0')
{
base_deployment = ostree_sysroot_get_merge_deployment (ot_sysroot, name);
if (base_deployment == NULL)
return glnx_throw (error, "No deployments found for os %s", name);
}
else
{
if (!rpmostreed_deployment_get_for_id (ot_sysroot, arg_deployid, &base_deployment, error))
return FALSE;
}
rust::Str os_name (name ?: "");
rust::Str deploy_id (arg_deployid ?: "");
base_deployment = ROSCXX_TRY_VAL (deployment_get_base (*ot_sysroot, deploy_id, os_name), error);

origin = rpmostree_origin_parse_deployment (base_deployment, error);
if (!origin)
Expand Down

0 comments on commit 56f2dcf

Please sign in to comment.