Compare commits

...

8 Commits

Author SHA1 Message Date
Mikaël Cluseau ee03452591 chore: Release init version 2.6.9 2026-06-09 16:06:20 +02:00
Mikaël Cluseau 7fef9eaf6c add OVMF.fd 2026-06-09 16:06:14 +02:00
Mikaël Cluseau 6a9875fad5 init: symlink modules firmware 2026-06-09 16:05:19 +02:00
Mikaël Cluseau 6a8805346f add example (but useful) dhcp initrd 2026-06-05 14:10:37 +02:00
Mikaël Cluseau acb8f28ab7 cargo update 2026-06-04 19:09:28 +02:00
Mikaël Cluseau d4ec6380f8 untar by ourselves 2026-06-04 19:08:54 +02:00
Mikaël Cluseau 3036b2f417 chore: Release init version 2.6.8 2026-06-02 06:38:05 +02:00
Mikaël Cluseau e72e6a0b3b seed: more atomic 2026-06-02 06:36:45 +02:00
7 changed files with 177 additions and 22 deletions
Generated
+32 -11
View File
@@ -126,9 +126,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.11.1" version = "2.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" checksum = "84d7ced0ae9557296835c32bf1b1e02b44c746701f898460fb000d7eaa84f00a"
[[package]] [[package]]
name = "blake2b_simd" name = "blake2b_simd"
@@ -185,9 +185,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]] [[package]]
name = "chrono" name = "chrono"
version = "0.4.44" version = "0.4.45"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327"
dependencies = [ dependencies = [
"iana-time-zone", "iana-time-zone",
"num-traits", "num-traits",
@@ -418,6 +418,16 @@ version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
[[package]]
name = "filetime"
version = "0.2.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759"
dependencies = [
"cfg-if",
"libc",
]
[[package]] [[package]]
name = "find-msvc-tools" name = "find-msvc-tools"
version = "0.1.9" version = "0.1.9"
@@ -882,7 +892,7 @@ dependencies = [
[[package]] [[package]]
name = "init" name = "init"
version = "2.6.7" version = "2.6.9"
dependencies = [ dependencies = [
"dkl", "dkl",
"env_logger", "env_logger",
@@ -901,6 +911,7 @@ dependencies = [
"serde_yaml", "serde_yaml",
"shell-escape", "shell-escape",
"sys-info", "sys-info",
"tar",
"termios", "termios",
"tokio", "tokio",
"unix_mode", "unix_mode",
@@ -1014,9 +1025,9 @@ checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.30" version = "0.4.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a"
[[package]] [[package]]
name = "lz4" name = "lz4"
@@ -1379,9 +1390,9 @@ dependencies = [
[[package]] [[package]]
name = "rpassword" name = "rpassword"
version = "7.5.3" version = "7.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "835a57a69104632d64deb0df2e09a69945cd7a6eab4070fc9b1d7e50cf6c3edc" checksum = "2da316a15f47e3d053de9cb2c439650bd8fa4aaeb9365f2e5f27f492ff73c196"
dependencies = [ dependencies = [
"libc", "libc",
"rtoolbox", "rtoolbox",
@@ -1709,6 +1720,16 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "tar"
version = "0.4.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840"
dependencies = [
"filetime",
"libc",
]
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.27.0" version = "3.27.0"
@@ -2445,9 +2466,9 @@ checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4"
[[package]] [[package]]
name = "yoke" name = "yoke"
version = "0.8.2" version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5"
dependencies = [ dependencies = [
"stable_deref_trait", "stable_deref_trait",
"yoke-derive", "yoke-derive",
+2 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "init" name = "init"
version = "2.6.7" version = "2.6.9"
edition = "2024" edition = "2024"
[profile.release] [profile.release]
@@ -32,3 +32,4 @@ openssl = "0.10.73"
reqwest = { git = "https://github.com/mcluseau/rs-reqwest", version = "0.13.1", features = ["native-tls", "system-proxy", "socks"], default-features = false } reqwest = { git = "https://github.com/mcluseau/rs-reqwest", version = "0.13.1", features = ["native-tls", "system-proxy", "socks"], default-features = false }
glob = "0.3.3" glob = "0.3.3"
hex = "0.4.3" hex = "0.4.3"
tar = { version = "0.4.46", default-features = false }
BIN
View File
Binary file not shown.
+62
View File
@@ -0,0 +1,62 @@
#! /bin/bash
base_initrd=dist/initrd
flavor=dhcp
dir=tmp/$flavor-initrd
dist=dist/$flavor
uki=$dist/bootx64.efi
linux_v=6.18.34
set -ex
mkdir -p tmp/dl $dist
linux=tmp/dl/linux-$linux_v
modules=tmp/dl/modules-$linux_v
[ -e $linux ] || curl -o $linux https://dkl.novit.io/dist/kernels/6.18.34
[ -e $modules ] || curl -o $modules https://dkl.novit.io/dist/layers/modules/6.18.34 # TODO .erofs
rm -fr $dir
mkdir $dir
cpio --quiet --extract --file $base_initrd --directory $dir
cp -rv $flavor/. $dir
cp $modules $dir/modules.fs
(cd $dir && find * |cpio --create -H newc -R 0:0) >$dir.cpio
if cpio -tF $dir.cpio 2>&1 |grep bytes.of.junk; then echo "bad cpio archive"; exit 1; fi
zstd -12 -T0 -vf $dir.cpio &&
mv $dir.cpio.zst $dist/initrd
cp $linux $dist/vmlinuz
ukify build --output $uki --os-release "Direktil DHCP" \
--linux $linux --initrd $dist/initrd --cmdline "console=tty0 console=ttyS0,115200"
MB=$(( 2**20 ))
sz=$(( ( $(stat -c %s $uki) + MB ) / MB + 2 ))
efi=$dist/efi.img
if [ -e $efi ]; then rm $efi; fi
truncate -s ${sz}M $efi
sgdisk -n 1:2048:0 -t 1:ef00 -c 1:"EFI System" $efi
offset=$(( 2048 * 512 ))
export MTOOLSRC=$(mktemp)
trap "rm -f $MTOOLSRC" exit
echo "drive e: file=\"$efi\" offset=$offset" >$MTOOLSRC
args="-i $efi@@$offset"
mformat -F e:
mmd e:EFI e:EFI/BOOT
mcopy $uki e:EFI/BOOT/BOOTX64.EFI
+37
View File
@@ -0,0 +1,37 @@
---
anti_phishing_code: "direktil<3"
modules: /modules.fs
auths:
- name: adm1@novit
sshKey: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICkpbU6sf4t0f6XAv9DuW3XH5iLM0AI5rc8PT2jwea1N
- name: adm2@novit
sshKey: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILIomzqVAIqb7BedauhAo2VgbLqme5Jx/vjGUqZLoJqF
ssh:
listen: "[::]:22"
networks:
- name: loopback
interfaces: [ { var: iface, n: 1, udev: !eq [INTERFACE, lo] } ]
script: |
ip a add 127.0.0.1/8 dev lo
ip a add ::1/128 dev lo
ip li set lo up
- name: main
interfaces:
- var: iface
n: -1
udev: !has ID_NET_NAME_MAC
script: |
ip link add main type bond mode active-backup
for l in $ifaces; do
ip link set $l master main
ip link set $l up
done
ip link set main up
udhcpc -b -i main
bootstrap:
dev: /dev/storage/bootstrap
+7
View File
@@ -166,6 +166,13 @@ async fn mount_modules(modules: &str, kernel_version: &str) -> Result<()> {
} }
symlink(modules_path, format!("/lib/modules/{kernel_version}"))?; symlink(modules_path, format!("/lib/modules/{kernel_version}"))?;
let firmware_path = &format!("/modules/lib/firmware/{kernel_version}");
if std::fs::exists(firmware_path)? {
fs::create_dir_all("/lib/firmware").await?;
symlink(firmware_path, format!("/lib/firmware/{kernel_version}"))?;
}
Ok(()) Ok(())
} }
+37 -10
View File
@@ -152,33 +152,48 @@ impl Verifier {
} }
async fn seed_config( async fn seed_config(
base_dir: &str, base_dir: impl Into<PathBuf>,
bs: &dkl::bootstrap::Bootstrap, bs: &dkl::bootstrap::Bootstrap,
verifier: &Verifier, verifier: &Verifier,
) -> Result<Vec<u8>> { ) -> Result<Vec<u8>> {
let cfg_path = &format!("{base_dir}/config.yaml"); let base_dir = base_dir.into();
if fs::try_exists(cfg_path).await? { let cfg_path = base_dir.join("config.yaml");
return Ok(fs::read(cfg_path).await?);
if fs::try_exists(&cfg_path).await? {
return verifier.verify_path(cfg_path).await;
} }
let bs_tar = "/bootstrap.tar"; let bs_tar = "/bootstrap.tar";
if !fs::try_exists(bs_tar).await? { if !fs::try_exists(&bs_tar).await? {
if bs.seed.is_none() { if bs.seed.is_none() {
return Err(format_err!( return Err(format_err!(
"no {cfg_path}, no {bs_tar} and no seed URL, can't bootstrap" "no {}, no {bs_tar} and no seed URL, can't bootstrap",
cfg_path.display()
)); ));
} }
fetch_bootstrap(bs, bs_tar).await?; fetch_bootstrap(bs, bs_tar).await?;
} }
try_exec("tar", &["xf", bs_tar, "-C", base_dir]).await?; let tmp_dir = base_dir.with_added_extension("new");
fs::create_dir_all(&tmp_dir).await?;
if !fs::try_exists(cfg_path).await? { untar(bs_tar, &tmp_dir)
return Err(format_err!("{cfg_path} does not exist after seeding")); .await
.map_err(|e| format_err!("untar failed: {e}"))?;
let cfg_path = tmp_dir.join("config.yaml");
if !fs::try_exists(&cfg_path).await? {
return Err(format_err!(
"{} does not exist after seeding",
cfg_path.display()
));
} }
verifier.verify_path(&cfg_path).await let cfg_bytes = verifier.verify_path(&cfg_path).await?;
fs::rename(tmp_dir, base_dir).await?;
Ok(cfg_bytes)
} }
async fn fetch_bootstrap(bs: &dkl::bootstrap::Bootstrap, output_file: &str) -> Result<()> { async fn fetch_bootstrap(bs: &dkl::bootstrap::Bootstrap, output_file: &str) -> Result<()> {
@@ -229,6 +244,18 @@ async fn fetch_bootstrap(bs: &dkl::bootstrap::Bootstrap, output_file: &str) -> R
Ok(()) Ok(())
} }
async fn untar(arch: impl Into<PathBuf>, target: impl Into<PathBuf>) -> Result<()> {
let arch = arch.into();
let target = target.into();
tokio::task::spawn_blocking(move || {
let tar = std::fs::File::open(arch)?;
let mut tar = tar::Archive::new(tar);
tar.unpack(target)
})
.await??;
Ok(())
}
fn default_root_tmpfs_opts() -> Option<String> { fn default_root_tmpfs_opts() -> Option<String> {
let mem = sys_info::mem_info() let mem = sys_info::mem_info()
.inspect_err(|e| warn!("failed to get system memory info, using default tmpfs size: {e}")) .inspect_err(|e| warn!("failed to get system memory info, using default tmpfs size: {e}"))