mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-02 07:34:45 +08:00
* refactor(config): normalize compute driver field names Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * refactor(config): introduce canonical gateway fields Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * refactor(config): enforce gateway schema version 2 Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(config): preserve compute driver runtime guarantees Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(config): address schema v2 review regressions Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(config): complete schema v2 migration safeguards Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(config): expand schema v2 regression coverage Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(config): add schema v2 parity manifest Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(config): correct parity manifest inventory Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * docs(config): record schema v2 intentional changes Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * docs(config): disposition schema v2 parity gaps Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): add dual schema parity harness Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): establish compute lifecycle parity baseline Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(config): preserve gateway option compatibility Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): record gateway option parity Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * docs(config): close gateway-wide parity gaps Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(podman): apply configured pids limit Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): validate Podman option parity Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): add Kubernetes option parity harness Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): record Kubernetes option parity Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): disposition VM parity lanes Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): add external driver parity lane Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(e2e): preserve external driver pull policy Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): attest parity artifacts and launches Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): require clean parity build sources Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): bind parity runtime artifacts Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(e2e): use isolated supervisor tags Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(e2e): qualify parity image tags Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(e2e): serve parity supervisor locally Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): isolate parity podman services Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): harden parity evidence provenance Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): pin parity sandbox artifacts Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): attest parity runtime inputs Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): bind parity runtime evidence Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): record compute boundary parity Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(e2e): disposition cross-cutting parity lanes Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(packaging): preflight gateway config upgrades Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(config): preserve rebase integration guarantees Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(ci): isolate temporary git signing config Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(config): update remaining schema v2 consumers Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(ci): provide e2fs tools to VM tests Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(config): align preflight with gateway startup Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(vm): preserve rootfs tar configuration Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * chore(config): adopt duration unit constructors Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(packaging): preflight RPM gateway config Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(config): address driver review findings Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(e2e): require fresh semantic parity evidence Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * fix(docker): update tests for renamed sandbox label Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> * test(gateway): preserve selective driver coverage after rebase Signed-off-by: Drew Newberry <anewberry@nvidia.com> --------- Signed-off-by: Jesse Jaggars <jjaggars@redhat.com> Signed-off-by: Drew Newberry <anewberry@nvidia.com> Co-authored-by: Drew Newberry <anewberry@nvidia.com>
270 lines
11 KiB
RPMSpec
270 lines
11 KiB
RPMSpec
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
%global crate openshell
|
|
%global openshell_version 0.0.37
|
|
%global openshell_cargo_version %{openshell_version}
|
|
# Python dist-info metadata intentionally follows the RPM Version. Dev build
|
|
# identity is represented by Release for RPM packages.
|
|
%global openshell_python_version %{openshell_version}
|
|
|
|
# Cargo/Rust builds with vendored deps do not produce debugsource listings
|
|
# in the format redhat-rpm-config expects (especially on EPEL).
|
|
%global debug_package %{nil}
|
|
|
|
Name: openshell
|
|
Version: %{openshell_version}
|
|
Release: 1.20260518180028805757.podman.toml.gateway.listener.11.g8c0cb7c8%{?dist}
|
|
Summary: Safe, sandboxed runtimes for autonomous AI agents
|
|
|
|
License: Apache-2.0
|
|
URL: https://github.com/NVIDIA/OpenShell
|
|
Source0: openshell-%{openshell_version}.tar.gz
|
|
Source1: openshell-%{openshell_version}-vendor.tar.xz
|
|
|
|
ExclusiveArch: x86_64 aarch64
|
|
|
|
# Cargo metadata generation
|
|
BuildRequires: cargo
|
|
BuildRequires: cargo-rpm-macros >= 25
|
|
BuildRequires: systemd-rpm-macros
|
|
|
|
# Man page generation
|
|
BuildRequires: pandoc
|
|
|
|
# Python sub-package build dependencies
|
|
BuildRequires: python3-devel
|
|
|
|
# Runtime: container runtime for package-managed gateway sandboxes.
|
|
# The gateway auto-detects Podman when the package-managed service starts.
|
|
Recommends: podman
|
|
|
|
%description
|
|
OpenShell provides safe, sandboxed runtimes for autonomous AI agents.
|
|
It offers a CLI for managing gateway registrations, sandboxes, and providers with
|
|
policy-enforced egress routing, credential proxying, and privacy-aware
|
|
profile-backed model-provider access.
|
|
|
|
# --- Gateway sub-package ---
|
|
%package gateway
|
|
Summary: OpenShell gateway server with Podman sandbox driver
|
|
Requires: podman
|
|
Requires: openssl
|
|
Requires: %{name} = %{version}-%{release}
|
|
|
|
%description gateway
|
|
OpenShell gateway server providing the control-plane API for sandbox
|
|
lifecycle management. This package installs Podman-oriented defaults in
|
|
gateway TOML while leaving compute driver selection to gateway auto-detection
|
|
or explicit operator configuration.
|
|
|
|
# --- Python SDK sub-package ---
|
|
%package -n python3-%{name}
|
|
Summary: OpenShell Python SDK for agent execution and management
|
|
# Use Recommends instead of Requires because Fedora 43+ ships older
|
|
# versions of grpcio (1.48) and protobuf (3.19) than the SDK needs.
|
|
# Users on distros with older packages can install these via pip/uv.
|
|
Recommends: python3-cloudpickle >= 3.0
|
|
Recommends: python3-grpcio >= 1.60
|
|
Recommends: python3-protobuf >= 4.25
|
|
Recommends: %{name}
|
|
|
|
%description -n python3-%{name}
|
|
Python SDK for OpenShell providing programmatic access to sandbox
|
|
management, agent execution, and provider access via gRPC.
|
|
|
|
%prep
|
|
%autosetup -n %{name}-%{version}
|
|
|
|
# Extract vendored Cargo dependencies and configure offline build
|
|
tar xf %{SOURCE1}
|
|
%cargo_prep -v vendor
|
|
|
|
# Patch workspace version from placeholder to actual build identity.
|
|
sed -i 's/^version = "0.0.0"/version = "%{openshell_cargo_version}"/' Cargo.toml
|
|
grep -q 'version = "%{openshell_cargo_version}"' Cargo.toml || (echo "ERROR: Cargo.toml version patch failed" && exit 1)
|
|
|
|
%build
|
|
test -x "${OPENSHELL_PREBUILT_BINARIES_DIR}/openshell"
|
|
test -x "${OPENSHELL_PREBUILT_BINARIES_DIR}/openshell-gateway"
|
|
|
|
# Generate vendored crate manifest and license metadata.
|
|
# cargo-vendor.txt is consumed by an RPM generator (from cargo-rpm-macros)
|
|
# to emit Provides: bundled(crate(...)) = version for every vendored dep.
|
|
%cargo_vendor_manifest
|
|
%{cargo_license_summary}
|
|
%{cargo_license} > LICENSE.dependencies
|
|
|
|
# Build man pages from markdown
|
|
pandoc -s -t man deploy/man/openshell.1.md -o openshell.1
|
|
pandoc -s -t man deploy/man/openshell-gateway.8.md -o openshell-gateway.8
|
|
|
|
%install
|
|
# --- CLI binary ---
|
|
install -Dpm 0755 "${OPENSHELL_PREBUILT_BINARIES_DIR}/%{name}" %{buildroot}%{_bindir}/%{name}
|
|
|
|
# --- Gateway binary ---
|
|
install -Dpm 0755 "${OPENSHELL_PREBUILT_BINARIES_DIR}/%{name}-gateway" %{buildroot}%{_bindir}/%{name}-gateway
|
|
|
|
# --- Default gateway TOML config template ---
|
|
# Shipped as a read-only reference in %{_datadir}. The systemd unit seeds a
|
|
# user-level copy at ~/.config/openshell/gateway.toml on first start.
|
|
install -Dpm 0644 deploy/rpm/gateway.toml.default %{buildroot}%{_datadir}/%{name}-gateway/gateway.toml.default
|
|
install -Dpm 0644 deploy/rpm/gateway.toml.default.v1 %{buildroot}%{_datadir}/%{name}-gateway/gateway.toml.default.v1
|
|
install -Dpm 0755 deploy/rpm/migrate-gateway-config.sh %{buildroot}%{_libexecdir}/%{name}-gateway-migrate-config
|
|
|
|
# --- Gateway systemd user unit ---
|
|
# Installed to the systemd user unit directory so any user can run:
|
|
# systemctl --user enable --now openshell-gateway.service
|
|
install -d %{buildroot}%{_userunitdir}
|
|
cat > %{buildroot}%{_userunitdir}/%{name}-gateway.service << 'EOF'
|
|
[Unit]
|
|
Description=OpenShell Gateway (user)
|
|
Documentation=https://github.com/NVIDIA/OpenShell
|
|
After=podman.socket
|
|
Wants=podman.socket
|
|
|
|
[Service]
|
|
Type=exec
|
|
# On first start the unit seeds a default TOML config and generates PKI.
|
|
# Client certs are placed in ~/.config/openshell/gateways/openshell/mtls/ so
|
|
# the CLI discovers them automatically.
|
|
# See /usr/share/doc/openshell-gateway/ for details.
|
|
|
|
# Seed a default TOML config on first start. On upgrade, replace only the exact
|
|
# schema-v1 config previously seeded by this package; preserve edited files.
|
|
# %%E expands to $XDG_CONFIG_HOME (~/.config) in user units.
|
|
ExecStartPre=%{_libexecdir}/%{name}-gateway-migrate-config %%E/openshell/gateway.toml /usr/share/openshell-gateway/gateway.toml.default /usr/share/openshell-gateway/gateway.toml.default.v1
|
|
|
|
# Reject an invalid selected configuration before generating certificates or
|
|
# starting the gateway. The environment file below applies to every command.
|
|
ExecStartPre=/usr/bin/openshell-gateway config preflight
|
|
|
|
# Auto-generate PKI on first start if not present.
|
|
# The default local TLS dir uses %%h because %%S resolves differently across
|
|
# systemd user-manager versions. gateway.env may override this path.
|
|
Environment=OPENSHELL_LOCAL_TLS_DIR=%%h/.local/state/openshell/tls
|
|
ExecStartPre=/usr/bin/openshell-gateway generate-certs --output-dir ${OPENSHELL_LOCAL_TLS_DIR} --server-san host.openshell.internal
|
|
|
|
# gateway.env is honored for backward compatibility with pre-1415 installs.
|
|
# New installs use runtime defaults; create gateway.toml to override.
|
|
# See TROUBLESHOOTING.md for the env-to-TOML migration guide.
|
|
EnvironmentFile=-%%E/openshell/gateway.env
|
|
ExecStart=/usr/bin/openshell-gateway
|
|
StateDirectory=openshell
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
|
|
# Security hardening
|
|
NoNewPrivileges=yes
|
|
ProtectSystem=strict
|
|
PrivateTmp=yes
|
|
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
EOF
|
|
|
|
# --- Gateway documentation ---
|
|
install -d %{buildroot}%{_docdir}/%{name}-gateway
|
|
install -pm 0644 deploy/rpm/QUICKSTART.md %{buildroot}%{_docdir}/%{name}-gateway/QUICKSTART.md
|
|
install -pm 0644 deploy/rpm/CONFIGURATION.md %{buildroot}%{_docdir}/%{name}-gateway/CONFIGURATION.md
|
|
install -pm 0644 deploy/rpm/TROUBLESHOOTING.md %{buildroot}%{_docdir}/%{name}-gateway/TROUBLESHOOTING.md
|
|
|
|
# --- Man pages ---
|
|
install -Dpm 0644 openshell.1 %{buildroot}%{_mandir}/man1/openshell.1
|
|
install -Dpm 0644 openshell-gateway.8 %{buildroot}%{_mandir}/man8/openshell-gateway.8
|
|
|
|
# --- Python SDK ---
|
|
# Install Python SDK modules (test files are intentionally excluded)
|
|
install -d %{buildroot}%{python3_sitelib}/%{name}
|
|
install -d %{buildroot}%{python3_sitelib}/%{name}/_proto
|
|
|
|
install -pm 0644 python/%{name}/__init__.py %{buildroot}%{python3_sitelib}/%{name}/
|
|
install -pm 0644 python/%{name}/sandbox.py %{buildroot}%{python3_sitelib}/%{name}/
|
|
install -pm 0644 python/%{name}/_proto/__init__.py %{buildroot}%{python3_sitelib}/%{name}/_proto/
|
|
install -pm 0644 python/%{name}/_proto/*.py %{buildroot}%{python3_sitelib}/%{name}/_proto/
|
|
|
|
# Create dist-info so importlib.metadata can resolve the package version
|
|
install -d %{buildroot}%{python3_sitelib}/%{name}-%{openshell_python_version}.dist-info
|
|
cat > %{buildroot}%{python3_sitelib}/%{name}-%{openshell_python_version}.dist-info/METADATA << EOF
|
|
Metadata-Version: 2.1
|
|
Name: %{name}
|
|
Version: %{openshell_python_version}
|
|
Summary: OpenShell Python SDK for agent execution and management
|
|
License: Apache-2.0
|
|
Requires-Python: >=3.12
|
|
Requires-Dist: cloudpickle>=3.0
|
|
Requires-Dist: grpcio>=1.60
|
|
Requires-Dist: protobuf>=4.25
|
|
EOF
|
|
|
|
# INSTALLER marker per PEP 376
|
|
echo "rpm" > %{buildroot}%{python3_sitelib}/%{name}-%{openshell_python_version}.dist-info/INSTALLER
|
|
|
|
# RECORD can be empty for RPM-managed installs
|
|
touch %{buildroot}%{python3_sitelib}/%{name}-%{openshell_python_version}.dist-info/RECORD
|
|
|
|
%check
|
|
# Smoke-test the CLI binary
|
|
%{buildroot}%{_bindir}/%{name} --version
|
|
|
|
# Smoke-test the gateway binary
|
|
%{buildroot}%{_bindir}/%{name}-gateway --version
|
|
|
|
# Smoke-test the Python SDK version metadata via importlib.metadata.
|
|
# We query the dist-info directly rather than importing the package because
|
|
# the full import pulls in grpcio and other runtime deps not present in the
|
|
# build environment.
|
|
PYTHONPATH=%{buildroot}%{python3_sitelib} %{python3} -c "from importlib.metadata import version; v = version('openshell'); print(v); assert v == '%{openshell_python_version}', f'expected %{openshell_python_version}, got {v}'"
|
|
|
|
# Verify the RPM default TOML config template was installed.
|
|
# A missing template means first-start seeding silently falls back to the
|
|
# binary default of 127.0.0.1, which breaks Podman sandbox connectivity.
|
|
test -f %{buildroot}%{_datadir}/%{name}-gateway/gateway.toml.default
|
|
test -f %{buildroot}%{_datadir}/%{name}-gateway/gateway.toml.default.v1
|
|
test -x %{buildroot}%{_libexecdir}/%{name}-gateway-migrate-config
|
|
|
|
# Verify the systemd unit invokes exact-default migration before startup.
|
|
grep -q '%{name}-gateway-migrate-config' %{buildroot}%{_userunitdir}/%{name}-gateway.service
|
|
grep -q 'gateway.toml.default.v1' %{buildroot}%{_userunitdir}/%{name}-gateway.service
|
|
|
|
%post gateway
|
|
%systemd_user_post %{name}-gateway.service
|
|
|
|
%preun gateway
|
|
%systemd_user_preun %{name}-gateway.service
|
|
|
|
%postun gateway
|
|
%systemd_user_postun_with_restart %{name}-gateway.service
|
|
|
|
%files
|
|
%license LICENSE
|
|
%license LICENSE.dependencies
|
|
%license cargo-vendor.txt
|
|
%doc README.md
|
|
%{_bindir}/%{name}
|
|
%{_mandir}/man1/openshell.1*
|
|
|
|
%files gateway
|
|
%license LICENSE
|
|
%license LICENSE.dependencies
|
|
%license cargo-vendor.txt
|
|
%doc %{_docdir}/%{name}-gateway/QUICKSTART.md
|
|
%doc %{_docdir}/%{name}-gateway/CONFIGURATION.md
|
|
%doc %{_docdir}/%{name}-gateway/TROUBLESHOOTING.md
|
|
%{_bindir}/%{name}-gateway
|
|
%{_userunitdir}/%{name}-gateway.service
|
|
%{_libexecdir}/%{name}-gateway-migrate-config
|
|
%{_datadir}/%{name}-gateway/gateway.toml.default
|
|
%{_datadir}/%{name}-gateway/gateway.toml.default.v1
|
|
%{_mandir}/man8/openshell-gateway.8*
|
|
|
|
%files -n python3-%{name}
|
|
%license LICENSE
|
|
%{python3_sitelib}/%{name}/
|
|
%{python3_sitelib}/%{name}-%{openshell_python_version}.dist-info/
|
|
|
|
%changelog
|
|
%autochangelog
|