From e18919e0efad0cd4ff44e9d13a805bcd586d1449 Mon Sep 17 00:00:00 2001 From: Felix Krull Date: Sun, 18 Oct 2020 13:21:53 +0200 Subject: [PATCH] src: manually implement SysrootDeployTreeOpts --- rust-bindings/rust/conf/ostree.toml | 13 +++ rust-bindings/rust/src/auto/sysroot.rs | 28 ++++-- rust-bindings/rust/src/auto/versions.txt | 2 +- rust-bindings/rust/src/lib.rs | 4 + .../rust/src/sysroot_deploy_tree_opts.rs | 98 +++++++++++++++++++ rust-bindings/rust/sys/src/auto/versions.txt | 2 +- 6 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 rust-bindings/rust/src/sysroot_deploy_tree_opts.rs diff --git a/rust-bindings/rust/conf/ostree.toml b/rust-bindings/rust/conf/ostree.toml index a8ca3fb5..0cbdbb02 100644 --- a/rust-bindings/rust/conf/ostree.toml +++ b/rust-bindings/rust/conf/ostree.toml @@ -88,6 +88,7 @@ manual = [ "OSTree.RepoCheckoutAtOptions", "OSTree.RepoCheckoutFilter", "OSTree.SysrootWriteDeploymentsOpts", + "OSTree.SysrootDeployTreeOpts", ] ignore = [ @@ -208,6 +209,18 @@ status = "generate" [[object]] name = "OSTree.Sysroot" status = "generate" + [[object.function]] + name = "deploy_tree_with_options" + [[object.function.parameter]] + name = "opts" + const = true + + [[object.function]] + name = "stage_tree_with_options" + [[object.function.parameter]] + name = "opts" + const = true + [[object.function]] name = "write_deployments_with_options" [[object.function.parameter]] diff --git a/rust-bindings/rust/src/auto/sysroot.rs b/rust-bindings/rust/src/auto/sysroot.rs index b066af07..0326df9d 100644 --- a/rust-bindings/rust/src/auto/sysroot.rs +++ b/rust-bindings/rust/src/auto/sysroot.rs @@ -30,6 +30,8 @@ use Deployment; #[cfg(any(feature = "v2016_4", feature = "dox"))] use DeploymentUnlockedState; use Repo; +#[cfg(any(feature = "v2020_7", feature = "dox"))] +use SysrootDeployTreeOpts; use SysrootSimpleWriteDeploymentFlags; #[cfg(any(feature = "v2017_4", feature = "dox"))] use SysrootWriteDeploymentsOpts; @@ -78,10 +80,15 @@ impl Sysroot { } } - //#[cfg(any(feature = "v2020_7", feature = "dox"))] - //pub fn deploy_tree_with_options>(&self, osname: Option<&str>, revision: &str, origin: Option<&glib::KeyFile>, provided_merge_deployment: Option<&Deployment>, opts: /*Ignored*/Option<&mut SysrootDeployTreeOpts>, cancellable: Option<&P>) -> Result { - // unsafe { TODO: call ostree_sys:ostree_sysroot_deploy_tree_with_options() } - //} + #[cfg(any(feature = "v2020_7", feature = "dox"))] + pub fn deploy_tree_with_options>(&self, osname: Option<&str>, revision: &str, origin: Option<&glib::KeyFile>, provided_merge_deployment: Option<&Deployment>, opts: Option<&SysrootDeployTreeOpts>, cancellable: Option<&P>) -> Result { + unsafe { + let mut out_new_deployment = ptr::null_mut(); + let mut error = ptr::null_mut(); + let _ = ostree_sys::ostree_sysroot_deploy_tree_with_options(self.to_glib_none().0, osname.to_glib_none().0, revision.to_glib_none().0, origin.to_glib_none().0, provided_merge_deployment.to_glib_none().0, mut_override(opts.to_glib_none().0), &mut out_new_deployment, cancellable.map(|p| p.as_ref()).to_glib_none().0, &mut error); + if error.is_null() { Ok(from_glib_full(out_new_deployment)) } else { Err(from_glib_full(error)) } + } + } pub fn deployment_set_kargs>(&self, deployment: &Deployment, new_kargs: &[&str], cancellable: Option<&P>) -> Result<(), glib::Error> { unsafe { @@ -344,10 +351,15 @@ impl Sysroot { } } - //#[cfg(any(feature = "v2020_7", feature = "dox"))] - //pub fn stage_tree_with_options>(&self, osname: Option<&str>, revision: &str, origin: Option<&glib::KeyFile>, merge_deployment: Option<&Deployment>, opts: /*Ignored*/&mut SysrootDeployTreeOpts, cancellable: Option<&P>) -> Result { - // unsafe { TODO: call ostree_sys:ostree_sysroot_stage_tree_with_options() } - //} + #[cfg(any(feature = "v2020_7", feature = "dox"))] + pub fn stage_tree_with_options>(&self, osname: Option<&str>, revision: &str, origin: Option<&glib::KeyFile>, merge_deployment: Option<&Deployment>, opts: &SysrootDeployTreeOpts, cancellable: Option<&P>) -> Result { + unsafe { + let mut out_new_deployment = ptr::null_mut(); + let mut error = ptr::null_mut(); + let _ = ostree_sys::ostree_sysroot_stage_tree_with_options(self.to_glib_none().0, osname.to_glib_none().0, revision.to_glib_none().0, origin.to_glib_none().0, merge_deployment.to_glib_none().0, mut_override(opts.to_glib_none().0), &mut out_new_deployment, cancellable.map(|p| p.as_ref()).to_glib_none().0, &mut error); + if error.is_null() { Ok(from_glib_full(out_new_deployment)) } else { Err(from_glib_full(error)) } + } + } pub fn try_lock(&self) -> Result { unsafe { diff --git a/rust-bindings/rust/src/auto/versions.txt b/rust-bindings/rust/src/auto/versions.txt index ca6fe281..a7300e77 100644 --- a/rust-bindings/rust/src/auto/versions.txt +++ b/rust-bindings/rust/src/auto/versions.txt @@ -1,2 +1,2 @@ Generated by gir (https://github.com/gtk-rs/gir @ 2d1ffab1) -from gir-files (https://github.com/gtk-rs/gir-files @ 28a5895+) +from gir-files (https://github.com/gtk-rs/gir-files @ 2bdb1c1) diff --git a/rust-bindings/rust/src/lib.rs b/rust-bindings/rust/src/lib.rs index 17635ead..78352506 100644 --- a/rust-bindings/rust/src/lib.rs +++ b/rust-bindings/rust/src/lib.rs @@ -60,6 +60,10 @@ pub use crate::commit_sizes_entry::*; mod sysroot_write_deployments_opts; #[cfg(any(feature = "v2017_4", feature = "dox"))] pub use crate::sysroot_write_deployments_opts::*; +#[cfg(any(feature = "v2020_7", feature = "dox"))] +mod sysroot_deploy_tree_opts; +#[cfg(any(feature = "v2020_7", feature = "dox"))] +pub use crate::sysroot_deploy_tree_opts::SysrootDeployTreeOpts; // tests #[cfg(test)] diff --git a/rust-bindings/rust/src/sysroot_deploy_tree_opts.rs b/rust-bindings/rust/src/sysroot_deploy_tree_opts.rs new file mode 100644 index 00000000..040ab63d --- /dev/null +++ b/rust-bindings/rust/src/sysroot_deploy_tree_opts.rs @@ -0,0 +1,98 @@ +use glib::translate::*; +use libc::c_char; +use ostree_sys::OstreeSysrootDeployTreeOpts; + +pub struct SysrootDeployTreeOpts<'a> { + pub override_kernel_argv: Option<&'a [&'a str]>, + pub overlay_initrds: Option<&'a [&'a str]>, +} + +impl<'a> Default for SysrootDeployTreeOpts<'a> { + fn default() -> Self { + SysrootDeployTreeOpts { + override_kernel_argv: None, + overlay_initrds: None, + } + } +} + +type OptionStrSliceStorage<'a> = + as ToGlibPtr<'a, *mut *mut c_char>>::Storage; + +impl<'a, 'b: 'a> ToGlibPtr<'a, *const OstreeSysrootDeployTreeOpts> for SysrootDeployTreeOpts<'b> { + type Storage = ( + Box, + OptionStrSliceStorage<'a>, + OptionStrSliceStorage<'a>, + ); + + fn to_glib_none(&'a self) -> Stash<*const OstreeSysrootDeployTreeOpts, Self> { + // Creating this struct from zeroed memory is fine since it's `repr(C)` and only contains + // primitive types. Zeroing it ensures we handle the unused bytes correctly. + // The struct needs to be boxed so the pointer we return remains valid even as the Stash is + // moved around. + let mut options = Box::new(unsafe { std::mem::zeroed::() }); + let override_kernel_argv = self.override_kernel_argv.to_glib_none(); + let overlay_initrds = self.overlay_initrds.to_glib_none(); + options.override_kernel_argv = override_kernel_argv.0; + options.overlay_initrds = overlay_initrds.0; + Stash( + options.as_ref(), + (options, override_kernel_argv.1, overlay_initrds.1), + ) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::{ffi::CStr, ptr::null_mut}; + + unsafe fn ptr_array_as_slice<'a, T>(ptr: *mut *mut T) -> &'a [*mut T] { + let mut len = 0; + while !(*ptr.offset(len)).is_null() { + len += 1; + } + std::slice::from_raw_parts(ptr, len as usize) + } + + unsafe fn str_ptr_array_to_vec<'a>(ptr: *mut *mut c_char) -> Vec<&'a str> { + ptr_array_to_slice(ptr) + .iter() + .map(|x| CStr::from_ptr(*x).to_str().unwrap()) + .collect() + } + + #[test] + fn should_convert_default_options() { + let options = SysrootDeployTreeOpts::default(); + let stash = options.to_glib_none(); + let ptr = stash.0; + unsafe { + assert_eq!((*ptr).override_kernel_argv, null_mut()); + assert_eq!((*ptr).overlay_initrds, null_mut()); + } + } + + #[test] + fn should_convert_non_default_options() { + let override_kernel_argv = vec!["quiet", "splash", "ro"]; + let overlay_initrds = vec!["overlay1", "overlay2"]; + let options = SysrootDeployTreeOpts { + override_kernel_argv: Some(&override_kernel_argv), + overlay_initrds: Some(&overlay_initrds), + }; + let stash = options.to_glib_none(); + let ptr = stash.0; + unsafe { + assert_eq!( + str_ptr_array_to_vec((*ptr).override_kernel_argv), + vec!["quiet", "splash", "ro"] + ); + assert_eq!( + str_ptr_array_to_vec((*ptr).overlay_initrds), + vec!["overlay1", "overlay2"] + ); + } + } +} diff --git a/rust-bindings/rust/sys/src/auto/versions.txt b/rust-bindings/rust/sys/src/auto/versions.txt index ca6fe281..a7300e77 100644 --- a/rust-bindings/rust/sys/src/auto/versions.txt +++ b/rust-bindings/rust/sys/src/auto/versions.txt @@ -1,2 +1,2 @@ Generated by gir (https://github.com/gtk-rs/gir @ 2d1ffab1) -from gir-files (https://github.com/gtk-rs/gir-files @ 28a5895+) +from gir-files (https://github.com/gtk-rs/gir-files @ 2bdb1c1)