Skip to content

Commit

Permalink
feat: better xtask run as sudo command
Browse files Browse the repository at this point in the history
  • Loading branch information
banditopazzo committed Sep 24, 2024
1 parent ed24020 commit 5844958
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 61 deletions.
1 change: 1 addition & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[alias]
xtask = "run --package xtask --"
surun = "run --package xtask -- surun"

[target.x86_64-unknown-linux-gnu]
rustflags = [
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
- name: Integration tests
if: endsWith(matrix.platform.target, 'musl')
run: |
cargo xtask test \
cargo xtask test-suite \
--force-architest \
--target=${{ matrix.platform.target }} \
--kernel-versions=${{ matrix.platform.kernel-versions }} \
Expand Down
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion xtask/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,15 @@ clap = { workspace = true, features = ["derive"] }
flate2 = { workspace = true }
indicatif = { workspace = true }
num_cpus = { workspace = true }
reqwest = { workspace = true, default-features = false, features = ["blocking", "json", "rustls-tls"] }
reqwest = { workspace = true, default-features = false, features = [
"blocking",
"json",
"rustls-tls",
] }
serde = { workspace = true, features = ["derive"] }
signal-hook = { workspace = true }
tar = { workspace = true }
uuid = { workspace = true, features = ["v4"] }
xshell = { workspace = true }
log = { workspace = true }
env_logger = { workspace = true }
8 changes: 4 additions & 4 deletions xtask/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,26 @@ with `sudo`.

To run the eBPF test suite you can use:
```sh
cargo xtask test
cargo xtask test-suite
```

## Run pulsar daemon

To run the agent daemon you can use:
```sh
cargo xtask pulsard
cargo surun pulsard
```

## Run pulsar client

To run the agent client you can use:
```sh
cargo xtask pulsar
cargo surun pulsar
```

## Run single probe

To run a single module you can use:
```sh
cargo xtask probe file-system-monitor
cargo surun --example standalone-probes file-system-monitor
```
1 change: 1 addition & 0 deletions xtask/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod surun;
24 changes: 10 additions & 14 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use clap::Parser;
use run::run_with_sudo;
use signal_hook::{consts::TERM_SIGNALS, iterator::Signals};
use xtask::surun::SuRunCommand;

mod run;
mod tempdir;
mod test;
mod test_suite;
mod vmlinux;

#[derive(Debug, Parser)]
Expand All @@ -16,29 +15,26 @@ pub struct Options {

#[derive(Debug, Parser)]
enum Command {
/// Run pulsar daemon with admin privileges
Pulsard(run::Options),
/// Run pulsar cli with admin privileges
Pulsar(run::Options),
/// Run a single module with admin privileges
Probe(run::Options),
/// Same as `cargo run` but with admin privileges (using `sudo -E` as runner)
#[clap(name = "surun")]
SuRun(SuRunCommand),
/// Run eBPF test suite with admin privileges
Test(test::Options),
TestSuite(test_suite::Options),
/// Build headers with BTF type definitions.
Vmlinux(vmlinux::Options),
}

fn main() {
let opts = Options::parse();

env_logger::init();

// Drop term signals: register a handler, but never check it
let _ = Signals::new(TERM_SIGNALS).expect("error setting signal handler");

let ret = match opts.command {
Command::Pulsard(opts) => run_with_sudo("pulsar-exec", &["pulsard"], opts),
Command::Pulsar(opts) => run_with_sudo("pulsar-exec", &["pulsar"], opts),
Command::Probe(opts) => run_with_sudo("probe", &[], opts),
Command::Test(opts) => test::run(opts),
Command::SuRun(cmd) => cmd.run(),
Command::TestSuite(opts) => test_suite::run(opts),
Command::Vmlinux(opts) => vmlinux::run(opts),
};

Expand Down
41 changes: 0 additions & 41 deletions xtask/src/run.rs

This file was deleted.

72 changes: 72 additions & 0 deletions xtask/src/surun.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use anyhow::{Context, Result};
use clap::Parser;
use xshell::{cmd, Shell};

#[derive(Debug, Parser)]
pub struct SuRunCommand {
/// Arguments normally passed to `cargo run`
#[clap(name = "ARGS", allow_hyphen_values = true)]
pub run_args: Vec<String>,
}

impl SuRunCommand {
pub fn run(&self) -> Result<()> {
let cargo = std::env::var("CARGO").unwrap();

let target_triple = match self
.run_args
.iter()
.skip_while(|arg| *arg != "--target")
.skip(1) // advance the `--target` identifier
.next()
{
Some(target_triple) => target_triple.to_owned(),
None => get_default_target(&cargo)
.context(format!("failed to get target triple with {cargo}"))?,
};

log::debug!("Detected host triple: {target_triple}");

let target_triple_env_runner = {
let tt_env_format = target_triple.to_uppercase().replace("-", "_");
format!("CARGO_TARGET_{tt_env_format}_RUNNER")
};

log::debug!("Overriding env variable: {target_triple_env_runner}");

let sh = Shell::new()?;

sh.set_var(target_triple_env_runner, "sudo -E");

let args = &self.run_args;

cmd!(sh, "{cargo} run {args...}").run()?;

Ok(())
}
}

/// Calls `cargo -vV`` in a subprocess and returns the default Clang target triple.
fn get_default_target(cargo_path: &str) -> Result<String> {
/// The [`rustc`][1] output field name that shows the target.
///
/// [1]: https://doc.rust-lang.org/rustc/what-is-rustc.html
const TARGET_FIELD: &str = "host: ";

// Query rustc for defaults.
let output = std::process::Command::new(cargo_path)
.arg("-vV")
.output()
.context(format!("failed to execute `{cargo_path} -vV`"))?;

// Decode stdout.
let stdout = std::str::from_utf8(&output.stdout).context("failed to read stdout into uft8")?;

// Parse the default target from stdout.
stdout
.lines()
.find(|l| l.starts_with(TARGET_FIELD))
.map(|l| &l[TARGET_FIELD.len()..])
.context(format!("failed to parse target from {cargo_path} output"))
.map(str::to_owned)
}
File renamed without changes.

0 comments on commit 5844958

Please sign in to comment.