From b8107a20302218f1d0547c8a541a40a3c48ddb54 Mon Sep 17 00:00:00 2001 From: Felix Obenhuber Date: Fri, 4 Aug 2023 13:26:47 +0200 Subject: [PATCH] Add permissions on global console (#1011) --- Cargo.lock | 1 + android/northstar.toml | 6 +- northstar-runtime/Cargo.toml | 3 +- northstar-runtime/src/api/model.rs | 8 +- northstar-runtime/src/npk/manifest/console.rs | 11 ++- northstar-runtime/src/npk/manifest/mod.rs | 2 +- northstar-runtime/src/runtime/config.rs | 51 +++++++--- northstar-runtime/src/runtime/console/mod.rs | 66 +++++++------ .../src/runtime/console/options.rs | 32 +++++++ .../src/runtime/console/permissions.rs | 93 +++++++++++++++++++ northstar-runtime/src/runtime/runtime.rs | 21 ++--- northstar-runtime/src/runtime/state.rs | 19 ++-- northstar-tests/src/runtime.rs | 17 +++- northstar.toml | 9 +- 14 files changed, 248 insertions(+), 91 deletions(-) create mode 100644 northstar-runtime/src/runtime/console/options.rs create mode 100644 northstar-runtime/src/runtime/console/permissions.rs diff --git a/Cargo.lock b/Cargo.lock index 6a0dbd88b..587f3fb0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1598,6 +1598,7 @@ dependencies = [ "cgroups-rs", "ed25519-dalek", "futures", + "heck 0.4.1", "hex", "hmac", "humanize-rs", diff --git a/android/northstar.toml b/android/northstar.toml index 7c4694172..fc66aa8cb 100644 --- a/android/northstar.toml +++ b/android/northstar.toml @@ -3,9 +3,9 @@ data_dir = "/data/northstar/data" socket_dir = "/dev/socket/northstar" cgroup = "northstar" -# Debug TCP console on localhost with full access -[debug] -console = "tcp://localhost:4200" +[console.global] +bind = "tcp://localhost:4200" +permissions = "full" [repositories.system] key = "/system/etc/northstar/system.pub" diff --git a/northstar-runtime/Cargo.toml b/northstar-runtime/Cargo.toml index 679d4121f..acd988087 100644 --- a/northstar-runtime/Cargo.toml +++ b/northstar-runtime/Cargo.toml @@ -24,6 +24,7 @@ caps = { version = "0.5.5", optional = true } cgroups-rs = { version = "0.3.2", features = ["serde"], optional = true } ed25519-dalek = { version = "1.0.1", optional = true } futures = { version = "0.3.27", default-features = true, optional = true } +heck = { version = "0.4.1", optional = true } hex = { version = "0.4.3", optional = true } hmac = { version = "0.12.1", features = ["reset"], optional = true } humanize-rs = { version = "0.1.5", optional = true } @@ -69,7 +70,7 @@ zip = { version = "0.6.6", default-features = false, optional = true } api = ["bytes", "futures", "npk", "pkg-version", "serde_json", "tokio", "tokio-util"] npk = ["base64", "byteorder", "ed25519-dalek", "hex", "humanize-rs", "itertools", "pkg-version", "rand_core", "seccomp", "serde_json", "serde_plain", "serde_with", "serde_yaml", "sha2", "strum", "strum_macros", "tempfile", "toml", "uuid", "zeroize", "zip"] rexec = ["nix", "memfd"] -runtime = ["api", "async-stream", "async-trait", "bincode", "bytesize", "caps", "cgroups-rs", "ed25519-dalek", "futures", "hex", "hmac", "humantime", "humantime-serde", "inotify", "itertools", "lazy_static", "libc", "loopdev", "memfd", "memoffset", "nanoid", "nix", "npk", "rlimit", "serde_plain", "tempfile", "tokio", "tokio-eventfd", "tokio-util", "url", "umask"] +runtime = ["api", "async-stream", "async-trait", "bincode", "bytesize", "caps", "cgroups-rs", "ed25519-dalek", "futures", "heck", "hex", "hmac", "humantime", "humantime-serde", "inotify", "itertools", "lazy_static", "libc", "loopdev", "memfd", "memoffset", "nanoid", "nix", "npk", "rlimit", "serde_plain", "tempfile", "tokio", "tokio-eventfd", "tokio-util", "url", "umask"] seccomp = ["bindgen", "caps", "lazy_static", "memoffset", "nix", "npk"] [dev-dependencies] diff --git a/northstar-runtime/src/api/model.rs b/northstar-runtime/src/api/model.rs index 0ccec79f6..603bd573d 100644 --- a/northstar-runtime/src/api/model.rs +++ b/northstar-runtime/src/api/model.rs @@ -3,10 +3,6 @@ use std::collections::{HashMap, HashSet}; /// Container name pub type Name = crate::common::name::Name; -/// Console configuration -pub type ConsoleConfiguration = crate::npk::manifest::console::Configuration; -/// Console permission entity -pub type ConsolePermission = crate::npk::manifest::console::Permission; /// Container identification pub type Container = crate::common::container::Container; /// Container exit code @@ -87,9 +83,7 @@ pub struct Connect { #[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] #[allow(missing_docs)] -pub struct ConnectAck { - pub configuration: ConsoleConfiguration, -} +pub struct ConnectAck; /// Connection nack #[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] diff --git a/northstar-runtime/src/npk/manifest/console.rs b/northstar-runtime/src/npk/manifest/console.rs index 352d17d17..201a93e03 100644 --- a/northstar-runtime/src/npk/manifest/console.rs +++ b/northstar-runtime/src/npk/manifest/console.rs @@ -9,11 +9,11 @@ use std::{collections::HashSet, fmt}; use strum::{EnumCount as _, IntoEnumIterator}; use strum_macros::{EnumCount, EnumIter}; -/// Console Quality of Service +/// Console permissions. #[skip_serializing_none] #[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize)] #[serde(deny_unknown_fields)] -pub struct Configuration { +pub struct Console { /// Permissions pub permissions: Permissions, } @@ -75,10 +75,15 @@ impl fmt::Display for Permission { pub struct Permissions(HashSet); impl Permissions { - /// Create a new `Console` with all permissions given + /// Create a new `Console` with all permissions. pub fn full() -> Permissions { Permissions(HashSet::from_iter(Permission::iter())) } + + /// Create a new `Console` without permissions. + pub fn empty() -> Permissions { + Permissions(HashSet::new()) + } } impl std::ops::Deref for Permissions { diff --git a/northstar-runtime/src/npk/manifest/mod.rs b/northstar-runtime/src/npk/manifest/mod.rs index 6f54bbcaf..7dc9f30e5 100644 --- a/northstar-runtime/src/npk/manifest/mod.rs +++ b/northstar-runtime/src/npk/manifest/mod.rs @@ -92,7 +92,7 @@ pub struct Manifest { /// Container version pub version: Version, /// Pass a console fd number in NORTHSTAR_CONSOLE - pub console: Option, + pub console: Option, /// Path to init #[validate(length(min = 1, max = 4096))] pub init: Option, diff --git a/northstar-runtime/src/runtime/config.rs b/northstar-runtime/src/runtime/config.rs index e272ffbc2..9245185ae 100644 --- a/northstar-runtime/src/runtime/config.rs +++ b/northstar-runtime/src/runtime/config.rs @@ -11,7 +11,10 @@ use nix::{sys::stat, unistd}; use serde::{de::Error as SerdeError, Deserialize, Deserializer}; use url::Url; -use crate::{common::non_nul_string::NonNulString, runtime::repository::RepositoryId}; +use crate::{ + common::non_nul_string::NonNulString, npk::manifest::console::Permissions, + runtime::repository::RepositoryId, +}; /// Runtime configuration #[derive(Clone, Debug, Deserialize)] @@ -44,10 +47,22 @@ pub struct Config { pub debug: Option, } +/// Globally accessible console. +#[derive(Clone, Debug, Deserialize)] +pub struct ConsoleGlobal { + /// Bind globally accesible console to this address. + #[serde(deserialize_with = "console_url")] + pub bind: Url, + /// Permissions + pub permissions: Permissions, + /// Console options + pub options: Option, +} + /// Console Quality of Service #[derive(Clone, Debug, Deserialize)] #[serde(deny_unknown_fields)] -pub struct Console { +pub struct ConsoleOptions { /// Token validity duration. #[serde(with = "humantime_serde", default = "default_token_validity")] pub token_validity: time::Duration, @@ -68,7 +83,7 @@ pub struct Console { pub npk_stream_timeout: time::Duration, } -impl Default for Console { +impl Default for ConsoleOptions { fn default() -> Self { Self { token_validity: default_token_validity(), @@ -80,6 +95,16 @@ impl Default for Console { } } +/// Console Quality of Service +#[derive(Clone, Default, Debug, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct Console { + /// Globally accessible console. + pub global: Option, + /// Options for console connections with containers. + pub options: Option, +} + /// Repository type #[derive(Clone, Debug, Deserialize)] pub enum RepositoryType { @@ -116,10 +141,6 @@ pub struct Repository { #[derive(Clone, Debug, Deserialize)] #[serde(deny_unknown_fields)] pub struct Debug { - /// Console configuration - #[serde(deserialize_with = "console")] - pub console: Url, - /// Commands to run before the container is started. // is replaced with the container name. // is replaced with the container init pid. @@ -170,7 +191,7 @@ fn is_rw(path: &Path) -> bool { } /// Validate the console url schemes are all "tcp" or "unix" -fn console<'de, D>(deserializer: D) -> Result +fn console_url<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { @@ -234,15 +255,15 @@ const fn default_max_request_size() -> u64 { #[test] #[allow(clippy::unwrap_used)] -fn console_url() { +fn validate_console_url() { let config = r#" data_dir = "target/northstar/data" run_dir = "target/northstar/run" socket_dir = "target/northstar/sockets" cgroup = "northstar" - -[debug] -console = "tcp://localhost:4200" +[console.global] +bind = "tcp://localhost:4200" +permissions = "full" "#; toml::from_str::(config).unwrap(); @@ -253,9 +274,9 @@ data_dir = "target/northstar/data" run_dir = "target/northstar/run" socket_dir = "target/northstar/sockets" cgroup = "northstar" - -[debug] -console = "http://localhost:4200" +[console.global] +bind = "http://localhost:4200" +permissions = "full" "#; assert!(toml::from_str::(config).is_err()); diff --git a/northstar-runtime/src/runtime/console/mod.rs b/northstar-runtime/src/runtime/console/mod.rs index 717dd2790..ebb51d643 100644 --- a/northstar-runtime/src/runtime/console/mod.rs +++ b/northstar-runtime/src/runtime/console/mod.rs @@ -31,12 +31,13 @@ use tokio::{ use tokio_util::{either::Either, io::ReaderStream, sync::CancellationToken}; use url::Url; -pub use crate::npk::manifest::console::{ - Configuration as ContainerConfiguration, Permission, Permissions, -}; -use crate::runtime::config::Console as RuntimeConfiguration; +pub use options::Options; +use permissions::Permission; +pub use permissions::Permissions; mod listener; +mod options; +mod permissions; mod throttle; // Request from the main loop to the console @@ -46,15 +47,6 @@ pub(crate) enum Request { Install(RepositoryId, mpsc::Receiver), } -/// Console configuration. -#[derive(Clone, Debug)] -pub(crate) struct Configuration { - /// Container specific console configuration. - pub container: ContainerConfiguration, - /// Runtime global configuration. - pub runtime: RuntimeConfiguration, -} - /// A console is responsible for monitoring and serving incoming client connections /// It feeds relevant events back to the runtime and forwards responses and notifications /// to connected clients @@ -83,13 +75,16 @@ impl Console { /// Spawn a task that listens on `url` for new connections. Spawn a task for /// each client - pub(super) async fn listen(&mut self, url: &Url, configuration: &Configuration) -> Result<()> { + pub(super) async fn listen( + &mut self, + url: &Url, + options: Options, + permissions: Permissions, + ) -> Result<()> { let event_tx = self.event_tx.clone(); let notification_tx = self.notification_tx.clone(); - let configuration = configuration.clone(); // Stop token for self *and* the connections let stop = self.stop.clone(); - let permissions = &configuration.container.permissions; debug!("Starting console on {url} with permissions \"{permissions}\"",); let listener = Listener::new(url) @@ -103,7 +98,8 @@ impl Console { event_tx, notification_tx, stop, - configuration, + options, + permissions, ) .await }), @@ -113,7 +109,8 @@ impl Console { event_tx, notification_tx, stop, - configuration, + options, + permissions, ) .await }), @@ -137,12 +134,12 @@ impl Console { peer: Peer, stop: CancellationToken, container: Option, - configuration: Configuration, + options: Options, + permissions: Permissions, event_tx: EventTx, mut notification_rx: broadcast::Receiver<(Container, ContainerEvent)>, timeout: Option, ) -> Result<()> { - let permissions = &configuration.container.permissions; if let Some(container) = &container { debug!( "Container {} connected with permissions {}", @@ -153,11 +150,11 @@ impl Console { } // Get a framed stream and sink interface. - let max_request_size = configuration.runtime.max_request_size; + let max_request_size = options.max_request_size; let stream = api::codec::framed_with_max_length(stream, max_request_size.try_into()?); // Limit requests per second - let max_requests_per_sec = configuration.runtime.max_requests_per_sec; + let max_requests_per_sec = options.max_requests_per_sec; const SECOND: time::Duration = time::Duration::from_secs(1); let mut stream = throttle::Throttle::new(stream, max_requests_per_sec, SECOND); @@ -232,10 +229,9 @@ impl Console { } // Looks good - send ConnectAck - let connect_ack = model::ConnectAck { - configuration: configuration.container.clone(), + let message = model::Message::ConnectAck { + connect_ack: model::ConnectAck, }; - let message = model::Message::ConnectAck { connect_ack }; if let Err(e) = stream.send(message).await { warn!("{}: Connection error: {}", peer, e); return Ok(()); @@ -284,7 +280,7 @@ impl Console { match item { Some(Ok(model::Message::Request { request })) => { trace!("{}: --> {:?}", peer, request); - let response = match process_request(&peer, &mut stream, &stop, &configuration, &event_tx, request).await { + let response = match process_request(&peer, &mut stream, &stop, &options, &permissions, &event_tx, request).await { Ok(response) => response, Err(e) => { warn!("Failed to process request: {}", e); @@ -329,7 +325,8 @@ async fn process_request( peer: &Peer, stream: &mut Framed, stop: &CancellationToken, - configuration: &Configuration, + options: &Options, + permissions: &Permissions, event_loop: &EventTx, request: model::Request, ) -> Result @@ -357,7 +354,6 @@ where model::Request::Uninstall { .. } => Permission::Uninstall, }; - let permissions = &configuration.container.permissions; if !permissions.contains(&required_permission) { return Ok(model::Message::Response { response: model::Response::PermissionDenied(request), @@ -386,7 +382,7 @@ where ); // Check the installation request size - let max_install_stream_size = configuration.runtime.max_npk_install_size; + let max_install_stream_size = options.max_npk_install_size; if size > max_install_stream_size { bail!("npk size too large"); } @@ -414,7 +410,7 @@ where // If the connections breaks: just break. If the receiver is dropped: just break. let mut take = ReaderStream::with_capacity(stream.get_mut().take(size), 1024 * 1024); - let timeout = configuration.runtime.npk_stream_timeout; + let timeout = options.npk_stream_timeout; while let Some(buf) = time::timeout(timeout, take.next()) .await .context("npk stream timeout")? @@ -435,7 +431,7 @@ where target, hex::encode(&shared) ); - let token_validity = configuration.runtime.token_validity; + let token_validity = options.token_validity; let token: Vec = Token::new(token_validity, user, target.as_ref().as_bytes(), shared).into(); let token = api::model::Token::from(token); @@ -459,7 +455,7 @@ where hex::encode(&shared) ); // The token has a valid length - verified by serde::deserialize - let token_validity = configuration.runtime.token_validity; + let token_validity = options.token_validity; let token = Token::from((token_validity, token.as_ref().to_vec())); let result = token .verify(user.as_ref().as_bytes(), target, &shared) @@ -501,7 +497,8 @@ async fn serve( event_tx: EventTx, notification_tx: NotificationTx, stop: CancellationToken, - configuration: Configuration, + options: Options, + permissions: Permissions, ) where C: Stream> + Unpin, S: AsyncWrite + AsyncRead + Unpin + Send + 'static, @@ -523,7 +520,8 @@ async fn serve( client.into(), stop.clone(), None, - configuration.clone(), + options.clone(), + permissions.clone(), event_tx.clone(), notification_tx.subscribe(), Some(time::Duration::from_secs(10)), diff --git a/northstar-runtime/src/runtime/console/options.rs b/northstar-runtime/src/runtime/console/options.rs new file mode 100644 index 000000000..e1b3812e9 --- /dev/null +++ b/northstar-runtime/src/runtime/console/options.rs @@ -0,0 +1,32 @@ +use serde::Deserialize; +use tokio::time; + +use crate::runtime::config::ConsoleOptions; + +/// Console Quality of Service +#[derive(Clone, Debug, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct Options { + /// Token validity duration. + pub token_validity: time::Duration, + /// Limits the number of requests processed per second. + pub max_requests_per_sec: usize, + /// Maximum request size in bytes + pub max_request_size: u64, + /// Maximum npk size in bytes. + pub max_npk_install_size: u64, + /// NPK stream timeout in seconds. + pub npk_stream_timeout: time::Duration, +} + +impl From for Options { + fn from(value: ConsoleOptions) -> Self { + Self { + token_validity: value.token_validity, + max_requests_per_sec: value.max_requests_per_sec, + max_request_size: value.max_request_size, + max_npk_install_size: value.max_npk_install_size, + npk_stream_timeout: value.npk_stream_timeout, + } + } +} diff --git a/northstar-runtime/src/runtime/console/permissions.rs b/northstar-runtime/src/runtime/console/permissions.rs new file mode 100644 index 000000000..e7f59fd2c --- /dev/null +++ b/northstar-runtime/src/runtime/console/permissions.rs @@ -0,0 +1,93 @@ +use heck::ToSnakeCase; +use itertools::Itertools; +use std::{collections::HashSet, fmt}; + +use crate::npk::manifest::console::{ + Permission as ManifestPermission, Permissions as ManifestPermissions, +}; + +/// Set of permissions. +#[derive(Debug, Clone)] +pub struct Permissions(HashSet); + +impl Permissions { + /// Returns true if permission is set. + pub fn contains(&self, permission: &Permission) -> bool { + self.0.contains(permission) + } +} + +impl fmt::Display for Permissions { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0.iter().sorted().format(", ")) + } +} + +#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] +pub enum Permission { + /// Identification + Ident, + /// Inspect a container + Inspect, + /// Install a container + Install, + /// Send a singal to a container + Kill, + /// List all containers + List, + /// Notifications + Notifications, + /// Mount a container + Mount, + /// List repositories + Repositories, + /// Shutdown the runtime + Shutdown, + /// Start a container + Start, + /// Start a container with extra args and env + StartWithArgsAndEnv, + /// Token creation + TokenCreate, + /// Token verification + TokenVerification, + /// Umount a container + Umount, + /// Uninstall a container + Uninstall, +} + +impl fmt::Display for Permission { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result { + let s = format!("{:?}", self).to_snake_case(); + write!(f, "{}", s) + } +} + +impl From for Permissions { + fn from(permissions: ManifestPermissions) -> Self { + Permissions(permissions.iter().cloned().map(Into::into).collect()) + } +} + +impl From for Permission { + fn from(permission: ManifestPermission) -> Permission { + match permission { + ManifestPermission::Ident => Permission::Ident, + ManifestPermission::Inspect => Permission::Inspect, + ManifestPermission::Install => Permission::Install, + ManifestPermission::Kill => Permission::Kill, + ManifestPermission::List => Permission::List, + ManifestPermission::Notifications => Permission::Notifications, + ManifestPermission::Mount => Permission::Mount, + ManifestPermission::Repositories => Permission::Repositories, + ManifestPermission::Shutdown => Permission::Shutdown, + ManifestPermission::Start => Permission::Start, + ManifestPermission::StartWithArgsAndEnv => Permission::StartWithArgsAndEnv, + ManifestPermission::TokenCreate => Permission::TokenCreate, + ManifestPermission::TokenVerification => Permission::TokenVerification, + ManifestPermission::Umount => Permission::Umount, + ManifestPermission::Uninstall => Permission::Uninstall, + } + } +} diff --git a/northstar-runtime/src/runtime/runtime.rs b/northstar-runtime/src/runtime/runtime.rs index baf602ab5..ac33c41f1 100644 --- a/northstar-runtime/src/runtime/runtime.rs +++ b/northstar-runtime/src/runtime/runtime.rs @@ -3,7 +3,7 @@ use crate::{ runtime::{ cgroups, config::Config, - console::{self, Configuration, Permissions}, + console, events::{ContainerEvent, Event}, exit_status::ExitStatus, fork, @@ -113,7 +113,7 @@ impl Runtime { /// Main loop async fn run( - config: Config, + mut config: Config, token: CancellationToken, forker: (Pid, Streams), ) -> anyhow::Result<()> { @@ -144,17 +144,14 @@ async fn run( let (event_tx, mut event_rx) = mpsc::channel::(config.event_buffer_size); let (notification_tx, _) = sync::broadcast::channel(config.notification_buffer_size); - // Initialize the console if configured - let console = if let Some(url) = config.debug.as_ref().map(|d| &d.console) { + // Initialize the console if bind address configured. + let console = if let Some(global) = config.console.global.take() { let mut console = console::Console::new(event_tx.clone(), notification_tx.clone()); - // Default debug console configuration with full access and no limits. - let configuration = Configuration { - container: crate::npk::manifest::console::Configuration { - permissions: Permissions::full(), - }, - runtime: config.console.clone(), - }; - console.listen(url, &configuration).await?; + let options = global.options.unwrap_or_default(); + let permissions = global.permissions; + console + .listen(&global.bind, options.into(), permissions.into()) + .await?; Some(console) } else { None diff --git a/northstar-runtime/src/runtime/state.rs b/northstar-runtime/src/runtime/state.rs index b55a7afeb..c9f514823 100644 --- a/northstar-runtime/src/runtime/state.rs +++ b/northstar-runtime/src/runtime/state.rs @@ -462,7 +462,7 @@ impl State { let stop = CancellationToken::new(); // We send the fd to the forker so that it can pass it to the init - let console_fd = if let Some(configuration) = manifest.console.clone() { + let console_fd = if let Some(contianer_configuration) = manifest.console.clone() { let peer = Peer::Container(container.clone()); let (runtime_stream, container_stream) = StdUnixStream::pair().expect("failed to create socketpair"); @@ -477,18 +477,21 @@ impl State { let events_tx = self.events_tx.clone(); let stop = stop.clone(); let container = Some(container.clone()); - let configuration = { - crate::runtime::console::Configuration { - container: configuration, - runtime: self.config.console.clone(), - } - }; + let options = self + .config + .console + .options + .clone() + .unwrap_or_default() + .into(); + let permissions = contianer_configuration.permissions.clone().into(); let connection = Console::connection( runtime, peer, stop, container, - configuration, + options, + permissions, events_tx, notifications, None, diff --git a/northstar-tests/src/runtime.rs b/northstar-tests/src/runtime.rs index 5bbc06f95..e090054f2 100644 --- a/northstar-tests/src/runtime.rs +++ b/northstar-tests/src/runtime.rs @@ -7,20 +7,21 @@ use nanoid::nanoid; use northstar_runtime::{ api::model::{Container, ExitStatus, Notification}, common::non_nul_string::NonNulString, + npk::manifest::console::Permissions, runtime::{ - config::{self}, + config::{self, Console, ConsoleGlobal}, Runtime as Northstar, }, }; use std::{ convert::{TryFrom, TryInto}, - fs, + env, fs, }; use tempfile::TempDir; use tokio::{fs::remove_file, net::UnixStream, pin, select, time}; pub fn console_url() -> url::Url { - let console = std::env::temp_dir().join(format!("northstar-{}-full", std::process::id())); + let console = env::temp_dir().join(format!("northstar-{}-full", std::process::id())); url::Url::parse(&format!("unix://{}", console.display())).unwrap() } @@ -124,11 +125,17 @@ impl Runtime { event_buffer_size: 128, notification_buffer_size: 128, loop_device_timeout: time::Duration::from_secs(10), - console: config::Console::default(), cgroup: NonNulString::try_from(format!("northstar-{}", nanoid!())).unwrap(), repositories, + console: Console { + global: Some(ConsoleGlobal { + bind: console_url(), + permissions: Permissions::full(), + options: None, + }), + ..Default::default() + }, debug: Some(config::Debug { - console: console_url(), commands: vec!["sudo strace -c -p ".into()], }), }; diff --git a/northstar.toml b/northstar.toml index ac6e9ed5b..d24fdb7f6 100644 --- a/northstar.toml +++ b/northstar.toml @@ -13,7 +13,7 @@ notification_buffer_size = 64 # Loop device timeout loop_device_timeout = "5s" -[console] +[console.options] # Token validity token_validity = "1m" # Limits the number of requests processed per second @@ -25,9 +25,14 @@ max_npk_install_size = "100MB" # NPK stream timeout npk_stream_timeout = "5s" +[console.global] +# Url +bind = "tcp://localhost:4200" +# Permissions +permissions = "full" + # Debug TCP console on localhost [debug] -console = "tcp://localhost:4200" # Start a set of commands after a container is started. # is replaced with the init PID of the container. # is replaced with the container name.