Files
OpenShell/crates/openshell-core
Fede Kamelhar 78376bd041 fix(installer): resolve the gateway config dir like the CLI does (#4063)
* fix(installer): resolve the gateway config dir like the CLI does

install.sh hardcoded $TARGET_HOME/.config/openshell in two places: the
readiness check, which reads the client certificates it expects the
gateway registration to have written, and the cleanup that removes a
stale openshell entry before re-adding it. The CLI instead keeps both
under $XDG_CONFIG_HOME/openshell whenever that variable is set, so with
the variable pointing anywhere other than ~/.config the installer and
the CLI looked in different directories: the readiness check waited for
certificates that were never going to appear there, and the cleanup left
the real stale entry in place.

Resolve the directory through as_target_user instead, which answers from
the same environment the CLI is invoked in. That covers both branches
without duplicating their logic: the same-user branch inherits the
caller's XDG_CONFIG_HOME, while the sudo and runuser branches reset the
environment and fall back to the target user's home.

An empty XDG_CONFIG_HOME falls back to $HOME/.config, following the XDG
base directory specification. The CLI diverges here: xdg_config_dir
treats a set-but-empty value as set and joins onto it, yielding the
relative path "openshell", which no installer path can usefully match.
Worth fixing separately in the CLI.

Signed-off-by: fede-kamel <fkamelhar@gmail.com>

* fix(core): treat an empty XDG_CONFIG_HOME as unset

xdg_config_dir() joined onto an empty XDG_CONFIG_HOME and resolved the
config root to the relative path "openshell", while the installer falls
back to $HOME/.config/openshell for the same value. Registration runs the
CLI with the caller's environment, so the two could disagree on where the
gateway entry lives.

Treat an empty value as unset, as the XDG base directory spec requires,
so the CLI and installer resolve the same directory. Add tests for a value
with spaces and drive registration cleanup through the helper for the
spaces and empty cases.

Signed-off-by: fede-kamel <fkamelhar@gmail.com>

---------

Signed-off-by: fede-kamel <fkamelhar@gmail.com>
2026-10-22 19:32:47 +00:00
..

openshell-core

Shared types, constants, configuration, and helpers used across OpenShell crates.

Isolation registrations

isolation_registration owns the operator registry's backend names, byte-stream endpoints, and shared validation. Its fallible conversions carry registrations through the compute-driver protobuf and back into the supervisor's JSON launch file. These routes contain no credentials or driver-owned launch coordinates.

Object Metadata

Top-level user-facing objects use a Kubernetes-style metadata convention. The metadata shape provides:

  • Stable server-generated ID.
  • Human-readable name.
  • Creation timestamp.
  • Optional labels for filtering and automation.

Code that works with object metadata should use the traits in openshell_core::metadata instead of reaching into protobuf fields directly:

use openshell_core::{ObjectId, ObjectLabels, ObjectName};

let id = sandbox.object_id();
let name = sandbox.object_name();
let labels = sandbox.object_labels();

Trait methods must tolerate missing metadata and return safe empty values rather than panicking.

Label Rules

Labels follow Kubernetes-style key and value conventions:

  • Keys may include an optional DNS-prefix followed by /.
  • Names are limited to alphanumeric characters plus -, _, and ..
  • Values use the same character set and may be empty.
  • Selectors use comma-separated key=value pairs with AND semantics.

Validate labels at API ingress before persisting objects.

Inference Profiles

Provider inference profiles live in this crate so the gateway, sandbox, and router agree on provider defaults. Profiles define:

  • Auth header style.
  • Default upstream headers.
  • Client-supplied passthrough headers.
  • Supported inference protocol shapes.

Do not duplicate provider-specific inference behavior in callers. Add shared behavior here, then consume it from the gateway, sandbox, and router.

Middleware Contracts

Built-in supervisor middleware identifiers, host-selector matching, and pure configuration validation live in openshell_core::middleware. Policy admission and the supervisor runtime consume the same contract without introducing a dependency from the policy crate to the supervisor implementation.

Protobuf Struct Conversion

Use openshell_core::proto_struct when crossing between serde_json values and prost_types::{Struct, Value}. Both conversion directions live in this module; JSON-to-protobuf conversion is fallible so callers cannot silently replace an unrepresentable number.