diff --git a/CHANGELOG.md b/CHANGELOG.md index b701ad68919..ff067772e1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,22 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) and the chang +## [3.131.1](https://github.com/metalbear-co/mirrord/tree/3.131.1) - 2025-01-28 + + +### Changed + +- mirrord commands now accept the `-f`/`--config-file` argument without the value as well. + When no value is provided, `./.mirrord/mirrord.json` is assumed. + [#1706](https://github.com/metalbear-co/mirrord/issues/1706) + + +### Fixed + +- Added ping pong subtask to mirrord-extproxy to keep agent connection alive while it is + up. [#3030](https://github.com/metalbear-co/mirrord/issues/3030) +- `agent.privileged` no longer affects targetless agents' pods. + ## [3.131.0](https://github.com/metalbear-co/mirrord/tree/3.131.0) - 2025-01-27 diff --git a/Cargo.lock b/Cargo.lock index d230c6c84f6..a9a5e72661a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2413,7 +2413,7 @@ dependencies = [ [[package]] name = "fileops" -version = "3.131.0" +version = "3.131.1" dependencies = [ "libc", ] @@ -3531,7 +3531,7 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "issue1317" -version = "3.131.0" +version = "3.131.1" dependencies = [ "actix-web", "env_logger 0.11.6", @@ -3541,7 +3541,7 @@ dependencies = [ [[package]] name = "issue1776" -version = "3.131.0" +version = "3.131.1" dependencies = [ "errno 0.3.10", "libc", @@ -3550,7 +3550,7 @@ dependencies = [ [[package]] name = "issue1776portnot53" -version = "3.131.0" +version = "3.131.1" dependencies = [ "libc", "socket2", @@ -3558,14 +3558,14 @@ dependencies = [ [[package]] name = "issue1899" -version = "3.131.0" +version = "3.131.1" dependencies = [ "libc", ] [[package]] name = "issue2001" -version = "3.131.0" +version = "3.131.1" dependencies = [ "libc", ] @@ -3886,7 +3886,7 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "listen_ports" -version = "3.131.0" +version = "3.131.1" [[package]] name = "litemap" @@ -4127,7 +4127,7 @@ dependencies = [ [[package]] name = "mirrord" -version = "3.131.0" +version = "3.131.1" dependencies = [ "actix-codec", "clap", @@ -4183,7 +4183,7 @@ dependencies = [ [[package]] name = "mirrord-agent" -version = "3.131.0" +version = "3.131.1" dependencies = [ "actix-codec", "async-trait", @@ -4241,7 +4241,7 @@ dependencies = [ [[package]] name = "mirrord-analytics" -version = "3.131.0" +version = "3.131.1" dependencies = [ "assert-json-diff", "base64 0.22.1", @@ -4255,7 +4255,7 @@ dependencies = [ [[package]] name = "mirrord-auth" -version = "3.131.0" +version = "3.131.1" dependencies = [ "bcder", "chrono", @@ -4276,7 +4276,7 @@ dependencies = [ [[package]] name = "mirrord-config" -version = "3.131.0" +version = "3.131.1" dependencies = [ "base64 0.22.1", "bimap", @@ -4300,7 +4300,7 @@ dependencies = [ [[package]] name = "mirrord-config-derive" -version = "3.131.0" +version = "3.131.1" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", @@ -4310,7 +4310,7 @@ dependencies = [ [[package]] name = "mirrord-console" -version = "3.131.0" +version = "3.131.1" dependencies = [ "bincode", "drain", @@ -4326,7 +4326,7 @@ dependencies = [ [[package]] name = "mirrord-intproxy" -version = "3.131.0" +version = "3.131.1" dependencies = [ "bytes", "exponential-backoff", @@ -4354,7 +4354,7 @@ dependencies = [ [[package]] name = "mirrord-intproxy-protocol" -version = "3.131.0" +version = "3.131.1" dependencies = [ "bincode", "mirrord-protocol", @@ -4364,7 +4364,7 @@ dependencies = [ [[package]] name = "mirrord-kube" -version = "3.131.0" +version = "3.131.1" dependencies = [ "actix-codec", "async-stream", @@ -4388,7 +4388,7 @@ dependencies = [ [[package]] name = "mirrord-layer" -version = "3.131.0" +version = "3.131.1" dependencies = [ "actix-codec", "base64 0.22.1", @@ -4431,7 +4431,7 @@ dependencies = [ [[package]] name = "mirrord-layer-macro" -version = "3.131.0" +version = "3.131.1" dependencies = [ "proc-macro2", "quote", @@ -4440,7 +4440,7 @@ dependencies = [ [[package]] name = "mirrord-macros" -version = "3.131.0" +version = "3.131.1" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", @@ -4450,7 +4450,7 @@ dependencies = [ [[package]] name = "mirrord-operator" -version = "3.131.0" +version = "3.131.1" dependencies = [ "base64 0.22.1", "bincode", @@ -4483,7 +4483,7 @@ dependencies = [ [[package]] name = "mirrord-progress" -version = "3.131.0" +version = "3.131.1" dependencies = [ "enum_dispatch", "indicatif", @@ -4517,7 +4517,7 @@ dependencies = [ [[package]] name = "mirrord-sip" -version = "3.131.0" +version = "3.131.1" dependencies = [ "apple-codesign", "object 0.36.7", @@ -4530,7 +4530,7 @@ dependencies = [ [[package]] name = "mirrord-vpn" -version = "3.131.0" +version = "3.131.1" dependencies = [ "futures", "ipnet", @@ -4878,7 +4878,7 @@ dependencies = [ [[package]] name = "outgoing" -version = "3.131.0" +version = "3.131.1" [[package]] name = "outref" @@ -5985,14 +5985,14 @@ dependencies = [ [[package]] name = "rust-bypassed-unix-socket" -version = "3.131.0" +version = "3.131.1" dependencies = [ "tokio", ] [[package]] name = "rust-e2e-fileops" -version = "3.131.0" +version = "3.131.1" dependencies = [ "libc", ] @@ -6008,7 +6008,7 @@ dependencies = [ [[package]] name = "rust-unix-socket-client" -version = "3.131.0" +version = "3.131.1" dependencies = [ "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index 4288306f5ca..6ac4dc9387a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ resolver = "2" # latest commits on rustls suppress certificate verification [workspace.package] -version = "3.131.0" +version = "3.131.1" edition = "2021" license = "MIT" readme = "README.md" diff --git a/mirrord-schema.json b/mirrord-schema.json index 0cebfb20ce9..1add0f98916 100644 --- a/mirrord-schema.json +++ b/mirrord-schema.json @@ -284,7 +284,7 @@ }, "disabled_capabilities": { "title": "agent.disabled_capabilities {#agent-disabled_capabilities}", - "description": "Disables specified Linux capabilities for the agent container. If nothing is disabled here, agent uses `NET_ADMIN`, `NET_RAW`, `SYS_PTRACE` and `SYS_ADMIN`.", + "description": "Disables specified Linux capabilities for the agent container. If nothing is disabled here, agent uses `NET_ADMIN`, `NET_RAW`, `SYS_PTRACE` and `SYS_ADMIN`.\n\nHas no effect when using the targetless mode, as targetless agent containers have no capabilities.", "type": [ "array", "null" @@ -423,7 +423,7 @@ }, "privileged": { "title": "agent.privileged {#agent-privileged}", - "description": "Run the mirror agent as privileged container. Defaults to `false`.\n\nMight be needed in strict environments such as Bottlerocket.", + "description": "Run the mirror agent as privileged container. Defaults to `false`.\n\nMight be needed in strict environments such as Bottlerocket.\n\nHas no effect when using the targetless mode, as targetless agent containers are never privileged.", "type": [ "boolean", "null" diff --git a/mirrord/cli/src/config.rs b/mirrord/cli/src/config.rs index 96548235ad4..0b36c9c796c 100644 --- a/mirrord/cli/src/config.rs +++ b/mirrord/cli/src/config.rs @@ -204,7 +204,8 @@ pub(super) struct ExecParams { pub disable_version_check: bool, /// Load config from config file - #[arg(short = 'f', long, value_hint = ValueHint::FilePath)] + /// When using -f flag without a value, defaults to "./.mirrord/mirrord.json" + #[arg(short = 'f', long, value_hint = ValueHint::FilePath, default_missing_value = "./.mirrord/mirrord.json", num_args = 0..=1)] pub config_file: Option, /// Kube context to use from Kubeconfig @@ -426,7 +427,8 @@ pub(super) struct PortForwardArgs { pub disable_version_check: bool, /// Load config from config file - #[arg(short = 'f', long, value_hint = ValueHint::FilePath)] + /// When using -f flag without a value, defaults to "./.mirrord/mirrord.json" + #[arg(short = 'f', long, value_hint = ValueHint::FilePath, default_missing_value = "./.mirrord/mirrord.json", num_args = 0..=1)] pub config_file: Option, /// Kube context to use from Kubeconfig @@ -587,7 +589,7 @@ pub(super) enum OperatorCommand { /// Print operator status Status { /// Specify config file to use - #[arg(short = 'f', long, value_hint = ValueHint::FilePath)] + #[arg(short = 'f', long, value_hint = ValueHint::FilePath, default_missing_value = "./.mirrord/mirrord.json", num_args = 0..=1)] config_file: Option, }, /// Operator session management commands. @@ -727,7 +729,7 @@ impl ListTargetArgs { #[derive(Args, Debug)] pub(super) struct ExtensionExecArgs { /// Specify config file to use - #[arg(short = 'f', long, value_hint = ValueHint::FilePath)] + #[arg(short = 'f', long, value_hint = ValueHint::FilePath, default_missing_value = "./mirrord.json", num_args = 0..=1)] pub config_file: Option, /// Specify target #[arg(short = 't')] @@ -766,7 +768,7 @@ pub(super) enum DiagnoseCommand { /// Check network connectivity and provide RTT (latency) statistics. Latency { /// Specify config file to use - #[arg(short = 'f', long, value_hint = ValueHint::FilePath)] + #[arg(short = 'f', long, value_hint = ValueHint::FilePath, default_missing_value = "./.mirrord/mirrord.json", num_args = 0..=1)] config_file: Option, }, } @@ -895,7 +897,8 @@ pub(super) struct VpnArgs { pub namespace: Option, /// Load config from config file - #[arg(short = 'f', long, value_hint = ValueHint::FilePath)] + /// When using -f flag without a value, defaults to "./.mirrord/mirrord.json" + #[arg(short = 'f', long, value_hint = ValueHint::FilePath, default_missing_value = "./.mirrord/mirrord.json", num_args = 0..=1)] pub config_file: Option, #[cfg(target_os = "macos")] diff --git a/mirrord/cli/src/error.rs b/mirrord/cli/src/error.rs index 8426737da0b..45bff2a09b0 100644 --- a/mirrord/cli/src/error.rs +++ b/mirrord/cli/src/error.rs @@ -113,6 +113,10 @@ pub(crate) enum ExternalProxyError { )] #[diagnostic(help("{GENERAL_BUG}"))] MissingTlsInfo, + + #[error("External proxy ping pong with the agent failed: {0}")] + #[diagnostic(help("{GENERAL_BUG}"))] + PingPongFailed(String), } /// Errors that can occur when executing the `mirrord intproxy` command. diff --git a/mirrord/cli/src/external_proxy.rs b/mirrord/cli/src/external_proxy.rs index 34bf46b82b8..3ff76dd6bd1 100644 --- a/mirrord/cli/src/external_proxy.rs +++ b/mirrord/cli/src/external_proxy.rs @@ -36,7 +36,7 @@ use local_ip_address::local_ip; use mirrord_analytics::{AnalyticsReporter, CollectAnalytics, Reporter}; use mirrord_config::LayerConfig; use mirrord_intproxy::agent_conn::{AgentConnection, ConnectionTlsError}; -use mirrord_protocol::DaemonCodec; +use mirrord_protocol::{ClientMessage, DaemonCodec, DaemonMessage, LogLevel, LogMessage}; use tokio::net::{TcpListener, TcpStream}; use tokio_rustls::server::TlsStream; use tokio_util::{either::Either, sync::CancellationToken}; @@ -81,6 +81,10 @@ pub async fn proxy(listen_port: u16, watch: drain::Watch) -> CliResult<()> { let mut analytics = AnalyticsReporter::new(config.telemetry, execution_kind, watch); (&config).collect_analytics(analytics.get_mut()); + // This connection is just to keep the agent alive as long as the client side is running. + let mut own_agent_conn = + connect_and_ping(&config, agent_connect_info.clone(), &mut analytics).await?; + let tls_acceptor = create_external_proxy_tls_acceptor(&config).await?; let listener = create_listen_socket(SocketAddr::new( local_ip().unwrap_or_else(|_| Ipv4Addr::UNSPECIFIED.into()), @@ -101,6 +105,8 @@ pub async fn proxy(listen_port: u16, watch: drain::Watch) -> CliResult<()> { config.external_proxy.start_idle_timeout, ))); + let mut ping_pong_ticker = tokio::time::interval(Duration::from_secs(30)); + loop { tokio::select! { conn = listener.accept() => { @@ -147,6 +153,53 @@ pub async fn proxy(listen_port: u16, watch: drain::Watch) -> CliResult<()> { } } + message = own_agent_conn.agent_rx.recv() => { + tracing::debug!(?message, "received message on own connection"); + + match message { + Some(DaemonMessage::Pong) => continue, + Some(DaemonMessage::LogMessage(LogMessage { + level: LogLevel::Error, + message, + })) => { + tracing::error!("agent log: {message}"); + } + Some(DaemonMessage::LogMessage(LogMessage { + level: LogLevel::Warn, + message, + })) => { + tracing::warn!("agent log: {message}"); + } + Some(DaemonMessage::Close(reason)) => { + return Err( + ExternalProxyError::PingPongFailed(format!( + "agent closed connection with message: {reason}" + )).into() + ); + } + Some(message) => { + return Err( + ExternalProxyError::PingPongFailed(format!( + "agent sent an unexpected message: {message:?}" + )).into() + ); + } + None => { + return Err( + ExternalProxyError::PingPongFailed( + "agent unexpectedly closed connection".to_string(), + ).into() + ); + } + } + } + + _ = ping_pong_ticker.tick() => { + tracing::debug!("sending ping"); + + let _ = own_agent_conn.agent_tx.send(ClientMessage::Ping).await; + } + _ = initial_connection_timeout.as_mut(), if connections.load(Ordering::Relaxed) == 0 => { tracing::debug!("closing listener due to initial connection timeout"); diff --git a/mirrord/config/configuration.md b/mirrord/config/configuration.md index 20d3dbc0e0e..57b5cd32900 100644 --- a/mirrord/config/configuration.md +++ b/mirrord/config/configuration.md @@ -196,6 +196,9 @@ Disables specified Linux capabilities for the agent container. If nothing is disabled here, agent uses `NET_ADMIN`, `NET_RAW`, `SYS_PTRACE` and `SYS_ADMIN`. +Has no effect when using the targetless mode, +as targetless agent containers have no capabilities. + ### agent.dns {#agent-dns} ### agent.ephemeral {#agent-ephemeral} @@ -355,6 +358,9 @@ Defaults to `false`. Might be needed in strict environments such as Bottlerocket. +Has no effect when using the targetless mode, +as targetless agent containers are never privileged. + ### agent.resources {#agent-resources} Set pod resource reqirements. (not with ephemeral agents) diff --git a/mirrord/config/src/agent.rs b/mirrord/config/src/agent.rs index caf1d131a25..7f8cbfa0967 100644 --- a/mirrord/config/src/agent.rs +++ b/mirrord/config/src/agent.rs @@ -236,6 +236,9 @@ pub struct AgentConfig { /// Disables specified Linux capabilities for the agent container. /// If nothing is disabled here, agent uses `NET_ADMIN`, `NET_RAW`, `SYS_PTRACE` and /// `SYS_ADMIN`. + /// + /// Has no effect when using the targetless mode, + /// as targetless agent containers have no capabilities. pub disabled_capabilities: Option>, /// ### agent.tolerations {#agent-tolerations} @@ -291,6 +294,9 @@ pub struct AgentConfig { /// Defaults to `false`. /// /// Might be needed in strict environments such as Bottlerocket. + /// + /// Has no effect when using the targetless mode, + /// as targetless agent containers are never privileged. #[config(default = false)] pub privileged: bool, diff --git a/mirrord/kube/src/api/container/job.rs b/mirrord/kube/src/api/container/job.rs index 7c3247a091f..190e1ebc518 100644 --- a/mirrord/kube/src/api/container/job.rs +++ b/mirrord/kube/src/api/container/job.rs @@ -291,9 +291,6 @@ mod test { "name": "mirrord-agent", "image": agent.image(), "imagePullPolicy": agent.image_pull_policy, - "securityContext": { - "privileged": agent.privileged - }, "command": ["./mirrord-agent", "-l", "3000", "targetless"], "env": [ { "name": "RUST_LOG", "value": agent.log_level }, diff --git a/mirrord/kube/src/api/container/pod.rs b/mirrord/kube/src/api/container/pod.rs index 984a3fd8afa..c627e3022bd 100644 --- a/mirrord/kube/src/api/container/pod.rs +++ b/mirrord/kube/src/api/container/pod.rs @@ -134,10 +134,6 @@ impl ContainerVariant for PodVariant<'_> { env: Some(env), // Add requests to avoid getting defaulted https://github.com/metalbear-co/mirrord/issues/579 resources: Some(resources), - security_context: Some(SecurityContext { - privileged: Some(agent.privileged), - ..Default::default() - }), ..Default::default() }], ..Default::default()