Skip to content

Commit

Permalink
WIP fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
lukewarmtemp committed Apr 26, 2024
1 parent 4e0e48d commit 6b2f0fc
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 69 deletions.
14 changes: 7 additions & 7 deletions lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
}
} else {
let fetched = crate::deploy::pull(sysroot, imgref, opts.quiet).await?;
let mut kargs = crate::deploy::get_kargs(repo, fetched.as_ref())?;
let kargs = crate::kargs::get_kargs(repo, &booted_deployment, fetched.as_ref())?;
let staged_digest = staged_image.as_ref().map(|s| s.image_digest.as_str());
let fetched_digest = fetched.manifest_digest.as_str();
tracing::debug!("staged: {staged_digest:?}");
Expand All @@ -380,7 +380,7 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
} else {
let osname = booted_deployment.osname();
let mut opts = ostree::SysrootDeployTreeOpts::default();
let kargs: Vec<&str> = kargs.iter_mut().map(|s| s.as_str() ).collect();
let kargs: Vec<&str> = kargs.iter().map(|s| s.as_str() ).collect();
opts.override_kernel_argv = Some(kargs.as_slice());
crate::deploy::stage(sysroot, &osname, &fetched, &spec, Some(opts)).await?;
changed = true;
Expand Down Expand Up @@ -455,7 +455,7 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
let new_spec = RequiredHostSpec::from_spec(&new_spec)?;

let fetched = crate::deploy::pull(sysroot, &target, opts.quiet).await?;
let mut kargs = crate::deploy::get_kargs(repo, fetched.as_ref())?;
let kargs = crate::kargs::get_kargs(repo, &booted_deployment, fetched.as_ref())?;

if !opts.retain {
// By default, we prune the previous ostree ref so it will go away after later upgrades
Expand All @@ -470,7 +470,7 @@ async fn switch(opts: SwitchOpts) -> Result<()> {

let stateroot = booted_deployment.osname();
let mut opts = ostree::SysrootDeployTreeOpts::default();
let kargs: Vec<&str> = kargs.iter_mut().map(|s| s.as_str() ).collect();
let kargs: Vec<&str> = kargs.iter().map(|s| s.as_str() ).collect();
opts.override_kernel_argv = Some(kargs.as_slice());
crate::deploy::stage(sysroot, &stateroot, &fetched, &new_spec, Some(opts)).await?;

Expand All @@ -497,18 +497,18 @@ async fn edit(opts: EditOpts) -> Result<()> {

if new_host.spec == host.spec {
println!("Edit cancelled, no changes made.");
return Ok(());
return Ok(());
}
let new_spec = RequiredHostSpec::from_spec(&new_host.spec)?;
let fetched = crate::deploy::pull(sysroot, new_spec.image, opts.quiet).await?;
let repo = &sysroot.repo();
let mut kargs = crate::deploy::get_kargs(repo, fetched.as_ref())?;
let kargs = crate::kargs::get_kargs(repo, &booted_deployment, fetched.as_ref())?;

// TODO gc old layers here

let stateroot = booted_deployment.osname();
let mut opts = ostree::SysrootDeployTreeOpts::default();
let kargs: Vec<&str> = kargs.iter_mut().map(|s| s.as_str() ).collect();
let kargs: Vec<&str> = kargs.iter().map(|s| s.as_str() ).collect();
opts.override_kernel_argv = Some(kargs.as_slice());
crate::deploy::stage(sysroot, &stateroot, &fetched, &new_spec, Some(opts)).await?;

Expand Down
63 changes: 1 addition & 62 deletions lib/src/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,9 @@ use ostree::{gio, glib};
use ostree_container::OstreeImageReference;
use ostree_ext::container as ostree_container;
use ostree_ext::container::store::PrepareResult;
use ostree_ext::ostree;
use ostree_ext::ostree::{self};
use ostree_ext::ostree::Deployment;
use ostree_ext::sysroot::SysrootLock;
use ostree_ext::prelude::FileExt;
use ostree_ext::prelude::Cast;
use ostree_ext::prelude::FileEnumeratorExt;

use crate::spec::HostSpec;
use crate::spec::ImageReference;
Expand Down Expand Up @@ -347,64 +344,6 @@ pub(crate) fn switch_origin_inplace(root: &Dir, imgref: &ImageReference) -> Resu
Ok(newest_deployment)
}

pub fn get_kargs(repo: &ostree::Repo, fetched: &ImageState) -> Result<Vec<String>> {
let cancellable = gio::Cancellable::NONE;

// Get the running kernel commandline arguments
let kargs = ostree::KernelArgs::new();
ostree::KernelArgs::append_proc_cmdline(
&kargs,
cancellable,
)?;
let mut kargs: Vec<String> = kargs.to_strv().iter().map(|s| { s.as_str().to_string() }).collect();

// Get the kargs in kargs.d of the booted system
let mut existing_kargs = vec![];
let fragments = liboverdrop::scan(&["/usr/lib"], "bootc/kargs.d", &["toml"], true);
for (_name, path) in fragments {
let buffer = std::fs::read_to_string(&path)?;
existing_kargs.push(buffer.trim().to_string());
}

// Get the kargs in kargs.d of the remote image
let mut remote_kargs = vec![];
let (fetched_tree, _) = repo.read_commit(fetched.ostree_commit.as_str(), cancellable)?;
let fetched_tree = fetched_tree.resolve_relative_path("/usr/lib/bootc/kargs.d");
let fetched_tree = fetched_tree.downcast::<ostree::RepoFile>().expect("downcast");
match fetched_tree.query_exists(cancellable) {
true => {}
false => {
return Ok(vec![]);
}
}
let queryattrs = "standard::name,standard::type";
let queryflags = gio::FileQueryInfoFlags::NOFOLLOW_SYMLINKS;
let fetched_iter = fetched_tree.enumerate_children(queryattrs, queryflags, cancellable)?;
while let Some(fetched_info) = fetched_iter.next_file(cancellable)? {
let fetched_child = fetched_iter.child(&fetched_info);
let fetched_child = fetched_child.downcast::<ostree::RepoFile>().expect("downcast");
fetched_child.ensure_resolved()?;
let fetched_contents_checksum = fetched_child.checksum();
let f = ostree::Repo::load_file(repo, fetched_contents_checksum.as_str(), cancellable)?;
let file_content = f.0;
let mut buffer = vec![];
let mut reader = ostree_ext::prelude::InputStreamExtManual::into_read(file_content.unwrap());
let _ = std::io::Read::read_to_end(&mut reader, &mut buffer);
let s = std::string::String::from_utf8(buffer)?;
remote_kargs.push(s.trim().to_string());
}

// get the diff between the existing and remote kargs
let mut added_kargs: Vec<String> = remote_kargs.clone().into_iter().filter(|item| !existing_kargs.contains(item)).collect();
let removed_kargs: Vec<String> = existing_kargs.clone().into_iter().filter(|item| !remote_kargs.contains(item)).collect();

// apply the diff to the system kargs
kargs.retain(|x| !removed_kargs.contains(x));
kargs.append(&mut added_kargs);

Ok(kargs)
}

#[test]
fn test_switch_inplace() -> Result<()> {
use cap_std::fs::DirBuilderExt;
Expand Down
99 changes: 99 additions & 0 deletions lib/src/kargs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use anyhow::Ok;
use anyhow::Result;

use ostree::gio;
use ostree_ext::ostree;
use ostree_ext::ostree::Deployment;
use crate::deploy::ImageState;
use ostree_ext::prelude::FileExt;
use ostree_ext::prelude::Cast;
use ostree_ext::prelude::FileEnumeratorExt;

use serde::Deserialize;

#[derive(Deserialize)]
struct Config {
kargs: Vec<String>,
supported: Supported,
}

#[derive(Deserialize)]
struct Supported {
architecture: String,
}

pub(crate) fn get_kargs(repo: &ostree::Repo, booted_deployment: &Deployment, fetched: &ImageState) -> Result<Vec<String>> {
let cancellable = gio::Cancellable::NONE;
let mut kargs: Vec<String> = vec![];

// Get the running kargs of the booted system
match ostree::Deployment::bootconfig(booted_deployment) {
Some(bootconfig) => {
match ostree::BootconfigParser::get(&bootconfig, "options") {
Some(options) => {
let options: Vec<&str> = options.split_whitespace().collect();
let mut options: Vec<String> = options.into_iter().map(|s| s.to_string()).collect();
kargs.append(&mut options);
},
None => ()
}
},
None => ()
};

// Get the kargs in kargs.d of the booted system
let mut existing_kargs: Vec<String> = vec![];
let fragments = liboverdrop::scan(&["/usr/lib"], "bootc/kargs.d", &["toml"], true);
for (_name, path) in fragments {
let s = std::fs::read_to_string(&path)?;
let mut parsed_kargs = parse_file(s.clone())?;
existing_kargs.append(&mut parsed_kargs);
}

// Get the kargs in kargs.d of the remote image
let mut remote_kargs: Vec<String> = vec![];
let (fetched_tree, _) = repo.read_commit(fetched.ostree_commit.as_str(), cancellable)?;
let fetched_tree = fetched_tree.resolve_relative_path("/usr/lib/bootc/kargs.d");
let fetched_tree = fetched_tree.downcast::<ostree::RepoFile>().expect("downcast");
match fetched_tree.query_exists(cancellable) {
true => {}
false => {
return Ok(vec![]);
}
}
let queryattrs = "standard::name,standard::type";
let queryflags = gio::FileQueryInfoFlags::NOFOLLOW_SYMLINKS;
let fetched_iter = fetched_tree.enumerate_children(queryattrs, queryflags, cancellable)?;
while let Some(fetched_info) = fetched_iter.next_file(cancellable)? {
let fetched_child = fetched_iter.child(&fetched_info);
let fetched_child = fetched_child.downcast::<ostree::RepoFile>().expect("downcast");
fetched_child.ensure_resolved()?;
let fetched_contents_checksum = fetched_child.checksum();
let f = ostree::Repo::load_file(repo, fetched_contents_checksum.as_str(), cancellable)?;
let file_content = f.0;
let mut reader = ostree_ext::prelude::InputStreamExtManual::into_read(file_content.unwrap());
let s = std::io::read_to_string(&mut reader)?;
let mut parsed_kargs = parse_file(s.clone())?;
remote_kargs.append(&mut parsed_kargs);
}

// get the diff between the existing and remote kargs
let mut added_kargs: Vec<String> = remote_kargs.clone().into_iter().filter(|item| !existing_kargs.contains(item)).collect();
let removed_kargs: Vec<String> = existing_kargs.clone().into_iter().filter(|item| !remote_kargs.contains(item)).collect();

// apply the diff to the system kargs
kargs.retain(|x| !removed_kargs.contains(x));
kargs.append(&mut added_kargs);

Ok(kargs)
}

pub fn parse_file(file_content: String) -> Result<Vec<String>> {
let arch = std::env::consts::ARCH;
let de: Config = toml::from_str(&file_content).unwrap();
let mut parsed_kargs: Vec<String> = vec![];
if de.supported.architecture == arch {
parsed_kargs = de.kargs;
}
return Ok(parsed_kargs);
}
1 change: 1 addition & 0 deletions lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

pub mod cli;
pub(crate) mod deploy;
pub(crate) mod kargs;
pub(crate) mod journal;
mod lsm;
pub(crate) mod metadata;
Expand Down

0 comments on commit 6b2f0fc

Please sign in to comment.