summaryrefslogtreecommitdiffstats
path: root/src/runner
diff options
context:
space:
mode:
Diffstat (limited to 'src/runner')
-rw-r--r--src/runner/runc.rs88
-rw-r--r--src/runner/runc/init.rs47
-rw-r--r--src/runner/runc/run.rs18
3 files changed, 142 insertions, 11 deletions
diff --git a/src/runner/runc.rs b/src/runner/runc.rs
index b323d5d..663dc7a 100644
--- a/src/runner/runc.rs
+++ b/src/runner/runc.rs
@@ -1,21 +1,87 @@
-use super::*;
-use crate::types::TaskMap;
+mod init;
+mod run;
-pub struct RuncRunner<'a> {
- tasks: &'a TaskMap,
+use std::{io, process};
+
+use ipc_channel::ipc;
+use nix::unistd;
+use serde::{Deserialize, Serialize};
+
+use crate::types::*;
+use crate::unshare;
+use crate::util::CheckDisconnect;
+
+#[derive(Debug, Deserialize, Serialize)]
+struct Request(TaskRef, Task, ipc::IpcSender<run::Error>);
+
+fn runner(init_error_sender: ipc::IpcSender<init::Error>, channel: ipc::IpcReceiver<Request>) -> ! {
+ if let Err(error) = init::runc_initialize() {
+ init_error_sender.send(error).expect("IPC send() failed");
+ process::exit(1);
+ }
+
+ drop(init_error_sender);
+
+ while let Ok(request) = channel.recv() {
+ let Request(task, task_def, reply_sender) = request;
+ if let Err(error) = run::handle_task(task, task_def) {
+ reply_sender.send(error).expect("IPC send() failed");
+ }
+ }
+
+ process::exit(0);
+}
+
+pub struct RuncRunner {
+ channel: ipc::IpcSender<Request>,
}
-impl<'a> RuncRunner<'a> {
- pub fn new(tasks: &'a TaskMap) -> Self {
- RuncRunner { tasks }
+impl RuncRunner {
+ /// Creates a new Runc runner
+ ///
+ /// Unsafe: Do not call in multithreaded processes
+ pub unsafe fn new() -> io::Result<Self> {
+ let (tx, rx) = ipc::channel().expect("IPC channel creation failed");
+ let (init_error_tx, init_error_rx) = ipc::channel().expect("IPC channel creation failed");
+
+ let pid = match unistd::fork().expect("fork()") {
+ unistd::ForkResult::Parent { child } => {
+ drop(rx);
+ drop(init_error_tx);
+ child
+ }
+ unistd::ForkResult::Child => {
+ drop(tx);
+ drop(init_error_rx);
+ runner(init_error_tx, rx);
+ /* Not reached */
+ }
+ };
+
+ init_error_rx
+ .recv()
+ .check_disconnect()
+ .expect("IPC recv() error")?;
+
+ unshare::idmap(pid)?;
+
+ Ok(RuncRunner { channel: tx })
}
}
-impl<'a> Runner for RuncRunner<'a> {
- fn run(&self, task: &TaskRef) -> Result<()> {
- let task_def = self.tasks.get(task).expect("Invalid TaskRef");
+impl super::Runner for RuncRunner {
+ fn run(&self, tasks: &TaskMap, task: &TaskRef) -> super::Result<()> {
+ let task_def = tasks.get(task).expect("Invalid TaskRef");
+ let (reply_tx, reply_rx) = ipc::channel().expect("IPC channel creation failed");
+
+ self.channel
+ .send(Request(task.clone(), task_def.clone(), reply_tx))
+ .expect("RuncRunner task submission failed");
- println!("{}:\n\t{:?}", task, task_def);
+ reply_rx
+ .recv()
+ .check_disconnect()
+ .expect("IPC recv() error")?;
Ok(())
}
diff --git a/src/runner/runc/init.rs b/src/runner/runc/init.rs
new file mode 100644
index 0000000..02b89e4
--- /dev/null
+++ b/src/runner/runc/init.rs
@@ -0,0 +1,47 @@
+use std::io;
+
+use nix::{
+ mount::{self, MsFlags},
+ sched::{self, CloneFlags},
+};
+use serde::{Deserialize, Serialize};
+
+fn mount_buildtmp() -> nix::Result<()> {
+ mount::mount::<_, _, _, str>(
+ Some("buildtmp"),
+ "build/tmp",
+ Some("tmpfs"),
+ MsFlags::empty(),
+ None,
+ )
+}
+
+#[derive(Debug, Deserialize, Serialize)]
+pub enum Error {
+ Code(i32),
+ String(String),
+}
+
+impl From<nix::Error> for Error {
+ fn from(error: nix::Error) -> Self {
+ match error {
+ nix::Error::Sys(code) => Error::Code(code as i32),
+ _ => Error::String(error.to_string()),
+ }
+ }
+}
+
+impl From<Error> for io::Error {
+ fn from(error: Error) -> Self {
+ match error {
+ Error::Code(code) => io::Error::from_raw_os_error(code),
+ Error::String(string) => io::Error::new(io::ErrorKind::Other, string),
+ }
+ }
+}
+
+pub fn runc_initialize() -> Result<(), Error> {
+ sched::unshare(CloneFlags::CLONE_NEWUSER | CloneFlags::CLONE_NEWNS)?;
+ mount_buildtmp()?;
+ Ok(())
+}
diff --git a/src/runner/runc/run.rs b/src/runner/runc/run.rs
new file mode 100644
index 0000000..2d13330
--- /dev/null
+++ b/src/runner/runc/run.rs
@@ -0,0 +1,18 @@
+use std::io;
+
+use serde::{Deserialize, Serialize};
+
+use crate::types::*;
+#[derive(Debug, Deserialize, Serialize)]
+pub struct Error;
+
+impl From<Error> for io::Error {
+ fn from(_: Error) -> Self {
+ io::Error::new(io::ErrorKind::Other, "Failed to run task")
+ }
+}
+
+pub fn handle_task(task: TaskRef, task_def: Task) -> Result<(), Error> {
+ println!("{}:\n\t{:?}", task, task_def);
+ Ok(())
+}