aboutsummaryrefslogtreecommitdiffstats
path: root/zone_nspawn/src/nspawn.rs
diff options
context:
space:
mode:
Diffstat (limited to 'zone_nspawn/src/nspawn.rs')
-rw-r--r--zone_nspawn/src/nspawn.rs86
1 files changed, 50 insertions, 36 deletions
diff --git a/zone_nspawn/src/nspawn.rs b/zone_nspawn/src/nspawn.rs
index 017e5a3..89f51ef 100644
--- a/zone_nspawn/src/nspawn.rs
+++ b/zone_nspawn/src/nspawn.rs
@@ -1,24 +1,53 @@
use std::{ffi::OsStr, path::PathBuf, process::Command};
+use async_trait::async_trait;
use tokio::sync::mpsc::UnboundedReceiver;
use wspty::{PtyCommand, PtyMaster};
+use zone_core::{Container, Runtime};
-use crate::{Container, Error, Result};
+use crate::{Error, Result};
#[derive(Default, Debug)]
pub struct NSpawn;
impl NSpawn {
- pub fn list(&self) -> Result<Vec<Container>> {
+ async fn spawn<O, S, C, A>(opts: O, cmd: C, kill_rx: UnboundedReceiver<()>) -> Result<PtyMaster>
+ where
+ O: IntoIterator<Item = S>,
+ S: AsRef<OsStr>,
+ C: IntoIterator<Item = A>,
+ A: AsRef<OsStr>,
+ {
+ let base_opts = ["--quiet", "--wait", "--collect", "--service-type=exec"];
+
+ let mut proc = tokio::process::Command::new("systemd-run");
+
+ proc.args(base_opts)
+ .args(opts)
+ .args(cmd)
+ .env("TERM", "xterm-256color");
+
+ PtyCommand::from(proc)
+ .run(kill_rx)
+ .await
+ .map_err(Error::from)
+ }
+}
+
+#[async_trait]
+impl Runtime for NSpawn {
+ type Error = crate::Error;
+
+ fn list(&self) -> Result<Vec<Container>> {
Command::new("machinectl")
.arg("list")
.args(["-o", "json"])
.output()
- .map(|o| serde_json::from_slice(o.stdout.as_slice()))?
.map_err(Error::from)
+ .and_then(|o| serde_json::from_slice(o.stdout.as_slice()).map_err(Error::from))
}
- pub fn create(&self, root: PathBuf, name: String) -> Result<()> {
+ fn create(&self, root: PathBuf, container: &Container) -> Result<()> {
let opts = [
"--settings=trusted",
"--quiet",
@@ -34,41 +63,25 @@ impl NSpawn {
Command::new("systemd-nspawn")
.arg("--machine")
- .arg(name)
+ .arg(container.to_string())
.arg("--directory")
.arg(root)
.args(opts)
- .status()?
+ .status()
+ .map_err(Error::from)?
.success()
.then(|| ())
- .ok_or_else(|| Error::NSpawn(format!("Failed to create container: {:?}", self)))
- }
-
- async fn spawn<O, S, C, A>(opts: O, cmd: C, kill_rx: UnboundedReceiver<()>) -> Result<PtyMaster>
- where
- O: IntoIterator<Item = S>,
- S: AsRef<OsStr>,
- C: IntoIterator<Item = A>,
- A: AsRef<OsStr>,
- {
- let base_opts = ["--quiet", "--wait", "--collect", "--service-type=exec"];
-
- let mut proc = tokio::process::Command::new("systemd-run");
-
- proc.args(base_opts)
- .args(opts)
- .args(cmd)
- .env("TERM", "xterm-256color");
-
- PtyCommand::from(proc)
- .run(kill_rx)
- .await
+ .ok_or_else(|| Error::Initialization(container.to_owned()))
.map_err(Error::from)
}
- pub async fn attach(&self, name: String, kill_rx: UnboundedReceiver<()>) -> Result<PtyMaster> {
+ async fn attach(
+ &self,
+ container: Container,
+ kill_rx: UnboundedReceiver<()>,
+ ) -> Result<PtyMaster> {
let opts = [
- &format!("{}={}", "--machine", name),
+ &format!("--machine={}", container),
"--pty",
"--send-sighup",
];
@@ -76,18 +89,19 @@ impl NSpawn {
Self::spawn(opts, cmd, kill_rx).await
}
- pub async fn run<C, S>(
+ async fn run<C, S>(
&self,
- name: String,
+ container: Container,
cmd: C,
kill_rx: UnboundedReceiver<()>,
) -> Result<PtyMaster>
where
C: IntoIterator<Item = S>,
+ C: std::marker::Send,
S: AsRef<OsStr>,
{
let opts = [
- &format!("{}={}", "--machine", name),
+ &format!("--machine={}", container),
"--pty",
"--send-sighup",
];
@@ -95,13 +109,13 @@ impl NSpawn {
Self::spawn(opts, cmd, kill_rx).await
}
- pub fn shutdown(name: String) -> Result<()> {
+ fn shutdown(container: Container) -> Result<()> {
Command::new("machinectl")
.arg("poweroff")
- .arg(&name)
+ .arg(container.to_string())
.status()?
.success()
.then(|| ())
- .ok_or_else(|| Error::NSpawn(format!("Failed to shutdown container: {:?}", name)))
+ .ok_or(Error::Shutdown(container))
}
}