diff --git a/container-runtime/src/Adapters/Systems/SystemForEmbassy/MainLoop.ts b/container-runtime/src/Adapters/Systems/SystemForEmbassy/MainLoop.ts index e5aaacfdb..cae3405b9 100644 --- a/container-runtime/src/Adapters/Systems/SystemForEmbassy/MainLoop.ts +++ b/container-runtime/src/Adapters/Systems/SystemForEmbassy/MainLoop.ts @@ -173,10 +173,16 @@ export class MainLoop { subcontainer, } ) + const env: Record = actionProcedure.inject + ? { + HOME: "/root", + } + : {} const executed = await container.exec( [actionProcedure.entrypoint, ...actionProcedure.args], - { input: JSON.stringify(timeChanged) }, + { input: JSON.stringify(timeChanged), env }, ) + if (executed.exitCode === 0) { await effects.setHealth({ id: healthId, @@ -227,6 +233,18 @@ export class MainLoop { }) return } + if (executed.exitCode && executed.exitCode > 0) { + await effects.setHealth({ + id: healthId, + name: value.name, + result: "failure", + message: + executed.stderr.toString() || + executed.stdout.toString() || + `Program exited with code ${executed.exitCode}:`, + }) + return + } await effects.setHealth({ id: healthId, name: value.name, diff --git a/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts b/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts index 1e0c34189..9e6382ca7 100644 --- a/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts +++ b/container-runtime/src/Adapters/Systems/SystemForEmbassy/index.ts @@ -750,6 +750,12 @@ export class SystemForEmbassy implements System { const subcontainer = actionProcedure.inject ? this.currentRunning?.mainSubContainerHandle : undefined + + const env: Record = actionProcedure.inject + ? { + HOME: "/root", + } + : {} const container = await DockerProcedureContainer.of( effects, this.manifest.id, @@ -769,6 +775,7 @@ export class SystemForEmbassy implements System { JSON.stringify(formData), ], timeoutMs, + { env }, ) ).stdout.toString(), ), diff --git a/core/Cargo.lock b/core/Cargo.lock index 1fccce36d..e9b9330e3 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -5144,6 +5144,7 @@ dependencies = [ "tracing-subscriber", "trust-dns-server", "ts-rs", + "tty-spawn", "typed-builder", "unix-named-pipe", "unshare", @@ -5886,6 +5887,17 @@ dependencies = [ "termcolor", ] +[[package]] +name = "tty-spawn" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb91489cf2611235ae8d755d66ab028437980ee573e2230c05af41b136236ad1" +dependencies = [ + "anyhow", + "nix 0.29.0", + "signal-hook", +] + [[package]] name = "tungstenite" version = "0.21.0" diff --git a/core/startos/Cargo.toml b/core/startos/Cargo.toml index d0228ba31..9b3e7a048 100644 --- a/core/startos/Cargo.toml +++ b/core/startos/Cargo.toml @@ -39,10 +39,10 @@ path = "src/main.rs" [features] cli = [] -container-runtime = ["procfs", "unshare"] +container-runtime = ["procfs", "unshare", "tty-spawn"] daemon = [] registry = [] -default = ["cli", "daemon"] +default = ["cli", "daemon", "registry", "container-runtime"] dev = [] unstable = ["console-subscriber", "tokio/tracing"] docker = [] @@ -205,6 +205,7 @@ tracing-journald = "0.3.0" tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } trust-dns-server = "0.23.1" ts-rs = { git = "https://github.com/dr-bonez/ts-rs.git", branch = "feature/top-level-as" } # "8.1.0" +tty-spawn = { version = "0.4.0", optional = true } typed-builder = "0.18.0" which = "6.0.3" unix-named-pipe = "0.2.0" diff --git a/core/startos/src/net/dns.rs b/core/startos/src/net/dns.rs index 090e845b0..016e5de9f 100644 --- a/core/startos/src/net/dns.rs +++ b/core/startos/src/net/dns.rs @@ -98,16 +98,8 @@ impl RequestHandler for Resolver { ) .await } - a => { - if a != RecordType::AAAA { - tracing::warn!( - "Non A-Record requested for {}: {:?}", - query.name(), - query.query_type() - ); - } - let mut res = Header::response_from_request(request.header()); - res.set_response_code(ResponseCode::NXDomain); + _ => { + let res = Header::response_from_request(request.header()); response_handle .send_response( MessageResponseBuilder::from_message_request(&*request).build( diff --git a/core/startos/src/service/effects/subcontainer/sync.rs b/core/startos/src/service/effects/subcontainer/sync.rs index e18586a54..f31eb8f62 100644 --- a/core/startos/src/service/effects/subcontainer/sync.rs +++ b/core/startos/src/service/effects/subcontainer/sync.rs @@ -2,15 +2,16 @@ use std::borrow::Cow; use std::collections::BTreeMap; use std::ffi::{c_int, OsStr, OsString}; use std::fs::File; +use std::io::IsTerminal; use std::os::unix::process::CommandExt; use std::path::{Path, PathBuf}; use std::process::{Command as StdCommand, Stdio}; use nix::sched::CloneFlags; use nix::unistd::Pid; -use rpc_toolkit::Context; use signal_hook::consts::signal::*; use tokio::sync::oneshot; +use tty_spawn::TtySpawn; use unshare::Command as NSCommand; use crate::service::effects::prelude::*; @@ -294,6 +295,37 @@ pub fn exec( command, }: ExecParams, ) -> Result<(), Error> { + if std::io::stdin().is_terminal() { + let mut cmd = TtySpawn::new("/usr/bin/start-cli"); + cmd.arg("subcontainer").arg("exec-command"); + if let Some(env) = env { + cmd.arg("--env").arg(env); + } + if let Some(workdir) = workdir { + cmd.arg("--workdir").arg(workdir); + } + if let Some(user) = user { + cmd.arg("--user").arg(user); + } + cmd.arg(&chroot); + cmd.args(command.iter()); + nix::sched::setns( + open_file_read(chroot.join("proc/1/ns/pid"))?, + CloneFlags::CLONE_NEWPID, + ) + .with_ctx(|_| (ErrorKind::Filesystem, "set pid ns"))?; + nix::sched::setns( + open_file_read(chroot.join("proc/1/ns/cgroup"))?, + CloneFlags::CLONE_NEWCGROUP, + ) + .with_ctx(|_| (ErrorKind::Filesystem, "set cgroup ns"))?; + nix::sched::setns( + open_file_read(chroot.join("proc/1/ns/ipc"))?, + CloneFlags::CLONE_NEWIPC, + ) + .with_ctx(|_| (ErrorKind::Filesystem, "set ipc ns"))?; + std::process::exit(cmd.spawn().with_kind(ErrorKind::Filesystem)?); + } let mut sig = signal_hook::iterator::Signals::new(FWD_SIGNALS)?; let (send_pid, recv_pid) = oneshot::channel(); std::thread::spawn(move || { diff --git a/sdk/lib/util/SubContainer.ts b/sdk/lib/util/SubContainer.ts index 0d5982886..bbc5c5f64 100644 --- a/sdk/lib/util/SubContainer.ts +++ b/sdk/lib/util/SubContainer.ts @@ -97,7 +97,8 @@ export class SubContainer implements ExecSpawnable { shared.push("run") } - fs.copyFile("/etc/resolv.conf", `${rootfs}/etc/resolv.conf`) + await fs.mkdir(`${rootfs}/etc`, { recursive: true }) + await fs.copyFile("/etc/resolv.conf", `${rootfs}/etc/resolv.conf`) for (const dirPart of shared) { const from = `/${dirPart}`