Skip to content

Commit 2321bb3

Browse files
kasimekaytsssun
authored andcommitted
bootstrap-containers: add support for custom entrypoint commands
Add command field to bootstrap container configuration and corresponding template support to customize container entrypoints. Implements CTR_COMMAND environment variable in service files that is passed to host-ctr. Signed-off-by: Yutong Sun <[email protected]>
1 parent c3fc0dd commit 2321bb3

File tree

4 files changed

+39
-5
lines changed

4 files changed

+39
-5
lines changed

packages/os/bootstrap-containers-toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[required-extensions]
22
bootstrap-containers = "v1"
3-
std = { version = "v1", helpers = ["if_not_null"] }
3+
std = { version = "v1", helpers = ["if_not_null", "toml_encode"]}
44
+++
55
{{#if_not_null settings.bootstrap-containers}}
66
{{#each settings.bootstrap-containers}}
@@ -17,5 +17,8 @@ user-data = "{{{this.user-data}}}"
1717
{{#if_not_null this.essential}}
1818
essential = {{this.essential}}
1919
{{/if_not_null}}
20+
{{#if_not_null this.command}}
21+
command = {{ toml_encode this.command }}
22+
{{/if_not_null}}
2023
{{/each}}
2124
{{/if_not_null}}

packages/os/[email protected]

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ ExecStart=/usr/bin/host-ctr run \
2222
--container-id='%i' \
2323
--source='${CTR_SOURCE}' \
2424
--container-type='bootstrap' \
25+
--command='${CTR_COMMAND}' \
2526
--registry-config=/etc/host-containers/host-ctr.toml
2627
ExecStartPost=/usr/bin/bootstrap-containers mark-bootstrap \
2728
--container-id '%i' \

sources/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sources/api/bootstrap-containers/src/main.rs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ struct BootstrapContainer {
106106
user_data: Option<ValidBase64>,
107107
#[serde(default, skip_serializing_if = "Option::is_none")]
108108
essential: Option<bool>,
109+
#[serde(default, skip_serializing_if = "Vec::is_empty")]
110+
command: Vec<String>,
109111
}
110112

111113
/// Stores user-supplied global arguments
@@ -275,6 +277,11 @@ where
275277
let mode = container_details.mode.clone().unwrap_or_default();
276278

277279
let essential = container_details.essential.unwrap_or(false);
280+
let command = serde_json::to_string(&container_details.command).context(
281+
error::SerializeContainerCommandSnafu {
282+
command: container_details.command.clone(),
283+
},
284+
)?;
278285

279286
// Create the directory regardless if user data was provided for the container
280287
let dir = Path::new(PERSISTENT_STORAGE_DIR).join(name);
@@ -299,7 +306,7 @@ where
299306

300307
// Write the environment file needed for the systemd service to have details
301308
// this specific bootstrap container
302-
write_config_files(name, source, &mode, essential)?;
309+
write_config_files(name, source, &mode, essential, command)?;
303310

304311
if mode == "off" {
305312
// If mode is 'off', disable the container, and clean up any left over tasks
@@ -311,7 +318,7 @@ where
311318

312319
if host_containerd_unit.is_active()? {
313320
debug!("Cleaning up container '{}'", name);
314-
command(
321+
crate::command(
315322
constants::HOST_CTR_BIN,
316323
[
317324
"clean-up",
@@ -325,7 +332,7 @@ where
325332

326333
// Clean up any left over tasks, before the container is enabled
327334
if host_containerd_unit.is_active()? && !systemd_unit.is_enabled()? {
328-
command(
335+
crate::command(
329336
constants::HOST_CTR_BIN,
330337
[
331338
"clean-up",
@@ -343,11 +350,18 @@ where
343350
}
344351

345352
/// Write out the EnvironmentFile that systemd uses to fill in arguments to host-ctr
346-
fn write_config_files<S1, S2, S3>(name: S1, source: S2, mode: S3, essential: bool) -> Result<()>
353+
fn write_config_files<S1, S2, S3, S4>(
354+
name: S1,
355+
source: S2,
356+
mode: S3,
357+
essential: bool,
358+
command: S4,
359+
) -> Result<()>
347360
where
348361
S1: AsRef<str>,
349362
S2: AsRef<str>,
350363
S3: AsRef<str>,
364+
S4: AsRef<str>,
351365
{
352366
let name = name.as_ref();
353367

@@ -366,6 +380,11 @@ where
366380
value: mode.as_ref(),
367381
},
368382
)?;
383+
writeln!(output, "CTR_COMMAND={}", command.as_ref()).context(
384+
error::WriteConfigurationValueSnafu {
385+
value: mode.as_ref(),
386+
},
387+
)?;
369388

370389
debug!("Writing environment file for unit '{}'", name);
371390
fs::write(&env_path, output).context(error::WriteConfigurationFileSnafu { path: env_path })?;
@@ -659,6 +678,16 @@ mod error {
659678

660679
#[snafu(display("Failed write value '{}': {}", value, source))]
661680
WriteConfigurationValue { value: String, source: fmt::Error },
681+
682+
#[snafu(display(
683+
"Failed to serialize container entrypoint command {:?}: {}",
684+
command,
685+
source
686+
))]
687+
SerializeContainerCommand {
688+
command: Vec<String>,
689+
source: serde_json::Error,
690+
},
662691
}
663692
}
664693

0 commit comments

Comments
 (0)