Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions commands/src/apply/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ pub fn run(
opts: &ApplyOpts,
providers: TelemetryProviders,
) -> ExitCode {
let t_start = Timestamp::now(); // For the report
let start_time = Instant::now(); // For metrics
let start_timestamp = Timestamp::now(); // goes in the the report
let run_timer = Instant::now(); // calculate run duration for metrics

let exit_code = match config::compile(host_file, opts) {
Ok(cfg) => {
let lock = lockfile::acquire(opts);

if lockfile::is_on(&start_time, &lock) {
if lockfile::is_on(&run_timer, &lock) {
ExitCode::FAILURE
} else {
let run_result = Applicator::from(cfg).run(opts);
let elapsed_time = start_time.elapsed();
let elapsed_time = run_timer.elapsed();
tracing::info!("Run time: {:.3?}", elapsed_time);

let run_exit_code = match run_result {
Expand All @@ -44,7 +44,7 @@ pub fn run(
fail_phase: None,
summary: Some(&apply_summary),
duration: &elapsed_time,
t_start,
t_start: start_timestamp,
t_end: Timestamp::now(),
host_file: host_file.map(|f| f.to_owned()),
opts,
Expand All @@ -69,7 +69,7 @@ pub fn run(
fail_phase: Some(FailPhase::Apply),
summary: None,
duration: &elapsed_time,
t_start,
t_start: start_timestamp,
t_end: Timestamp::now(),
host_file: host_file.map(|f| f.to_owned()),
opts,
Expand Down Expand Up @@ -100,7 +100,7 @@ pub fn run(
}
};

metrics::send(ApplyStatus::Fail(e.into()), &start_time.elapsed());
metrics::send(ApplyStatus::Fail(e.into()), &run_timer.elapsed());
ExitCode::FAILURE
}
};
Expand Down
21 changes: 11 additions & 10 deletions doc/commands/apply.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@ There are options:
Useful for cleaning up during development, but should be used with extreme
caution. It has no short value, so you can't type it by accident.
- `--no-lock` makes Gurp not check for, create, or remove its runtime lock file.
- `--no-report` Gurp normally writes a JSON report in `/var/log/` at the end
of a run. This option turns of that report.
- `--pre-run-noop` Runs a no-op before the normal apply: this is very
fast and minimises the chance of a partially applied config. Can be
problematic in some circumstances. For instance, if your config adds a `pkg`
repo then installs packages from it.
- `--no-report` Gurp normally writes a JSON report in `/var/log/` at the end of
a run. This option turns of that report.
- `--pre-run-noop` Runs a no-op before the normal apply: this is very fast and
minimises the chance of a partially applied config. Can be problematic in some
circumstances. For instance, if your config adds a `pkg` repo then installs
packages from it.
- `--post-run-noop` If a Gurp `apply` makes a change to the system state, this
option makes it immediately re-run the config as a no-op. If the no-op finds
changes must be made, Gurp assumes it failed to correctly assert state, and
Expand All @@ -92,10 +92,11 @@ There are options:
- `-O, --only <REGEX>` Makes Gurp only apply resources whose IDs match the given
Rust regex.
- `-D, --define <DEFINE>` Can be used multiple time, with the values used to
build a Janet struct, `gurp-user-defs` with global scope, visible during the
compile phase. If `DEFINE` is of the form `key=value`, the struct gets `key`
as a symbol and `value` as a string. If `DEFINE` is `key` only, the struct
gets `key` as a symbol, with a value of boolean `true`.
build a Janet struct, `gurp-user-defs` set as a dynamic binding with global
scope, visible during the compile phase. If `DEFINE` is of the form
`key=value`, the struct gets `key` as a symbol and `value` as a string. If
`DEFINE` is `key` only, the struct gets `key` as a symbol, with a value of
boolean `true`.
- `-S, --splay <SPLAY>` pauses for a random time up to a maximum of `SPLAY`
seconds prior to applying. A splay time can also be set via `control-data`,
but the command-line value takes precedence.
Expand Down
1 change: 1 addition & 0 deletions doc/doers/zone.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ None
## Notes

- You must supply exactly one of `:file` and `:server`.
- On a bootstrap run, `gurp-user-defs` contains `:is-bootstrap true`, so you can change behaviour on an initial run.

# zone/cloudinit

Expand Down
2 changes: 2 additions & 0 deletions doers/src/zone/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ fn bootstrap(zone: &str, conf: &ZoneConfig, opts: &ApplyOpts) -> anyhow::Result<
bootstrap_args.push(format!("--metrics-to={metrics_host}"));
}

bootstrap_args.push("-Dis-bootstrap".to_owned());

ensure!(
exactly_one_some!(bootstrap_conf.server, bootstrap_conf.file),
"bootstrap requires exactly one of :file and :server"
Expand Down
8 changes: 4 additions & 4 deletions embed/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub fn gurp(vmopts: &ApplyVmOpts, destroy: bool) -> anyhow::Result<JanetClient>
}

if vmopts.define.is_empty() {
janet_instructions.push_str(r#"(defglobal "gurp-user-defs" {})"#);
janet_instructions.push_str(r#"(setdyn :gurp-user-defs {})"#);
} else {
janet_instructions.push_str(&define_string(vmopts));
}
Expand All @@ -60,7 +60,7 @@ fn destroyer_string() -> String {
/// contain an '=', are split on that char, with the first part becoming a struct key (keyword)
/// and the second becoming the corresponding value (string). If there is no '=', the whole value
/// becomes a key (keyword) and the value is set to true (boolean).
fn define_string(vmopts: &ApplyVmOpts) -> String {
pub fn define_string(vmopts: &ApplyVmOpts) -> String {
tracing::debug!("setting gurp-user-defs");

let bindings = vmopts
Expand All @@ -87,7 +87,7 @@ fn define_string(vmopts: &ApplyVmOpts) -> String {
if bindings.is_empty() {
String::new()
} else {
format!(r#"(defglobal "gurp-user-defs" (struct {bindings}))"#)
format!(r#"(setdyn :gurp-user-defs (struct {bindings}))"#)
}
}

Expand Down Expand Up @@ -125,7 +125,7 @@ mod tests {
};

assert_eq!(
r#"(defglobal "gurp-user-defs" (struct (keyword "boolean") true (keyword "key") "value"))"#,
r#"(setdyn :gurp-user-defs (struct (keyword "boolean") true (keyword "key") "value"))"#,
define_string(&opts)
);
}
Expand Down
2 changes: 1 addition & 1 deletion embed/src/compiler.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::client;
use super::client;
use anyhow::Context;
use camino::Utf8Path;
use common::constants::SERVER_PORT;
Expand Down
4 changes: 3 additions & 1 deletion janet/src/doers/zone/bootstrap.janet
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
bootstrap"}}

:notes
["You must supply exactly one of `:file` and `:server`."])
["You must supply exactly one of `:file` and `:server`."
"On a bootstrap run, `gurp-user-defs` contains `:is-bootstrap true`, so
you can change behaviour on an initial run."])

(defn bootstrap
"Given a spec, return config to bootstrap a zone"
Expand Down
18 changes: 10 additions & 8 deletions janet/src/dsl.janet
Original file line number Diff line number Diff line change
Expand Up @@ -306,19 +306,21 @@
(default key-column 0)
(tabular-rows->struct (lines tabular-output) key-column))

(defn gurp-user-defs
"A shim around the :gurp-user-defs dyn for backward compatibility"
[key]
(let [user-defs (dyn :gurp-user-defs {})]
(user-defs (keyword key))))

(defn recreate?
"Returns 1 (true) or 0 (false) depending on whether the user has defined
:recreate-zone-<name> or :recreate-all-zones. To be used in conjunction with
the zone :recreate property"
[zone-name]
(let [user-defs (get (curenv) 'gurp-user-defs)]
(if (not user-defs)
0
(if (or
((user-defs :value) (keyword "recreate-all-zones"))
((user-defs :value) (keyword "recreate-zone-" zone-name)))
1
0))))
(if (or (gurp-user-defs :recreate-all-zones)
(gurp-user-defs (keyword "recreate-zone-" zone-name)))
1
0))

(defn num-field-sort
"Sort a file when each line's first field is numeric"
Expand Down
Loading