Skip to content

Commit 9819f7e

Browse files
committed
feat: add quirk feature
1 parent aba1c14 commit 9819f7e

File tree

6 files changed

+286
-3
lines changed

6 files changed

+286
-3
lines changed

Cargo.lock

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ disk = { path = "./disk" }
2424
install = { path = "./install" }
2525

2626
[workspace]
27-
members = ["disk", "install"]
27+
members = ["disk", "install", "quirk"]
2828

2929
[patch.crates-io]
3030
loopdev = { git = "https://github.com/eatradish/loopdev", rev = "0dde43a15320cf84148e57fed8aec6683755c04f" }

install/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ faster-hex = "0.10.0"
2121
serde_json = "1.0.128"
2222
num_enum = "0.7.3"
2323
snafu = "0.8.5"
24+
quirk = { path = "../quirk" }
2425

2526
[features]
2627
default = []

install/src/lib.rs

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::{
2+
collections::HashSet,
23
fmt::{Display, Formatter},
34
fs::{self, create_dir_all, read_dir},
45
io::{self, Write},
@@ -26,6 +27,7 @@ use grub::RunGrubError;
2627
use locale::SetHwclockError;
2728
use mount::{mount_root_path, UmountError};
2829
use num_enum::IntoPrimitive;
30+
use quirk::get_matches_quirk;
2931
use rustix::{
3032
fs::sync,
3133
io::Errno,
@@ -350,7 +352,7 @@ macro_rules! cancel_install_exit {
350352
};
351353
}
352354

353-
#[derive(Clone, IntoPrimitive)]
355+
#[derive(Clone, IntoPrimitive, PartialEq, Eq)]
354356
#[repr(u8)]
355357
enum InstallationStage {
356358
SetupPartition = 1,
@@ -368,6 +370,7 @@ enum InstallationStage {
368370
UmountInnerPath,
369371
UmountEFIPath,
370372
UmountRootPath,
373+
Quirk,
371374
Done,
372375
}
373376

@@ -395,6 +398,7 @@ impl Display for InstallationStage {
395398
Self::UmountInnerPath => "umount inner path",
396399
Self::UmountEFIPath => "umount EFI path",
397400
Self::UmountRootPath => "umount root path",
401+
Self::Quirk => "run quirk",
398402
Self::Done => "done",
399403
};
400404

@@ -419,7 +423,8 @@ impl InstallationStage {
419423
Self::CopyLog => Self::UmountInnerPath,
420424
Self::UmountInnerPath => Self::UmountEFIPath,
421425
Self::UmountEFIPath => Self::UmountRootPath,
422-
Self::UmountRootPath => Self::Done,
426+
Self::UmountRootPath => Self::Quirk,
427+
Self::Quirk => Self::Done,
423428
Self::Done => Self::Done,
424429
}
425430
}
@@ -436,6 +441,37 @@ impl InstallConfig {
436441
) -> Result<bool, InstallErr> {
437442
debug!("Install config: {:#?}", self);
438443

444+
let quirks = get_matches_quirk("/usr/share/deploykit-backend/quirks");
445+
446+
let mut no_run = HashSet::new();
447+
let mut quirk_commands = vec![];
448+
449+
for quirk in quirks {
450+
if let Some(skip_stages) = quirk.skip_stages {
451+
no_run.extend(skip_stages);
452+
}
453+
quirk_commands.push(quirk.command);
454+
}
455+
456+
let no_run = no_run
457+
.iter()
458+
.flat_map(|x| match x.as_str() {
459+
"SetupPartition" => Some(InstallationStage::SetupPartition),
460+
"DownloadSquashfs" => Some(InstallationStage::DownloadSquashfs),
461+
"ExtractSquashfs" => Some(InstallationStage::ExtractSquashfs),
462+
"GenerateFstab" => Some(InstallationStage::GenerateFstab),
463+
"Dracut" => Some(InstallationStage::Dracut),
464+
"InstallGrub" => Some(InstallationStage::InstallGrub),
465+
"GenerateSshKey" => Some(InstallationStage::GenerateSshKey),
466+
"ConfigureSystem" => Some(InstallationStage::ConfigureSystem),
467+
"SwapOff" => Some(InstallationStage::SwapOff),
468+
x => {
469+
error!("Unsupport skip step: {x}");
470+
None
471+
}
472+
})
473+
.collect::<Vec<_>>();
474+
439475
let root_fd = get_dir_fd(Path::new("/")).context(GetDirFdSnafu)?;
440476

441477
let mut stage = InstallationStage::default();
@@ -464,11 +500,17 @@ impl InstallConfig {
464500
InstallationStage::UmountInnerPath => 8,
465501
InstallationStage::UmountEFIPath => 8,
466502
InstallationStage::UmountRootPath => 8,
503+
InstallationStage::Quirk => 8,
467504
InstallationStage::Done => 8,
468505
};
469506

470507
step.store(num, Ordering::SeqCst);
471508

509+
if no_run.contains(&stage) {
510+
stage = stage.get_next_stage();
511+
continue;
512+
}
513+
472514
let res = match stage {
473515
InstallationStage::SetupPartition => self
474516
.setup_partition(&progress, &tmp_mount_path, &cancel_install)
@@ -538,6 +580,27 @@ impl InstallConfig {
538580
.context(UmountSnafu)
539581
.context(PostInstallationSnafu)
540582
.map(|_| true),
583+
InstallationStage::Quirk => {
584+
for cmd in &quirk_commands {
585+
let out = match Command::new("bash").arg("-c").arg(cmd).output() {
586+
Ok(out) => out,
587+
Err(e) => {
588+
error!("Run {} failed: {}", cmd, e);
589+
continue;
590+
}
591+
};
592+
593+
if !out.status.success() {
594+
error!(
595+
"Run {} failed: stderr: {}",
596+
cmd,
597+
String::from_utf8_lossy(&out.stderr)
598+
)
599+
}
600+
}
601+
602+
Ok(true)
603+
}
541604
InstallationStage::Done => break,
542605
};
543606

quirk/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "quirk"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]
7+
toml = "0.8"
8+
serde = { version = "1", features = ["derive"] }
9+
walkdir = "2"
10+
fancy-regex = "0.14.0"
11+
glob = "0.3"
12+
snafu = "0.8"
13+
tracing = "0.1.40"

0 commit comments

Comments
 (0)