Skip to content

Commit 203e57f

Browse files
committed
Add --gvisor option for better sandboxing
1 parent 6f8755e commit 203e57f

File tree

4 files changed

+50
-8
lines changed

4 files changed

+50
-8
lines changed

src/cli.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{config::Config, Context, FULL_VERSION, LONG_VERSION};
1+
use crate::{FULL_VERSION, LONG_VERSION, config::Config, context::Context};
22
use clap::{Args, Parser, Subcommand};
33
use std::path::PathBuf;
44

@@ -84,6 +84,12 @@ pub struct CmdStartArgs {
8484
#[arg(long, env = crate::ENV_CONTAINER)]
8585
pub name: Option<String>,
8686

87+
/// Use gvisor runtime for better sandboxing (EXPERIMENTAL)
88+
///
89+
/// Requires runsc to be in PATH
90+
#[arg(long, value_name = "BOOL", default_missing_value = "true", require_equals = true, num_args = 0..=1)]
91+
pub gvisor: Option<bool>,
92+
8793
/// Set container default shell
8894
#[arg(long)]
8995
pub shell: Option<String>,

src/commands/cmd_start.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ pub fn start_container(ctx: Context, mut cli_args: CmdStartArgs) -> Result<()> {
154154

155155
// prefer options from cli
156156
cli_args.shell = cli_args.shell.or(config.shell);
157+
cli_args.gvisor = cli_args.gvisor.or(Some(config.gvisor));
157158
cli_args.network = cli_args.network.or(Some(config.network));
158159
cli_args.pipewire = cli_args.pipewire.or(Some(config.pipewire));
159160
cli_args.pulseaudio = cli_args.pulseaudio.or(Some(config.pulseaudio));
@@ -205,6 +206,19 @@ pub fn start_container(ctx: Context, mut cli_args: CmdStartArgs) -> Result<()> {
205206
"--detach-keys=",
206207
]);
207208

209+
if cli_args.gvisor.unwrap_or(false) {
210+
if !crate::executable_in_path("runsc") {
211+
return Err(anyhow!("Could not find gvisor (runsc) in path"));
212+
}
213+
214+
// TODO do i want the --rootless flag for runsc?
215+
cmd.args([
216+
// it seems it can look for it in path
217+
"--runtime=runsc",
218+
"--runtime-flag", "ignore-cgroups",
219+
]);
220+
}
221+
208222
cmd.args([
209223
format!("--name={}", container_name),
210224
format!("--label=manager={}", ctx.engine),

src/config/v1.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ code_docs_struct! {
3535
#[serde(default)]
3636
pub shell: Option<String>,
3737

38+
/// Use gvisor runtime for better sandboxing
39+
#[serde(default)]
40+
pub gvisor: bool,
41+
3842
/// Set network access
3943
#[serde(default)]
4044
pub network: bool,
@@ -85,7 +89,7 @@ code_docs_struct! {
8589
/// script itself is responsible for running arcam start with all the arguments
8690
///
8791
/// This allows you total control of the container startup which also
88-
/// makes it dangerous if you do not check the config file beforhand
92+
/// makes it dangerous if you do not check the config file beforehand
8993
///
9094
/// NOTE: the script is ran using "/bin/sh"
9195
pub host_pre_init: Option<String>,

tests/podman/test_start.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,20 @@ use anyhow::Result;
33
use assert_cmd::Command;
44
use arcam::engine::Podman;
55

6-
#[test]
7-
#[ignore = "requires podman"]
8-
fn cmd_start_podman() -> Result<()> {
6+
fn start_podman(gvisor: bool) -> Result<()> {
97
let tempdir = tempfile::tempdir()?;
108

11-
let cmd = Command::cargo_bin("arcam")?
12-
.args(["start", DEBIAN_IMAGE])
13-
.current_dir(tempdir.path())
9+
let mut cmd = Command::cargo_bin("arcam")?;
10+
cmd.current_dir(tempdir.path());
11+
cmd.args(["start"]);
12+
13+
if gvisor {
14+
cmd.arg("--gvisor");
15+
}
16+
17+
cmd.arg(DEBIAN_IMAGE);
18+
19+
let cmd = cmd
1420
.assert()
1521
.success();
1622

@@ -42,3 +48,15 @@ fn cmd_start_podman() -> Result<()> {
4248

4349
Ok(())
4450
}
51+
52+
#[test]
53+
#[ignore = "requires podman"]
54+
fn cmd_start_podman() -> Result<()> {
55+
start_podman(false)
56+
}
57+
58+
#[test]
59+
#[ignore = "requires podman and gvisor"]
60+
fn cmd_start_podman_gvisor() -> Result<()> {
61+
start_podman(true)
62+
}

0 commit comments

Comments
 (0)