summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2024-01-26 20:02:45 +0200
committerLars Wirzenius <liw@liw.fi>2024-01-26 20:12:53 +0200
commite05e9f7eb69258b0909625289c4eb599d3cc8b47 (patch)
tree4fc427cd317d7b1b55b14f624e1af4b0b78fd23a
parentb11ee78fe32b9482b4b83d636ea8cfb7b6563a8a (diff)
downloadambient-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.md33
-rw-r--r--src/action.rs26
-rw-r--r--src/run.rs21
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)]
diff --git a/src/run.rs b/src/run.rs
index 9c2a25d..53d48bc 100644
--- a/src/run.rs
+++ b/src/run.rs
@@ -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),