Skip to content

Commit c2086ff

Browse files
committed
initial commit (configuration, registration, launch, executor)
0 parents  commit c2086ff

12 files changed

+1751
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
/Cargo.lock

Cargo.toml

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[package]
2+
name = "gitlab-meta-runner"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
anyhow = "1.0.87"
8+
async-process = "2.2.4"
9+
async-std = "1.13.0"
10+
clap = { version = "4.5.17", features = ["derive", "string"] }
11+
clap-verbosity-flag = "2.2.1"
12+
colored = "2.1.0"
13+
dirs = "5.0.1"
14+
futures = "0.3.30"
15+
gitlab = "0.1705.0"
16+
http = "1.1.0"
17+
itertools = "0.13.0"
18+
log = "0.4.22"
19+
serde = "1.0.210"
20+
serde_derive = "1.0.210"
21+
serde_json = "1.0.128"
22+
shellexpand = "3.1.0"
23+
simple_logger = { version = "5.0.0", features = ["stderr"] }
24+
tokio = { version = "1.40.0", features = ["full"] }
25+
toml = "0.8.19"

src/check_config.rs

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
use anyhow::Context;
2+
use colored::Colorize;
3+
use log::info;
4+
5+
use crate::{
6+
cli,
7+
config::read_config,
8+
template::{
9+
expand_executor_config_template, expand_launch_config_template,
10+
expand_runner_config_template,
11+
},
12+
};
13+
14+
pub fn check(paths: &cli::Paths) -> anyhow::Result<()> {
15+
let config = read_config(&paths.config_file).context(format!(
16+
"Failed reading config file {:?}",
17+
paths.config_file
18+
))?;
19+
let num_jobs = config.launch.as_ref().map_or(1, |v| v.group_size);
20+
for (instance_name, instance) in &config.runners {
21+
expand_runner_config_template(&config.runner, instance_name, instance).context(format!(
22+
"Failed expanding [runner] for instance {}",
23+
instance_name
24+
))?;
25+
expand_executor_config_template(&config, instance_name, instance).context(format!(
26+
"Failed expanding [executor] for instance {}",
27+
instance_name
28+
))?;
29+
expand_launch_config_template(paths, &config, instance_name, instance, num_jobs).context(
30+
format!("Failed expanding [launch] for instance {}", instance_name),
31+
)?;
32+
}
33+
info!("Config check successful, no errors found");
34+
Ok(())
35+
}
36+
37+
pub fn show(paths: &cli::Paths) -> anyhow::Result<()> {
38+
let config = read_config(&paths.config_file).context(format!(
39+
"Failed reading config file {:?}",
40+
paths.config_file
41+
))?;
42+
info!("{}", "Full configuration".green());
43+
println!(
44+
"{}",
45+
toml::to_string_pretty(&config).context("Failed printing config")?
46+
);
47+
let num_jobs = config.launch.as_ref().map_or(1, |v| v.group_size);
48+
for (instance_name, instance) in &config.runners {
49+
println!(
50+
"{}",
51+
format!("gitlab-runner configuration for runner {}", instance_name).green()
52+
);
53+
println!(
54+
"{}",
55+
toml::to_string_pretty(
56+
&expand_runner_config_template(&config.runner, instance_name, instance).context(
57+
format!("Failed expanding [runner] for instance {}", instance_name)
58+
)?
59+
)
60+
.context("Failed printing config")?
61+
);
62+
println!(
63+
"{}",
64+
format!("executor configuration for runner {}", instance_name).green()
65+
);
66+
println!(
67+
"{}",
68+
toml::to_string_pretty(
69+
&expand_executor_config_template(&config, instance_name, instance).context(
70+
format!("Failed expanding [executor] for instance {}", instance_name)
71+
)?
72+
)
73+
.context("Failed printing config")?
74+
);
75+
println!(
76+
"{}",
77+
format!("launch configuration for runner {}", instance_name).green()
78+
);
79+
println!(
80+
"{}",
81+
toml::to_string_pretty(
82+
&expand_launch_config_template(paths, &config, instance_name, instance, num_jobs)
83+
.context(format!(
84+
"Failed expanding [launch] for instance {}",
85+
instance_name
86+
),)?
87+
)
88+
.context("Failed printing config")?
89+
);
90+
}
91+
Ok(())
92+
}

src/cli.rs

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
use std::path::PathBuf;
2+
3+
use clap::{Args, Parser, Subcommand};
4+
use clap_verbosity_flag::{InfoLevel, Verbosity};
5+
6+
use crate::config;
7+
8+
#[derive(Debug, Args)]
9+
pub struct Paths {
10+
/// Configuration file for the meta-runner
11+
#[arg(long, default_value = config::get_default_config_file_path().into_os_string())]
12+
pub config_file: PathBuf,
13+
/// Directory used to store meta-runner data (registered runners, their tokens and generated gitlab-runner config files)
14+
/// The files in this directory will be prefixed by the meta-runner's name
15+
#[arg(long, default_value = config::get_default_data_dir().into_os_string(), verbatim_doc_comment)]
16+
pub data_dir: PathBuf,
17+
/// Path for the generated gitlab-runner configuration file.
18+
/// Only use this if you don't want to use the default location in `data_dir`
19+
#[arg(long, verbatim_doc_comment)]
20+
pub generated_config_file: Option<PathBuf>,
21+
}
22+
23+
#[derive(Debug, Subcommand)]
24+
pub enum ExecutorCommand {
25+
// Run the config step of the custom executor
26+
Config,
27+
// Run the prepare step of the custom executor
28+
Prepare,
29+
// Run the run step of the custom executor
30+
Run {
31+
/// The script to be executed
32+
script_name: PathBuf,
33+
/// The step to be executed in the script
34+
step_name: String,
35+
},
36+
// Run the cleanup step of the custom executor
37+
Cleanup,
38+
}
39+
40+
#[derive(Debug, Args)]
41+
pub struct ExecutorOptions {
42+
/// The name of the runner configuration to use
43+
pub runner_name: String,
44+
#[command(subcommand)]
45+
pub command: ExecutorCommand,
46+
}
47+
48+
#[derive(Debug, Subcommand)]
49+
pub enum Command {
50+
/// Creates an example configuration file
51+
CreateExampleConfig,
52+
/// Prints the example configuration
53+
ShowExampleConfig,
54+
/// Checks the configuration for validity
55+
CheckConfig,
56+
/// Show the configuration instantiated for each runner
57+
ShowConfig,
58+
/// Updates runner registrations and gitlab-runner config files
59+
Configure,
60+
/// Run the custom executor
61+
Executor(ExecutorOptions),
62+
/// Run the meta-runner a single time to dispatch runners for all currently pending jobs
63+
RunSingle,
64+
/// Run the meta-runner continuously to dispatch runners at regular intervals
65+
Run,
66+
}
67+
68+
#[derive(Parser, Debug)]
69+
pub struct CliOptions {
70+
#[command(subcommand)]
71+
pub command: Command,
72+
/// Config file paths
73+
#[command(flatten)]
74+
pub paths: Paths,
75+
#[command(flatten)]
76+
pub verbose: Verbosity<InfoLevel>,
77+
}

0 commit comments

Comments
 (0)