diff --git a/rust/src/cxxrsutil.rs b/rust/src/cxxrsutil.rs index 17023e21..97247c0c 100644 --- a/rust/src/cxxrsutil.rs +++ b/rust/src/cxxrsutil.rs @@ -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; diff --git a/rust/src/daemon.rs b/rust/src/daemon.rs index b348d7f7..54958682 100644 --- a/rust/src/daemon.rs +++ b/rust/src/daemon.rs @@ -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(()) +} diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 03ff982c..8e8e1b1d 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -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 diff --git a/src/daemon/rpmostreed-deployment-utils.cxx b/src/daemon/rpmostreed-deployment-utils.cxx index 6cc3c794..71558efe 100644 --- a/src/daemon/rpmostreed-deployment-utils.cxx +++ b/src/daemon/rpmostreed-deployment-utils.cxx @@ -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, diff --git a/src/libpriv/rpmostree-cxxrs-prelude.h b/src/libpriv/rpmostree-cxxrs-prelude.h index 96585b42..45568bb8 100644 --- a/src/libpriv/rpmostree-cxxrs-prelude.h +++ b/src/libpriv/rpmostree-cxxrs-prelude.h @@ -29,4 +29,5 @@ namespace rpmostreecxx { typedef ::OstreeRepo OstreeRepo; typedef ::OstreeDeployment OstreeDeployment; typedef ::GCancellable GCancellable; + typedef ::GVariantDict GVariantDict; }