diff options
author | Lars Wirzenius <liw@liw.fi> | 2024-01-26 20:02:45 +0200 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2024-01-26 20:12:53 +0200 |
commit | e05e9f7eb69258b0909625289c4eb599d3cc8b47 (patch) | |
tree | 4fc427cd317d7b1b55b14f624e1af4b0b78fd23a | |
parent | b11ee78fe32b9482b4b83d636ea8cfb7b6563a8a (diff) | |
download | ambient-driver-e05e9f7eb69258b0909625289c4eb599d3cc8b47.tar.gz |
feat! add rsync post-plan action
This is a breaking change as it changes how the rsync effect is
achieved.
Signed-off-by: Lars Wirzenius <liw@liw.fi>
Sponsored-by: author
-rw-r--r-- | ambient-driver.md | 33 | ||||
-rw-r--r-- | src/action.rs | 26 | ||||
-rw-r--r-- | src/run.rs | 21 |
3 files changed, 60 insertions, 20 deletions
diff --git a/ambient-driver.md b/ambient-driver.md index 5e20085..a0a38b8 100644 --- a/ambient-driver.md +++ b/ambient-driver.md @@ -270,3 +270,36 @@ projects: echo "counter is now $(cat "$counter")." find "$cache" -ls ~~~ +# Publish files via rsync + +_Requirement:_ Artifacts can be published via rsync to a server. + +_Justification:_ This allows publishing many kinds of things. + +_Stakeholders:_ Lars + +~~~scenario +given an installed ambient-driver +given file .config/ambient-driver/config.yaml from config.yaml +given an Ambient VM image ambient.qcow2 +given file rsync.yaml +given a directory srcdir +given file srcdir/data.dat from rsync.yaml + +given a directory serverdir +when I run ambient-driver run rsync.yaml --target serverdir +then file serverdir/hello.txt contains "hello, world" +~~~ + +~~~{#rsync.yaml .file .yaml} +projects: + hello: + image: ambient.qcow2 + source: srcdir + plan: + - action: shell + shell: | + echo hello, world > /workspace/artifacts/hello.txt + post_plan: + - action: rsync +~~~ diff --git a/src/action.rs b/src/action.rs index de4dd18..c62a286 100644 --- a/src/action.rs +++ b/src/action.rs @@ -7,8 +7,10 @@ use log::{debug, info}; use serde::{Deserialize, Serialize}; use crate::{ + config::RunCommand, project::{Project, State}, qemu, + util::{rsync_server, UtilError}, vdrive::{VirtualDriveBuilder, VirtualDriveError}, }; @@ -44,6 +46,7 @@ impl PreAction { pub enum PostAction { Dummy, Pwd, + Rsync, } impl PostAction { @@ -51,11 +54,17 @@ impl PostAction { &["dummy", "pwd"] } - pub fn execute(&self, project: &Project, _state: &State) -> Result<(), ActionError> { + pub fn execute( + &self, + project: &Project, + state: &State, + run: &RunCommand, + ) -> Result<(), ActionError> { debug!("Plan::execute: {:#?}", self); match self { Self::Dummy => dummy(), Self::Pwd => pwd(project), + Self::Rsync => rsync(state, run), } } } @@ -70,6 +79,15 @@ fn pwd(project: &Project) -> Result<(), ActionError> { Ok(()) } +fn rsync(state: &State, run: &RunCommand) -> Result<(), ActionError> { + if let Some(target) = &run.target() { + rsync_server(&state.artifactsdir(), target)?; + } else { + return Err(ActionError::RsyncTargetMissing); + } + Ok(()) +} + fn cargo_fetch(project: &Project, state: &State) -> Result<(), ActionError> { let cargo_home = state.statedir().join("dependencies"); // FIXME: hardcoded pathname if !cargo_home.exists() { @@ -381,6 +399,12 @@ pub enum ActionError { #[error("failed to create symlink {0} -> {1}")] Symlink(PathBuf, PathBuf, #[source] std::io::Error), + + #[error(transparent)] + Util(#[from] UtilError), + + #[error("for the rsync action you must specify an rsync target (config or command line)")] + RsyncTargetMissing, } #[cfg(test)] @@ -14,7 +14,7 @@ use crate::{ plan::{Plan, PlanError}, project::{Project, ProjectError, Projects, State}, qemu::{self, Qemu, QemuError}, - util::{changes_file, dput, mkdir, mkdir_child, recreate_dir, rsync_server, UtilError}, + util::{changes_file, dput, mkdir, mkdir_child, recreate_dir, UtilError}, vdrive::{VirtualDriveBuilder, VirtualDriveError}, }; @@ -43,7 +43,6 @@ fn cmd_run(config: &EffectiveConfig, run: &RunCommand) -> Result<(), RunError> { mkdir(&dependencies)?; } - let mut rsync_target = None; let mut dput_target = None; for (name, project) in chosen(run, &projects) { @@ -115,24 +114,11 @@ fn cmd_run(config: &EffectiveConfig, run: &RunCommand) -> Result<(), RunError> { vdrive.extract_to(&artifactsdir)?; if project.publish_artifacts() { - if let Some(target) = run.target() { - rsync_target = Some(target); - } else { - return Err(RunError::TargetMissing); - } - if let Some(target) = run.dput_target() { dput_target = Some(target); } } - if let Some(target) = rsync_target { - debug!("publishing artifacts to {}", target); - rsync_server(&artifactsdir, target)?; - } else { - debug!("not publishing artifacts: not requested"); - } - if let Some(target) = dput_target { debug!("publishing artifacts with dput {}", target); let changes = changes_file(&artifactsdir)?; @@ -141,7 +127,7 @@ fn cmd_run(config: &EffectiveConfig, run: &RunCommand) -> Result<(), RunError> { debug!("Executing post-plan steps"); for action in project.post_plan() { - action.execute(project, &state)?; + action.execute(project, &state, run)?; } if is_git(project.source()) { @@ -295,9 +281,6 @@ fn cmd_actions() { #[derive(Debug, thiserror::Error)] pub enum RunError { - #[error("for ikiwiki projects you must specify an rsync target")] - TargetMissing, - #[error(transparent)] Project(#[from] ProjectError), |