Clean up smelly code in inject.rs
CI / build (push) Successful in 13s

This commit is contained in:
2026-09-08 22:50:39 +02:00
parent c2a9f00fc0
commit 5960cfe430
2 changed files with 20 additions and 38 deletions
+2 -3
View File
@@ -76,9 +76,8 @@ fn build_inner(
) -> Result<()> {
let config = inject::inspect_config(image)?;
let command = cmd.unwrap_or_else(|| inject::infer_command(&config));
let env = inject::env(&config);
let working_dir = inject::working_dir(&config);
let exec_script = inject::build_exec_script(&command, &env, working_dir);
let exec_script =
inject::build_exec_script(&command, &config.env, config.working_dir.as_deref());
inject::inject(mount_path, &exec_script)?;
println!("Injected /slim/ (init + exec)");
+18 -35
View File
@@ -3,6 +3,7 @@
use anyhow::{Context, Result, anyhow};
use serde::Deserialize;
use std::fmt::Write as _;
use std::fs;
use std::path::Path;
@@ -14,13 +15,13 @@ const SLIM_INIT: &str = include_str!("scripts/slim-init.sh");
#[serde(rename_all = "PascalCase")]
pub struct Config {
#[serde(default)]
cmd: Option<Vec<String>>,
pub cmd: Vec<String>,
#[serde(default)]
entrypoint: Option<Vec<String>>,
pub entrypoint: Vec<String>,
#[serde(default)]
env: Option<Vec<String>>,
pub env: Vec<String>,
#[serde(default)]
working_dir: Option<String>,
pub working_dir: Option<String>,
}
pub fn inspect_config(image: &str) -> Result<Config> {
@@ -42,40 +43,21 @@ pub fn inspect_config(image: &str) -> Result<Config> {
/// Concatenates ENTRYPOINT + CMD (Docker semantics). If neither is present,
/// falls back to `/bin/sh`.
pub fn infer_command(config: &Config) -> String {
let entrypoint = config.entrypoint.as_deref().filter(|e| !e.is_empty());
let cmd = config.cmd.as_deref().filter(|c| !c.is_empty());
let parts = config.entrypoint.iter().chain(config.cmd.iter());
let parts: Vec<_> = parts.map(|s| s.as_str()).collect();
let parts: Vec<String> = match (entrypoint, cmd) {
(Some(ep), Some(c)) => {
let mut parts = ep.to_vec();
parts.extend(c.iter().cloned());
parts
match &parts[..] {
[] => "/bin/sh".into(),
["/bin/sh" | "sh", "-c", cmd] => cmd.to_string(),
_ => shell_join(&parts),
}
(Some(ep), None) => ep.to_vec(),
(None, Some(c)) => c.to_vec(),
(None, None) => vec!["/bin/sh".to_string()],
};
if parts.len() == 3 && (parts[0] == "/bin/sh" || parts[0] == "sh") && parts[1] == "-c" {
parts[2].clone()
} else {
shell_join(&parts)
}
}
pub fn env(config: &Config) -> Vec<String> {
config.env.clone().unwrap_or_default()
}
pub fn working_dir(config: &Config) -> Option<&str> {
config.working_dir.as_deref()
}
fn shell_escape(s: &str) -> String {
format!("'{}'", s.replace('\'', "'\\''"))
}
fn shell_join(parts: &[String]) -> String {
fn shell_join(parts: &[&str]) -> String {
parts
.iter()
.map(|p| shell_escape(p))
@@ -87,18 +69,19 @@ fn shell_join(parts: &[String]) -> String {
pub fn build_exec_script(command: &str, env: &[String], working_dir: Option<&str>) -> String {
let mut lines = String::from("#!/bin/sh\n");
if let Some(dir) = working_dir.filter(|d| !d.is_empty()) {
lines.push_str(&format!("cd {} 2>/dev/null\n", shell_escape(dir)));
_ = writeln!(&mut lines, "cd {} 2>/dev/null", shell_escape(dir));
}
for var in env {
if let Some((key, val)) = var.split_once('=') {
lines.push_str(&format!(
"export {}={}\n",
_ = writeln!(
&mut lines,
"export {}={}",
shell_escape(key),
shell_escape(val)
));
);
}
}
lines.push_str(&format!("exec /bin/sh -c {}\n", shell_escape(command)));
_ = writeln!(&mut lines, "exec /bin/sh -c {}", shell_escape(command));
lines
}