Skip to content
Merged
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
6 changes: 3 additions & 3 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ jobs:
# contract change (e.g. a removed/added required field) against that
# stale image would 400 and abort. The "Seed platform resources" step
# runs it once the working-tree images are swapped in.
KIND_SKIP_SEED: "true"
SKIP_SEED: "true"
run: make kind-up

# Block until each triggered component build has concluded.
Expand Down Expand Up @@ -460,12 +460,12 @@ jobs:
# Seed platform resources now that the working-tree images are live (the
# swap above rolled them in). Deferred from kind-up so the seed exercises
# this PR's request contract instead of the baseline placeholder image.
# KIND_SEED_STRICT fails the job here with the real HTTP error if a create
# SEED_STRICT fails the job here with the real HTTP error if a create
# is rejected, rather than surfacing later as a confusing discovery miss.
- name: Seed platform resources
env:
DATABASE_PROVIDER: ${{ matrix.database-provider }}
KIND_SEED_STRICT: "true"
SEED_STRICT: "true"
run: make kind-seed

- name: Run e2e tests
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ apm_modules/
# Kind swap tracking
.kind-swaps

# OpenShift per-namespace swap tracking
.openshift-swaps/

# Temporary kustomize wrap dirs used by openshift-up
.openshift-render.*/

# Local tool binaries (built by make kind-prereqs)
bin/

Expand Down
274 changes: 223 additions & 51 deletions DEVELOPMENT.md

Large diffs are not rendered by default.

131 changes: 100 additions & 31 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ KIND_HOT_RELOAD?=true
KIND_HOST_MOUNT_PATH?=$(shell git rev-parse --show-toplevel 2>/dev/null || pwd)
KIND_KEYCLOAK_URL?=
LOCAL_IMAGES?=
PULL_SECRET?=
KIND_PULL_SECRET?=

# Prerequisite versions
Expand Down Expand Up @@ -66,6 +67,13 @@ HYPERSHELL_DATABASE_IMAGE?=
KIND_CONFIG=deploy/kind/kind-config.yaml
KIND_DNS_PORT?=5553

# OpenShift ephemeral-namespace development. The cluster is a precondition;
# these names select the shared Gateway the administrator already provisioned.
# The gateway base domain is discovered from that Gateway's listener hostname.
GATEWAY_API_GATEWAY_NAME?=openshell-grpc-gateway
GATEWAY_API_GATEWAY_NAMESPACE?=openshift-ingress
GATEWAY_IMAGE?=quay.io/opendatahub/odh-openshell-gateway:v0.0.109-rhaiv.0@sha256:a80b79e514826e8d57ea137749cf18a6e7f3d92e26bfefe005f3a9c4a55b8bdd

# Service hostnames (routed through the networking Gateway)
API_HOSTNAME=api.hypershell.localhost
CONSOLE_HOSTNAME=console.hypershell.localhost
Expand All @@ -84,26 +92,33 @@ help:
@echo " HyperShell Makefile"
@echo " ==================="
@echo ""
@echo " Local Development (Kind)"
@echo " All targets operate on KIND_NAMESPACE (default: hypershell-system)."
@echo " Local Development"
@echo " Targets are kind-<name> or openshift-<name>. They do the same work."
@echo ""
@echo " Kind uses KIND_NAMESPACE (default hypershell-system); kind-up creates the cluster."
@echo " OpenShift uses the current oc project (oc project -q); OPENSHIFT_NAMESPACE overrides."
@echo " OpenShift requires an existing cluster; openshift-up does not create one."
@echo ""
@echo " <prefix>-up Deploy the stack (Kind also creates the cluster)"
@echo " <prefix>-down Remove the environment namespace(s)"
@echo " <prefix>-teardown Kind: destroy the cluster. OpenShift: same as -down"
@echo " <prefix>-status Show cluster, pods, services/Routes, swap state"
@echo " <prefix>-api-server-up Build + swap API server from working tree"
@echo " <prefix>-api-server-down Revert API server to baseline image"
@echo " <prefix>-control-plane-up Build + swap control plane from working tree"
@echo " <prefix>-control-plane-down Revert control plane to baseline image"
@echo " <prefix>-web-console-up Swap web console (Kind: hot reload by default)"
@echo " <prefix>-web-console-down Revert web console to baseline image"
@echo ""
@echo " Kind Specific"
@echo " kind-env Print environment variables for local setup"
@echo " kind-up Create cluster + deploy all components (OIDC enabled)"
@echo " LOCAL_IMAGES=true: build from working tree (default)"
@echo " LOCAL_IMAGES=true BUILD_SOURCE=baseline: build from origin/main"
@echo " KIND_SKIP_SEED=true: defer seeding (run kind-seed later)"
@echo " kind-seed Seed platform resources into a running cluster"
@echo " kind-down Remove namespace and its resources"
@echo " kind-teardown Destroy Kind cluster, stop cloud-provider-kind"
@echo " kind-status Show cluster info, pods, services, swap state"
@echo " SKIP_SEED=true: defer seeding during kind-up / openshift-up"
@echo " SEED_STRICT=true: fail the command if seeding is incomplete"
@echo " kind-fix-ports Re-establish host port forwarding (443 + 8080)"
@echo " kind-api-server-up Build + swap API server from working tree"
@echo " kind-api-server-down Revert API server to baseline image"
@echo " kind-control-plane-up Build + swap control plane from working tree"
@echo " kind-control-plane-down Revert control plane to baseline image"
@echo " kind-web-console-up Hot reload (default) or build + swap web console (KIND_HOT_RELOAD=false)"
@echo " kind-web-console-down Revert web console to baseline image"
@echo " kind-gateway-trust Print SSL_CERT_FILE export so the openshell CLI trusts the dev CA"
@echo " LOCAL_IMAGES=true Build baseline images from the working tree (kind-up)"
@echo " BUILD_SOURCE=baseline With LOCAL_IMAGES=true, build from origin/main"
@echo ""
@echo " Build"
@echo " build-all Build all container images"
Expand All @@ -114,7 +129,7 @@ help:
@echo ""
@echo " Test & Lint"
@echo " test-all Run all test suites"
@echo " e2e Run E2E tests locally (requires Kind cluster)"
@echo " e2e Run E2E tests against target KUBECONFIG cluster"
@echo " e2e-performance Run the performance harness (requires a running cluster)"
@echo " e2e-performance-report Tabulate recent local performance runs"
@echo " lint Run all linters (Go + JS/TS)"
Expand Down Expand Up @@ -295,7 +310,7 @@ test-all: install-js

export CONTAINER_ENGINE KIND_CLUSTER_NAME KIND_NAMESPACE
export KIND_HOT_RELOAD KIND_HOST_MOUNT_PATH KIND_KEYCLOAK_URL LOCAL_IMAGES BUILD_SOURCE
export KIND_PULL_SECRET
export KIND_PULL_SECRET PULL_SECRET
export GATEWAY_API_VERSION KIND_VERSION CLOUD_PROVIDER_KIND_REPO CLOUD_PROVIDER_KIND_REF CLOUD_PROVIDER_KIND_BRANCH CERT_MANAGER_VERSION CNPG_VERSION AGENT_SANDBOX_VERSION
export HYPERSHELL_DATABASE_IMAGE
export IMAGE_REGISTRY IMAGE_TAG KIND_CONFIG
Expand All @@ -305,6 +320,8 @@ export api_server_local control_plane_local web_console_local
export build_version build_time
export API_HOSTNAME CONSOLE_HOSTNAME HEALTH_HOSTNAME KEYCLOAK_HOSTNAME METRICS_HOSTNAME KEYCLOAK_OIDC_ISSUER
export KIND_DNS_PORT
export OPENSHIFT_NAMESPACE SWAP_REGISTRY SWAP_REPOSITORY SWAP_PLATFORM SWAP_ARCH PULL_SECRET SKIP_SEED SEED_STRICT
export GATEWAY_API_GATEWAY_NAME GATEWAY_API_GATEWAY_NAMESPACE GATEWAY_IMAGE

# Build cloud-provider-kind from a fork that adds BackendTLSPolicy support
# (TLS re-encryption to backends). The fork also bundles the podman 6+ kind
Expand Down Expand Up @@ -361,6 +378,7 @@ kind-env:
@echo "export KIND_HOST_MOUNT_PATH=$(KIND_HOST_MOUNT_PATH)"
@echo "export KIND_KEYCLOAK_URL=$(KIND_KEYCLOAK_URL)"
@echo "export LOCAL_IMAGES=$(LOCAL_IMAGES)"
@echo "export PULL_SECRET=$(PULL_SECRET)"
@echo "export KIND_PULL_SECRET=$(KIND_PULL_SECRET)"
@echo "export KIND_DB_IMAGE=$(KIND_DB_IMAGE)"
@echo "export GATEWAY_API_VERSION=$(GATEWAY_API_VERSION)"
Expand All @@ -386,56 +404,108 @@ kind-env:

.PHONY: kind-up
kind-up:
@scripts/kind/up.sh
@CLUSTER_DRIVER=kind scripts/cluster/up.sh

.PHONY: kind-seed
kind-seed:
@scripts/kind/seed.sh
@CLUSTER_DRIVER=kind scripts/cluster/seed.sh

.PHONY: kind-down
kind-down:
@scripts/kind/down.sh
@CLUSTER_DRIVER=kind scripts/cluster/down.sh

.PHONY: kind-teardown
kind-teardown:
@scripts/kind/teardown.sh
@CLUSTER_DRIVER=kind scripts/cluster/teardown.sh

.PHONY: kind-status
kind-status:
@scripts/kind/status.sh
@CLUSTER_DRIVER=kind scripts/cluster/status.sh

.PHONY: kind-fix-ports
kind-fix-ports:
@scripts/kind/port-forward.sh

.PHONY: kind-api-server-up
kind-api-server-up:
@scripts/kind/swap-component.sh up api-server
@CLUSTER_DRIVER=kind scripts/cluster/swap.sh up api-server

.PHONY: kind-api-server-down
kind-api-server-down:
@scripts/kind/swap-component.sh down api-server
@CLUSTER_DRIVER=kind scripts/cluster/swap.sh down api-server

.PHONY: kind-control-plane-up
kind-control-plane-up:
@scripts/kind/swap-component.sh up control-plane
@CLUSTER_DRIVER=kind scripts/cluster/swap.sh up control-plane

.PHONY: kind-control-plane-down
kind-control-plane-down:
@scripts/kind/swap-component.sh down control-plane
@CLUSTER_DRIVER=kind scripts/cluster/swap.sh down control-plane

.PHONY: kind-web-console-up
kind-web-console-up:
@scripts/kind/swap-component.sh up web-console
@CLUSTER_DRIVER=kind scripts/cluster/swap.sh up web-console

.PHONY: kind-web-console-down
kind-web-console-down:
@scripts/kind/swap-component.sh down web-console
@CLUSTER_DRIVER=kind scripts/cluster/swap.sh down web-console

.PHONY: kind-gateway-trust
kind-gateway-trust:
@scripts/kind/gateway-trust.sh

# ============================================================================
# OpenShift cluster lifecycle - shell logic lives in scripts/cluster/
# ============================================================================

.PHONY: openshift-up
openshift-up:
@CLUSTER_DRIVER=openshift scripts/cluster/up.sh

.PHONY: openshift-seed
openshift-seed:
@CLUSTER_DRIVER=openshift scripts/cluster/seed.sh

.PHONY: openshift-down
openshift-down:
@CLUSTER_DRIVER=openshift scripts/cluster/down.sh

.PHONY: openshift-teardown
openshift-teardown:
@CLUSTER_DRIVER=openshift scripts/cluster/teardown.sh

.PHONY: openshift-status
openshift-status:
@CLUSTER_DRIVER=openshift scripts/cluster/status.sh

.PHONY: openshift-api-server-up
openshift-api-server-up:
@CLUSTER_DRIVER=openshift scripts/cluster/swap.sh up api-server

.PHONY: openshift-api-server-down
openshift-api-server-down:
@CLUSTER_DRIVER=openshift scripts/cluster/swap.sh down api-server

.PHONY: openshift-control-plane-up
openshift-control-plane-up:
@CLUSTER_DRIVER=openshift scripts/cluster/swap.sh up control-plane

.PHONY: openshift-control-plane-down
openshift-control-plane-down:
@CLUSTER_DRIVER=openshift scripts/cluster/swap.sh down control-plane

.PHONY: openshift-web-console-up
openshift-web-console-up:
@CLUSTER_DRIVER=openshift scripts/cluster/swap.sh up web-console

.PHONY: openshift-web-console-down
openshift-web-console-down:
@CLUSTER_DRIVER=openshift scripts/cluster/swap.sh down web-console

.PHONY: openshift-test
openshift-test:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Minor] New test harness is not wired into CI. make openshift-test runs the 650-line scripts/cluster/lib_test.sh (plus the rewrite-namespaces.py logic), but no workflow in .github/workflows/ invokes it, and scripts/cluster/ isn't covered by any lint/shellcheck job. Regressions in the driver/rewriter logic won't be caught. The PR body lists "CI automation" as out of scope, so a follow-up is fine — but please track adding this target (and shellcheck for scripts/cluster/) to CI so the suite actually guards the code. Confidence: High.

@bash scripts/cluster/lib_test.sh

generate-cli:
cd scripts/cli-generator && go run . \
--spec ../../components/api-server/openapi/openapi.yaml \
Expand All @@ -457,10 +527,9 @@ E2E_INFRA_DRIVER ?= kind
.PHONY: e2e
e2e:
@echo ""
@echo "==> Running E2E tests ($(E2E_INFRA_DRIVER))"
@echo "==> Running E2E tests"
@echo ""
@E2E_INFRA_DRIVER=$(E2E_INFRA_DRIVER) \
E2E_PROVISION_TIMEOUT=300 \
@E2E_PROVISION_TIMEOUT=300 \
E2E_SANDBOX_TIMEOUT=180 \
bash tests/e2e/e2e-openshell.sh

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ Or apply a kustomize patch via `deploy/openshift/kustomization.yaml` with your s
|---|---|---|---|
| `HYPERSHELL_GRPC_SERVER_ADDR` | `localhost:9000` | ✓ | gRPC address of the API server |
| `HYPERSHELL_API_SERVER_URL` | `http://localhost:8000` | ✓ | HTTP address of the API server |
| `HYPERSHELL_NAMESPACE` | `hypershell-system` | ✓ | Namespace the control plane runs in (used for trusted CA bundle source) |
| `HYPERSHELL_NAMESPACE` | pod namespace | ✓ | Namespace this controller runs in. In cluster this is the downward API (`metadata.namespace`), so the value is unique to that controller. It is also the `hypershell.redhat.io/instance` identity stamped on gateway namespaces so GC never reaps another HyperShell's workloads. |
| `GATEWAY_IMAGE` | *(none)* | **✓ required** | Container image for tenant gateways (pinned by digest; no fallback). Set in `deploy/base/controller.yaml` |
| `GATEWAY_SUPERVISOR_IMAGE` | *(none)* | **✓ required** | Container image for gateway supervisors (pinned by digest; no fallback). Set in `deploy/base/controller.yaml` |
| `GATEWAY_API_GATEWAY_NAME` | *(required)* | ✓ | Name of the pre-existing Gateway resource that tenant GRPCRoutes attach to |
Expand Down
17 changes: 14 additions & 3 deletions components/api-server/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# syntax=docker/dockerfile:1
FROM registry.access.redhat.com/hi/go:1.26.7@sha256:4c7c064cc73698c13384d1445ab93595f3b9309dd89ed45b9992e67284e3ed82 AS builder
# HI pins are the per-arch manifests from hi/go:1.26.7 and hi/static:1787099997.
# BUILDARCH selects a native Go toolchain; TARGETARCH selects the runtime and GOARCH.
# Bump amd64 and arm64 together when changing tags.
ARG BUILDARCH
ARG TARGETARCH

FROM registry.access.redhat.com/hi/go:1.26.7@sha256:2a2215ce496fdd33fdc19739eaadde902f7719c8be222f22f92fd7da02c889cb AS go-amd64
FROM registry.access.redhat.com/hi/go:1.26.7@sha256:ba850dda34c47052bb8db5561c80c43fb08d0f9a729c90fddd755a2d5b46f74b AS go-arm64
FROM go-${BUILDARCH} AS builder

WORKDIR /workspace

Expand All @@ -13,12 +21,15 @@ COPY openapi/ openapi/

ARG GIT_VERSION=unknown
ARG BUILD_TIME=unknown
RUN CGO_ENABLED=0 go build -mod=mod -ldflags="-s -w \
ARG TARGETARCH
RUN CGO_ENABLED=0 GOOS=linux GOARCH="${TARGETARCH}" go build -mod=mod -ldflags="-s -w \
-X github.com/openshift-online/hypershell/components/api-server/pkg/api.Version=${GIT_VERSION} \
-X 'github.com/openshift-online/hypershell/components/api-server/pkg/api.BuildTime=${BUILD_TIME}'" \
-o hypershell ./cmd/hypershell

FROM registry.access.redhat.com/hi/static:1787099997@sha256:f4d5109b57cf7eab0a7adc566f2d78f80fa0c5ec9ccab698c9fb8eb448db6071
FROM registry.access.redhat.com/hi/static:1787099997@sha256:3d43712a61ce01c7049e983e7f4c4609aaad7582c7bbd930b57372f82c446f98 AS static-amd64
FROM registry.access.redhat.com/hi/static:1787099997@sha256:2ccd532da5e8868a92f479a7268a2fce65279c1f7c8a8dd0880d399c04d6a356 AS static-arm64
FROM static-${TARGETARCH}

COPY --from=builder /workspace/hypershell /usr/local/bin/

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ func newControlPlaneProvisionerFromEnvironment() (ServiceAccountProvisioner, err
if address == "" {
return nil, nil
}
// grpc-go DNS does not apply kube-DNS search domains. Callers must pass a
// cluster-local FQDN (see deploy/base/api-server.yaml).
connection, err := grpc.NewClient(address, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
return nil, fmt.Errorf("create control-plane provisioner client: %w", err)
Expand Down
17 changes: 14 additions & 3 deletions components/cli/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# syntax=docker/dockerfile:1
FROM registry.access.redhat.com/hi/go:1.26.7@sha256:4c7c064cc73698c13384d1445ab93595f3b9309dd89ed45b9992e67284e3ed82 AS builder
# HI pins are the per-arch manifests from hi/go:1.26.7 and hi/static:1787099997.
# BUILDARCH selects a native Go toolchain; TARGETARCH selects the runtime and GOARCH.
# Bump amd64 and arm64 together when changing tags.
ARG BUILDARCH
ARG TARGETARCH

FROM registry.access.redhat.com/hi/go:1.26.7@sha256:2a2215ce496fdd33fdc19739eaadde902f7719c8be222f22f92fd7da02c889cb AS go-amd64
FROM registry.access.redhat.com/hi/go:1.26.7@sha256:ba850dda34c47052bb8db5561c80c43fb08d0f9a729c90fddd755a2d5b46f74b AS go-arm64
FROM go-${BUILDARCH} AS builder

WORKDIR /workspace

Expand All @@ -9,9 +17,12 @@ RUN go mod download
COPY cmd/ cmd/
COPY pkg/ pkg/

RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o hsctl ./cmd/hypershell
ARG TARGETARCH
RUN CGO_ENABLED=0 GOOS=linux GOARCH="${TARGETARCH}" go build -ldflags="-s -w" -o hsctl ./cmd/hypershell

FROM registry.access.redhat.com/hi/static:1787099997@sha256:f4d5109b57cf7eab0a7adc566f2d78f80fa0c5ec9ccab698c9fb8eb448db6071
FROM registry.access.redhat.com/hi/static:1787099997@sha256:3d43712a61ce01c7049e983e7f4c4609aaad7582c7bbd930b57372f82c446f98 AS static-amd64
FROM registry.access.redhat.com/hi/static:1787099997@sha256:2ccd532da5e8868a92f479a7268a2fce65279c1f7c8a8dd0880d399c04d6a356 AS static-arm64
FROM static-${TARGETARCH}

COPY --from=builder /workspace/hsctl /usr/local/bin/

Expand Down
17 changes: 14 additions & 3 deletions components/control-plane/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# syntax=docker/dockerfile:1
FROM registry.access.redhat.com/hi/go:1.26.7@sha256:4c7c064cc73698c13384d1445ab93595f3b9309dd89ed45b9992e67284e3ed82 AS builder
# HI pins are the per-arch manifests from hi/go:1.26.7 and hi/static:1787099997.
# BUILDARCH selects a native Go toolchain; TARGETARCH selects the runtime and GOARCH.
# Bump amd64 and arm64 together when changing tags.
ARG BUILDARCH
ARG TARGETARCH

FROM registry.access.redhat.com/hi/go:1.26.7@sha256:2a2215ce496fdd33fdc19739eaadde902f7719c8be222f22f92fd7da02c889cb AS go-amd64
FROM registry.access.redhat.com/hi/go:1.26.7@sha256:ba850dda34c47052bb8db5561c80c43fb08d0f9a729c90fddd755a2d5b46f74b AS go-arm64
FROM go-${BUILDARCH} AS builder

WORKDIR /workspace

Expand All @@ -16,9 +24,12 @@ COPY components/api-server/proto/ components/api-server/proto/
COPY components/control-plane/cmd/ components/control-plane/cmd/
COPY components/control-plane/internal/ components/control-plane/internal/

RUN cd components/control-plane && CGO_ENABLED=0 go build -mod=mod -ldflags="-s -w" -o /workspace/hypershell-controller ./cmd/hypershell-controller
ARG TARGETARCH
RUN cd components/control-plane && CGO_ENABLED=0 GOOS=linux GOARCH="${TARGETARCH}" go build -mod=mod -ldflags="-s -w" -o /workspace/hypershell-controller ./cmd/hypershell-controller

FROM registry.access.redhat.com/hi/static:1787099997@sha256:f4d5109b57cf7eab0a7adc566f2d78f80fa0c5ec9ccab698c9fb8eb448db6071
FROM registry.access.redhat.com/hi/static:1787099997@sha256:3d43712a61ce01c7049e983e7f4c4609aaad7582c7bbd930b57372f82c446f98 AS static-amd64
FROM registry.access.redhat.com/hi/static:1787099997@sha256:2ccd532da5e8868a92f479a7268a2fce65279c1f7c8a8dd0880d399c04d6a356 AS static-arm64
FROM static-${TARGETARCH}

COPY --from=builder /workspace/hypershell-controller /usr/local/bin/
COPY components/control-plane/manifests/ /manifests/
Expand Down
Loading
Loading