bootstrap:

This commit is contained in:
Mikaël Cluseau
2025-07-09 05:45:35 +02:00
parent f45fbe116e
commit 69e670abe1
5 changed files with 42 additions and 19 deletions

11
Cargo.lock generated
View File

@ -247,6 +247,7 @@ dependencies = [
"serde_json", "serde_json",
"serde_yaml", "serde_yaml",
"shell-escape", "shell-escape",
"sys-info",
"termios", "termios",
"tokio", "tokio",
"unix_mode", "unix_mode",
@ -577,6 +578,16 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "sys-info"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c"
dependencies = [
"cc",
"libc",
]
[[package]] [[package]]
name = "termios" name = "termios"
version = "0.3.3" version = "0.3.3"

View File

@ -29,3 +29,4 @@ unix_mode = "0.1.4"
cpio = "0.4.1" cpio = "0.4.1"
lz4 = "1.28.1" lz4 = "1.28.1"
base64 = "0.22.1" base64 = "0.22.1"
sys-info = "0.9.1"

View File

@ -1,5 +1,5 @@
use eyre::{format_err, Result}; use eyre::{format_err, Result};
use log::info; use log::{info, warn};
use std::path::Path; use std::path::Path;
use tokio::{ use tokio::{
fs, fs,
@ -20,7 +20,7 @@ pub async fn bootstrap(cfg: Config) {
}) })
.await; .await;
let boot_version = utils::param("version", "current"); let boot_version = utils::param("version").unwrap_or("current");
let base_dir = &format!("/bootstrap/{boot_version}"); let base_dir = &format!("/bootstrap/{boot_version}");
retry_or_ignore(async || { retry_or_ignore(async || {
@ -169,9 +169,25 @@ async fn fetch_bootstrap(seed_url: &str, output_file: &str) -> Result<()> {
Ok(()) Ok(())
} }
fn default_root_tmpfs_opts() -> Option<String> {
let mem = sys_info::mem_info()
.inspect_err(|e| warn!("failed to get system memory info, using default tmpfs size: {e}"))
.ok()?;
let mem_size = mem.total /* kiB */ / 1024;
let fs_size = 1024.min(mem_size / 2);
info!("system has {mem_size} MiB of memory, allowing {fs_size} MiB for root tmpfs");
Some(format!("size={fs_size}m"))
}
async fn mount_system(cfg: &dkl::Config, bs_dir: &str, verifier: &Verifier) { async fn mount_system(cfg: &dkl::Config, bs_dir: &str, verifier: &Verifier) {
let opts = match utils::param("root-opts") {
Some(s) => Some(s.to_string()),
None => default_root_tmpfs_opts(),
};
let mem_dir = "/mem"; let mem_dir = "/mem";
mount(None, mem_dir, "tmpfs", Some("size=512m")).await; mount(None, mem_dir, "tmpfs", opts.as_deref()).await;
let layers_dir = &format!("{mem_dir}/layers"); let layers_dir = &format!("{mem_dir}/layers");
let mut lower_dir = String::new(); let mut lower_dir = String::new();
@ -316,14 +332,10 @@ async fn mount_filesystems(mounts: &[dkl::Mount], root: &str) {
mount( mount(
Some(&m.dev), Some(&m.dev),
&path, &path,
m.r#type (m.r#type.as_deref())
.as_ref()
.filter(|s| !s.is_empty()) .filter(|s| !s.is_empty())
.map_or("ext4", |s| s.as_str()), .unwrap_or("ext4"),
m.options m.options.as_deref().filter(|v| !v.is_empty()),
.as_ref()
.filter(|v| !v.is_empty())
.map(|s| s.as_str()),
) )
.await; .await;
} }

View File

@ -11,8 +11,9 @@ async fn main() -> Result<()> {
dklog::init(); dklog::init();
let call_name = env::args().next().unwrap_or("init".into()); let call_name = env::args().next();
let call_name = (call_name.rsplit_once('/').map(|(_, n)| n)).unwrap_or(call_name.as_str()); let call_name = call_name.as_deref().unwrap_or("init");
let call_name = call_name.rsplit_once('/').map_or(call_name, |(_, n)| n);
let result = match call_name { let result = match call_name {
"init" => { "init" => {

View File

@ -20,16 +20,14 @@ pub fn bool_param(name: &str) -> bool {
cmdline().any(|part| part == name1 || part == name2) cmdline().any(|part| part == name1 || part == name2)
} }
pub fn param<'t>(name: &'t str, default: &'t str) -> &'t str { pub fn param(name: &str) -> Option<&'static str> {
let prefix1 = &format!("dkl.{name}="); let prefix1 = &format!("dkl.{name}=");
let prefix2 = &format!("direktil.{name}="); let prefix2 = &format!("direktil.{name}=");
cmdline() cmdline().find_map(|part| {
.find_map(|part| { part.strip_prefix(prefix1)
part.strip_prefix(prefix1) .or_else(|| part.strip_prefix(prefix2))
.or_else(|| part.strip_prefix(prefix2)) })
})
.unwrap_or(default)
} }
pub struct NameAliases { pub struct NameAliases {