8 Commits

Author SHA1 Message Date
Mikaël Cluseau ddc82199fb cargo update 2026-02-21 08:18:07 +01:00
Mikaël Cluseau 61d31bc22c dls::Config.extra_ca_certs 2026-02-21 08:17:42 +01:00
Mikaël Cluseau d2293df011 base64: be a tolerant reader 2026-02-10 21:23:11 +01:00
Mikaël Cluseau 723cecff1b fix vg name compat 2026-02-10 15:41:40 +01:00
Mikaël Cluseau e8c9ee9885 wow base64 w/ and wo/ padding are incompatible 2026-01-25 21:59:23 +01:00
Mikaël Cluseau 6a6536bdfb files: add content64 for base64 encoded values 2026-01-25 20:01:50 +01:00
Mikaël Cluseau a6dc420275 cargo update 2026-01-07 18:24:14 +01:00
Mikaël Cluseau d9fa31ec33 bootstrap: impl Default for NetworkInterface 2026-01-07 18:24:02 +01:00
6 changed files with 822 additions and 193 deletions
Generated
+792 -189
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -13,6 +13,7 @@ codegen-units = 1
[dependencies] [dependencies]
async-compression = { version = "0.4.27", features = ["tokio", "zstd"] } async-compression = { version = "0.4.27", features = ["tokio", "zstd"] }
base32 = "0.5.1" base32 = "0.5.1"
base64 = "0.22.1"
bytes = "1.10.1" bytes = "1.10.1"
chrono = { version = "0.4.41", default-features = false, features = ["clock", "now"] } chrono = { version = "0.4.41", default-features = false, features = ["clock", "now"] }
clap = { version = "4.5.40", features = ["derive", "env"] } clap = { version = "4.5.40", features = ["derive", "env"] }
@@ -30,7 +31,7 @@ lz4 = "1.28.1"
nix = { version = "0.30.1", features = ["user"] } nix = { version = "0.30.1", features = ["user"] }
openssl = "0.10.73" openssl = "0.10.73"
page_size = "0.6.0" page_size = "0.6.0"
reqwest = { version = "0.12.20", features = ["json", "stream", "native-tls"] } reqwest = { version = "0.13.1", features = ["json", "stream", "native-tls"] }
serde = { version = "1.0.219", features = ["derive"] } serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.140" serde_json = "1.0.140"
serde_yaml = "0.9.34" serde_yaml = "0.9.34"
+6
View File
@@ -3,6 +3,8 @@ use log::info;
use std::path::Path; use std::path::Path;
use tokio::fs; use tokio::fs;
use crate::base64_decode;
pub async fn files(files: &[crate::File], root: &str) -> Result<()> { pub async fn files(files: &[crate::File], root: &str) -> Result<()> {
for file in files { for file in files {
let path = chroot(root, &file.path); let path = chroot(root, &file.path);
@@ -15,6 +17,10 @@ pub async fn files(files: &[crate::File], root: &str) -> Result<()> {
use crate::FileKind as K; use crate::FileKind as K;
match &file.kind { match &file.kind {
K::Content(content) => fs::write(path, content.as_bytes()).await?, K::Content(content) => fs::write(path, content.as_bytes()).await?,
K::Content64(content) => {
let content = base64_decode(content)?;
fs::write(path, content).await?
}
K::Dir(true) => fs::create_dir(path).await?, K::Dir(true) => fs::create_dir(path).await?,
K::Dir(false) => {} // shouldn't happen, but semantic is to ignore K::Dir(false) => {} // shouldn't happen, but semantic is to ignore
K::Symlink(tgt) => fs::symlink(tgt, path).await?, K::Symlink(tgt) => fs::symlink(tgt, path).await?,
+12 -1
View File
@@ -78,6 +78,17 @@ pub struct NetworkInterface {
pub udev: Option<UdevFilter>, pub udev: Option<UdevFilter>,
} }
impl Default for NetworkInterface {
fn default() -> Self {
Self {
var: "iface".into(),
n: 1,
regexps: Vec::new(),
udev: Some(UdevFilter::Eq("INTERFACE".into(), "eth0".into())),
}
}
}
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
pub struct SSHServer { pub struct SSHServer {
pub listen: String, pub listen: String,
@@ -94,7 +105,7 @@ impl Default for SSHServer {
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
pub struct LvmVG { pub struct LvmVG {
#[serde(alias = "vg")] #[serde(rename = "vg", alias = "name")]
pub name: String, pub name: String,
pub pvs: LvmPV, pub pvs: LvmPV,
+2
View File
@@ -170,6 +170,8 @@ pub struct Config {
pub host_templates: Vec<HostConfig>, pub host_templates: Vec<HostConfig>,
#[serde(default, rename = "SSLConfig")] #[serde(default, rename = "SSLConfig")]
pub ssl_config: String, pub ssl_config: String,
#[serde(default, deserialize_with = "deserialize_null_as_default")]
pub extra_ca_certs: Map<String, String>,
} }
// compensate for go's encoder pitfalls // compensate for go's encoder pitfalls
+8 -2
View File
@@ -1,10 +1,10 @@
pub mod apply; pub mod apply;
pub mod proxy;
pub mod bootstrap; pub mod bootstrap;
pub mod dls; pub mod dls;
pub mod dynlay; pub mod dynlay;
pub mod fs; pub mod fs;
pub mod logger; pub mod logger;
pub mod proxy;
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)] #[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
pub struct Config { pub struct Config {
@@ -63,9 +63,10 @@ pub struct File {
} }
#[derive(Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)] #[derive(Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "lowercase")]
pub enum FileKind { pub enum FileKind {
Content(String), Content(String),
Content64(String),
Symlink(String), Symlink(String),
Dir(bool), Dir(bool),
} }
@@ -80,3 +81,8 @@ impl Config {
self.files.iter().find(|f| f.path == path) self.files.iter().find(|f| f.path == path)
} }
} }
pub fn base64_decode(s: &str) -> Result<Vec<u8>, base64::DecodeError> {
use base64::{prelude::BASE64_STANDARD_NO_PAD as B64, Engine};
B64.decode(s.trim_end_matches('='))
}