Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions helix-cli/src/commands/dashboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use crate::utils::command_exists;
use eyre::{Result, eyre};
use std::process::{Command, Stdio};

// The dashboard is always a container (Docker/Podman), never native.

const DASHBOARD_IMAGE: &str = "public.ecr.aws/p8l2s5f1/helix-dashboard:latest";
const DASHBOARD_CONTAINER_NAME: &str = "helix-dashboard";

Expand Down Expand Up @@ -43,6 +45,7 @@ async fn start(
match runtime {
ContainerRuntime::Docker => "host.docker.internal".to_string(),
ContainerRuntime::Podman => "host.containers.internal".to_string(),
ContainerRuntime::Native => "localhost".to_string(),
}
Comment on lines 45 to 48

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Dashboard container unreachable on macOS/Windows with native runtime

The comment above says "The dashboard is always a container (Docker/Podman), never native", yet "localhost" is returned for the Native arm. Inside a Docker or Podman container on macOS and Windows, localhost resolves to the container itself, not the host. So when container_runtime = "native", the HelixDB process is running directly on the host, but the dashboard container would try to reach it at localhost and fail to connect. On Linux with host networking this works, but on macOS/Windows users would see connection errors from the dashboard. Consider returning "host.docker.internal" (or the equivalent per the outer runtime responsible for the dashboard) instead, or explicitly blocking helix dashboard when running the native runtime.

} else {
host
Expand Down
4 changes: 2 additions & 2 deletions helix-cli/src/commands/delete.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::config::InstanceInfo;
use crate::local_runtime::LocalRuntime;
use crate::local_runtime::Runtime;
use crate::output::Operation;
use crate::project::ProjectContext;
use crate::utils::{print_confirm, print_warning};
Expand All @@ -24,7 +24,7 @@ pub async fn run(instance: String, yes: bool) -> Result<()> {

let op = Operation::new("Deleting", &instance);
if matches!(info, InstanceInfo::Local(_)) {
let _ = LocalRuntime::new(&project).prune_instance(&instance);
let _ = Runtime::for_project(&project).prune(&instance);
}

project.config.local.remove(&instance);
Expand Down
4 changes: 2 additions & 2 deletions helix-cli/src/commands/logs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::commands::auth::require_auth;
use crate::config::InstanceInfo;
use crate::enterprise_cloud::cloud_base_url;
use crate::local_runtime::LocalRuntime;
use crate::local_runtime::Runtime;
use crate::project::ProjectContext;
use crate::prompts;
use chrono::{DateTime, Duration, Utc};
Expand Down Expand Up @@ -34,7 +34,7 @@ pub async fn run(
"--range, --start, and --end are only supported for Enterprise logs; local logs use docker/podman logs"
));
}
LocalRuntime::new(&project).logs(&instance, follow)?;
Runtime::for_project(&project).logs(&instance, follow)?;
}
InstanceInfo::Enterprise(config) => {
if follow {
Expand Down
4 changes: 2 additions & 2 deletions helix-cli/src/commands/prune.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::local_runtime::LocalRuntime;
use crate::local_runtime::Runtime;
use crate::output::Operation;
use crate::project::ProjectContext;
use crate::prompts::{self, PruneSelection};
Expand Down Expand Up @@ -26,7 +26,7 @@ pub async fn run(instance: Option<String>, all: bool, yes: bool) -> Result<()> {

async fn prune_one(project: &ProjectContext, instance: &str) -> Result<()> {
let op = Operation::new("Pruning", instance);
let removed_container = LocalRuntime::new(project).prune_instance(instance)?;
let removed_container = Runtime::for_project(project).prune(instance)?;
let workspace = project.instance_workspace(instance);
let removed_workspace = workspace.exists();
if workspace.exists() {
Expand Down
4 changes: 2 additions & 2 deletions helix-cli/src/commands/restart.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::config::InstanceInfo;
use crate::local_runtime::LocalRuntime;
use crate::local_runtime::Runtime;
use crate::output::Operation;
use crate::project::ProjectContext;
use crate::prompts;
Expand All @@ -12,7 +12,7 @@ pub async fn run(instance: Option<String>) -> Result<()> {
return Err(eyre!("'{instance}' is not a local v2 instance"));
};
let op = Operation::new("Restarting", &instance);
LocalRuntime::new(&project).restart(&instance, config)?;
Runtime::for_project(&project).restart(&instance, config)?;
op.success();
Ok(())
}
Expand Down
10 changes: 5 additions & 5 deletions helix-cli/src/commands/run.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::config::{InstanceInfo, LocalStorageMode};
use crate::local_runtime::LocalRuntime;
use crate::local_runtime::Runtime;
use crate::output::{Operation, Verbosity};
use crate::project::ProjectContext;
use crate::prompts;
Expand Down Expand Up @@ -36,18 +36,18 @@ pub async fn run(
}

project.ensure_instance_dir(&instance)?;
let runtime = LocalRuntime::new(&project);
let runtime = Runtime::for_project(&project);
if foreground {
crate::output::info("Running in foreground. Press Ctrl-C to stop.");
runtime.run_foreground(&instance, &config).await?;
runtime.start_foreground(&instance, &config).await?;
op.success();
} else {
runtime.run_detached(&instance, &config)?;
runtime.start(&instance, &config)?;
op.success();
if Verbosity::current().show_normal() {
Operation::print_details(&[
("URL", &format!("http://localhost:{}", config.port)),
("Container", &runtime.container_name(&instance)),
("Container", &runtime.display_name(&instance)),
]);
}
}
Expand Down
10 changes: 6 additions & 4 deletions helix-cli/src/commands/status.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::config::InstanceInfo;
use crate::local_runtime::LocalRuntime;
use crate::local_runtime::Runtime;
use crate::project::ProjectContext;
use crate::prompts::{self, StatusSelection};
use crate::utils::{print_field, print_header, print_newline};
Expand All @@ -13,15 +13,17 @@ pub async fn run(instance: Option<String>) -> Result<()> {
print_field("Root", &project.root.display().to_string());
print_newline();

let runtime = LocalRuntime::new(&project);
let runtime = Runtime::for_project(&project);
print_header("Instances");
match resolve_status_selection(&project, instance)? {
StatusSelection::All => {
for name in project.config.list_instances() {
print_instance(&project, &runtime, name)?;
}
}
StatusSelection::Instance(instance) => print_instance(&project, &runtime, &instance)?,
StatusSelection::Instance(instance) => {
print_instance(&project, &runtime, &instance)?
}
}

Ok(())
Expand All @@ -41,7 +43,7 @@ fn resolve_status_selection(
Ok(StatusSelection::All)
}

fn print_instance(project: &ProjectContext, runtime: &LocalRuntime, name: &str) -> Result<()> {
fn print_instance(project: &ProjectContext, runtime: &Runtime, name: &str) -> Result<()> {
match project.config.get_instance(name)? {
InstanceInfo::Local(config) => {
let status = runtime.status(name)?;
Expand Down
4 changes: 2 additions & 2 deletions helix-cli/src/commands/stop.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::config::InstanceInfo;
use crate::local_runtime::LocalRuntime;
use crate::local_runtime::Runtime;
use crate::output::Operation;
use crate::project::ProjectContext;
use crate::prompts;
Expand All @@ -15,7 +15,7 @@ pub async fn run(instance: Option<String>) -> Result<()> {
return Err(eyre!("'{instance}' is not a local v2 instance"));
}
let op = Operation::new("Stopping", &instance);
if LocalRuntime::new(&project).stop(&instance)? {
if Runtime::for_project(&project).stop(&instance)? {
op.success();
} else {
crate::output::info(&format!("Instance '{instance}' was not running"));
Expand Down
7 changes: 7 additions & 0 deletions helix-cli/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,29 @@ pub enum ContainerRuntime {
#[default]
Docker,
Podman,
Native,
}

impl ContainerRuntime {
pub const fn binary(&self) -> &'static str {
match self {
Self::Docker => "docker",
Self::Podman => "podman",
Self::Native => "native",
}
}

pub const fn label(&self) -> &'static str {
match self {
Self::Docker => "Docker",
Self::Podman => "Podman",
Self::Native => "Native",
}
}

pub const fn is_native(&self) -> bool {
matches!(self, Self::Native)
}
}

fn default_container_runtime() -> ContainerRuntime {
Expand Down
Loading