Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Add support for pinned sb implementation #135

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
4 changes: 1 addition & 3 deletions src/runtime_service/run_pod_sandbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,7 @@ impl CRIService {
debug!("Created pod sandbox {:?}", sandbox);

// Run the sandbox
sandbox
.run()
.map_err(|e| Status::internal(format!("run pod sandbox: {}", e)))?;
sandbox.run().await.map_err(|e| Status::internal(format!("run pod sandbox: {}", e)))?;
info!("Started pod sandbox {}", sandbox);

// Build and return the response
Expand Down
14 changes: 9 additions & 5 deletions src/sandbox/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

pub mod pinned;

use async_trait::async_trait;
use anyhow::Result;
use bitflags::bitflags;
use derive_builder::Builder;
Expand Down Expand Up @@ -76,9 +77,10 @@ pub struct SandboxData {
annotations: HashMap<String, String>,
}

#[async_trait]
pub trait Pod {
/// Run a previously created sandbox.
fn run(&mut self, _: &SandboxData) -> Result<()> {
async fn run(&mut self, _: &SandboxData) -> Result<()> {
Ok(())
}

Expand All @@ -102,16 +104,16 @@ pub trait Pod {

impl<T> Sandbox<T>
where
T: Default + Pod,
T: Default + Pod + Send,
{
/// Retrieve the unique identifier for the sandbox
pub fn id(&self) -> &str {
&self.data.id
}

/// Wrapper for the implementations `run` method
pub fn run(&mut self) -> Result<()> {
self.implementation.run(&self.data)
pub async fn run(&mut self) -> Result<()> {
Ok(self.implementation.run(&self.data).await?)
}

#[allow(dead_code)]
Expand Down Expand Up @@ -187,8 +189,10 @@ pub mod tests {
remove_called: bool,
ready: bool,
}

#[async_trait]
impl Pod for Mock {
fn run(&mut self, _: &SandboxData) -> Result<()> {
async fn run(&mut self, _: &SandboxData) -> Result<()> {
self.run_called = true;
self.ready = true;
Ok(())
Expand Down
69 changes: 65 additions & 4 deletions src/sandbox/pinned.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,69 @@
//! A pod sandbox implementation which does pin it's namespaces to file descriptors.
//! A pod sandbox implementation which does pin its namespaces to file descriptors.

use crate::sandbox::Pod;
use crate::sandbox::{LinuxNamespaces, Pod, SandboxData};
use async_trait::async_trait;
use anyhow::{bail, Context, Result};
use tokio::process::Command;
use which::which;
use std::path::PathBuf;

#[derive(Default)]
pub struct PinnedSandbox {}
pub struct PinnedSandbox {
pinner_path: PathBuf,
namespaces_dir: String,
ready: bool,
}

impl Pod for PinnedSandbox {}
impl PinnedSandbox {
pub fn new(pinner: &str) -> Result<PinnedSandbox> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@saschagrunert We want to be able to setup a PinnedSandbox::new and then use it in the Sandbox but that doesn't work so we may need to use trait objects.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, yes it might be the better approach to use trait objects here. 👍

let path = which(pinner)
.with_context(|| format!("failed to find {} in PATH", pinner))?;
let ps = PinnedSandbox {
pinner_path: path,
// TODO: Make this configurable
namespaces_dir: String::from("/var/run/cri"),
ready: false,
};
Ok(ps)
}
}

#[async_trait]
impl Pod for PinnedSandbox {
async fn run(&mut self, sd: &SandboxData) -> Result<()> {
let mut args = Vec::new();
args.push("-d");
args.push(&self.namespaces_dir);
args.push("-f");
args.push(&sd.id);
Comment on lines +34 to +38
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let mut args = Vec::new();
args.push("-d");
args.push(&self.namespaces_dir);
args.push("-f");
args.push(&sd.id);
let mut args = vec!["-d", &self.namespaces_dir, "-f", &sd.id];

let linux_namespaces = sd.linux_namespaces.context("linux namespaces not set")?;
if linux_namespaces.contains(LinuxNamespaces::NET) {
args.push("-n");
}
if linux_namespaces.contains(LinuxNamespaces::IPC) {
args.push("-i");
}
if linux_namespaces.contains(LinuxNamespaces::UTS) {
args.push("-u");
}
let output = Command::new(&self.pinner_path).args(&args[..]).output().await?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let output = Command::new(&self.pinner_path).args(&args[..]).output().await?;
let output = Command::new(&self.pinner_path).args(args).output().await?;

if !output.status.success() {
bail!("Failed to pin namespaces for sandbox")
}
self.ready = true;
Ok(())
}

fn stop(&mut self, _: &SandboxData) -> Result<()> {
self.ready = false;
Ok(())
}

fn remove(&mut self, _: &SandboxData) -> Result<()> {
Ok(())
}

fn ready(&mut self, _: &SandboxData) -> Result<bool> {
Ok(false)
}
}