feat: add executor config

This commit is contained in:
Matthieu Bessat 2024-07-28 18:34:03 +02:00
parent 9f7c81644d
commit 3e2ec661a1
5 changed files with 96 additions and 17 deletions

View file

@ -2,11 +2,12 @@
## TODO ## TODO
- [x] Add CSS badge and color code on job status
- [ ] Add tasks timeout
- [ ] Support connecting to remote server by SSH to execute task remotely - [ ] Support connecting to remote server by SSH to execute task remotely
- [ ] Implement basic auth with OAuth2 - [ ] Implement basic auth with OAuth2
- [ ] Add a way to categorize tasks, regroup tasks - [ ] Add a way to categorize tasks, regroup tasks
- [ ] Don't use long UUID, but only ids - [ ] Don't use long UUID, but only ids
- [ ] Add CSS badge and color code on job status
- [ ] Validating config file - [ ] Validating config file
- validate schedule CRON syntax - validate schedule CRON syntax
- [ ] Add `Dockerfile` and docker-compose example - [ ] Add `Dockerfile` and docker-compose example

View file

@ -1,17 +1,44 @@
instance:
name: Example organization
logo_uri: https://example.org/logo.png
executor:
environment:
SUPER_COOL_DEFAULT_ENV: 438548
tasks: tasks:
- id: do_magic_stuff do_magic_stuff:
name: Do magic incantation name: Do magic incantation
env: environment:
PYTHONUNBUFFERED: "1" PYTHONUNBUFFERED: "1"
SIMULATION_SPEED: 0.2 SIMULATION_SPEED: 11
command: command:
- /usr/bin/python3 - /usr/bin/python3
- /home/mbess/workspace/autotasker/examples/do_something_1.py - /path/to/autotasker/examples/do_something_1.py
store_logs: true
- id: reindex_db reindex_db:
name: Reindex the whole database name: Reindex the whole database
env: {} env: {}
command: command:
- ls - ls
- /etc/fstab - /etc/fstab
schedule:
hours: 1
clean_up:
name: Clean up things
env: {}
command:
- cat
- /etc/environment
schedule:
"0 * * * * *"
webhooks:
- id: 1
name: "Trigger magic stuff"
token: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
target_tasks:
- do_magic_stuff
debounce_secs: 10

View file

@ -1,11 +1,11 @@
instance: executor:
name: Example company environment:
logo_uri: https://src.lefuturiste.fr/images/lefuturiste-300-300.png SUPER_COOL_DEFAULT_ENV: 438548
tasks: tasks:
do_magic_stuff: do_magic_stuff:
name: Do magic incantation name: Do magic incantation
env: environment:
PYTHONUNBUFFERED: "1" PYTHONUNBUFFERED: "1"
SIMULATION_SPEED: 11 SIMULATION_SPEED: 11
command: command:

View file

@ -112,11 +112,14 @@ async fn run_task(state: AppState, order: ExecutorOrder) -> Result<()> {
cmd.args(task.command.iter().skip(1).collect::<Vec<&String>>()) cmd.args(task.command.iter().skip(1).collect::<Vec<&String>>())
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.stderr(Stdio::piped()); .stderr(Stdio::piped());
for (key, val) in task.env.iter() { // add OS environment variables from default config and task config
for (key, val) in state.config.executor.environment.iter() {
cmd.env(key, val);
}
for (key, val) in task.environment.iter() {
cmd.env(key, val); cmd.env(key, val);
} }
let status = execute_process(&state, &order, &mut cmd).await?; let status = execute_process(&state, &order, &mut cmd).await?;
if !status.success() { if !status.success() {
error!("Non successful exit code found: {}", status); error!("Non successful exit code found: {}", status);
} }

View file

@ -83,9 +83,13 @@ enum ScheduleConfig {
#[fully_pub] #[fully_pub]
struct Task { struct Task {
name: String, name: String,
#[serde(default)]
description: Option<String>, description: Option<String>,
env: HashMap<String, String>, /// OS environment to add at runtime
#[serde(default)]
environment: HashMap<String, String>,
command: Vec<String>, command: Vec<String>,
#[serde(default)]
schedule: Option<ScheduleConfig> schedule: Option<ScheduleConfig>
} }
@ -99,11 +103,55 @@ struct ExecutorOrder {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[fully_pub] #[fully_pub]
/// branding config of the autotasker
struct InstanceConfig { struct InstanceConfig {
name: String, name: String,
logo_uri: String logo_uri: String
} }
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
#[fully_pub]
enum LogPolicy {
ErrorsOnly,
HeadAndTailOnly,
#[default]
All
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[fully_pub]
struct ExecutorConfig {
/// the maximum duration of a task run in seconds
#[serde(default)]
execution_timeout: u64,
/// the maximum heap memory that a task can allocate in KiloBytes
#[serde(default)]
max_memory: u64,
/// the default filter logs policy to apply on a task output
#[serde(default)]
log_policy: LogPolicy,
/// default OS environment to add at runtime
#[serde(default)]
environment: HashMap<String, String>,
}
impl Default for ExecutorConfig {
fn default() -> ExecutorConfig {
ExecutorConfig {
execution_timeout: 1000,
max_memory: 100_000,
log_policy: LogPolicy::All,
environment: HashMap::from([
("EXECUTOR".into(), "autotasker".into())
])
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[fully_pub] #[fully_pub]
struct Webhook { struct Webhook {
@ -122,9 +170,9 @@ struct Webhook {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[fully_pub] #[fully_pub]
struct Config { struct Config {
instance: InstanceConfig, #[serde(default = "ExecutorConfig::default")]
executor: ExecutorConfig,
instance: Option<InstanceConfig>,
tasks: HashMap<String, Task>, tasks: HashMap<String, Task>,
webhooks: Option<Vec<Webhook>> webhooks: Option<Vec<Webhook>>
} }