daemon: Move some "deployment variant" generation to Rust

More prep for https://github.com/coreos/rpm-ostree/pull/2388

This was actually also my first time really trying out the
latest gtk-rs `glib::Variant` API, which is one of the major
things we need to use to progress oxidation more.
This commit is contained in:
Colin Walters 2021-02-23 14:11:48 +00:00 committed by OpenShift Merge Robot
parent 6cf0f87412
commit d8230bfb6d
5 changed files with 62 additions and 36 deletions

View File

@ -100,13 +100,20 @@ bind_ostree_obj!(Deployment);
// try to instead create a bind_gio_obj!() macro or so.
#[repr(transparent)]
pub struct FFIGCancellable(gio_sys::GCancellable);
unsafe impl ExternType for FFIGCancellable {
type Id = type_id!(rpmostreecxx::GCancellable);
type Kind = cxx::kind::Trivial;
}
impl_wrap!(FFIGCancellable, gio::Cancellable, gio_sys::GCancellable);
#[repr(transparent)]
pub struct FFIGVariantDict(glib_sys::GVariantDict);
unsafe impl ExternType for FFIGVariantDict {
type Id = type_id!(rpmostreecxx::GVariantDict);
type Kind = cxx::kind::Trivial;
}
impl_wrap!(FFIGVariantDict, glib::VariantDict, glib_sys::GVariantDict);
// An error type helper; separate from the GObject bridging
mod err {
use std::error::Error as StdError;

View File

@ -20,3 +20,49 @@ pub(crate) fn deployment_generate_id(
deployment.get_deployserial()
)
}
pub(crate) fn deployment_populate_variant(
mut sysroot: Pin<&mut crate::FFIOstreeSysroot>,
mut deployment: Pin<&mut crate::FFIOstreeDeployment>,
mut dict: Pin<&mut crate::FFIGVariantDict>,
) -> CxxResult<()> {
let sysroot = &sysroot.gobj_wrap();
let deployment = &deployment.gobj_wrap();
let dict = dict.gobj_wrap();
let id = deployment_generate_id(deployment.gobj_rewrap());
// First, basic values from ostree
dict.insert("id", &id);
dict.insert("osname", &deployment.get_osname().expect("osname").as_str());
dict.insert("checksum", &deployment.get_csum().expect("csum").as_str());
dict.insert_value(
"serial",
&glib::Variant::from(deployment.get_deployserial() as i32),
);
let booted: bool = sysroot
.get_booted_deployment()
.map(|b| b.equal(deployment))
.unwrap_or_default();
dict.insert("booted", &booted);
let live_state =
crate::live::get_live_apply_state(sysroot.gobj_rewrap(), deployment.gobj_rewrap())?;
if !live_state.inprogress.is_empty() {
dict.insert("live-inprogress", &live_state.inprogress.as_str());
}
if !live_state.commit.is_empty() {
dict.insert("live-replaced", &live_state.commit.as_str());
}
/* Staging status */
if deployment.is_staged() {
dict.insert("staged", &true);
if std::path::Path::new("/run/ostree/staged-deployment-locked").exists() {
dict.insert("finalization-locked", &true);
}
}
Ok(())
}

View File

@ -37,6 +37,7 @@ pub mod ffi {
type OstreeRepo = crate::FFIOstreeRepo;
type OstreeDeployment = crate::FFIOstreeDeployment;
type GCancellable = crate::FFIGCancellable;
type GVariantDict = crate::FFIGVariantDict;
}
/// Currently cxx-rs doesn't support mappings; like probably most projects,
@ -80,6 +81,11 @@ pub mod ffi {
// daemon.rs
extern "Rust" {
fn deployment_generate_id(deployment: Pin<&mut OstreeDeployment>) -> String;
fn deployment_populate_variant(
mut sysroot: Pin<&mut OstreeSysroot>,
mut deployment: Pin<&mut OstreeDeployment>,
mut dict: Pin<&mut GVariantDict>,
) -> Result<()>;
}
// initramfs.rs

View File

@ -235,42 +235,8 @@ rpmostreed_deployment_generate_variant (OstreeSysroot *sysroot,
GVariantDict dict;
g_variant_dict_init (&dict, NULL);
/* First, basic values from ostree */
auto id = rpmostreecxx::deployment_generate_id (*deployment);
g_variant_dict_insert (&dict, "id", "s", id.c_str());
const gchar *osname = ostree_deployment_get_osname (deployment);
if (osname != NULL)
g_variant_dict_insert (&dict, "osname", "s", osname);
rpmostreecxx::deployment_populate_variant(*sysroot, *deployment, dict);
const gchar *csum = ostree_deployment_get_csum (deployment);
g_variant_dict_insert (&dict, "checksum", "s", csum);
gint serial = ostree_deployment_get_deployserial (deployment);
g_variant_dict_insert (&dict, "serial", "i", serial);
/* Booted status */
const gboolean is_booted = g_strcmp0 (booted_id, id.c_str()) == 0;
if (booted_id != NULL)
g_variant_dict_insert (&dict, "booted", "b", is_booted);
if (is_booted)
{
auto live_state = rpmostreecxx::get_live_apply_state(*sysroot, *deployment);
if (live_state.inprogress.length() > 0)
g_variant_dict_insert (&dict, "live-inprogress", "s", live_state.inprogress.c_str());
if (live_state.commit.length() > 0)
g_variant_dict_insert (&dict, "live-replaced", "s", live_state.commit.c_str());
}
/* Staging status */
if (ostree_deployment_is_staged (deployment))
{
g_variant_dict_insert (&dict, "staged", "b", TRUE);
if (!glnx_fstatat_allow_noent (AT_FDCWD, _OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED,
NULL, 0, error))
return FALSE;
g_variant_dict_insert (&dict, "finalization-locked", "b", errno == 0);
}
/* Load the commit object */
g_autoptr(GVariant) commit = NULL;
if (!ostree_repo_load_variant (repo,

View File

@ -29,4 +29,5 @@ namespace rpmostreecxx {
typedef ::OstreeRepo OstreeRepo;
typedef ::OstreeDeployment OstreeDeployment;
typedef ::GCancellable GCancellable;
typedef ::GVariantDict GVariantDict;
}