From 9ed328aebd519c1921d20d96ca03ac9e2ea890cf Mon Sep 17 00:00:00 2001 From: Jeremy Cline Date: Fri, 19 Jul 2024 20:33:59 +0000 Subject: [PATCH 1/2] azure-init: Accept providing user groups via the CLI Debian uses "sudo" as the group for having do-anything sudo permissions, where-as Fedora uses "wheel". Otherwise the same binary works fine for both. I don't see an advantage to baking the groups into the binary, so this is a take on runtime configuration. Accept a list of supplementary groups to use when provisioning the user so the same binary can be used for both. Values can be provided using the "-g" or "--groups" argument, or by setting the "AZURE_INIT_USER_GROUPS" environment variable. If no groups are provided, the default remains "wheel". I found this helpful when testing #105. We could expand this to allow more runtime tweaks to, for example, the backend in use if folks like this. --- Cargo.toml | 7 +++++++ src/main.rs | 24 +++++++++++++++++++++++- tests/cli.rs | 17 +++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 tests/cli.rs diff --git a/Cargo.toml b/Cargo.toml index d1f6e398..4d57dc9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,13 @@ anyhow = "1.0.81" tokio = { version = "1", features = ["full"] } tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } tracing = "0.1.40" +# We work fine with any version of 4, but 4.5 bumped MSRV to 1.74 +clap = { version = "<=4.4", features = ["derive", "cargo", "env"] } + +[dev-dependencies] +# Purely for the MSRV requirement. +assert_cmd = "<=2.0.13" +predicates = "3" [dependencies.libazureinit] path = "libazureinit" diff --git a/src/main.rs b/src/main.rs index 757d5d36..f19f9539 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use std::process::ExitCode; use anyhow::Context; +use clap::Parser; use libazureinit::imds::InstanceMetadata; use libazureinit::User; use libazureinit::{ @@ -20,6 +21,24 @@ use tracing_subscriber::EnvFilter; const VERSION: &str = env!("CARGO_PKG_VERSION"); +/// Minimal provisioning agent for Azure +/// +/// Create a user, add SSH public keys, and set the hostname. +#[derive(Parser, Debug)] +struct Cli { + /// List of supplementary groups of the provisioned user account. + /// + /// Values can be comma-separated and the argument can be provided multiple times. + #[arg( + long, + short, + env = "AZURE_INIT_USER_GROUPS", + value_delimiter = ',', + default_value = "wheel" + )] + groups: Vec, +} + #[instrument] fn get_environment() -> Result { let ovf_devices = get_mount_device(None)?; @@ -96,6 +115,8 @@ async fn main() -> ExitCode { #[instrument] async fn provision() -> Result<(), anyhow::Error> { + let opts = Cli::parse(); + let mut default_headers = header::HeaderMap::new(); let user_agent = header::HeaderValue::from_str( format!("azure-init v{VERSION}").as_str(), @@ -124,7 +145,8 @@ async fn provision() -> Result<(), anyhow::Error> { .clone() .ok_or::(LibError::InstanceMetadataFailure)?; - let user = User::new(username, im.compute.public_keys); + let user = + User::new(username, im.compute.public_keys).with_groups(opts.groups); Provision::new(im.compute.os_profile.computer_name, user) .hostname_provisioners([ diff --git a/tests/cli.rs b/tests/cli.rs new file mode 100644 index 00000000..72b333a7 --- /dev/null +++ b/tests/cli.rs @@ -0,0 +1,17 @@ +use std::process::Command; + +use assert_cmd::prelude::*; +use predicates::prelude::*; + +// Assert help text includes the --groups flag +#[test] +fn help_groups() -> Result<(), Box> { + let mut command = Command::cargo_bin("azure-init")?; + command.arg("--help"); + command + .assert() + .success() + .stdout(predicate::str::contains("-g, --groups ")); + + Ok(()) +} From c8b0e826d695fc1a800e870106aecf31be69972a Mon Sep 17 00:00:00 2001 From: Jeremy Cline Date: Mon, 22 Jul 2024 20:55:26 +0000 Subject: [PATCH 2/2] Clarify priority of environment variables vs CLI args Arguments provided as CLI arguments (`azure-init --groups=wheel,deal`) override any arguments provided by environment variables. They are not merged. --- src/main.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main.rs b/src/main.rs index f19f9539..f33df1fa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,6 +24,9 @@ const VERSION: &str = env!("CARGO_PKG_VERSION"); /// Minimal provisioning agent for Azure /// /// Create a user, add SSH public keys, and set the hostname. +/// +/// Arguments provided via command-line arguments override any arguments provided +/// via environment variables. #[derive(Parser, Debug)] struct Cli { /// List of supplementary groups of the provisioned user account.