Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
20 changes: 20 additions & 0 deletions docs/reference/sandbox-compute-drivers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,26 @@ For maintainer-level implementation details, refer to the [Podman driver README]

Select Podman with `compute_drivers = ["podman"]` in `[openshell.gateway]`. Configure Podman driver values such as `socket_path`, `network_name`, `supervisor_image`, `stop_timeout_secs`, `image_pull_policy`, `grpc_endpoint`, `host_gateway_ip`, `sandbox_ssh_socket_path`, `sandbox_pids_limit`, and `guest_tls_*` in `[openshell.drivers.podman]`.

### macOS Podman Socket Path

On macOS, Homebrew-installed Podman does not create the default socket path
that the driver probes (`~/.local/share/containers/podman/machine/podman.sock`).
The actual API socket lives under `/var/folders/` in a path that macOS can
rotate after a reboot.

If the gateway fails with `Podman socket not found; is podman machine running?`
while `podman machine list` shows a running machine, set the
`OPENSHELL_PODMAN_SOCKET` environment variable to the dynamic socket path:

```shell
export OPENSHELL_PODMAN_SOCKET="$(podman machine inspect --format '{{.ConnectionInfo.PodmanSocket.Path}}')"
```

Add this to your shell profile or gateway launch environment so it resolves
correctly after each reboot. Alternatively, set `socket_path` in
`[openshell.drivers.podman]` to the current path, but note that the path may
change when macOS rotates `/var/folders/`.

Podman sandboxes default to a 45-second graceful stop window before Podman escalates from `SIGTERM` to `SIGKILL`. Set `stop_timeout_secs` in gateway config, or `OPENSHELL_STOP_TIMEOUT` for the standalone driver, when a local runtime needs a different teardown window.

Stop stops the existing Podman container while retaining its named workspace
Expand Down
37 changes: 6 additions & 31 deletions e2e/rust/tests/driver_config_volume.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ async fn connect_container_api(driver: &str) -> Result<Docker, String> {
"docker" => Docker::connect_with_local_defaults()
.map_err(|err| format!("connect to Docker API: {err}"))?,
"podman" => {
let socket = podman_socket_path();
let socket = podman_socket_path()?;
let socket_display = socket.display().to_string();
Docker::connect_with_unix(
socket
Expand All @@ -525,36 +525,11 @@ async fn connect_container_api(driver: &str) -> Result<Docker, String> {
Ok(docker)
}

fn podman_socket_path() -> PathBuf {
if let Some(path) = std::env::var_os("OPENSHELL_PODMAN_SOCKET") {
return PathBuf::from(path);
}

#[cfg(target_os = "macos")]
{
let home = std::env::var_os("HOME").unwrap_or_default();
PathBuf::from(home).join(".local/share/containers/podman/machine/podman.sock")
}
#[cfg(target_os = "linux")]
{
std::env::var_os("XDG_RUNTIME_DIR").map_or_else(
|| {
let uid = std::process::Command::new("id")
.arg("-u")
.output()
.ok()
.and_then(|output| {
String::from_utf8(output.stdout)
.ok()
.map(|value| value.trim().to_string())
})
.filter(|value| !value.is_empty())
.unwrap_or_else(|| "1000".to_string());
PathBuf::from(format!("/run/user/{uid}/podman/podman.sock"))
},
|xdg| PathBuf::from(xdg).join("podman/podman.sock"),
)
}
fn podman_socket_path() -> Result<PathBuf, String> {
let path = std::env::var_os("OPENSHELL_PODMAN_SOCKET").ok_or_else(|| {
"OPENSHELL_PODMAN_SOCKET must be set by e2e/with-podman-gateway.sh".to_string()
})?;
Ok(PathBuf::from(path))
}

fn unique_volume_name(driver: &str) -> String {
Expand Down
8 changes: 4 additions & 4 deletions e2e/support/gateway-common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -218,11 +218,11 @@ e2e_build_gateway_binaries() {
if [ -z "${OPENSHELL_GATEWAY_BIN:-}" ]; then
echo "Building openshell-gateway..."
if [ "${OPENSHELL_E2E_EXTERNAL_COMPUTE_DRIVER:-0}" = "1" ]; then
cargo build "${jobs[@]}" \
cargo build ${jobs[@]+"${jobs[@]}"} \
-p openshell-gateway --bin openshell-gateway \
--no-default-features --features telemetry
else
cargo build "${jobs[@]}" \
cargo build ${jobs[@]+"${jobs[@]}"} \
-p openshell-gateway --bin openshell-gateway
fi
else
Expand All @@ -231,7 +231,7 @@ e2e_build_gateway_binaries() {

if [ -z "${OPENSHELL_BIN:-}" ]; then
echo "Building openshell-cli..."
cargo build "${jobs[@]}" \
cargo build ${jobs[@]+"${jobs[@]}"} \
-p openshell-cli
else
echo "Using prebuilt openshell CLI at ${OPENSHELL_BIN}"
Expand Down Expand Up @@ -265,7 +265,7 @@ e2e_build_external_driver() {
else
printf -v "${output_var}" '%s' "${target_dir}/debug/${binary}"
echo "Building external ${binary}..."
cargo build "${jobs[@]}" -p "${package}" --bin "${binary}"
cargo build ${jobs[@]+"${jobs[@]}"} -p "${package}" --bin "${binary}"
fi
if [ ! -x "${!output_var}" ]; then
echo "ERROR: expected external driver binary at ${!output_var}" >&2
Expand Down
15 changes: 11 additions & 4 deletions e2e/with-podman-gateway.sh
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,11 @@ with_podman_config() {
}

podman_cmd() {
with_podman_config podman "$@"
if [ -n "${OPENSHELL_PODMAN_SOCKET:-}" ]; then
with_podman_config podman --url "unix://${OPENSHELL_PODMAN_SOCKET}" "$@"
else
with_podman_config podman "$@"
fi
}

WORKDIR_PARENT="${TMPDIR:-/tmp}"
Expand Down Expand Up @@ -234,15 +238,17 @@ default_podman_socket_path() {

ensure_podman_api_socket() {
if [ -n "${OPENSHELL_PODMAN_SOCKET:-}" ]; then
export CONTAINER_HOST="${CONTAINER_HOST:-unix://${OPENSHELL_PODMAN_SOCKET}}"
return 0
fi

local default_socket
default_socket="$(default_podman_socket_path || true)"
if [ -n "${default_socket}" ] \
&& [ -S "${default_socket}" ] \
&& podman_cmd --url "unix://${default_socket}" info >/dev/null 2>&1; then
&& with_podman_config podman --url "unix://${default_socket}" info >/dev/null 2>&1; then
export OPENSHELL_PODMAN_SOCKET="${default_socket}"
export CONTAINER_HOST="${CONTAINER_HOST:-unix://${OPENSHELL_PODMAN_SOCKET}}"
return 0
fi

Expand All @@ -266,12 +272,13 @@ ensure_podman_api_socket() {
>"${PODMAN_SERVICE_LOG}" 2>&1 &
PODMAN_SERVICE_PID=$!
export OPENSHELL_PODMAN_SOCKET="${PODMAN_SOCKET}"
export CONTAINER_HOST="${CONTAINER_HOST:-unix://${OPENSHELL_PODMAN_SOCKET}}"

local elapsed=0
local timeout=30
while [ "${elapsed}" -lt "${timeout}" ]; do
if [ -S "${PODMAN_SOCKET}" ] \
&& podman_cmd --url "unix://${PODMAN_SOCKET}" info >/dev/null 2>&1; then
&& podman_cmd info >/dev/null 2>&1; then
return 0
fi

Expand Down Expand Up @@ -375,12 +382,12 @@ if ! command -v podman >/dev/null 2>&1; then
echo "ERROR: podman CLI is required to run Podman-backed e2e tests" >&2
exit 2
fi
ensure_podman_api_socket
if ! podman_cmd info >/dev/null 2>&1; then
echo "ERROR: podman service is not reachable (podman info failed)" >&2
echo " Start it with 'podman machine start' on macOS, or the user service on Linux." >&2
exit 2
fi
ensure_podman_api_socket

e2e_build_gateway_binaries "${ROOT}" TARGET_DIR GATEWAY_BIN CLI_BIN
export OPENSHELL_BIN="${CLI_BIN}"
Expand Down
2 changes: 1 addition & 1 deletion tasks/scripts/stage-prebuilt-binaries.sh
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ build_component_for_arch() {
if [[ -n "$build_rustflags" ]]; then
export RUSTFLAGS="$build_rustflags"
fi
CARGO_INCREMENTAL=0 mise x -- "${cargo_env[@]}" "${cargo_subcommand[@]}" "${args[@]}"
CARGO_INCREMENTAL=0 mise x -- ${cargo_env[@]+"${cargo_env[@]}"} "${cargo_subcommand[@]}" "${args[@]}"
)

binary_path="${ROOT}/target/${target}/release/${binary}"
Expand Down
Loading