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<()> { ) -> Result<()> {
let config = inject::inspect_config(image)?; let config = inject::inspect_config(image)?;
let command = cmd.unwrap_or_else(|| inject::infer_command(&config)); let command = cmd.unwrap_or_else(|| inject::infer_command(&config));
let env = inject::env(&config); let exec_script =
let working_dir = inject::working_dir(&config); inject::build_exec_script(&command, &config.env, config.working_dir.as_deref());
let exec_script = inject::build_exec_script(&command, &env, working_dir);
inject::inject(mount_path, &exec_script)?; inject::inject(mount_path, &exec_script)?;
println!("Injected /slim/ (init + exec)"); println!("Injected /slim/ (init + exec)");
+18 -35
View File
@@ -3,6 +3,7 @@
use anyhow::{Context, Result, anyhow}; use anyhow::{Context, Result, anyhow};
use serde::Deserialize; use serde::Deserialize;
use std::fmt::Write as _;
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
@@ -14,13 +15,13 @@ const SLIM_INIT: &str = include_str!("scripts/slim-init.sh");
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]
pub struct Config { pub struct Config {
#[serde(default)] #[serde(default)]
cmd: Option<Vec<String>>, pub cmd: Vec<String>,
#[serde(default)] #[serde(default)]
entrypoint: Option<Vec<String>>, pub entrypoint: Vec<String>,
#[serde(default)] #[serde(default)]
env: Option<Vec<String>>, pub env: Vec<String>,
#[serde(default)] #[serde(default)]
working_dir: Option<String>, pub working_dir: Option<String>,
} }
pub fn inspect_config(image: &str) -> Result<Config> { 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, /// Concatenates ENTRYPOINT + CMD (Docker semantics). If neither is present,
/// falls back to `/bin/sh`. /// falls back to `/bin/sh`.
pub fn infer_command(config: &Config) -> String { pub fn infer_command(config: &Config) -> String {
let entrypoint = config.entrypoint.as_deref().filter(|e| !e.is_empty()); let parts = config.entrypoint.iter().chain(config.cmd.iter());
let cmd = config.cmd.as_deref().filter(|c| !c.is_empty()); let parts: Vec<_> = parts.map(|s| s.as_str()).collect();
let parts: Vec<String> = match (entrypoint, cmd) { match &parts[..] {
(Some(ep), Some(c)) => { [] => "/bin/sh".into(),
let mut parts = ep.to_vec(); ["/bin/sh" | "sh", "-c", cmd] => cmd.to_string(),
parts.extend(c.iter().cloned()); _ => shell_join(&parts),
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 { fn shell_escape(s: &str) -> String {
format!("'{}'", s.replace('\'', "'\\''")) format!("'{}'", s.replace('\'', "'\\''"))
} }
fn shell_join(parts: &[String]) -> String { fn shell_join(parts: &[&str]) -> String {
parts parts
.iter() .iter()
.map(|p| shell_escape(p)) .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 { pub fn build_exec_script(command: &str, env: &[String], working_dir: Option<&str>) -> String {
let mut lines = String::from("#!/bin/sh\n"); let mut lines = String::from("#!/bin/sh\n");
if let Some(dir) = working_dir.filter(|d| !d.is_empty()) { 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 { for var in env {
if let Some((key, val)) = var.split_once('=') { if let Some((key, val)) = var.split_once('=') {
lines.push_str(&format!( _ = writeln!(
"export {}={}\n", &mut lines,
"export {}={}",
shell_escape(key), shell_escape(key),
shell_escape(val) 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 lines
} }