Relocate the primitive agent into the agent directory and wire in block scoped steps for the dir step
This was WAY EASIER than I thought it would be, which has me extra pumped about this design decision. The pipeline.yml sent to the agent: --- steps: - symbol: sh parameters: script: 'ls -lah | tail -n 5' - symbol: sh parameters: script: 'echo "Hello world from a script"' - symbol: dir parameters: directory: 'stdlib' block: - symbol: sh parameters: script: 'pwd && ls -lah' - symbol: echo parameters: message: 'Hello from a block-scoped step!' - symbol: unknown parameters: message: 'this should fail' Then executing it in the tree: ❯ STEPS_DIR=$PWD/tmp ./target/debug/otto-agent ./test-pipeline.yml sh exists sh exists dir exists unknown/manifest.yml does not exist, step cannot execute NORMALLY THIS WOULD ERROR BEFORE ANYTHING EXECUTES --- -rw-r--r-- 1 tyler users 1.1K Feb 20 2020 system.dot -rw-r--r-- 1 tyler users 43K Feb 20 2020 system.png drwxr-xr-x 7 tyler users 4.0K Oct 17 15:25 target -rw-r--r-- 1 tyler users 1.5K Oct 22 20:38 test-pipeline.yml drwxr-xr-x 5 tyler users 4.0K Oct 22 20:35 tmp Hello world from a script sh exists echo exists --- /home/tyler/source/git/otto/stdlib total 20K drwxr-xr-x 5 tyler users 4.0K Oct 22 20:02 . drwxr-xr-x 22 tyler users 4.0K Oct 22 20:38 .. drwxr-xr-x 4 tyler users 4.0K Oct 22 20:19 dir drwxr-xr-x 2 tyler users 4.0K Oct 22 20:28 echo drwxr-xr-x 4 tyler users 4.0K Oct 21 19:40 sh Hello from a block-scoped step! Voila!
This commit is contained in:
parent
43116fdd5a
commit
c11c05aac0
|
@ -215,6 +215,7 @@ dependencies = [
|
|||
name = "dir-step"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"otto-agent 0.1.0",
|
||||
"serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_yaml 0.8.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -610,6 +611,17 @@ dependencies = [
|
|||
"tar 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "otto-agent"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"nanomsg 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"osp 0.1.0",
|
||||
"serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_yaml 0.8.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "otto-auctioneer"
|
||||
version = "0.1.0"
|
||||
|
@ -668,17 +680,6 @@ dependencies = [
|
|||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "primitive-agent"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"nanomsg 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"osp 0.1.0",
|
||||
"serde 1.0.117 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_yaml 0.8.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.18"
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
members = [
|
||||
"auctioneer",
|
||||
|
||||
"agents/primitive",
|
||||
"agent",
|
||||
|
||||
"eventbus",
|
||||
"eventbus-cli",
|
||||
|
|
|
@ -1,12 +1,20 @@
|
|||
[package]
|
||||
name = "primitive-agent"
|
||||
name = "otto-agent"
|
||||
version = "0.1.0"
|
||||
authors = ["R. Tyler Croy <rtyler@brokenco.de>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "ottoagent"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "otto-agent"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
serde_yaml = "~0.8.13"
|
||||
serde = {version = "~1.0.117", features = ["rc", "derive"]}
|
||||
osp = { path = "../../osp" }
|
||||
osp = { path = "../osp" }
|
||||
tempfile = "~3.1.0"
|
||||
nanomsg = "0.7.2"
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
|
||||
use serde::Deserialize;
|
||||
use serde_yaml::Value;
|
||||
use std::collections::HashMap;
|
||||
|
@ -10,17 +9,17 @@ use std::process::Command;
|
|||
use tempfile::NamedTempFile;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
struct Pipeline {
|
||||
steps: Vec<Step>,
|
||||
pub struct Pipeline {
|
||||
pub steps: Vec<Step>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
struct Step {
|
||||
symbol: String,
|
||||
parameters: Value,
|
||||
pub struct Step {
|
||||
pub symbol: String,
|
||||
pub parameters: Value,
|
||||
}
|
||||
|
||||
fn run(steps_dir: &str, steps: &Vec<Step>) -> std::io::Result<()> {
|
||||
pub fn run(steps_dir: &str, steps: &Vec<Step>) -> std::io::Result<()> {
|
||||
let dir = Path::new(steps_dir);
|
||||
|
||||
if ! dir.is_dir() {
|
||||
|
@ -55,7 +54,6 @@ fn run(steps_dir: &str, steps: &Vec<Step>) -> std::io::Result<()> {
|
|||
if let Some(runner) = manifests.get(&step.symbol) {
|
||||
let m_path = m_paths.get(&step.symbol).expect("Failed to grab the step library path");
|
||||
let entrypoint = m_path.join(&runner.entrypoint.path);
|
||||
println!("entry: {:?}", entrypoint);
|
||||
|
||||
let mut file = NamedTempFile::new()?;
|
||||
let mut step_args = HashMap::new();
|
||||
|
@ -76,23 +74,7 @@ fn run(steps_dir: &str, steps: &Vec<Step>) -> std::io::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn main() -> std::io::Result<()>{
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let steps_dir = std::env::var("STEPS_DIR").expect("STEPS_DIR must be defined");
|
||||
|
||||
if args.len() != 2 {
|
||||
panic!("The sh step can only accept a single argument: the parameters file path");
|
||||
}
|
||||
|
||||
let file = File::open(&args[1])?;
|
||||
|
||||
match serde_yaml::from_reader::<File, Pipeline>(file) {
|
||||
Err(e) => {
|
||||
panic!("Failed to parse parameters file: {:#?}", e);
|
||||
}
|
||||
Ok(invoke) => {
|
||||
run(&steps_dir, &invoke.steps);
|
||||
},
|
||||
};
|
||||
Ok(())
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
use std::fs::File;
|
||||
|
||||
use ottoagent::*;
|
||||
|
||||
fn main() -> std::io::Result<()>{
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let steps_dir = std::env::var("STEPS_DIR").expect("STEPS_DIR must be defined");
|
||||
|
||||
if args.len() != 2 {
|
||||
panic!("The sh step can only accept a single argument: the parameters file path");
|
||||
}
|
||||
|
||||
let file = File::open(&args[1])?;
|
||||
|
||||
match serde_yaml::from_reader::<File, Pipeline>(file) {
|
||||
Err(e) => {
|
||||
panic!("Failed to parse parameters file: {:#?}", e);
|
||||
}
|
||||
Ok(invoke) => {
|
||||
run(&steps_dir, &invoke.steps);
|
||||
},
|
||||
};
|
||||
Ok(())
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
= Otto Agents
|
||||
|
||||
This directory contains a number of agent implementations with varying levels
|
||||
of functionality.
|
|
@ -80,6 +80,8 @@ pub enum ParameterType {
|
|||
StringParameter,
|
||||
#[serde(rename = "boolean")]
|
||||
BoolParameter,
|
||||
#[serde(rename = "block")]
|
||||
BlockParameter,
|
||||
}
|
||||
|
||||
/** Simple function for serde defaults */
|
||||
|
|
|
@ -7,3 +7,4 @@ edition = "2018"
|
|||
[dependencies]
|
||||
serde_yaml = "~0.8.13"
|
||||
serde = {version = "~1.0.117", features = ["derive"]}
|
||||
otto-agent = { path = "../../agent" }
|
||||
|
|
|
@ -1,64 +1,25 @@
|
|||
# This manifest captures the basic functionality of the Jenkins Pipeline `sh`
|
||||
# step
|
||||
---
|
||||
# The symbol defines how this step should present in the pipeline
|
||||
symbol: sh
|
||||
# Description is help text
|
||||
symbol: dir
|
||||
description: |
|
||||
The `sh` step executes a shell script within the given execution context
|
||||
The `dir` step executes a collection of steps from within the specified directory
|
||||
|
||||
# List all the files/globs to include in the packaged artifact
|
||||
includes:
|
||||
# Paths are treated as relative from wherever osp is invoked from
|
||||
- name: target/release/sh-step
|
||||
# Steps the entire prefix of the file name, placing the file in the root of
|
||||
# the artifact
|
||||
- name: target/release/dir-step
|
||||
flatten: true
|
||||
# A name starting with ./ is treated to be relative to the manifest.yml
|
||||
- name: ./README.adoc
|
||||
|
||||
# The entrypoint tells the Otto agent which actual binary to use when
|
||||
# executing.
|
||||
entrypoint:
|
||||
path: sh-step
|
||||
# Multiarch tells the agent that this should be executed on all platforms. In
|
||||
# which case case it may be "blindly" invoked.
|
||||
#
|
||||
# Non-multiarch steps will be attempt to be invoked with
|
||||
# `${entrypoint.path}-${arch}-${vendor}-${system}-${abi}` similar to how
|
||||
# Rust manages target triples: https://doc.rust-lang.org/nightly/rustc/platform-support.html
|
||||
path: dir-step
|
||||
multiarch: false
|
||||
|
||||
parameters:
|
||||
- name: script
|
||||
- name: directory
|
||||
required: true
|
||||
type: string
|
||||
description: |
|
||||
Runs a Bourne shell script, typically on a Unix node. Multiple lines are accepted.
|
||||
THe directory to enter into, will error if the directory doesn't already exist
|
||||
|
||||
An interpreter selector may be used, for example: `#!/usr/bin/perl`
|
||||
|
||||
Otherwise the system default shell will be run, using the `-xe` flags (you can specify `set +e` and/or `set +x` to disable those).
|
||||
|
||||
- name: encoding
|
||||
- name: block
|
||||
description: |
|
||||
Encoding of the stdout/stderr output, not typically needed as the system will
|
||||
default to whatever `LC_TYPE` is defined.
|
||||
type: string
|
||||
required: false
|
||||
|
||||
- name: label
|
||||
description: |
|
||||
A label to identify the shell step in a GUI.
|
||||
type: string
|
||||
required: false
|
||||
|
||||
- name: returnStatus
|
||||
description: Compatibility support only, doesn't do anything
|
||||
type: boolean
|
||||
required: false
|
||||
|
||||
- name: returnStdout
|
||||
description: Compatibility support only, doesn't do anything
|
||||
type: boolean
|
||||
required: false
|
||||
Block containing the steps to execute in the directory
|
||||
type: block
|
||||
required: true
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
*/
|
||||
|
||||
use serde::Deserialize;
|
||||
use serde_yaml::Value;
|
||||
use std::fs::File;
|
||||
|
||||
use ottoagent::*;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
struct Invocation {
|
||||
parameters: Parameters,
|
||||
|
@ -17,12 +18,9 @@ struct Parameters {
|
|||
block: Vec<Step>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
struct Step {
|
||||
symbol: String,
|
||||
parameters: Value,
|
||||
}
|
||||
fn main() -> std::io::Result<()> {
|
||||
let steps_dir = std::env::var("STEPS_DIR").expect("STEPS_DIR must be defined");
|
||||
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
|
||||
if args.len() != 2 {
|
||||
|
@ -37,6 +35,9 @@ fn main() -> std::io::Result<()> {
|
|||
}
|
||||
Ok(invoke) => {
|
||||
// do things
|
||||
std::env::set_current_dir(&invoke.parameters.directory)
|
||||
.expect("Failed to set current directory, perhaps it doesn't exist");
|
||||
run(&steps_dir, &invoke.parameters.block);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'yaml'
|
||||
|
||||
cat $1 | gawk 'match($0, /\s+message:\s+["](.*)?["]/, a) {print a[1]}'
|
||||
data = YAML.load(File.read(ARGV.first))
|
||||
|
||||
if data['parameters']
|
||||
puts data['parameters']['message']
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue