diff options
author | Lars Wirzenius <liw@liw.fi> | 2023-08-19 09:03:26 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2023-08-19 09:45:45 +0300 |
commit | b46384d45225b58b1efc5ca195560baa7b8369c7 (patch) | |
tree | a8facc1c79171b80d8ec81207ebdc130d6715366 | |
parent | 0bd2cf284755610a52b081368756170c69835868 (diff) | |
download | ambient-run-b46384d45225b58b1efc5ca195560baa7b8369c7.tar.gz |
feat: per-user and per-project configurations can specify a VM image
The per-project configuration setting overrides the per-user setting.
Sponsored-by: author
-rw-r--r-- | ambient-run.md | 5 | ||||
-rw-r--r-- | src/bin/ambient-run.rs | 4 | ||||
-rw-r--r-- | src/config.rs | 7 | ||||
-rw-r--r-- | src/project.rs | 40 |
4 files changed, 44 insertions, 12 deletions
diff --git a/ambient-run.md b/ambient-run.md index 57b47d9..e290364 100644 --- a/ambient-run.md +++ b/ambient-run.md @@ -122,14 +122,17 @@ then stdout, as YAML, matches file full-config.yaml ~~~ ~~~{#default.yaml .file .yaml} +image: /my/image.qcow2 max_cpus: 4 ~~~ ~~~{#extra.yaml .file .yaml} +image: /other/image.qcow2 max_cpus: 8 ~~~ ~~~{#full-config.yaml .file .yaml} +image: /other/image.qcow2 max_cpus: 8 ~~~ @@ -146,6 +149,7 @@ _Stakeholder:_ Lars ~~~scenario given an installed ambient-run +given file .config/ambient-run/config.yaml from default.yaml given file project.yaml when I run ambient-run project project.yaml then stdout, as YAML, matches file full-project.yaml @@ -160,6 +164,7 @@ shell: | source: . shell: | cargo test +image: /my/image.qcow2 ~~~ ### Show per-build configuration diff --git a/src/bin/ambient-run.rs b/src/bin/ambient-run.rs index d81c96a..da74b15 100644 --- a/src/bin/ambient-run.rs +++ b/src/bin/ambient-run.rs @@ -97,8 +97,8 @@ struct ProjectCommand { } impl ProjectCommand { - fn run(&self, _global: &Args, _config: &Config) -> Result<(), AmbientRunError> { - let project = Project::load(&self.filename)?; + fn run(&self, _global: &Args, config: &Config) -> Result<(), AmbientRunError> { + let project = Project::load(&self.filename, config)?; println!("{}", project.as_yaml()?); Ok(()) } diff --git a/src/config.rs b/src/config.rs index f87b347..28e6e96 100644 --- a/src/config.rs +++ b/src/config.rs @@ -13,6 +13,9 @@ const CONFIG: &str = "config.yaml"; pub struct Config { /// Maximum number of virtual CPUs the build VM may have. pub max_cpus: usize, + + /// Path to base image to use. This can also be specified by the project. + pub image: Option<PathBuf>, } impl Config { @@ -40,6 +43,9 @@ impl Config { if let Some(n) = snippet.max_cpus { self.max_cpus = n; } + if snippet.image.is_some() { + self.image = snippet.image; + } Ok(()) } @@ -53,6 +59,7 @@ impl Config { #[serde(deny_unknown_fields)] struct ConfigSnippet { max_cpus: Option<usize>, + image: Option<PathBuf>, } /// Return canonical path name to default configuration file. diff --git a/src/project.rs b/src/project.rs index a9eb5dc..b672867 100644 --- a/src/project.rs +++ b/src/project.rs @@ -1,5 +1,6 @@ //! ambient-run project build information handling. +use crate::config::Config; use serde::{Deserialize, Serialize}; use std::path::{Path, PathBuf}; @@ -8,13 +9,30 @@ use std::path::{Path, PathBuf}; pub struct Project { source: PathBuf, shell: String, + image: PathBuf, } impl Project { /// Load build instructions from named file. - pub fn load(filename: &Path) -> Result<Self, ProjectError> { - let mut project = Self::default(); + pub fn load(filename: &Path, config: &Config) -> Result<Self, ProjectError> { + let no_image = PathBuf::from("/no/image/specified"); + let image = if let Some(image) = &config.image { + image.to_path_buf() + } else { + no_image.clone() + }; + let mut project = Self { + source: PathBuf::from("."), + shell: "".into(), + image, + }; project.add_from(filename)?; + if project.shell.is_empty() { + return Err(ProjectError::NoShell); + } + if project.image == no_image { + return Err(ProjectError::NoImage); + } Ok(project) } @@ -33,6 +51,9 @@ impl Project { if let Some(x) = snippet.shell { self.shell = x; } + if let Some(x) = snippet.image { + self.image = x; + } Ok(()) } @@ -42,19 +63,12 @@ impl Project { } } -impl Default for Project { - fn default() -> Self { - Self { - source: PathBuf::from("."), - shell: "echo do nothing by default\n".into(), - } - } -} #[derive(Debug, Deserialize)] #[serde(deny_unknown_fields)] struct ProjectSnippet { source: Option<PathBuf>, shell: Option<String>, + image: Option<PathBuf>, } /// Possible errors from configuration file handling. @@ -69,4 +83,10 @@ pub enum ProjectError { #[error("failed to serialize project build instructions as YAML")] AsYaml(#[source] serde_yaml::Error), + + #[error("no shell commands for building specified by project")] + NoShell, + + #[error("no image specified by project or config")] + NoImage, } |