From a5d659645fb7252214ff2ff406d4a0062b91c5f2 Mon Sep 17 00:00:00 2001 From: Haven Xia Date: Tue, 20 Oct 2026 10:49:17 -0700 Subject: [PATCH 1/2] Delete hack/install-ate.sh and hack/install-ate-kind.sh Signed-off-by: Haven Xia --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/workflows/pr-workflow.yaml | 37 +--- AGENTS.md | 4 +- README.md | 8 +- benchmarking/README.md | 8 +- benchmarking/automation/README.md | 4 +- benchmarking/automation/orchestrator.py | 10 +- benchmarking/automation/test_orchestrator.py | 4 +- benchmarking/automation/tests.yaml | 4 +- benchmarking/automation/util.py | 2 +- benchmarking/nighthawk-egress/README.md | 6 +- benchmarking/nighthawk-ingress/README.md | 4 +- benchmarking/nighthawk-ingress/run-dev.sh | 2 +- benchmarking/telemetry/README.md | 2 +- cmd/ate-setup/README.md | 9 +- cmd/ate-setup/cli-diff.md | 4 - cmd/ate-setup/commands.md | 192 ++++++++---------- cmd/ate-setup/differences.md | 26 +-- cmd/ate-setup/internal/cmd/csi_test.go | 2 +- cmd/ate-setup/internal/cmd/root.go | 10 +- cmd/ate-setup/internal/config/config.go | 7 +- cmd/ate-setup/internal/config/config_test.go | 9 +- cmd/ate-setup/internal/config/file.go | 3 +- cmd/ate-setup/internal/config/load.go | 17 +- cmd/ate-setup/internal/config/load_test.go | 10 +- cmd/ate-setup/internal/steps/apienv.go | 2 +- cmd/ate-setup/internal/steps/csi.go | 7 +- cmd/ate-setup/internal/steps/csi_test.go | 11 +- cmd/ate-setup/main.go | 5 +- cmd/ate-setup/preflight_test.go | 32 +-- cmd/kubectl-ate/README.md | 2 +- .../internal/cmd/actortemplate_test.go | 2 +- demos/claude-code-multiplex/README.md | 2 +- demos/counter/README.md | 8 +- demos/counter/counter-template.yaml.tmpl | 2 +- demos/egress/README.md | 8 +- demos/egress/test-egress.sh | 2 +- demos/jupyter/README.md | 8 +- demos/multi-template/README.md | 4 +- demos/sandbox/README.md | 4 +- docs/authorization.md | 6 +- docs/dev/best-practices/otel-collector.md | 4 +- docs/dev/mitm-egress-test-runbook.md | 6 +- docs/egress-credential-injection.md | 4 +- docs/examples/substrate-install.yaml | 2 +- docs/operator-install.md | 6 +- hack/install-ate-kind.sh | 44 ---- hack/install-ate.sh | 35 ---- hack/install-microvm-deps.sh | 4 +- hack/microvm-assets/README.md | 5 +- hack/microvm-assets/stage-to-rustfs.sh | 2 +- hack/run-e2e-kind.sh | 6 +- hack/run-microvm-demo-kind.sh | 4 +- hack/run-microvm-demo.sh | 33 ++- hack/setup-csi-hostpath-kind.sh | 140 ------------- .../deploy/example/storageclass-nfs.yaml | 4 +- hack/verify-atenet-drain.sh | 3 +- hack/verify-egress-demo.sh | 2 +- internal/e2e/README.md | 10 +- internal/e2e/credprovider.go | 2 +- internal/e2e/env.go | 4 +- internal/e2e/sandbox.go | 12 +- internal/e2e/sandbox_test.go | 4 +- .../egresscredinject/egresscredinject_test.go | 2 +- .../e2e/suites/egressmitm/goldenboot_test.go | 2 +- internal/e2e/suites/security/README.md | 2 +- internal/e2e/trustbundle.go | 2 +- manifests/ate-install/atenet-egress.yaml | 2 +- manifests/ate-install/base/kustomization.yaml | 15 +- .../cloudsql/proxy-sidecar-patch.yaml | 4 +- .../kind/atelet/kustomization.yaml | 2 +- manifests/ate-install/kind/kustomization.yaml | 7 +- .../podcert-size10/kustomization.yaml | 2 +- .../postgres-config-patch.yaml | 7 +- .../microvm/sandboxconfig-microvm.yaml.tmpl | 2 +- tools/setup-gcp/README.md | 2 +- tools/setup-gcp/cloud-sql.md | 4 +- tools/setup-gcp/cmd/cloudsql.go | 6 +- tools/setup-gcp/cmd/cloudsql_test.go | 2 +- 79 files changed, 282 insertions(+), 608 deletions(-) delete mode 100644 cmd/ate-setup/cli-diff.md delete mode 100755 hack/install-ate-kind.sh delete mode 100755 hack/install-ate.sh delete mode 100755 hack/setup-csi-hostpath-kind.sh diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index b320dd3366..26879fe159 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -47,7 +47,7 @@ body: label: Steps to Reproduce description: How can the issue be reproduced? Provide commands, scripts, or manifests (e.g., ActorTemplate). placeholder: | - 1. Deploy Substrate with `hack/install-ate-kind.sh ...` + 1. Deploy Substrate with `go run ./cmd/ate-setup --kind ...` 2. Apply manifest `kubectl apply -f ...` 3. Run command `...` 4. See error diff --git a/.github/workflows/pr-workflow.yaml b/.github/workflows/pr-workflow.yaml index a6a0b009c1..70c1e94b77 100644 --- a/.github/workflows/pr-workflow.yaml +++ b/.github/workflows/pr-workflow.yaml @@ -267,27 +267,14 @@ jobs: # gateway. ATE_PREVIEW above selects the preview features. env: ATE_ATENET_DATAPLANE: ${{ matrix.dataplane }} - NO_DEV_ENV: "true" - KO_DOCKER_REPO: "localhost:5001" - ATE_INSTALL_KIND: "true" - BUCKET_NAME: "ate-snapshot" - KIND_CLUSTER_NAME: "kind" - KUBECTL_CONTEXT: "kind-kind" - run: go run ./cmd/ate-setup deploy ate-system + run: go run ./cmd/ate-setup --kind deploy ate-system - name: Enable NFS # Load NFS kernel modules so in-cluster NFS server and CSI driver can run. run: | sudo modprobe nfs || true sudo modprobe nfsd || true - name: Install CSI NFS driver - env: - NO_DEV_ENV: "true" - KO_DOCKER_REPO: "localhost:5001" - ATE_INSTALL_KIND: "true" - BUCKET_NAME: "ate-snapshot" - KIND_CLUSTER_NAME: "kind" - KUBECTL_CONTEXT: "kind-kind" - run: go run ./cmd/ate-setup setup csi nfs + run: go run ./cmd/ate-setup --kind setup csi nfs - name: Deploy micro-VM counter demo # Stages the (cached) assets into the cluster's rustfs and deploys the # counter-microvm demo onto the control plane installed above. The demo @@ -296,29 +283,15 @@ jobs: ATE_ATENET_DATAPLANE: ${{ matrix.dataplane }} run: hack/run-microvm-demo-kind.sh - name: Deploy gVisor counter demo - env: - NO_DEV_ENV: "true" - KO_DOCKER_REPO: "localhost:5001" - ATE_INSTALL_KIND: "true" - BUCKET_NAME: "ate-snapshot" - KIND_CLUSTER_NAME: "kind" - KUBECTL_CONTEXT: "kind-kind" - run: go run ./cmd/ate-setup deploy demo counter + run: go run ./cmd/ate-setup --kind deploy demo counter - name: Deploy egress demos # TestActorEgress in the networking suite builds its Actor from the egress # ActorTemplate for the class under test, so both fixtures have to exist # before their respective lane runs. The demo's actors trust the CA the # gateway mints its leaves from. - env: - NO_DEV_ENV: "true" - KO_DOCKER_REPO: "localhost:5001" - ATE_INSTALL_KIND: "true" - BUCKET_NAME: "ate-snapshot" - KIND_CLUSTER_NAME: "kind" - KUBECTL_CONTEXT: "kind-kind" run: | - go run ./cmd/ate-setup deploy demo egress - go run ./cmd/ate-setup deploy demo egress-microvm + go run ./cmd/ate-setup --kind deploy demo egress + go run ./cmd/ate-setup --kind deploy demo egress-microvm - name: Trust local TLS origins in egress gateway run: hack/setup-e2e-egress-tls-kind.sh # scale the idle sandbox class's demo pools to zero so each lane has the node diff --git a/AGENTS.md b/AGENTS.md index c393aafa88..0bfc01ea1c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -66,7 +66,7 @@ It takes the Kubernetes control-plane out of the critical path to achieve lower Agent Substrate relies on the fact that agent-like applications tend to be idle most of the time to achieve heavy multiplexing. For development, it's recommended to read the `README.md` and `CONTRIBUTING.md` in the root folder. -See `hack/install-ate.sh` and `tools/setup-gcp` for provisioning and deploying clusters and GCP resources. +See `cmd/ate-setup` and `tools/setup-gcp` for provisioning and deploying clusters and GCP resources. ## Repository Layout @@ -104,7 +104,7 @@ See `docs/dev/code-layout.md` for the full rationale and per-directory details. The dev entry points are the scripts under `hack/` and the `cmd/ate-setup` installer. ### Building and Installing -- **Install from source**: `go run ./cmd/ate-setup deploy ate-system` (or the `hack/install-ate.sh` shim) builds every image with ko as part of the install; see `cmd/ate-setup/README.md` +- **Install from source**: `go run ./cmd/ate-setup deploy ate-system` builds every image with ko as part of the install; see `cmd/ate-setup/README.md` - **Binaries**: `go build -o bin/kubectl-ate ./cmd/kubectl-ate`, `go build -o bin/ate-setup ./cmd/ate-setup` - **Release images**: `VERSION=TAG go run ./cmd/ate-setup publish release-images --ko-docker-repo REPO` (the release set, `images.ReleaseComponents`, all tagged `TAG`; see `docs/dev/releasing.md`) - **Release binaries**: `VERSION=TAG go run ./cmd/ate-setup publish release-binaries --out DIR` (`kubectl-ate` for linux and darwin, amd64 and arm64, with `.sha256` files) diff --git a/README.md b/README.md index acdcecaf84..c692069798 100644 --- a/README.md +++ b/README.md @@ -119,11 +119,11 @@ To quickly set up the complete environment: hack/create-kind-cluster.sh # install Substrate -hack/install-ate-kind.sh deploy ate-system --credential-provider='{"name":"k8s.io"}' \ +go run ./cmd/ate-setup --kind deploy ate-system --credential-provider='{"name":"k8s.io"}' \ --ingress-allowed-spiffe-ids=spiffe://cluster.local/ns/ate-system/sa/atenet-client # install counter demo -hack/install-ate-kind.sh deploy demo counter +go run ./cmd/ate-setup --kind deploy demo counter # install kubectl-ate go install ./cmd/kubectl-ate @@ -215,8 +215,8 @@ go run ./tools/setup-gcp create bucket To run the PostgreSQL store backend on Cloud SQL — with IAM database authentication and no passwords — see [tools/setup-gcp/cloud-sql.md](tools/setup-gcp/cloud-sql.md). -Similarly, you can deploy or cleanup specific Agent Substrate components using -the installation script. See `go run ./cmd/ate-setup` for all options. +Similarly, you can deploy or clean up specific Agent Substrate components with +`ate-setup`. See `go run ./cmd/ate-setup --help` for all options. ```bash # Re-deploy only ate-apiserver of the ATE system go run ./cmd/ate-setup deploy apiserver diff --git a/benchmarking/README.md b/benchmarking/README.md index 2f315fb39d..94dd80da78 100644 --- a/benchmarking/README.md +++ b/benchmarking/README.md @@ -30,7 +30,7 @@ scenario ladder, read [observability.md](observability.md). > ```bash > ATE_API_AUTHZ_BOOTSTRAP_OWNERS=system:serviceaccount:ate-system:ate-client,spiffe://cluster.local/ns/benchmarking/sa/default \ > ATE_INGRESS_ALLOWED_SPIFFE_IDS=spiffe://cluster.local/ns/benchmarking/sa/default \ -> ./hack/install-ate.sh deploy ate-system +> go run ./cmd/ate-setup deploy ate-system > ``` > The nightly automation sets both itself; see > [automation/README.md](automation/README.md). @@ -154,7 +154,7 @@ and state restoration latency when a durable directory is attached to the actor. * `glutton-storage`: Attaches an external CSI volume instead of a durable directory. `deploy_locust.sh` and `workloads/deploy.sh` deploy it only when `--storage-class-name` names an existing StorageClass. To run it on - NFS, install with `hack/install-ate.sh setup csi nfs` and pass + NFS, install with `go run ./cmd/ate-setup setup csi nfs` and pass `--storage-class-name csi-nfs-sc`, the class the e2e tests also use. #### DurDir Reported Metrics @@ -628,7 +628,7 @@ limits of ate-api-server and Postgres. Isolate mode takes the nodes out by installing substrate with a fake data plane: ```bash -hack/install-ate.sh deploy ate-system --fake-data-plane +go run ./cmd/ate-setup deploy ate-system --fake-data-plane ./benchmarking/workloads/deploy.sh --deploy --worker-count 200 \ --fake-atelet-env FAKE_ATELET_DELAY=500ms ``` @@ -674,7 +674,7 @@ Fake actors need neither. fake-atelet takes the storage settings of atelet's objectstore-plugin sidecar, whose writes it takes over, so its snapshot placeholders go to the storage the install points atelet at. The install refuses a cluster whose WorkerPools still have worker pods, which would -outlive ate-controller. A normal `hack/install-ate.sh deploy ate-system` +outlive ate-controller. A normal `ate-setup deploy ate-system` puts the real data plane back, and `delete ate-system` removes the fakes either way. Never use the mode on a cluster that serves real actors: actors placed on fake Workers do not exist. diff --git a/benchmarking/automation/README.md b/benchmarking/automation/README.md index 7f36ddf5be..50c5cd5d62 100644 --- a/benchmarking/automation/README.md +++ b/benchmarking/automation/README.md @@ -18,7 +18,7 @@ the router capacity benchmark — see 4. `docker build && docker push` builds the runner image for each test type in use, tagged with the commit hash: `${KO_DOCKER_REPO}/locust-test:` and/or `${KO_DOCKER_REPO}/nighthawk-ingress-test:`. -5. `hack/install-ate.sh deploy ate-system` (with `ATE_CREDENTIAL_PROVIDER` +5. `go run ./cmd/ate-setup deploy ate-system` (with `ATE_CREDENTIAL_PROVIDER` in `.ate-dev-env.sh`, or `--credential-provider` in the test's `ateArgs`) + `benchmarking/workloads/deploy.sh --deploy --sandbox-class ` (these build & push substrate / workload @@ -147,7 +147,7 @@ principal://iam.googleapis.com/projects//locations/global/worklo - `roles/container.admin` on the test cluster's project — required to manage cluster-scoped resources (CRDs, ClusterRoles, ClusterRoleBindings, - Namespaces) that `hack/install-ate.sh deploy ate-system` creates. + Namespaces) that `ate-setup deploy ate-system` creates. `container.developer` is not enough — it intentionally omits the `container.clusterRoles.*` and `container.customResourceDefinitions.*` permissions. diff --git a/benchmarking/automation/orchestrator.py b/benchmarking/automation/orchestrator.py index f60e90e455..c50fdc2946 100644 --- a/benchmarking/automation/orchestrator.py +++ b/benchmarking/automation/orchestrator.py @@ -126,7 +126,7 @@ def apply_target_cluster( target_cluster: str, target_cluster_dir: str = TARGET_CLUSTER_DIR ) -> None: """Copy target_cluster_dir/.sh into the cloned - substrate repo as .ate-dev-env.sh (so install-ate.sh / deploy.sh source + substrate repo as .ate-dev-env.sh (so ate-setup / deploy.sh source it) and merge it into this process's env (so the orchestrator's own gcloud / docker / kubectl calls see the same values). Resets os.environ to the startup baseline first so vars defined by a previous target @@ -390,7 +390,7 @@ def validate_and_normalize_tests(tests: list[dict[str, Any]]) -> None: def substrate_args(test: dict[str, Any]) -> list[str]: - """Return the hack/install-ate.sh deploy ate-system arguments for a + """Return the ate-setup deploy ate-system arguments for a tests.yaml entry: its ateArgs, then the fake data plane flag its isolate block asks for. The teardown needs no matching flag: delete ate-system removes the fake data plane whether or not it was installed.""" @@ -413,11 +413,11 @@ def deploy_substrate(ate_args: Iterable[str] = ()) -> None: "ATE_API_AUTHZ_BOOTSTRAP_OWNERS": f"{CLIENT_PRINCIPAL},{BENCHMARK_RUNNER_PRINCIPAL}", "ATE_INGRESS_ALLOWED_SPIFFE_IDS": BENCHMARK_RUNNER_PRINCIPAL, } - run(["hack/install-ate.sh", "deploy", "ate-system", *(str(a) for a in ate_args)], env=env) + run(["go", "run", "./cmd/ate-setup", "deploy", "ate-system", *(str(a) for a in ate_args)], env=env) def teardown_substrate() -> None: - run_no_check(["hack/install-ate.sh", "delete", "ate-system"]) + run_no_check(["go", "run", "./cmd/ate-setup", "delete", "ate-system"]) def install_microvm_deps() -> None: @@ -595,7 +595,7 @@ def main() -> None: # Per-target-cluster caches: re-running setup for the same target # cluster is wasted work, so we track what was last set up and only # redo it when the target cluster name changes (substrate images get - # rebuilt by install-ate.sh each test anyway via ko apply). Runner + # rebuilt by ate-setup each test anyway via ko). Runner # images are built lazily per test type, so a locust-only tests.yaml # never builds the nighthawk image and vice versa. last_target = None diff --git a/benchmarking/automation/test_orchestrator.py b/benchmarking/automation/test_orchestrator.py index 77833d43ba..3cf8f809b8 100644 --- a/benchmarking/automation/test_orchestrator.py +++ b/benchmarking/automation/test_orchestrator.py @@ -68,7 +68,7 @@ class DeploySubstrateTest(unittest.TestCase): def test_runner_and_client_are_bootstrap_owners(self, run): orchestrator.deploy_substrate(["--credential-provider={}"]) cmd = run.call_args.args[0] - self.assertEqual(cmd, ["hack/install-ate.sh", "deploy", "ate-system", "--credential-provider={}"]) + self.assertEqual(cmd, ["go", "run", "./cmd/ate-setup", "deploy", "ate-system", "--credential-provider={}"]) env = run.call_args.kwargs["env"] owners = env["ATE_API_AUTHZ_BOOTSTRAP_OWNERS"].split(",") self.assertEqual( @@ -92,7 +92,7 @@ def test_keeps_the_rest_of_the_environment(self, run): @mock.patch("orchestrator.run_no_check") def test_teardown_substrate(self, run_no_check): orchestrator.teardown_substrate() - run_no_check.assert_called_once_with(["hack/install-ate.sh", "delete", "ate-system"]) + run_no_check.assert_called_once_with(["go", "run", "./cmd/ate-setup", "delete", "ate-system"]) class DeployWorkloadsTest(unittest.TestCase): diff --git a/benchmarking/automation/tests.yaml b/benchmarking/automation/tests.yaml index a9d43827b7..1a5eae67ef 100644 --- a/benchmarking/automation/tests.yaml +++ b/benchmarking/automation/tests.yaml @@ -52,14 +52,14 @@ # large workerCount fleets whose image pulls or scheduling # outrun the default. # ateArgs Optional. List of strings appended verbatim to -# `hack/install-ate.sh deploy ate-system` when this +# `ate-setup deploy ate-system` when this # test's substrate is deployed (e.g. ["--atenet-dataplane=agentgateway"]). # The deploy requires --credential-provider; set it here # as one YAML string, '--credential-provider={"name":"k8s.io"}' # (no shell quoting: the args are passed without a shell), # or as ATE_CREDENTIAL_PROVIDER in .ate-dev-env.sh. # isolate Optional. Isolate mode: installs substrate with the fake -# data plane (hack/install-ate.sh deploy ate-system --fake-data-plane), which +# data plane (ate-setup deploy ate-system --fake-data-plane), which # serves the WorkerPool without worker pods: fake-atelet # takes atelet's place on every atelet node and answers each # lifecycle call after a delay, and fake-workersync honors diff --git a/benchmarking/automation/util.py b/benchmarking/automation/util.py index ad6a183906..330d21b4f5 100644 --- a/benchmarking/automation/util.py +++ b/benchmarking/automation/util.py @@ -114,7 +114,7 @@ def isolate_block(test: dict) -> dict | None: def isolate_install_args(test: dict) -> list[str]: - """Return the hack/install-ate.sh flags a tests.yaml entry's isolate block + """Return the ate-setup flags a tests.yaml entry's isolate block installs the fake data plane with, or none without a block. The installer only chooses the data plane; the block's tuning goes to deploy.sh.""" return [] if isolate_block(test) is None else ["--fake-data-plane"] diff --git a/benchmarking/nighthawk-egress/README.md b/benchmarking/nighthawk-egress/README.md index f01faaf57a..3377329c26 100644 --- a/benchmarking/nighthawk-egress/README.md +++ b/benchmarking/nighthawk-egress/README.md @@ -36,19 +36,19 @@ variable when deploying ATE. 1. **Cluster with Agent Substrate deployed**: - **Existing cluster** (with `.ate-dev-env.sh` configured): ```bash - hack/install-ate.sh deploy ate-system \ + go run ./cmd/ate-setup deploy ate-system \ --credential-provider='{"name":"k8s.io"}' \ --ingress-allowed-spiffe-ids=spiffe://cluster.local/ns/nighthawk/sa/default ``` - **Local `kind` cluster**: ```bash - hack/install-ate-kind.sh deploy ate-system \ + go run ./cmd/ate-setup --kind deploy ate-system \ --credential-provider='{"enabled":false}' \ --ingress-allowed-spiffe-ids=spiffe://cluster.local/ns/nighthawk/sa/default ``` - To set the `atenet-egress` Envoy worker thread count (`--concurrency`), set `E2E_ATE_ENVOY_CONCURRENCY` when deploying: ```bash - E2E_ATE_ENVOY_CONCURRENCY=1 hack/install-ate-kind.sh deploy ate-system --credential-provider='{"name":"k8s.io"}' --ingress-allowed-spiffe-ids=spiffe://cluster.local/ns/nighthawk/sa/default + E2E_ATE_ENVOY_CONCURRENCY=1 go run ./cmd/ate-setup --kind deploy ate-system --credential-provider='{"name":"k8s.io"}' --ingress-allowed-spiffe-ids=spiffe://cluster.local/ns/nighthawk/sa/default ``` - Provision CA bundle which includes cluster's trust bundle, so that egress gateway can trust nighhawk's test server cert, run: ```bash diff --git a/benchmarking/nighthawk-ingress/README.md b/benchmarking/nighthawk-ingress/README.md index 1dd1d9bb14..21b1c75f70 100644 --- a/benchmarking/nighthawk-ingress/README.md +++ b/benchmarking/nighthawk-ingress/README.md @@ -120,7 +120,7 @@ requests 2×`envoyCpu` CPUs; the runner requests `clientConcurrency`+1). ```bash # .ate-dev-env.sh at the repo root, then: -hack/install-ate.sh deploy ate-system \ +go run ./cmd/ate-setup deploy ate-system \ --credential-provider='{"name":"k8s.io"}' \ --ingress-allowed-spiffe-ids=spiffe://cluster.local/ns/benchmarking/sa/benchmark-runner benchmarking/workloads/deploy.sh --deploy --worker-count 50 --sandbox-class gvisor @@ -149,7 +149,7 @@ Flags: `--envoy-cpu`, `--actors`, `--tail-latency-slo-ms`, `--atespace`, Notes: - The script does not redeploy substrate — if substrate code changed, - rerun `hack/install-ate.sh deploy ate-system` first. + rerun `go run ./cmd/ate-setup deploy ate-system` first. - `--atespace` isolates actor *fleets* between experiments sharing a cluster; capacity runs themselves still need the router exclusively (the cpu pin is global and the run saturates it). diff --git a/benchmarking/nighthawk-ingress/run-dev.sh b/benchmarking/nighthawk-ingress/run-dev.sh index e20dd51e1a..7990c874ca 100755 --- a/benchmarking/nighthawk-ingress/run-dev.sh +++ b/benchmarking/nighthawk-ingress/run-dev.sh @@ -80,7 +80,7 @@ docker info >/dev/null 2>&1 || { kubectl get deployment atenet-router -n ate-system >/dev/null 2>&1 || { echo "ERROR: substrate is not deployed on ${CLUSTER_NAME}. Run:" >&2 - echo " hack/install-ate.sh deploy ate-system --credential-provider='{\"name\":\"k8s.io\"}' --ingress-allowed-spiffe-ids=spiffe://cluster.local/ns/benchmarking/sa/benchmark-runner" >&2 + echo " go run ./cmd/ate-setup deploy ate-system --credential-provider='{\"name\":\"k8s.io\"}' --ingress-allowed-spiffe-ids=spiffe://cluster.local/ns/benchmarking/sa/benchmark-runner" >&2 exit 1 } diff --git a/benchmarking/telemetry/README.md b/benchmarking/telemetry/README.md index a5d991b037..e097b3e8b0 100644 --- a/benchmarking/telemetry/README.md +++ b/benchmarking/telemetry/README.md @@ -73,7 +73,7 @@ holds the same count connector and gives the same two counts. A meter in front of it would add a hop and measure nothing new. The meter exists for GKE only, where the managed collector cannot hold a connector. -`hack/install-ate.sh` installs the collector and a Prometheus with it, thus a +`ate-setup --kind` installs the collector and a Prometheus with it, thus a kind cluster needs no other step: ```bash diff --git a/cmd/ate-setup/README.md b/cmd/ate-setup/README.md index 17e1d8c248..540dc84c5f 100644 --- a/cmd/ate-setup/README.md +++ b/cmd/ate-setup/README.md @@ -7,10 +7,6 @@ go run ./cmd/ate-setup [global flags] [flags] go build -o bin/ate-setup ./cmd/ate-setup ``` -`ate-setup` is the installer. `hack/install-ate.sh` is a shim over it, kept so -that existing command lines and CI jobs keep working; it holds no install logic -of its own. - ## Installing pre-built images By default every image is built from the checkout with `ko`, which is what a @@ -37,10 +33,7 @@ the checkout, which should be the tag being installed. Each reference is pinned to the digest its tag names, so the registry has to be readable from here as well as from the cluster. -- [`commands.md`](commands.md) — every command with its `hack/install-ate.sh` - equivalent. +- [`commands.md`](commands.md) — every command, and the common global flags. - [`differences.md`](differences.md) — where the Go port deliberately behaves differently from the shell scripts it replaced, and what was reproduced exactly. -- [`cli-diff.md`](cli-diff.md) — what a `hack/install-ate.sh` user can observe - after the switch. diff --git a/cmd/ate-setup/cli-diff.md b/cmd/ate-setup/cli-diff.md deleted file mode 100644 index 5f538cd2a9..0000000000 --- a/cmd/ate-setup/cli-diff.md +++ /dev/null @@ -1,4 +0,0 @@ -# `hack/install-ate.sh` after the move to `ate-setup` - -`hack/install-ate.sh` no longer installs anything. It merely directly invokes -`go run ./cmd/ate-setup`. New logic should not be added to it. \ No newline at end of file diff --git a/cmd/ate-setup/commands.md b/cmd/ate-setup/commands.md index b10ce64d40..28ed5d6fcf 100644 --- a/cmd/ate-setup/commands.md +++ b/cmd/ate-setup/commands.md @@ -1,48 +1,43 @@ # ate-setup commands -Every `ate-setup` command alongside the equivalent `hack/install-ate.sh` flag. - -`ate-setup` is the installer. `hack/install-ate.sh` is a shim that translates -the flags below onto these commands, so an existing invocation keeps working; -this table is how to write it directly, and -[`cli-diff.md`](cli-diff.md) covers what the translation does not cover. +Every `ate-setup` command, and the common global flags. +`go run ./cmd/ate-setup --help` lists them all. ``` go run ./cmd/ate-setup [global flags] [flags] ``` -`hack/install-ate.sh` accepts its flags in any order and runs one action per -flag, in command line order. `ate-setup` runs exactly one command per -invocation, so a shell line that passed several `--deploy-*` flags becomes -several `ate-setup` calls — which is what the shim does with it. +`ate-setup` runs exactly one command per invocation. ## Global flags -These configure every command. `hack/install-ate.sh` collects its equivalents in -a pre-scan pass, so they may appear anywhere on its command line. - -| `ate-setup` | `hack/install-ate.sh` | Notes | -|---|---|---| -| `--kind` | `hack/install-ate-kind.sh`, or `ATE_INSTALL_KIND=true` | Kind overlays, the local registry, and host-architecture image builds | -| `--atenet-dataplane envoy\|agentgateway` | `--atenet-dataplane envoy\|agentgateway` | atenet ingress and egress dataplane (default `envoy`) | -| `--rollout-timeout DURATION` | `--rollout-timeout DURATION` | Readiness timeout for workloads (default `60s`). Unlike the shell flag it also governs the podcertificate-controller and CSI waits, which stay at their 120s default until it is passed | -| `--podcert-workers-per-signer N` | `--podcert-workers-per-signer N` | Concurrent workers per podcertificate-controller signer | -| `--cluster-size size0\|size10` | `--cluster-size size0\|size10` | Footprint profile (default `size0`). `size10` assumes a dedicated PostgreSQL node: it resizes the bundled StatefulSet and its `postgresql.conf`, pins the apiserver's connection pool, and raises the podcertificate-controller's API rate limits. `ATE_INSTALL_CLUSTER_SIZE` when the flag is absent | -| `--ateapi-postgres-storage-class NAME` | `ATE_API_POSTGRES_STORAGE_CLASS=NAME` | StorageClass for the bundled PostgreSQL volume instead of the cluster default, such as `dynamic-rwo` on GKE so C4 and N4 nodes can attach it. An existing install must delete the postgres StatefulSet and its claim first | -| `--cordon-system-infra-components` | `--cordon-system-infra-components` | Keep the system infra components, such as ate-api-server, atenet-router, atenet-egress and postgres, off the worker nodes. Assumes a small shared pool labeled and tainted `ate.dev/workloadType=ate-system-infra:NoSchedule`, across which each workload's replicas are spread, and a one-node pool labeled and tainted `ate.dev/workloadType=ate-postgres:NoSchedule` for postgres alone. `ATE_INSTALL_CORDON_SYSTEM_INFRA_COMPONENTS=true` when the flag is absent | -| `--fake-data-plane` | `--fake-data-plane` | Install the fake data plane for control-plane benchmarks: fake-atelet takes atelet's place in its DaemonSet, taking its objectstore-plugin's storage settings, ate-controller is scaled to zero, and fake-workersync honors every WorkerPool with fake Workers on the fake-atelet nodes. Reaches `deploy ate-system`, `deploy atelet`, and `deploy ate-controller`; only `deploy ate-system` switches a cluster between the real and fake data planes, and the other two refuse a data plane other than the installed one. `deploy ate-system --fake-data-plane` refuses a cluster whose WorkerPools have worker pods. fake-atelet runs with its defaults; a benchmark tunes it through the optional `fake-atelet-tuning` ConfigMap, whose `FAKE_ATELET_*` variables set its flags, and which no install creates or resets. Actors do not exist; never use it on a cluster that serves real actors. `ATE_INSTALL_FAKE_DATA_PLANE=true` when the flag is absent | -| `--ingress-allowed-spiffe-ids IDS` | `--ingress-allowed-spiffe-ids IDS`, or `ATE_INGRESS_ALLOWED_SPIFFE_IDS=IDS` | Comma-separated SPIFFE IDs (exact match) of the clients the ingress router lets reach actors; any listed client may reach any actor. Unset, no client may reach actors through the router. Both dataplanes require a Pod Identity CA client certificate on HTTPS and TLS CONNECT. The SPIFFE URI SAN allowlist may be checked during or after TLS, including after CONNECT acceptance, but unlisted clients must be denied before actor routing. The podidentity signer issues `spiffe://cluster.local/ns//sa/` | -| `--experimental-additional-egress-extproc-service NS/SVC:PORT` | `--experimental-additional-egress-extproc-service NS/SVC:PORT` | External processor authorization filter | -| `--credential-provider JSON` | `--credential-provider JSON`, or `ATE_CREDENTIAL_PROVIDER` | Required by `deploy ate-system` and `deploy atenet`. A JSON object: `{"name":"k8s.io"}` deploys and uses the bundled Kubernetes Secrets provider, with a NetworkPolicy that admits only the egress gateway; `{"enabled":false}` turns egress credential injection off; `{"name":"","address":":"}` uses a provider you deploy yourself. See [`docs/egress-credential-injection.md`](../../docs/egress-credential-injection.md) | -| `--ateapi-log-level LEVEL` | `--ateapi-log-level LEVEL`, or `ATE_API_LOG_LEVEL=LEVEL` | ate-api-server log level: `debug`, `info`, `warn`, or `error`. Written to the `ate-api-config` ConfigMap on every deploy when set; unset keeps the installed level (`info` on a new install). The server picks up a change without restarting | -| `--otlp-endpoint URL` | `--otlp-endpoint URL`, or `ATE_OTLP_ENDPOINT=URL` | Send control plane telemetry to `URL` instead of the cluster default (see [`benchmarking/telemetry/README.md`](../../benchmarking/telemetry/README.md)) | -| `--preview GATES` | `--preview GATES`, or `ATE_PREVIEW=GATES` | Preview gates passed as `--preview` to every substrate component: comma-separated gate names, or `ALL` for all. `ATE_PREVIEW` or `config.preview` when the flag is absent. An explicit `--preview=''` turns them all off, even when `ATE_PREVIEW` is set | -| `--context NAME` | `KUBECTL_CONTEXT=NAME` | Kubeconfig context; still defaults to `KUBECTL_CONTEXT` | -| `--kubeconfig PATH` | `KUBECONFIG=PATH` | Explicit kubeconfig path | -| `--no-dev-env` | `NO_DEV_ENV=1` | Skip `.ate-dev-env.sh` at the repository root | -| `--version` / `-v` | — | New; the shell installer had no version | -| `--image-repo REPO` | — | New. Install pre-built images from `REPO` instead of building them with `ko` | -| `--image-tag TAG` | — | New. The tag those images carry. Each of the two requires the other | +These configure every command, and may appear before or after it, except +`--version`, which takes no command. +[`docs/operator-install.md`](../../docs/operator-install.md#settings) lists +every setting with its environment variable. + +| Flag | Notes | +|---|---| +| `--kind` | Kind overlays, the local registry, and host-architecture image builds. `ATE_INSTALL_KIND=true` when the flag is absent | +| `--atenet-dataplane envoy\|agentgateway` | atenet ingress and egress dataplane (default `envoy`) | +| `--rollout-timeout DURATION` | Readiness timeout for workloads (default `60s`). It also governs the podcertificate-controller and CSI waits, which stay at their 120s default until it is passed | +| `--podcert-workers-per-signer N` | Concurrent workers per podcertificate-controller signer | +| `--cluster-size size0\|size10` | Footprint profile (default `size0`). `size10` assumes a dedicated PostgreSQL node: it resizes the bundled StatefulSet and its `postgresql.conf`, pins the apiserver's connection pool, and raises the podcertificate-controller's API rate limits. `ATE_INSTALL_CLUSTER_SIZE` when the flag is absent | +| `--ateapi-postgres-storage-class NAME` | StorageClass for the bundled PostgreSQL volume instead of the cluster default, such as `dynamic-rwo` on GKE so C4 and N4 nodes can attach it. An existing install must delete the postgres StatefulSet and its claim first. `ATE_API_POSTGRES_STORAGE_CLASS` when the flag is absent | +| `--cordon-system-infra-components` | Keep the system infra components, such as ate-api-server, atenet-router, atenet-egress and postgres, off the worker nodes. Assumes a small shared pool labeled and tainted `ate.dev/workloadType=ate-system-infra:NoSchedule`, across which each workload's replicas are spread, and a one-node pool labeled and tainted `ate.dev/workloadType=ate-postgres:NoSchedule` for postgres alone. `ATE_INSTALL_CORDON_SYSTEM_INFRA_COMPONENTS=true` when the flag is absent | +| `--fake-data-plane` | Install the fake data plane for control-plane benchmarks: fake-atelet takes atelet's place in its DaemonSet, taking its objectstore-plugin's storage settings, ate-controller is scaled to zero, and fake-workersync honors every WorkerPool with fake Workers on the fake-atelet nodes. Reaches `deploy ate-system`, `deploy atelet`, and `deploy ate-controller`; only `deploy ate-system` switches a cluster between the real and fake data planes, and the other two refuse a data plane other than the installed one. `deploy ate-system --fake-data-plane` refuses a cluster whose WorkerPools have worker pods. fake-atelet runs with its defaults; a benchmark tunes it through the optional `fake-atelet-tuning` ConfigMap, whose `FAKE_ATELET_*` variables set its flags, and which no install creates or resets. Actors do not exist; never use it on a cluster that serves real actors. `ATE_INSTALL_FAKE_DATA_PLANE=true` when the flag is absent | +| `--ingress-allowed-spiffe-ids IDS` | Comma-separated SPIFFE IDs (exact match) of the clients the ingress router lets reach actors; any listed client may reach any actor. Unset, no client may reach actors through the router. Both dataplanes require a Pod Identity CA client certificate on HTTPS and TLS CONNECT. The SPIFFE URI SAN allowlist may be checked during or after TLS, including after CONNECT acceptance, but unlisted clients must be denied before actor routing. The podidentity signer issues `spiffe://cluster.local/ns//sa/`. `ATE_INGRESS_ALLOWED_SPIFFE_IDS` when the flag is absent | +| `--experimental-additional-egress-extproc-service NS/SVC:PORT` | External processor authorization filter | +| `--credential-provider JSON` | Required by `deploy ate-system` and `deploy atenet`. A JSON object: `{"name":"k8s.io"}` deploys and uses the bundled Kubernetes Secrets provider, with a NetworkPolicy that admits only the egress gateway; `{"enabled":false}` turns egress credential injection off; `{"name":"","address":":"}` uses a provider you deploy yourself. See [`docs/egress-credential-injection.md`](../../docs/egress-credential-injection.md). `ATE_CREDENTIAL_PROVIDER` when the flag is absent | +| `--ateapi-log-level LEVEL` | ate-api-server log level: `debug`, `info`, `warn`, or `error`. Written to the `ate-api-config` ConfigMap on every deploy when set; unset keeps the installed level (`info` on a new install). The server picks up a change without restarting. `ATE_API_LOG_LEVEL` when the flag is absent | +| `--otlp-endpoint URL` | Send control plane telemetry to `URL` instead of the cluster default (see [`benchmarking/telemetry/README.md`](../../benchmarking/telemetry/README.md)). `ATE_OTLP_ENDPOINT` when the flag is absent | +| `--preview GATES` | Preview gates passed as `--preview` to every substrate component: comma-separated gate names, or `ALL` for all. `ATE_PREVIEW` or `config.preview` when the flag is absent. An explicit `--preview=''` turns them all off, even when `ATE_PREVIEW` is set | +| `--context NAME` | Kubeconfig context. `KUBECTL_CONTEXT` when the flag is absent | +| `--kubeconfig PATH` | Explicit kubeconfig path. `KUBECONFIG` when the flag is absent | +| `--no-dev-env` | Skip `.ate-dev-env.sh` at the repository root. `NO_DEV_ENV=1` when the flag is absent | +| `--version` / `-v` | Print the version | +| `--image-repo REPO` | Install pre-built images from `REPO` instead of building them with `ko` | +| `--image-tag TAG` | The tag those images carry. Each of the two requires the other | Both have an environment equivalent, read when the flag is absent: `ATE_IMAGE_REPO` and `ATE_IMAGE_TAG`. @@ -56,9 +51,7 @@ replaces an existing cluster with the same name. Deploy the control plane before deploying demos or benchmarks. These commands check for `deployment/ate-controller` in the configured system namespace before creating workload resources. An existing Deployment passes this check; normal -rollout waits still diagnose workloads that cannot become ready. The shell shim -runs actions in argument order, so put `--deploy-ate-system` before demo or -benchmark deployment flags when combining them on one command line. +rollout waits still diagnose workloads that cannot become ready. ## Installing pre-built images @@ -105,17 +98,15 @@ that already names a manifest is used as written, and is not looked up. ## Deploy -| `ate-setup` | `hack/install-ate.sh` | -|---|---| -| `deploy ate-system` | `--deploy-ate-system` | -| `deploy ate-system --setup-csi=nfs` | `--deploy-ate-system --setup-csi=nfs` | -| `deploy atelet` | `--deploy-atelet` | -| `deploy apiserver` | `--deploy-ate-apiserver` | -| `deploy ate-controller` | (no shell equivalent) | -| `deploy atenet` | `--deploy-atenet` | -| `deploy podcertificate-controller` | (no shell equivalent) | -| `deploy sandboxconfig` | (no shell equivalent) | -| `deploy postgres` | (no shell equivalent) | +- `deploy ate-system` +- `deploy ate-system --setup-csi=nfs` +- `deploy atelet` +- `deploy apiserver` +- `deploy ate-controller` +- `deploy atenet` +- `deploy podcertificate-controller` +- `deploy sandboxconfig` +- `deploy postgres` `deploy ate-system` is the whole control plane: CRDs, RBAC, the store, the apiserver, the controller, atenet, and atelet. It creates every `create` @@ -124,11 +115,9 @@ a running cluster. ## Publish -| `ate-setup` | `hack/install-ate.sh` | -|---|---| -| `publish worker-images` | (no shell equivalent) | -| `publish release-images` | (no shell equivalent) | -| `publish release-binaries` | (no shell equivalent) | +- `publish worker-images` +- `publish release-images` +- `publish release-binaries` `publish worker-images` builds and pushes the worker images for the checked-out build and prints their refs; a WorkerPool points `spec.workerImage` @@ -146,11 +135,9 @@ attaches the files to the draft release. ## Delete -| `ate-setup` | `hack/install-ate.sh` | -|---|---| -| `delete ate-system` | `--delete-ate-system` | -| `delete atenet` | `--delete-atenet` | -| `delete all` | `--delete-all` | +- `delete ate-system` +- `delete atenet` +- `delete all` `delete all` removes every registered demo and then the control plane. @@ -158,73 +145,60 @@ attaches the files to the draft release. Individual secrets and config that `deploy ate-system` creates automatically. -| `ate-setup` | `hack/install-ate.sh` | -|---|---| -| `create jwt-authority-pool` | `--create-jwt-authority-pool-secret` | -| `create actor-id-ca-pool` | `--create-actor-id-ca-pool-secret` | -| `create actor-id-ca-certs` | `--create-actor-id-ca-certs-secret` | -| `create egress-mitm-ca-pool` | `--create-egress-mitm-ca-pool-secret` | -| `create podcertificate-controller-cas` | `--create-podcertificate-controller-cas` | -| `create api-server-env-vars` | `--create-api-server-env-vars` | -| `create api-authentication-config` | `--create-api-authentication-config` | -| `create api-config` | `--create-api-config` | +- `create jwt-authority-pool` +- `create actor-id-ca-pool` +- `create actor-id-ca-certs` +- `create egress-mitm-ca-pool` +- `create podcertificate-controller-cas` +- `create api-server-env-vars` +- `create api-authentication-config` +- `create api-config` ## Setup -| `ate-setup` | `hack/install-ate.sh` | -|---|---| -| `setup csi [driver]` | `--setup-csi[=DRIVER]` | +- `setup csi [driver]` -`driver` is one of `nfs`, `hostpath`, `both`, or `none`; `setup csi` with `none` as the default option. The hostpath is for KIND clusters only. NFS has no such +`driver` is one of `nfs`, `hostpath`, `both`, or `none`, and defaults to `nfs`. The hostpath is for KIND clusters only. NFS has no such restriction, but it does need the `nfsd` kernel module loaded on the nodes. ## Benchmarks -| `ate-setup` | `hack/install-ate.sh` | -|---|---| -| `deploy benchmarks` | `--deploy-benchmarks` | -| `delete benchmarks` | `--delete-benchmarks` | -| `--worker-count N` | `--benchmark-worker-count N` (default `1`) | -| `--sandbox-class gvisor\|microvm` | `--benchmark-sandbox-class CLASS` (default `gvisor`) | -| `BENCHMARK_ACTOR_MEMORY=SIZE` | `--benchmark-actor-memory SIZE` (default `256Mi`) | - -The memory limit has no flag: `benchmarking/workloads/deploy.sh` has always -taken it from the environment, and the shim exports it. - -The other two flags are per-command in `ate-setup` and global in -`hack/install-ate.sh`, which forwards them to whichever benchmark action runs. -See +- `deploy benchmarks` +- `delete benchmarks` +- `--worker-count N` (default `1`) +- `--sandbox-class gvisor|microvm` (default `gvisor`) +- `--benchmark-actor-memory SIZE` (default `256Mi`) + +`--benchmark-actor-memory` is a global flag (`BENCHMARK_ACTOR_MEMORY` when it +is absent); the other two are flags of the benchmark commands. See [`benchmarking/README.md`](../../benchmarking/README.md). ## Demos -| `ate-setup` | `hack/install-ate.sh` | +- `deploy demo NAME` +- `delete demo NAME` + +`NAME` is one of: + +| Command | Description | |---|---| -| `deploy demo NAME` | `--deploy-demo-NAME` | -| `delete demo NAME` | `--delete-demo-NAME` | - -`NAME` is the demo without its `demo-` prefix: - -| `ate-setup` | `hack/install-ate.sh` | Description | -|---|---|---| -| `deploy demo counter` | `--deploy-demo-counter` | A counter actor exercising snapshot, resume, and atenet ingress | -| `deploy demo counter --with-external-volume [--storage-class NAME]` | `--deploy-demo-counter-with-external-volume` (`STORAGE_CLASS=NAME`) | The same, plus an external volume and a pre-seeded file to validate (requires `--preview=ExternalVolumes`). Run `setup csi` first and name the class it created, e.g. `csi-nfs-sc`; defaults to `standard` | -| `deploy demo counter-microvm` | `--deploy-demo-counter-microvm` | The counter demo on microVM workers. Run `hack/install-microvm-deps.sh --install` first | -| `deploy demo egress` | `--deploy-demo-egress` | Egress policy enforcement through atenet; the actors trust the egress gateway's CA | -| `deploy demo egress-microvm` | `--deploy-demo-egress-microvm` | The same on microVM workers. Run `hack/install-microvm-deps.sh --install` first | -| `deploy demo jupyter` | `--deploy-demo-jupyter` | A Jupyter notebook server per actor, reached through atenet ingress | -| `deploy demo sandbox` | `--deploy-demo-sandbox` | An on-demand sandbox actor driven by the sandbox client | -| `deploy demo multi-template` | `--deploy-demo-multi-template` | Two ActorTemplates sharing one WorkerPool | -| `deploy demo parking` | `--deploy-demo-parking` | Actor parking and unparking on a small WorkerPool | -| `deploy demo claude-code-multiplex` | `--deploy-demo-claude-code-multiplex` | Several Claude Code agents multiplexed onto one WorkerPool (requires `ANTHROPIC_API_KEY`, `BUCKET_NAME`, `KO_DOCKER_REPO`) | - -Each has a matching `delete demo NAME` / `--delete-demo-NAME`. Demo flags bind +| `deploy demo counter` | A counter actor exercising snapshot, resume, and atenet ingress | +| `deploy demo counter --with-external-volume [--storage-class NAME]` | The same, plus an external volume and a pre-seeded file to validate (requires `--preview=ExternalVolumes`). Run `setup csi` first and name the class it created, e.g. `csi-nfs-sc`; defaults to `standard` | +| `deploy demo counter-microvm` | The counter demo on microVM workers. Run `hack/install-microvm-deps.sh --install` first | +| `deploy demo egress` | Egress policy enforcement through atenet; the actors trust the egress gateway's CA | +| `deploy demo egress-microvm` | The same on microVM workers. Run `hack/install-microvm-deps.sh --install` first | +| `deploy demo jupyter` | A Jupyter notebook server per actor, reached through atenet ingress | +| `deploy demo sandbox` | An on-demand sandbox actor driven by the sandbox client | +| `deploy demo multi-template` | Two ActorTemplates sharing one WorkerPool | +| `deploy demo parking` | Actor parking and unparking on a small WorkerPool | +| `deploy demo claude-code-multiplex` | Several Claude Code agents multiplexed onto one WorkerPool (requires `ANTHROPIC_API_KEY`, `BUCKET_NAME`, `KO_DOCKER_REPO`) | + +Each has a matching `delete demo NAME`. Demo flags bind to the deploy side only; teardown never reads them. The demo list is not hard-coded here — it is built from the registry in [`internal/demos`](internal/demos), one package per demo, so `go run ./cmd/ate-setup deploy demo --help` is authoritative for both the list and the per-demo flags. A new demo is a new package there, added to -[`internal/demos/all`](internal/demos/all) and mirrored into the `ATE_DEMOS` -list in `hack/install-ate.sh`, which a test keeps in step with the registry. +[`internal/demos/all`](internal/demos/all). diff --git a/cmd/ate-setup/differences.md b/cmd/ate-setup/differences.md index 12209ac94b..d97a6bbdb7 100644 --- a/cmd/ate-setup/differences.md +++ b/cmd/ate-setup/differences.md @@ -3,17 +3,13 @@ `ate-setup` is a Go port of `hack/install-ate.sh`, the seven `hack/install-demo-*.sh` scripts it sourced, and `hack/setup-csi-*-kind.sh`. -The port has replaced them. The demo scripts are deleted, and -`hack/install-ate.sh` is a shim holding no install logic of its own: it -translates the flags and environment variables the installer has always -accepted onto `ate-setup` commands, so existing command lines keep working. See -[`commands.md`](commands.md) for the flag-by-flag mapping. - -This document covers what changed *behind* that mapping: the design decisions -of the port, against the shell it replaced. For what a user of -`hack/install-ate.sh` can observe after the switch, see -[`cli-diff.md`](cli-diff.md). For anything listed in neither, the port is -intended to be behavior-preserving. +The port has replaced them. `hack/install-ate.sh`, the demo scripts, and +`hack/setup-csi-hostpath-kind.sh` are deleted. See +[`commands.md`](commands.md) for the commands. + +This document covers the design decisions of the port, against the shell it +replaced. For anything not listed here, the port is intended to be +behavior-preserving. ## What is deliberately unchanged @@ -21,8 +17,7 @@ These were treated as contracts and reproduced exactly: - **Step log lines.** `log.Step` prints the same cyan `[step]: name` and the same step names (`deploy_ate_system`, `create_api_server_env_vars`, - `demo-counter_deploy`), so CI log scrapers keep working. Two lines lost a - parenthesized qualifier; see [`cli-diff.md`](cli-diff.md). + `demo-counter_deploy`), so CI log scrapers keep working. - **Manifest ordering.** Applying a directory is non-recursive and lexical, as `kubectl apply -f ` was. `delete_ate_system` depends on that ordering and the shell comments called out specific filename hazards, so @@ -58,8 +53,7 @@ These were treated as contracts and reproduced exactly: | Repository root | `git rev-parse --show-toplevel`, then `cd` | walk up for `go.mod`; no `chdir`, all paths absolute | The one-action-per-run change is the most visible: a line that passed -`--deploy-ate-system --deploy-demo-counter` becomes two `ate-setup` calls. That -is what the shim does with it, so the combined form keeps working. +`--deploy-ate-system --deploy-demo-counter` becomes two `ate-setup` calls. Invalid input now fails before any cluster mutation. `--atenet-dataplane=nginx` used to be caught by a pre-scan validation pass; `--worker-count 0` was not @@ -186,7 +180,7 @@ teardown after the CRDs are gone must not fail. Beyond that, deletes are strict. **Cluster profiles are new.** `--cluster-size` and `--cordon-system-infra-components` -postdate the shell installer, which the shim forwards them to. `size10` +postdate the shell installer. `size10` renders the `podcert-size10` overlay and resizes the bundled PostgreSQL from `postgres-size10/postgres-config-patch.yaml`; `--cordon-system-infra-components` composes the diff --git a/cmd/ate-setup/internal/cmd/csi_test.go b/cmd/ate-setup/internal/cmd/csi_test.go index 393a4dfc5d..106d67ece8 100644 --- a/cmd/ate-setup/internal/cmd/csi_test.go +++ b/cmd/ate-setup/internal/cmd/csi_test.go @@ -81,7 +81,7 @@ func TestAnUnknownCSIDriverIsRejectedBeforeAnythingRuns(t *testing.T) { // The accepted spellings have to make it past the same check, including the // bare `setup csi` that takes the default. func TestAcceptedCSIDriversPassArgumentValidation(t *testing.T) { - accepted := []string{"nfs", "hostpath", "both", "none", "true", "false", ""} + accepted := []string{"nfs", "hostpath", "both", "none"} t.Run("setup csi", func(t *testing.T) { for _, driver := range accepted { diff --git a/cmd/ate-setup/internal/cmd/root.go b/cmd/ate-setup/internal/cmd/root.go index 4fa51941ed..a33a97cf7b 100644 --- a/cmd/ate-setup/internal/cmd/root.go +++ b/cmd/ate-setup/internal/cmd/root.go @@ -216,10 +216,7 @@ func recordRun(cmd *cobra.Command, runErr error) { } } -// Root is the command tree, for callers that need to inspect it rather than -// run it. hack/install-ate.sh translates the historical installer flags into -// ate-setup command lines, and its test resolves each one against this to check -// it still names a command that exists. +// Root is the command tree, for tests that run it in-process. func Root() *cobra.Command { return rootCmd } // Execute runs the command tree. @@ -234,6 +231,11 @@ func Execute() { // ExecuteC reports which command ran, which the failure record needs and // Execute does not return. executed, err := rootCmd.ExecuteC() + // Cobra rejects an unknown command only at the root. Below it, a command + // that only groups others prints its help for any argument and succeeds. + if err == nil && !executed.Runnable() && executed.Flags().NArg() > 0 { + err = fmt.Errorf("unknown command %q for %q", executed.Flags().Arg(0), executed.CommandPath()) + } if err != nil { fmt.Fprintln(os.Stderr, "Error:", err) // After the error, so the retry line is the last thing on screen: diff --git a/cmd/ate-setup/internal/config/config.go b/cmd/ate-setup/internal/config/config.go index 7a80966d89..bf300d7469 100644 --- a/cmd/ate-setup/internal/config/config.go +++ b/cmd/ate-setup/internal/config/config.go @@ -429,10 +429,9 @@ func (c *Config) Path(parts ...string) string { return filepath.Join(append([]string{c.Root}, parts...)...) } -// kindUnsetVars are the GKE-specific variables the shell kind installer unset -// before delegating, so that a developer who had already sourced -// .ate-dev-env.sh into their shell did not end up pointing a local install at a -// cloud project. +// kindUnsetVars are the GKE-specific variables a Kind install drops, so that a +// developer who has already sourced .ate-dev-env.sh into their shell does not +// point a local install at a cloud project. var kindUnsetVars = []string{ "GCE_REGION", "CLUSTER_LOCATION", "NETWORK", "SUBNETWORK", "MEMORYSTORE_INSTANCE", "PROJECT_ID", diff --git a/cmd/ate-setup/internal/config/config_test.go b/cmd/ate-setup/internal/config/config_test.go index b50366e1d9..074fa5f99e 100644 --- a/cmd/ate-setup/internal/config/config_test.go +++ b/cmd/ate-setup/internal/config/config_test.go @@ -859,9 +859,8 @@ func TestLoadOtlpEndpoint(t *testing.T) { } } -// hack/install-ate-kind.sh exports ATE_INSTALL_KIND rather than passing a flag, -// so the environment has to select the Kind profile as completely as --kind -// does; a Kind install that only half-applied would push images to the wrong +// ATE_INSTALL_KIND has to select the Kind profile as completely as --kind does; +// a Kind install that only half-applied would push images to the wrong // registry. func TestLoadKindFromEnvironment(t *testing.T) { loadEnv(t) @@ -1178,8 +1177,8 @@ func TestLoadEnvoyConcurrency(t *testing.T) { } } -// --kind must reproduce the exports in the shell kind installer, including -// clearing the GKE coordinates and isolating the snapshot bucket name. +// --kind must apply the whole Kind profile, including clearing the GKE +// coordinates and isolating the snapshot bucket name. func TestLoadKindProfile(t *testing.T) { loadEnv(t) t.Setenv("PROJECT_ID", "some-gke-project") diff --git a/cmd/ate-setup/internal/config/file.go b/cmd/ate-setup/internal/config/file.go index 542628e7a0..683f94a8a5 100644 --- a/cmd/ate-setup/internal/config/file.go +++ b/cmd/ate-setup/internal/config/file.go @@ -61,8 +61,7 @@ func ParseFile(path string) (*File, error) { raw, err := os.ReadFile(path) if err != nil { // Name the absolute path: a relative one means different files from - // different working directories, and the shell installer changes to - // the repository root before running. + // different working directories. abs, absErr := filepath.Abs(path) if absErr != nil { abs = path diff --git a/cmd/ate-setup/internal/config/load.go b/cmd/ate-setup/internal/config/load.go index fa16bd5176..c553243a67 100644 --- a/cmd/ate-setup/internal/config/load.go +++ b/cmd/ate-setup/internal/config/load.go @@ -31,10 +31,6 @@ import ( ) // ConfigPathEnv names the configuration document when --config is not given. -// -// It exists so the file channel crosses hack/install-ate.sh, which forwards -// only a fixed set of flags but passes the whole environment to the child -// process. Every other setting reaches ate-setup that way already. const ConfigPathEnv = "ATE_CONFIG" // LoadOptions carries the inputs that select where configuration comes from, @@ -85,11 +81,9 @@ func LoadFlags(fs *pflag.FlagSet, o LoadOptions) (*Config, error) { // configPathFrom picks the configuration document, flag over environment. // -// A relative path resolves against the working directory, which is the -// repository root when the shell installer invoked this: it does cd "$ROOT" -// before running the binary. ParseFile reports the absolute path it tried, so -// a path that meant something else from the caller's directory is visible in -// the error rather than silently missing. +// A relative path resolves against the working directory. ParseFile reports +// the absolute path it tried, so a path that meant something else from the +// caller's directory is visible in the error rather than silently missing. func configPathFrom(o LoadOptions) string { if o.ConfigPath != "" { return o.ConfigPath @@ -143,9 +137,8 @@ func resolveKind(fs *pflag.FlagSet, file *File, env map[string]string) bool { // mergeDevEnv layers .ate-dev-env.sh underneath the process environment. // -// Sourcing is skipped for Kind installs the same way the shell kind installer -// exports NO_DEV_ENV: the GKE-shaped variables in a developer's file would -// otherwise point a local install at a cloud project. +// Sourcing is skipped for Kind installs: the GKE-shaped variables in a +// developer's file would otherwise point a local install at a cloud project. func mergeDevEnv(root string, env map[string]string, noDevEnv, kind bool) error { if noDevEnv || kind || os.Getenv("NO_DEV_ENV") != "" { return nil diff --git a/cmd/ate-setup/internal/config/load_test.go b/cmd/ate-setup/internal/config/load_test.go index b48f8b3ebe..0ac2c83c29 100644 --- a/cmd/ate-setup/internal/config/load_test.go +++ b/cmd/ate-setup/internal/config/load_test.go @@ -128,9 +128,8 @@ func TestLoadFlagsRejectsBadConfigPath(t *testing.T) { } } -// The file channel must cross hack/install-ate.sh, which forwards only a fixed -// set of flags but passes the whole environment through. ATE_CONFIG is how it -// gets there without a shim change. +// ATE_CONFIG names the document when --config is absent, and the flag +// outranks it. func TestConfigPathFromEnvironment(t *testing.T) { loadEnv(t) path := filepath.Join(t.TempDir(), "install.yaml") @@ -191,9 +190,8 @@ func TestConfigPathFromEnvironment(t *testing.T) { }) } -// A relative path means different files from different working directories, -// and the shell installer changes to the repository root. The error names the -// absolute path so that is visible rather than silent. +// A relative path means different files from different working directories. +// The error names the absolute path so that is visible rather than silent. func TestMissingConfigErrorNamesAbsolutePath(t *testing.T) { loadEnv(t) t.Setenv(ConfigPathEnv, "no-such-config.yaml") diff --git a/cmd/ate-setup/internal/steps/apienv.go b/cmd/ate-setup/internal/steps/apienv.go index 481f72de1e..1fc1e4e3d0 100644 --- a/cmd/ate-setup/internal/steps/apienv.go +++ b/cmd/ate-setup/internal/steps/apienv.go @@ -312,7 +312,7 @@ func (e *Env) EnsureEnvVarsSafeStandalone(ctx context.Context) error { } return fmt.Errorf("the running ate-api-server Deployment does not reference the %s Secret; "+ "rewriting the env vars alone would leave it without a DSN on its next restart. "+ - "Run `ate-setup deploy ate-apiserver` instead, which also updates the Deployment", SecretAPIEnvVars) + "Run `ate-setup deploy apiserver` instead, which also updates the Deployment", SecretAPIEnvVars) } // annotateAPIServerEnvHash stamps the running Deployment's pod template with diff --git a/cmd/ate-setup/internal/steps/csi.go b/cmd/ate-setup/internal/steps/csi.go index f42183257b..f93b8bc779 100644 --- a/cmd/ate-setup/internal/steps/csi.go +++ b/cmd/ate-setup/internal/steps/csi.go @@ -69,17 +69,12 @@ type csiDriverSpec struct { // installsNothing reports whether the value selects no driver at all. func (s csiDriverSpec) installsNothing() bool { return !s.hostpath && !s.nfs } -// csiDrivers is every accepted --setup-csi value. "true", "false" and the empty -// string are the shell installer's boolean spellings, from before the flag grew -// driver names, and still work. +// csiDrivers is every accepted --setup-csi value. var csiDrivers = map[string]csiDriverSpec{ "nfs": {nfs: true}, "hostpath": {hostpath: true}, "both": {hostpath: true, nfs: true}, - "true": {hostpath: true, nfs: true}, "none": {}, - "false": {}, - "": {}, } // ValidateCSIDriver reports whether driver names something --setup-csi accepts. diff --git a/cmd/ate-setup/internal/steps/csi_test.go b/cmd/ate-setup/internal/steps/csi_test.go index 695593f140..21b56e4c9b 100644 --- a/cmd/ate-setup/internal/steps/csi_test.go +++ b/cmd/ate-setup/internal/steps/csi_test.go @@ -59,12 +59,10 @@ func TestSetupCSIDecidesBeforeTouchingTheCluster(t *testing.T) { error string }{ {name: "none", driver: "none"}, - {name: "the shell installer's false", driver: "false"}, - {name: "unset", driver: ""}, {name: "hostpath off Kind", driver: "hostpath", error: "only supported for Kind"}, {name: "both off Kind", driver: "both", error: "only supported for Kind"}, - {name: "the shell installer's true off Kind", driver: "true", error: "only supported for Kind"}, {name: "unknown driver", driver: "nfsv4", error: `unknown CSI driver "nfsv4"`}, + {name: "the shell installer's true", driver: "true", error: `unknown CSI driver "true"`}, } { t.Run(tc.name, func(t *testing.T) { e := &Env{Cfg: &config.Config{Kind: tc.kind}} @@ -170,9 +168,7 @@ func TestTheNFSSetupsApplyTheSharedStorageClass(t *testing.T) { } } -// Both spellings of each driver selection have to keep selecting the same -// thing: --setup-csi was a boolean in the shell installer, and the scripts and -// dev-env files that still pass true or false have to keep working. +// Each --setup-csi value selects the drivers its name says. func TestCSIDriverSpellings(t *testing.T) { for _, tc := range []struct { driver string @@ -181,10 +177,7 @@ func TestCSIDriverSpellings(t *testing.T) { {"nfs", csiDriverSpec{nfs: true}}, {"hostpath", csiDriverSpec{hostpath: true}}, {"both", csiDriverSpec{hostpath: true, nfs: true}}, - {"true", csiDriverSpec{hostpath: true, nfs: true}}, {"none", csiDriverSpec{}}, - {"false", csiDriverSpec{}}, - {"", csiDriverSpec{}}, } { t.Run(tc.driver, func(t *testing.T) { got, ok := csiDrivers[tc.driver] diff --git a/cmd/ate-setup/main.go b/cmd/ate-setup/main.go index d115f75c5c..2f8c227b3d 100644 --- a/cmd/ate-setup/main.go +++ b/cmd/ate-setup/main.go @@ -13,10 +13,7 @@ // limitations under the License. // Command ate-setup installs and tears down Agent Substrate on a Kubernetes -// cluster. It is the installer; hack/install-ate.sh is a shim that translates -// its historical flags onto these commands. See cmd/ate-setup/commands.md for -// the flag-by-flag mapping and cmd/ate-setup/cli-diff.md for what the -// translation does not cover. +// cluster. See cmd/ate-setup/commands.md for its commands. package main import ( diff --git a/cmd/ate-setup/preflight_test.go b/cmd/ate-setup/preflight_test.go index 729907dc9e..8ac37e7f4e 100644 --- a/cmd/ate-setup/preflight_test.go +++ b/cmd/ate-setup/preflight_test.go @@ -40,9 +40,8 @@ func repoRoot(t *testing.T) string { return strings.TrimSpace(string(out)) } -// Each invocation gets its own command tree and flags, including invocations -// made by the real shell shims. The test executable runs the installer without -// rebuilding it or contacting a real cluster. +// Each invocation gets its own command tree and flags. The test executable runs +// the installer without rebuilding it or contacting a real cluster. func TestInstallerPreflightProcess(t *testing.T) { if os.Getenv("ATE_SETUP_PREFLIGHT_TEST") != "1" { return @@ -66,17 +65,6 @@ func runPreflightInstaller(t *testing.T, kubeconfig, dockerStatus string, args . } for name, source := range map[string]string{ "docker": "#!/bin/sh\necho called >> \"$PREFLIGHT_DOCKER_LOG\"\nexit \"$PREFLIGHT_DOCKER_STATUS\"\n", - "go": `#!/bin/sh -if [ "$*" = "env GOARCH" ]; then - echo amd64 -elif [ "$1" = run ] && [ "$2" = ./cmd/ate-setup ]; then - shift 2 - exec "$PREFLIGHT_EXECUTABLE" -test.run='^TestInstallerPreflightProcess$' -- "$@" -else - echo "unexpected go invocation: $*" >&2 - exit 1 -fi -`, } { if err := os.WriteFile(filepath.Join(bin, name), []byte(source), 0o755); err != nil { t.Fatal(err) @@ -93,7 +81,6 @@ fi "NO_DEV_ENV=true", "ATE_NO_REPORT_DEFAULTS=1", "ATE_SETUP_PREFLIGHT_TEST=1", - "PREFLIGHT_EXECUTABLE=" + executable, "PREFLIGHT_DOCKER_STATUS=" + dockerStatus, "PREFLIGHT_DOCKER_LOG=" + filepath.Join(bin, "docker.log"), } @@ -197,6 +184,21 @@ func TestKindInstallerHelpNeedsNoCluster(t *testing.T) { } } +// Cobra rejects an unknown command only at the root, so a typo one level down +// used to print help and exit 0 having installed nothing. +func TestInstallerRejectsUnknownSubcommand(t *testing.T) { + for _, args := range [][]string{ + {"deploy", "demo-counter"}, + {"deploy", "demo", "demo-counter"}, + } { + out, code := runPreflightInstaller(t, preflightKubeconfig(t, ""), "0", args...) + want := `unknown command "demo-counter"` + if code == 0 || !strings.Contains(out, want) { + t.Errorf("%v: exit=%d, want an error containing %q\n%s", args, code, want, out) + } + } +} + func TestInstallerControlPlaneCheckPreservesErrorsAndAllowsInstalledSystem(t *testing.T) { for _, installed := range []bool{false, true} { t.Run(fmt.Sprintf("installed=%t", installed), func(t *testing.T) { diff --git a/cmd/kubectl-ate/README.md b/cmd/kubectl-ate/README.md index 340d696e26..2c86821b69 100644 --- a/cmd/kubectl-ate/README.md +++ b/cmd/kubectl-ate/README.md @@ -49,7 +49,7 @@ gcloud beta container clusters update CLUSTER_NAME \ **Local (kind):** -The kind overlay installed by `hack/install-ate-kind.sh --deploy-ate-system` already provisions an in-cluster OpenTelemetry Collector and Jaeger in the `otel-system` namespace. No additional setup is required. +The kind overlay installed by `ate-setup --kind deploy ate-system` already provisions an in-cluster OpenTelemetry Collector and Jaeger in the `otel-system` namespace. No additional setup is required. Port-forward the Jaeger UI and invoke any command with `--trace`: ```bash diff --git a/cmd/kubectl-ate/internal/cmd/actortemplate_test.go b/cmd/kubectl-ate/internal/cmd/actortemplate_test.go index 5ce5d737fa..6ca43a6d9f 100644 --- a/cmd/kubectl-ate/internal/cmd/actortemplate_test.go +++ b/cmd/kubectl-ate/internal/cmd/actortemplate_test.go @@ -158,7 +158,7 @@ func TestActorTemplateFromManifest_DemoManifests(t *testing.T) { if err != nil { t.Fatalf("reading demo manifest: %v", err) } - // The install scripts substitute the bucket and drop the unused + // ate-setup substitutes the bucket and drops the unused // optional placeholder lines before applying. rendered := strings.ReplaceAll(string(data), "${BUCKET_NAME}", "ate-snapshots") var kept []string diff --git a/demos/claude-code-multiplex/README.md b/demos/claude-code-multiplex/README.md index 1e2c4c930d..2669a379ca 100644 --- a/demos/claude-code-multiplex/README.md +++ b/demos/claude-code-multiplex/README.md @@ -44,7 +44,7 @@ This guide assumes you know Kubernetes and the general shape of agent runtimes ( |---|---| | `demos/claude-code-multiplex/claude-code-multiplex.yaml.tmpl` | Namespace and WorkerPool manifest | | `demos/claude-code-multiplex/agent-*-template.yaml.tmpl` | One protojson ActorTemplate per agent, created through the ate API with `kubectl ate create actor-template` | -| `cmd/ate-setup/internal/demos/claudemultiplex/` | The installer's demo package, behind `--deploy-demo-claude-code-multiplex` / `--delete-demo-claude-code-multiplex` | +| `cmd/ate-setup/internal/demos/claudemultiplex/` | The installer's demo package, behind `deploy demo claude-code-multiplex` / `delete demo claude-code-multiplex` | | `demos/claude-code-multiplex/workload/` | The agent container image source (Dockerfile + entrypoint that wires Claude Code; built and pushed by the deploy step) | | `demos/claude-code-multiplex/ui/` | Static dashboard (`index.html` + `server.go`) that talks to the cluster | diff --git a/demos/counter/README.md b/demos/counter/README.md index 4886c7d222..712a0b0f1f 100644 --- a/demos/counter/README.md +++ b/demos/counter/README.md @@ -19,7 +19,7 @@ The demo uses two kinds of resources: the `WorkerPool` is a Kubernetes CRD, whil > [!NOTE] > Do not manually edit `demos/counter/counter.yaml.tmpl` or -> `demos/counter/counter-template.yaml.tmpl`. The installation script +> `demos/counter/counter-template.yaml.tmpl`. `ate-setup` > automatically injects your `${BUCKET_NAME}` environment variable during > deployment. @@ -59,17 +59,17 @@ go run ./cmd/ate-setup deploy demo counter-microvm
Installation on GVisor -Use the core installation script to build the image and deploy the demo to your cluster: +Use `ate-setup` to build the image and deploy the demo to your cluster: ```bash -./hack/install-ate.sh --deploy-demo-counter +go run ./cmd/ate-setup deploy demo counter ``` To enable validation of reading from an external volume (e.g. `/external-data/test.txt`), run: ```bash -./hack/install-ate.sh --deploy-demo-counter-with-external-volume --preview=ExternalVolumes +go run ./cmd/ate-setup deploy demo counter --with-external-volume --preview=ExternalVolumes ``` This command will: diff --git a/demos/counter/counter-template.yaml.tmpl b/demos/counter/counter-template.yaml.tmpl index 9f53b504c5..b92c17ee2a 100644 --- a/demos/counter/counter-template.yaml.tmpl +++ b/demos/counter/counter-template.yaml.tmpl @@ -18,7 +18,7 @@ # atespace must exist. # # The ${...}_ARG/MOUNTS/VOLUMES placeholder lines are dropped on a plain -# deploy and filled in by --deploy-demo-counter-with-external-volume. +# deploy and filled in by `deploy demo counter --with-external-volume`. metadata: atespace: ate-demo-counter name: counter diff --git a/demos/egress/README.md b/demos/egress/README.md index 923c0c2647..381dc05def 100644 --- a/demos/egress/README.md +++ b/demos/egress/README.md @@ -58,11 +58,11 @@ ActorTemplate, worker pool, test, and manual walkthrough are otherwise the same. ```bash # Envoy (default) -./hack/install-ate-kind.sh --deploy-ate-system --credential-provider='{"name":"k8s.io"}' \ +go run ./cmd/ate-setup --kind deploy ate-system --credential-provider='{"name":"k8s.io"}' \ --ingress-allowed-spiffe-ids=spiffe://cluster.local/ns/ate-system/sa/atenet-client # agentgateway -./hack/install-ate-kind.sh --deploy-ate-system --atenet-dataplane=agentgateway --credential-provider='{"name":"k8s.io"}' \ +go run ./cmd/ate-setup --kind deploy ate-system --atenet-dataplane=agentgateway --credential-provider='{"name":"k8s.io"}' \ --ingress-allowed-spiffe-ids=spiffe://cluster.local/ns/ate-system/sa/atenet-client ``` @@ -94,7 +94,7 @@ rejects that option with agentgateway rather than silently omitting it. (step 3 below) and `kubectl ate get egress-policy` reads it back; the e2e suites create theirs with `e2e.EnsureEgressPolicy`. An `all` rule reproduces the pre-policy behavior. - **Actor-identity trust** — the gateway mounts the `actor-id-ca-certs` Secret, a cert-only copy of - the actor-identity CA root that `hack/install-ate.sh` derives from `actor-id-ca-pool` (which also + the actor-identity CA root that `ate-setup` derives from `actor-id-ca-pool` (which also holds the CA signing key and is deliberately *not* mounted here). ## Prerequisites @@ -107,7 +107,7 @@ rejects that option with agentgateway rather than silently omitting it. ## Deploy the demo fixture ```bash -go run ./cmd/ate-setup deploy demo egress +go run ./cmd/ate-setup --kind deploy demo egress ``` The install applies the worker pool, creates the `ate-demo-egress` atespace and diff --git a/demos/egress/test-egress.sh b/demos/egress/test-egress.sh index 83a4cc3ae4..061289684e 100755 --- a/demos/egress/test-egress.sh +++ b/demos/egress/test-egress.sh @@ -23,7 +23,7 @@ # certificate, cannot open a tunnel: the gateway trusts the actor-identity # CA, so the mTLS handshake itself is refused. # -# Prerequisites: a substrate cluster with `--deploy-demo-egress` applied, plus +# Prerequisites: a substrate cluster with `ate-setup deploy demo egress` applied, plus # kubectl and kubectl-ate on PATH. The install's --ingress-allowed-spiffe-ids # must include spiffe://cluster.local/ns/ate-system/sa/atenet-client. See demos/egress/README.md. # diff --git a/demos/jupyter/README.md b/demos/jupyter/README.md index 8931321ab9..da6cd8fe87 100644 --- a/demos/jupyter/README.md +++ b/demos/jupyter/README.md @@ -6,7 +6,7 @@ This demo runs a Jupyter Notebook on Agent Substrate. It demonstrates how standa - A local Kubernetes cluster via Kind (or GKE). - `ko` installed for building images. -- A GCS bucket for storing snapshots, or an in-cluster snapshot repository (handled automatically by the kind install script). +- A GCS bucket for storing snapshots, or an in-cluster snapshot repository (handled automatically by `ate-setup --kind`). ## Quickstart on Kind @@ -22,14 +22,14 @@ For local development, Agent Substrate provides helper scripts to get a Kind clu 2. **Install Agent Substrate core system to the Kind cluster:** ```bash - ./hack/install-ate-kind.sh --deploy-ate-system --credential-provider='{"name":"k8s.io"}' \ + go run ./cmd/ate-setup --kind deploy ate-system --credential-provider='{"name":"k8s.io"}' \ --ingress-allowed-spiffe-ids=spiffe://cluster.local/ns/ate-system/sa/atenet-client ``` 3. **Deploy the Jupyter Notebook Demo:** ```bash - ./hack/install-ate-kind.sh --deploy-demo-jupyter + go run ./cmd/ate-setup --kind deploy demo jupyter ``` ## Creating and Accessing Your Jupyter Actor @@ -99,7 +99,7 @@ Or, even easier, you can rely on "transparent resume" — just refresh the page Uninstall the demo deployment — this deletes the demo's actors, the actor template, and the `ate-demo-jupyter` atespace: ```bash -./hack/install-ate-kind.sh --delete-demo-jupyter +go run ./cmd/ate-setup --kind delete demo jupyter ``` Uninstall the entire local Kind cluster: diff --git a/demos/multi-template/README.md b/demos/multi-template/README.md index 0ac1e739e9..6fee8feba5 100644 --- a/demos/multi-template/README.md +++ b/demos/multi-template/README.md @@ -19,8 +19,8 @@ or namespace. ### 1. Build and Deploy > [!NOTE] -> Do not manually edit the `demos/multi-template/*.yaml.tmpl` manifests. The -> installation script automatically injects your `${BUCKET_NAME}` environment +> Do not manually edit the `demos/multi-template/*.yaml.tmpl` manifests. +> `ate-setup` automatically injects your `${BUCKET_NAME}` environment > variable during deployment. ```bash diff --git a/demos/sandbox/README.md b/demos/sandbox/README.md index 843bef752e..a7635e3646 100644 --- a/demos/sandbox/README.md +++ b/demos/sandbox/README.md @@ -25,9 +25,9 @@ It allows you to run arbitrary commands in an sandboxed, isolated container (run ### 1. Build and Deploy > [!NOTE] -> Do not manually edit the `demos/sandbox/*.yaml.tmpl` manifests. The installation script automatically injects your `${BUCKET_NAME}` environment variable during deployment. +> Do not manually edit the `demos/sandbox/*.yaml.tmpl` manifests. `ate-setup` automatically injects your `${BUCKET_NAME}` environment variable during deployment. -Use the core installation script to build the image and deploy the demo to your cluster: +Use `ate-setup` to build the image and deploy the demo to your cluster: ```bash go run ./cmd/ate-setup deploy demo sandbox diff --git a/docs/authorization.md b/docs/authorization.md index ab5cb19cd5..98ac56ff02 100644 --- a/docs/authorization.md +++ b/docs/authorization.md @@ -70,7 +70,7 @@ if those break. For example, with a JWT provider whose tokens carry the user's email as `sub`: ```sh -ATE_API_AUTHZ_BOOTSTRAP_OWNERS=alice@example.com,bob@example.com hack/install-ate.sh --deploy-ate-system +ATE_API_AUTHZ_BOOTSTRAP_OWNERS=alice@example.com,bob@example.com go run ./cmd/ate-setup deploy ate-system ``` To make your Google account a bootstrap owner, use its numeric `sub`: @@ -78,7 +78,7 @@ To make your Google account a bootstrap owner, use its numeric `sub`: ```sh gcloud auth print-identity-token | cut -d. -f2 | base64 -d 2>/dev/null | jq -r .sub # your sub ATE_API_AUTHZ_BOOTSTRAP_OWNERS=,system:serviceaccount:ate-system:ate-client \ - hack/install-ate.sh --deploy-ate-system # keep ate-client for demos and benchmarks + go run ./cmd/ate-setup deploy ate-system # keep ate-client for demos and benchmarks ``` Then add the Google provider to the `ate-api-authentication` ConfigMap and @@ -280,7 +280,7 @@ redeploy `ate-api-server` can recover: redeploy with a bootstrap owner they can use, fix the policies, then redeploy with the intended owners. ```sh -ATE_API_AUTHZ_BOOTSTRAP_OWNERS=alice@example.com hack/install-ate.sh --deploy-ate-system +ATE_API_AUTHZ_BOOTSTRAP_OWNERS=alice@example.com go run ./cmd/ate-setup deploy ate-system ``` ## Production readiness diff --git a/docs/dev/best-practices/otel-collector.md b/docs/dev/best-practices/otel-collector.md index ab34989c9d..48900738c1 100644 --- a/docs/dev/best-practices/otel-collector.md +++ b/docs/dev/best-practices/otel-collector.md @@ -14,7 +14,7 @@ shows up, see [Actor Observability](../../observability.md). |---|---|---| | [GKE Managed OpenTelemetry](#gke-managed-opentelemetry-gke-only) | Deployment behind a ClusterIP Service | GKE | | [Self-managed DaemonSet](#self-managed-daemonset) | One collector per node | You | -| [kind](#local-development-kind) | Single-replica Deployment plus Jaeger | Bundled with `install-ate-kind.sh` | +| [kind](#local-development-kind) | Single-replica Deployment plus Jaeger | Bundled with `ate-setup --kind` | This guide does not recommend one over another — that depends on your cluster, your telemetry volume, and who is on call for the collector. It documents what @@ -504,7 +504,7 @@ failure. ## Local Development (kind) -`hack/install-ate-kind.sh` installs a collector plus Jaeger into +`ate-setup --kind` installs a collector plus Jaeger into the `otel-system` namespace — see `manifests/ate-install/kind/otel-collector.yaml`. It is a single-replica Deployment, which is appropriate for a one-node kind cluster. The kind diff --git a/docs/dev/mitm-egress-test-runbook.md b/docs/dev/mitm-egress-test-runbook.md index 2d3a7c978c..2c0a54fc9f 100644 --- a/docs/dev/mitm-egress-test-runbook.md +++ b/docs/dev/mitm-egress-test-runbook.md @@ -22,7 +22,7 @@ setup in [Running the microVM runtime locally](microvm-local.md). ```bash ./hack/create-kind-cluster.sh kubectl config use-context kind-kind -ATE_CREDENTIAL_PROVIDER='{"name":"k8s.io"}' ./hack/install-ate-kind.sh --deploy-ate-system +ATE_CREDENTIAL_PROVIDER='{"name":"k8s.io"}' go run ./cmd/ate-setup --kind deploy ate-system ``` For microVM, install its assets before deploying the fixture: @@ -36,8 +36,8 @@ Deploy both egress ActorTemplates and add local-origin trust to the current gateway: ```bash -ATE_CREDENTIAL_PROVIDER='{"name":"k8s.io"}' ./hack/install-ate-kind.sh --deploy-demo-egress -ATE_CREDENTIAL_PROVIDER='{"name":"k8s.io"}' ./hack/install-ate-kind.sh --deploy-demo-egress-microvm +ATE_CREDENTIAL_PROVIDER='{"name":"k8s.io"}' go run ./cmd/ate-setup --kind deploy demo egress +ATE_CREDENTIAL_PROVIDER='{"name":"k8s.io"}' go run ./cmd/ate-setup --kind deploy demo egress-microvm ./hack/setup-e2e-egress-tls-kind.sh ``` diff --git a/docs/egress-credential-injection.md b/docs/egress-credential-injection.md index 4891b452c8..0b583ebd09 100644 --- a/docs/egress-credential-injection.md +++ b/docs/egress-credential-injection.md @@ -180,12 +180,12 @@ the credential. ### Enable it **1. The gateway.** The provider is selected when the egress gateway is -deployed, with `--deploy-ate-system` or `--deploy-atenet`, for either the Envoy +deployed, with `deploy ate-system` or `deploy atenet`, for either the Envoy or agentgateway dataplane. The selection is required: an install that wants no injection says so with `{"enabled":false}`. ```bash -hack/install-ate.sh --deploy-atenet --credential-provider='{"name":"k8s.io"}' +go run ./cmd/ate-setup deploy atenet --credential-provider='{"name":"k8s.io"}' ``` `--credential-provider` (or `ATE_CREDENTIAL_PROVIDER` when the flag is diff --git a/docs/examples/substrate-install.yaml b/docs/examples/substrate-install.yaml index a2ca9618da..5ffbca089c 100644 --- a/docs/examples/substrate-install.yaml +++ b/docs/examples/substrate-install.yaml @@ -16,7 +16,7 @@ # An Agent Substrate installation, as a document an operator owns. # # ate-setup deploy ate-system --config substrate-install.yaml -# ATE_CONFIG=substrate-install.yaml hack/install-ate.sh --deploy-ate-system +# ATE_CONFIG=substrate-install.yaml ate-setup deploy ate-system # # Every setting here can equally be an environment variable or a flag; see # docs/operator-install.md for the full list and the precedence between them. diff --git a/docs/operator-install.md b/docs/operator-install.md index 15b649a8a3..225610d191 100644 --- a/docs/operator-install.md +++ b/docs/operator-install.md @@ -23,13 +23,9 @@ Pass it with `--config`, or name it in `ATE_CONFIG`: ```bash ate-setup deploy ate-system --config substrate-install.yaml -ATE_CONFIG=substrate-install.yaml hack/install-ate.sh --deploy-ate-system +ATE_CONFIG=substrate-install.yaml ate-setup deploy ate-system ``` -`ATE_CONFIG` is how the document reaches the shell installer, which forwards -only a fixed set of flags and otherwise passes settings by inheriting the -environment. - A worked example is at [docs/examples/substrate-install.yaml](examples/substrate-install.yaml). ### Keys are nested; the table below is flat diff --git a/hack/install-ate-kind.sh b/hack/install-ate-kind.sh deleted file mode 100755 index 4c4e1ffc6e..0000000000 --- a/hack/install-ate-kind.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2026 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -o errexit -o nounset -o pipefail - -ROOT="$(git rev-parse --show-toplevel)" -cd "${ROOT}" - -# shellcheck disable=SC2155 # safe initialization -goarch=$(go env GOARCH) - -# override reading dev env -export NO_DEV_ENV="true" -# we will push images to the local registry -export KO_DOCKER_REPO="${KO_DOCKER_REPO:-localhost:5001}" -# we want to build for the host architecture -export KO_DEFAULTPLATFORMS="linux/${goarch}" -# install resolved manifests using Kustomize overlay for local Kind cluster -export ATE_INSTALL_KIND="true" -# use default bucket name for local deployment -export BUCKET_NAME="ate-snapshots" -# target the local kind cluster's context (mirrors run-microvm-demo-kind.sh) so -# the install doesn't land on whatever kubeconfig current-context happens to be, -# or on nothing at all, which kubectl reports as a localhost:8080 dial failure. -# An explicit KUBECTL_CONTEXT still wins. -KIND_CLUSTER_NAME="${KIND_CLUSTER_NAME:-kind}" -export KUBECTL_CONTEXT="${KUBECTL_CONTEXT:-kind-${KIND_CLUSTER_NAME}}" -# unset other env from ate-dev-env.sh in case the developer already sourced them -unset GCE_REGION CLUSTER_LOCATION NETWORK SUBNETWORK MEMORYSTORE_INSTANCE PROJECT_ID - -go run ./cmd/ate-setup "$@" diff --git a/hack/install-ate.sh b/hack/install-ate.sh deleted file mode 100755 index edc0fb905f..0000000000 --- a/hack/install-ate.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2026 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Installs Agent Substrate. -# -# This is a translation shim: cmd/ate-setup carries out every action, and this -# script only maps the flags and environment variables the installer has always -# accepted onto its commands, so existing command lines and CI jobs keep -# working unchanged. It deliberately holds no install logic of its own. -# -# New work belongs in cmd/ate-setup. See cmd/ate-setup/commands.md for the -# equivalent invocation of each flag below, and cmd/ate-setup/cli-diff.md for -# the behaviors that differ after the move. -# -# The environment variables the installer reads -- BUCKET_NAME, KO_DOCKER_REPO, -# PROJECT_ID, CLUSTER_NAME, CLUSTER_LOCATION, KUBECTL_CONTEXT, NO_DEV_ENV, the -# ATE_API_POSTGRES_* set, and the rest -- are read by ate-setup directly, as is -# .ate-dev-env.sh. They need no translation and are not repeated here. - -set -o errexit -o nounset -o pipefail - -go run ./cmd/ate-setup "$@" diff --git a/hack/install-microvm-deps.sh b/hack/install-microvm-deps.sh index acfe705d23..312da2e346 100755 --- a/hack/install-microvm-deps.sh +++ b/hack/install-microvm-deps.sh @@ -15,7 +15,7 @@ # limitations under the License. # Install (or delete) the cluster-wide micro-VM (kata + cloud-hypervisor) -# dependencies. This is opt-in on top of hack/install-ate.sh --deploy-ate-system, +# dependencies. This is opt-in on top of ate-setup deploy ate-system, # which only installs the default gVisor SandboxConfig. Used by: # * hack/run-microvm-demo.sh (before applying the counter-microvm demo) # * benchmarking/automation/orchestrator.py (before deploying a microvm @@ -106,7 +106,7 @@ if [[ -z "${KUBECTL_CONTEXT}" ]] && ! kubectl config current-context >/dev/null exit 1 fi -# ANSI color codes for prettier output (mirrors hack/install-ate.sh). +# ANSI color codes for prettier output. COLOR_CYAN='\033[1;36m' COLOR_RESET='\033[0m' log() { diff --git a/hack/microvm-assets/README.md b/hack/microvm-assets/README.md index 1436ef4e68..00580b90d5 100644 --- a/hack/microvm-assets/README.md +++ b/hack/microvm-assets/README.md @@ -31,8 +31,9 @@ it as a device, which is what places microVM workers there. 2. **Bring up the cluster + control plane:** ```sh - hack/create-kind-cluster.sh # mounts /dev/kvm into the nodes - hack/install-ate-kind.sh # control plane + rustfs (bucket: ate-snapshots) + hack/create-kind-cluster.sh # mounts /dev/kvm into the nodes + # control plane + rustfs (bucket: ate-snapshots) + go run ./cmd/ate-setup --kind deploy ate-system --credential-provider='{"name":"k8s.io"}' ``` 3. **Stage assets into rustfs:** diff --git a/hack/microvm-assets/stage-to-rustfs.sh b/hack/microvm-assets/stage-to-rustfs.sh index 5fbd9c1e8b..4409937ec0 100755 --- a/hack/microvm-assets/stage-to-rustfs.sh +++ b/hack/microvm-assets/stage-to-rustfs.sh @@ -19,7 +19,7 @@ # plugin (per manifests/microvm/sandboxconfig-microvm.yaml.tmpl). The plugin # refuses assets stored under a snapshot location # (/atespaces/), so keep them outside it. -# Run after the cluster is up (hack/install-ate-kind.sh) and assemble.sh has produced $OUT. +# Run after the cluster is up (ate-setup --kind deploy ate-system) and assemble.sh has produced $OUT. # # The S3 client runs in a throwaway container (the same pinned amazon/aws-cli # image as the rustfs-bucket-init Job), so developers don't need the `aws` CLI diff --git a/hack/run-e2e-kind.sh b/hack/run-e2e-kind.sh index 5585228b9d..d532bdbe97 100755 --- a/hack/run-e2e-kind.sh +++ b/hack/run-e2e-kind.sh @@ -22,8 +22,8 @@ cd "${ROOT}" # Runs the E2E tests against a local Kind cluster. # # This wraps hack/run-e2e.sh with the same Kind-specific environment that -# hack/install-ate-kind.sh uses, so the snapshot bucket and image repo match -# what was installed in the cluster. All arguments are forwarded to +# ate-setup --kind uses, so the snapshot bucket and image repo match what was +# installed in the cluster. All arguments are forwarded to # hack/run-e2e.sh (run with -h to see them). # override reading dev env -- otherwise .ate-dev-env.sh would clobber the @@ -32,7 +32,7 @@ cd "${ROOT}" export NO_DEV_ENV="true" # images are pushed to the local registry export KO_DOCKER_REPO="${KO_DOCKER_REPO:-localhost:5001}" -# only build fixtures for the host arch, like install-ate-kind.sh +# only build fixtures for the host arch, like ate-setup --kind export KO_DEFAULTPLATFORMS="${KO_DEFAULTPLATFORMS:-linux/$(go env GOARCH)}" # default bucket name for local deployment (served by in-cluster rustfs) export BUCKET_NAME="ate-snapshots" diff --git a/hack/run-microvm-demo-kind.sh b/hack/run-microvm-demo-kind.sh index 683e6d8d00..0702d85fc2 100755 --- a/hack/run-microvm-demo-kind.sh +++ b/hack/run-microvm-demo-kind.sh @@ -21,7 +21,7 @@ cd "${ROOT}" # Bring up the counter-microvm demo on a local kind cluster. Wraps # hack/run-microvm-demo.sh with the same kind-specific environment that -# hack/install-ate-kind.sh uses, so the image repo and snapshot bucket match what +# ate-setup --kind uses, so the image repo and snapshot bucket match what # gets installed in the cluster. All arguments are forwarded to run-microvm-demo.sh. # shellcheck disable=SC2155 # safe initialization @@ -34,7 +34,7 @@ export NO_DEV_ENV="true" export KO_DOCKER_REPO="${KO_DOCKER_REPO:-localhost:5001}" # build for the host architecture export KO_DEFAULTPLATFORMS="linux/${goarch}" -# use the kind control-plane path (install-ate-kind.sh) + stage assets to rustfs +# use the kind control-plane path (ate-setup --kind) + stage assets to rustfs export ATE_INSTALL_KIND="true" # default bucket name for local deployment (served by the in-cluster rustfs) export BUCKET_NAME="${BUCKET_NAME:-ate-snapshots}" diff --git a/hack/run-microvm-demo.sh b/hack/run-microvm-demo.sh index 85baf6c4ea..9ef7334c14 100755 --- a/hack/run-microvm-demo.sh +++ b/hack/run-microvm-demo.sh @@ -16,10 +16,10 @@ # One-shot bring-up of the counter-microvm demo. GKE/dev-env by default; for a # local kind cluster use hack/run-microvm-demo-kind.sh (which sets the kind env -# and calls this script), mirroring install-ate.sh / install-ate-kind.sh. +# and calls this script). # # Composes: -# 1. hack/install-ate.sh --deploy-ate-system (control plane) +# 1. ate-setup deploy ate-system (control plane) # 2. hack/install-microvm-deps.sh --install (asset build/stage + cluster-wide # microvm SandboxConfig) # 3. Deploy the counter-microvm demo (worker pool manifest, atespace, and @@ -29,7 +29,7 @@ # registry / bucket settings unless NO_DEV_ENV is set. The control plane deploy # requires a credential provider selection, which reaches it only through the # environment here: export ATE_CREDENTIAL_PROVIDER (e.g. '{"name":"k8s.io"}'; -# see hack/install-ate.sh --help) before running this, the kind wrapper +# see go run ./cmd/ate-setup --help) before running this, the kind wrapper # included. The printed `kubectl ate proxy actor` step also needs # ATE_INGRESS_ALLOWED_SPIFFE_IDS to include spiffe://cluster.local/ns/ate-system/sa/atenet-client. # @@ -42,8 +42,8 @@ # PROJECT_ID (optional) GCP project for the GCS asset upload (GKE path). # ARCH target arch (default: from KO_DEFAULTPLATFORMS, else host arch). # OUT asset dir (default: $PWD/bin/microvm-assets/$ARCH, gitignored). -# ATE_INSTALL_KIND "true" for the kind path (stage assets to rustfs + install-ate-kind.sh); -# default false uploads assets to GCS + uses install-ate.sh. +# ATE_INSTALL_KIND "true" for the kind path (stage assets to rustfs + ate-setup --kind); +# default false uploads assets to GCS. set -o errexit -o nounset -o pipefail @@ -73,7 +73,7 @@ if [[ -z "${KO_DOCKER_REPO}" ]]; then fi export KO_DOCKER_REPO -# ANSI color codes for prettier output (mirrors hack/install-ate.sh). +# ANSI color codes for prettier output. COLOR_CYAN='\033[1;36m' COLOR_RESET='\033[0m' log() { @@ -82,13 +82,9 @@ log() { # --- 1. deploy the control plane ------------------------------------------- log "Deploying the ate control plane (deploy ate-system)..." -if [[ "${ATE_INSTALL_KIND}" == "true" ]]; then - # install-ate-kind.sh sets NO_DEV_ENV/KO_DOCKER_REPO/ARCH/ATE_INSTALL_KIND itself. - KUBECTL_CONTEXT="${KUBECTL_CONTEXT}" hack/install-ate-kind.sh deploy ate-system -else - # GKE path: pass KO_DOCKER_REPO/BUCKET_NAME/KUBECTL_CONTEXT through the env. - KUBECTL_CONTEXT="${KUBECTL_CONTEXT}" hack/install-ate.sh deploy ate-system -fi +# ate-setup reads ATE_INSTALL_KIND from the environment, so this covers the kind +# path too. +KUBECTL_CONTEXT="${KUBECTL_CONTEXT}" go run ./cmd/ate-setup deploy ate-system # --- 2. install micro-VM deps (assets + cluster-wide SandboxConfig) -------- # install-microvm-deps.sh handles the assemble/stage/apply flow. Ordering @@ -103,14 +99,9 @@ if [[ -n "${KUBECTL_CONTEXT}" ]]; then fi # The demo handler applies the worker pool, creates the atespace and the -# ActorTemplate through the ate API, and waits for the golden snapshot; -# dispatch through install-ate.sh like step 1. -log "Deploying the counter-microvm demo (--deploy-demo-counter-microvm)..." -if [[ "${ATE_INSTALL_KIND}" == "true" ]]; then - KUBECTL_CONTEXT="${KUBECTL_CONTEXT}" hack/install-ate-kind.sh deploy demo counter-microvm -else - KUBECTL_CONTEXT="${KUBECTL_CONTEXT}" hack/install-ate.sh deploy demo counter-microvm -fi +# ActorTemplate through the ate API, and waits for the golden snapshot. +log "Deploying the counter-microvm demo (deploy demo counter-microvm)..." +KUBECTL_CONTEXT="${KUBECTL_CONTEXT}" go run ./cmd/ate-setup deploy demo counter-microvm log "Demo applied. Next steps:" cat </dev/null 2>&1 || true -# Also delete our custom service and SC -kubectl delete service csi-hostpath-controller -n default >/dev/null 2>&1 || true -kubectl delete storageclass csi-hostpath-sc >/dev/null 2>&1 || true - -# Also clean up the host directories inside Kind node (best effort) -echo "Cleaning up CSI directories on Kind node..." -KIND_CLUSTER_NAME="${KIND_CLUSTER_NAME:-kind}" -KIND_NODE=$(kubectl get nodes -l '!node-role.kubernetes.io/control-plane' -o name | head -n 1 | cut -d'/' -f2) -if [ -z "${KIND_NODE}" ]; then - KIND_NODE=$(kubectl get nodes -o name | head -n 1 | cut -d'/' -f2) -fi -echo "Using Kind node: ${KIND_NODE}" -if docker ps | grep -q "${KIND_NODE}"; then - # Unmount any stale mounts to prevent "device or resource busy" - docker exec "${KIND_NODE}" sh -c ' - for mnt in $(mount | grep /var/lib/ate | awk "{print \$3}"); do - echo "Unmounting stale mount: ${mnt}" - umount -f "${mnt}" || true - done - ' || true - # Only delete contents, keep the directory itself to preserve mounts of running pods (like atelet) - docker exec "${KIND_NODE}" sh -c 'rm -rf /var/lib/ate/*' || true -else - echo "Warning: Kind node ${KIND_NODE} not running. Skipping directory cleanup." -fi - -# 2 Expose CSI Controller over TCP Service. -# This Service must be created before the driver pod deploys for the servicednssigner -# because servicednssigner to issue a certificate. -echo "Exposing CSI Controller over TCP Service..." -cat </dev/null 2>&1; then - echo "Error: csi-hostpathplugin StatefulSet was not created!" - exit 1 -fi - -# 4. Patch the CSI Driver to mount Substrate directory -echo "Patching CSI Hostpath StatefulSet..." -kubectl patch statefulset csi-hostpathplugin -n default --patch " -spec: - template: - spec: - nodeSelector: - kubernetes.io/hostname: ${KIND_NODE} - containers: - - name: hostpath - volumeMounts: - - name: ate-base - mountPath: /var/lib/ate - mountPropagation: Bidirectional - volumes: - - name: ate-base - hostPath: - path: /var/lib/ate - type: DirectoryOrCreate -" - -# 6. Create the StorageClass -echo "Creating csi-hostpath-sc StorageClass..." -kubectl apply -f "${DRIVER_DIR}/examples/csi-storageclass.yaml" - -# 7. Wait for pods to be ready -echo "Waiting for CSI Hostpath and Proxy pods to be Ready..." -kubectl rollout status statefulset/csi-hostpathplugin -n default --timeout=120s -kubectl rollout status statefulset/csi-hostpath-socat -n default --timeout=120s - -# 8. Create the CSIDriverConfig for Substrate -echo "Creating hostpath.csi.k8s.io CSIDriverConfig..." -cat </dev/null 2>&1 || true - -echo "CSI Hostpath setup complete!" diff --git a/hack/third_party/csi-driver-nfs/deploy/example/storageclass-nfs.yaml b/hack/third_party/csi-driver-nfs/deploy/example/storageclass-nfs.yaml index e097d86bda..8d4a456ce6 100644 --- a/hack/third_party/csi-driver-nfs/deploy/example/storageclass-nfs.yaml +++ b/hack/third_party/csi-driver-nfs/deploy/example/storageclass-nfs.yaml @@ -1,6 +1,6 @@ # The csi-nfs-sc StorageClass, backed by the dev NFS server in -# hack/csi/nfs-server.yaml. `ate-setup setup csi nfs` (hack/install-ate.sh -# --setup-csi=nfs) and hack/setup-csi-nfs-kind.sh both apply this file, so the +# hack/csi/nfs-server.yaml. `ate-setup setup csi nfs` and +# hack/setup-csi-nfs-kind.sh both apply this file, so the # e2e tests, demos and benchmarks all provision from the same class. # # Based on deploy/example/storageclass-nfs.yaml from diff --git a/hack/verify-atenet-drain.sh b/hack/verify-atenet-drain.sh index f7dabd00bd..122bdd781c 100755 --- a/hack/verify-atenet-drain.sh +++ b/hack/verify-atenet-drain.sh @@ -33,7 +33,8 @@ # the e2e runner executes suites in parallel, so this check must run alone. # # Prerequisites: a cluster with the ate system and the counter demo installed -# (hack/install-ate-kind.sh --deploy-ate-system --credential-provider='{"name":"k8s.io"}' --deploy-demo-counter), +# (go run ./cmd/ate-setup --kind deploy ate-system --credential-provider='{"name":"k8s.io"}', then +# go run ./cmd/ate-setup --kind deploy demo counter), # and no actors currently running on the counter demo pool (the pool is scaled # to 1 for the duration of the check and restored afterwards). # diff --git a/hack/verify-egress-demo.sh b/hack/verify-egress-demo.sh index 55cfb78b03..72729f62c2 100755 --- a/hack/verify-egress-demo.sh +++ b/hack/verify-egress-demo.sh @@ -16,7 +16,7 @@ # # Preconditions: # hack/create-kind-cluster.sh -# hack/install-ate-kind.sh --deploy-demo-egress, on an install whose +# go run ./cmd/ate-setup --kind deploy demo egress, on an install whose # --ingress-allowed-spiffe-ids includes spiffe://cluster.local/ns/ate-system/sa/atenet-client # # The egress demo Actor accepts {"url":"..."} and performs an HTTP GET. With diff --git a/internal/e2e/README.md b/internal/e2e/README.md index 01bdaf3e36..a3f5972267 100644 --- a/internal/e2e/README.md +++ b/internal/e2e/README.md @@ -20,8 +20,8 @@ $ go test -v ./internal/e2e/suites/... -args --e2e The e2e tests assume you have a cluster set up with Agent Substrate installed with the `--e2e-tuning` component, for example via -`hack/install-ate.sh deploy ate-system --e2e-tuning --credential-provider='{"name":"k8s.io"}'` -or `hack/install-ate-kind.sh deploy ate-system --e2e-tuning --credential-provider='{"name":"k8s.io"}'`. +`go run ./cmd/ate-setup deploy ate-system --e2e-tuning --credential-provider='{"name":"k8s.io"}'` +(add `--kind` for a local Kind cluster). The egress credential injection suite needs that bundled provider, which is what CI installs on the envoy lane; see `internal/e2e/suites/egresscredinject`. @@ -34,7 +34,7 @@ selects which, by repointing every fixture at its variant --- see [sandbox.go](sandbox.go). Unset means gVisor. ```shell -# gVisor (the default), against the demos install-ate-kind.sh deploys +# gVisor (the default), against the counter and egress demos $ hack/run-e2e-kind.sh -v -args --no-color # microVM, against the counter-microvm and egress-microvm demos @@ -45,8 +45,8 @@ The microVM lane needs its fixtures installed first, which also needs a node with `/dev/kvm` (`hack/create-kind-cluster.sh` detects one and labels the node): ```shell -$ hack/run-microvm-demo-kind.sh # counter-microvm + assets -$ hack/install-ate-kind.sh --deploy-demo-egress-microvm # egress-microvm +$ hack/run-microvm-demo-kind.sh # counter-microvm + assets +$ go run ./cmd/ate-setup --kind deploy demo egress-microvm # egress-microvm ``` A handful of knobs override the class defaults, mostly for a cluster that diff --git a/internal/e2e/credprovider.go b/internal/e2e/credprovider.go index bd18c9d819..d222a9d2c4 100644 --- a/internal/e2e/credprovider.go +++ b/internal/e2e/credprovider.go @@ -59,7 +59,7 @@ const ( // // The provider itself and the gateway's side of the connection — the // credential-provider configuration — are the install's -// (hack/install-ate.sh --credential-provider='{"name":"k8s.io"}'), not +// (ate-setup --credential-provider='{"name":"k8s.io"}'), not // something this helper can retrofit: the rollout wait below fails on a // cluster installed without them. func ConfigureCredentialProvider(t *testing.T) { diff --git a/internal/e2e/env.go b/internal/e2e/env.go index 0491442528..fa5fe5619c 100644 --- a/internal/e2e/env.go +++ b/internal/e2e/env.go @@ -36,8 +36,8 @@ func CheckEnv(keys ...string) (map[string]string, error) { } // SystemNamespaceEnv names the namespace the substrate control plane under test -// was installed into. It mirrors the ATE_NAMESPACE hack/install-ate.sh -// installed with, and the namespace the deployment was installed into. +// was installed into. It mirrors the ate-setup --namespace (ATE_NAMESPACE) +// the control plane was installed with. const SystemNamespaceEnv = "E2E_SYSTEM_NAMESPACE" // SystemNamespace returns the namespace the control plane under test runs in, diff --git a/internal/e2e/sandbox.go b/internal/e2e/sandbox.go index 878c155bc0..387e409058 100644 --- a/internal/e2e/sandbox.go +++ b/internal/e2e/sandbox.go @@ -44,7 +44,7 @@ func IsMicroVM() bool { return SandboxClass() == SandboxClassMicroVM } type Fixture struct { Namespace string Name string - // DeployWith is the install flag or script that creates the fixture, so a + // DeployWith is the ate-setup command that creates the fixture, so a // missing one reports how to fix it rather than just failing. DeployWith string } @@ -61,7 +61,7 @@ type SubstrateFixture struct { // PoolNamespace and PoolName locate the WorkerPool CRD. PoolNamespace string PoolName string - // DeployWith is the install flag or script that creates the fixture, so a + // DeployWith is the ate-setup command that creates the fixture, so a // missing one reports how to fix it rather than just failing. DeployWith string } @@ -77,7 +77,7 @@ func SubstrateCounterFixture() SubstrateFixture { Name: "counter", PoolNamespace: "ate-demo-counter", PoolName: "counter", - DeployWith: "hack/install-ate-kind.sh --deploy-demo-counter", + DeployWith: "go run ./cmd/ate-setup --kind deploy demo counter", } if IsMicroVM() { f = SubstrateFixture{ @@ -85,7 +85,7 @@ func SubstrateCounterFixture() SubstrateFixture { Name: "counter-microvm", PoolNamespace: "ate-demo-counter-microvm", PoolName: "counter-microvm", - DeployWith: "hack/install-ate-kind.sh --deploy-demo-counter-microvm", + DeployWith: "go run ./cmd/ate-setup --kind deploy demo counter-microvm", } } if v := os.Getenv("E2E_SUBSTRATE_TEMPLATE_ATESPACE"); v != "" { @@ -110,13 +110,13 @@ func EgressFixture() Fixture { return Fixture{ Namespace: "ate-demo-egress-microvm", Name: "egress-microvm", - DeployWith: "hack/install-ate-kind.sh --deploy-demo-egress-microvm", + DeployWith: "go run ./cmd/ate-setup --kind deploy demo egress-microvm", } } return Fixture{ Namespace: "ate-demo-egress", Name: "egress", - DeployWith: "hack/install-ate-kind.sh --deploy-demo-egress", + DeployWith: "go run ./cmd/ate-setup --kind deploy demo egress", } } diff --git a/internal/e2e/sandbox_test.go b/internal/e2e/sandbox_test.go index 2b4a7db7d6..9ac345e2be 100644 --- a/internal/e2e/sandbox_test.go +++ b/internal/e2e/sandbox_test.go @@ -231,7 +231,7 @@ func TestSubstrateCounterFixture(t *testing.T) { Name: "counter", PoolNamespace: "ate-demo-counter", PoolName: "counter", - DeployWith: "hack/install-ate-kind.sh --deploy-demo-counter", + DeployWith: "go run ./cmd/ate-setup --kind deploy demo counter", } if got != want { t.Errorf("SubstrateCounterFixture() = %+v, want %+v", got, want) @@ -245,7 +245,7 @@ func TestSubstrateCounterFixture(t *testing.T) { Name: "counter-microvm", PoolNamespace: "ate-demo-counter-microvm", PoolName: "counter-microvm", - DeployWith: "hack/install-ate-kind.sh --deploy-demo-counter-microvm", + DeployWith: "go run ./cmd/ate-setup --kind deploy demo counter-microvm", } if got != want { t.Errorf("SubstrateCounterFixture() = %+v, want %+v", got, want) diff --git a/internal/e2e/suites/egresscredinject/egresscredinject_test.go b/internal/e2e/suites/egresscredinject/egresscredinject_test.go index f557743730..ae64812a12 100644 --- a/internal/e2e/suites/egresscredinject/egresscredinject_test.go +++ b/internal/e2e/suites/egresscredinject/egresscredinject_test.go @@ -107,7 +107,7 @@ var withPlaceholder = []string{ // be made with the bundled provider, which deploys the k8s-credential-provider // and points the egress gateway at it. Locally: // -// hack/install-ate-kind.sh --deploy-atenet --credential-provider='{"name":"k8s.io"}' +// go run ./cmd/ate-setup --kind deploy atenet --credential-provider='{"name":"k8s.io"}' // hack/setup-e2e-egress-tls-kind.sh // hack/run-e2e-kind.sh ./internal/e2e/suites/egresscredinject -v -args --no-color func TestActorEgressCredentialInjection(t *testing.T) { diff --git a/internal/e2e/suites/egressmitm/goldenboot_test.go b/internal/e2e/suites/egressmitm/goldenboot_test.go index fb8a862500..09215bc123 100644 --- a/internal/e2e/suites/egressmitm/goldenboot_test.go +++ b/internal/e2e/suites/egressmitm/goldenboot_test.go @@ -41,7 +41,7 @@ var bootFetchManifests = e2e.SubstrateFixtureManifests{ // goldenEgressPolicy is a preview feature: install the cluster with its gate // and pass the gate to the suite, which skips the test otherwise. // -// ATE_PREVIEW=GoldenEgressPolicy hack/install-ate-kind.sh +// ATE_PREVIEW=GoldenEgressPolicy go run ./cmd/ate-setup --kind deploy ate-system --credential-provider='{"name":"k8s.io"}' // hack/run-e2e-kind.sh ./internal/e2e/suites/egressmitm -run TestGoldenBootEgress -v -args --no-color --preview=GoldenEgressPolicy func TestGoldenBootEgress(t *testing.T) { e2e.RequirePreview(t, preview.GateGoldenEgressPolicy) diff --git a/internal/e2e/suites/security/README.md b/internal/e2e/suites/security/README.md index e41410f208..d92fa3b7f0 100644 --- a/internal/e2e/suites/security/README.md +++ b/internal/e2e/suites/security/README.md @@ -17,7 +17,7 @@ hack/create-kind-cluster.sh 2. Install the control plane (slow step — pulls ~570 MB): ``` -hack/install-ate-kind.sh --deploy-ate-system +go run ./cmd/ate-setup --kind deploy ate-system --credential-provider='{"name":"k8s.io"}' ``` Stop here — the NFS/CSI and demo steps CI runs are for other suites; this suite needs none of them. diff --git a/internal/e2e/trustbundle.go b/internal/e2e/trustbundle.go index 01f0dbc781..f0615fb3d9 100644 --- a/internal/e2e/trustbundle.go +++ b/internal/e2e/trustbundle.go @@ -43,7 +43,7 @@ const ( // EgressTrustBundleObjectName is the reconciler-owned ClusterTrustBundle. EgressTrustBundleObjectName = "egress-mitm.ate.dev:mitm:primary-bundle" - // egressCAPoolSecretName is not release-prefixed: hack/install-ate.sh + // egressCAPoolSecretName is not release-prefixed: ate-setup // creates it under this fixed name and the reconciler looks it up the same // way, so it does not follow the deployment's naming. egressCAPoolSecretName = "egress-mitm-ca-pool" diff --git a/manifests/ate-install/atenet-egress.yaml b/manifests/ate-install/atenet-egress.yaml index 231c44c9a5..88a0945fd6 100644 --- a/manifests/ate-install/atenet-egress.yaml +++ b/manifests/ate-install/atenet-egress.yaml @@ -302,7 +302,7 @@ data: # policy ext_proc on every request. They also carry an # #ATE_MITM_EXTPROC_FILTER marker, with a matching # #ATE_MITM_EXTPROC_CLUSTER in the cluster list: inert comments until - # hack/install-ate.sh is run with + # ate-setup is run with # --experimental-additional-egress-extproc-service, which replaces each # with a generated block for an additional, external processor. The # marker sits below the policy filter, so that processor sees only diff --git a/manifests/ate-install/base/kustomization.yaml b/manifests/ate-install/base/kustomization.yaml index e1519c964a..765aaf937b 100644 --- a/manifests/ate-install/base/kustomization.yaml +++ b/manifests/ate-install/base/kustomization.yaml @@ -19,14 +19,13 @@ kind: Kustomization # via envFrom. The kind overlay lists its own copy of the same ConfigMap name # instead of building on this directory, so the two never collide. # -# pod-certificate-controller.yaml is deliberately absent. The installers -# (hack/install-ate.sh and cmd/ate-setup) apply it on their own before this -# bundle, through the podcert-size10 overlay on large clusters, and then set -# WORKERS_PER_SIGNER on the Deployment. Listing the base file here would -# re-apply it after those steps and revert both the overlay's flags and the -# env override. The same goes for the sandboxconfig and atenet-egress files: -# the installers apply the variant they select, so they are not listed here -# either. +# pod-certificate-controller.yaml is deliberately absent. cmd/ate-setup +# applies it on its own before this bundle, through the podcert-size10 overlay +# on large clusters, and then sets WORKERS_PER_SIGNER on the Deployment. +# Listing the base file here would re-apply it after those steps and revert +# both the overlay's flags and the env override. The same goes for the +# sandboxconfig and atenet-egress files: cmd/ate-setup applies the variant it +# selects, so they are not listed here either. resources: - ../ate-api-server.yaml - ../ate-idp-server.yaml diff --git a/manifests/ate-install/cloudsql/proxy-sidecar-patch.yaml b/manifests/ate-install/cloudsql/proxy-sidecar-patch.yaml index 5981617016..307e1fc563 100644 --- a/manifests/ate-install/cloudsql/proxy-sidecar-patch.yaml +++ b/manifests/ate-install/cloudsql/proxy-sidecar-patch.yaml @@ -13,7 +13,7 @@ # limitations under the License. # Strategic-merge patch adding a Cloud SQL Auth Proxy sidecar to -# ate-api-server. Applied by hack/install-ate.sh only when +# ate-api-server. Applied by ate-setup only when # ATE_API_POSTGRES_CLOUDSQL_INSTANCE is set. # # The proxy owns transport security (TLS 1.3 tunnel with ephemeral @@ -24,7 +24,7 @@ # 127.0.0.1:5432 in plaintext that never leaves the pod's network namespace. # # All CSQL_PROXY_* configuration comes from the ate-api-server-envvars -# ConfigMap (written by install-ate.sh); the instance connection name is the +# ConfigMap (written by ate-setup); the instance connection name is the # proxy's single positional argument, expanded by Kubernetes from the same # ConfigMap. spec: diff --git a/manifests/ate-install/kind/atelet/kustomization.yaml b/manifests/ate-install/kind/atelet/kustomization.yaml index 0616973c6b..c86c0393f6 100644 --- a/manifests/ate-install/kind/atelet/kustomization.yaml +++ b/manifests/ate-install/kind/atelet/kustomization.yaml @@ -40,7 +40,7 @@ patches: # The OTLP endpoint comes from the ate-otel-config ConfigMap the # atelet DaemonSet consumes via envFrom; the kind copy lives at # ../ate-otel-config.yaml and is applied by the parent overlay or - # by hack/install-ate.sh for a targeted redeploy. + # by ate-setup for a targeted redeploy. # kind nodes ship no credential provider plugin (the args above # leave the --image-credential-provider-* flags unset), so drop # the base manifest's host mounts instead of fabricating empty diff --git a/manifests/ate-install/kind/kustomization.yaml b/manifests/ate-install/kind/kustomization.yaml index c757f2362f..c7cb712c3a 100644 --- a/manifests/ate-install/kind/kustomization.yaml +++ b/manifests/ate-install/kind/kustomization.yaml @@ -22,10 +22,9 @@ kind: Kustomization # in the bundle and an overlay would be a duplicate resource. ate-setup applies # the ConfigMap directly for the single-component redeploys. # -# pod-certificate-controller.yaml is deliberately absent, as in ../base: the -# installers (hack/install-ate.sh and cmd/ate-setup) apply and delete it on -# their own, and re-applying the base file from this bundle would revert the -# WORKERS_PER_SIGNER override. +# pod-certificate-controller.yaml is deliberately absent, as in ../base: +# cmd/ate-setup applies and deletes it on its own, and re-applying the base +# file from this bundle would revert the WORKERS_PER_SIGNER override. resources: - ./ate-api-server - ../ate-idp-server.yaml diff --git a/manifests/ate-install/podcert-size10/kustomization.yaml b/manifests/ate-install/podcert-size10/kustomization.yaml index ec6798b6be..9869b5736e 100644 --- a/manifests/ate-install/podcert-size10/kustomization.yaml +++ b/manifests/ate-install/podcert-size10/kustomization.yaml @@ -15,7 +15,7 @@ # size10 cluster overlay for podcertificate-controller: raises the client-go # rate limits above the built-in 5 QPS / 10 burst so signing keeps up with # the request volume the size10 postgres profile enables. Selected by -# hack/install-ate.sh and cmd/ate-setup when --cluster-size=size10. +# cmd/ate-setup when --cluster-size=size10. apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization diff --git a/manifests/ate-install/postgres-size10/postgres-config-patch.yaml b/manifests/ate-install/postgres-size10/postgres-config-patch.yaml index ba73324efb..2b04e43059 100644 --- a/manifests/ate-install/postgres-size10/postgres-config-patch.yaml +++ b/manifests/ate-install/postgres-size10/postgres-config-patch.yaml @@ -12,13 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Merged into postgres-config when --cluster-size=size10: hack/install-ate.sh -# applies it with `kubectl patch --type merge`, cmd/ate-setup folds it into -# the rendered ConfigMap before the apply. Either way only the postgresql.conf +# Merged into postgres-config when --cluster-size=size10: cmd/ate-setup folds +# it into the rendered ConfigMap before the apply. Only the postgresql.conf # key is replaced, without touching pg_hba.conf or reload-tls.sh, both defined # in manifests/ate-install/postgres/postgres.yaml. # -# Sized to match the size10 container resources both installers set (140 GiB +# Sized to match the size10 container resources ate-setup sets (140 GiB # memory, 80 vCPU request, no CPU limit, on a dedicated node). Every value # below depends on those numbers -- if the container is resized the tuning # has to move with it. diff --git a/manifests/microvm/sandboxconfig-microvm.yaml.tmpl b/manifests/microvm/sandboxconfig-microvm.yaml.tmpl index 19bd5b6fd3..2423d99e03 100644 --- a/manifests/microvm/sandboxconfig-microvm.yaml.tmpl +++ b/manifests/microvm/sandboxconfig-microvm.yaml.tmpl @@ -14,7 +14,7 @@ # Cluster-wide SandboxConfig for the micro-VM (kata + cloud-hypervisor) sandbox # class. Unlike sandboxconfig-gvisor.yaml (applied unconditionally by -# hack/install-ate.sh --deploy-ate-system), this is opt-in: apply via +# ate-setup deploy ate-system), this is opt-in: apply via # hack/install-microvm-deps.sh --install after staging the asset set # (assemble.sh + stage-to-gcs.sh / stage-to-rustfs.sh). A microvm WorkerPool # resolves it as its class default (or names it via configRef: microvm), so diff --git a/tools/setup-gcp/README.md b/tools/setup-gcp/README.md index f0c685de76..82fa35866a 100644 --- a/tools/setup-gcp/README.md +++ b/tools/setup-gcp/README.md @@ -254,7 +254,7 @@ project-level IAM permissions. atelet and ate-api authenticate via [GKE Workload Identity Federation](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity): their Kubernetes ServiceAccounts (`ate-system/atelet` and -`ate-system/ate-api-server`, created by `install-ate.sh`) are addressed +`ate-system/ate-api-server`, created by `ate-setup`) are addressed directly as IAM principals. The one Google service account `create iam` creates is the snapshot transfer account⁴, which ate-api-server's credential exchange impersonates and downscopes per actor for every snapshot transfer. diff --git a/tools/setup-gcp/cloud-sql.md b/tools/setup-gcp/cloud-sql.md index e23db311cf..ee8c6302f0 100644 --- a/tools/setup-gcp/cloud-sql.md +++ b/tools/setup-gcp/cloud-sql.md @@ -21,7 +21,7 @@ authentication**](https://docs.cloud.google.com/sql/docs/postgres/iam-authentica - **Cloud-agnostic code** — ateapi itself knows nothing about Cloud SQL. The sidecar is a deployment-time patch (`manifests/ate-install/cloudsql/proxy-sidecar-patch.yaml`) applied by - `hack/install-ate.sh` only when a Cloud SQL instance is configured. + `ate-setup` only when a Cloud SQL instance is configured. ## 1. Provision @@ -163,7 +163,7 @@ Optional environment variables: (default: `max(4, NumCPU)`). It does not affect the owner and watch pools, which are capped at 2 and 3 connections. -Changing the installed configuration rolls ate-api-server: the install script +Changing the installed configuration rolls ate-api-server: ate-setup stamps a hash of the rendered configuration into the pod template (`ate.dev/env-hash`). diff --git a/tools/setup-gcp/cmd/cloudsql.go b/tools/setup-gcp/cmd/cloudsql.go index 7c0ca565a1..8e8e43fac3 100644 --- a/tools/setup-gcp/cmd/cloudsql.go +++ b/tools/setup-gcp/cmd/cloudsql.go @@ -35,7 +35,7 @@ import ( ) // The ateapi store database and the Kubernetes identity that connects to it. -// These match the atepg store (hack/install-ate.sh) and the ate-api-server +// These match the atepg store (ate-setup) and the ate-api-server // deployment. const ( cloudSQLDatabase = "atepg" @@ -196,7 +196,7 @@ func cloudSQLInstanceSpec(cfg *Config) (*sqladmin.DatabaseInstance, error) { settings := &sqladmin.Settings{ Tier: cfg.CloudSQLTier, // This tool provisions private-services-access instances exclusively. - // The ATE_API_POSTGRES_CLOUDSQL_IP_TYPE setting in install-ate.sh exists + // The ATE_API_POSTGRES_CLOUDSQL_IP_TYPE setting in ate-setup exists // only to connect to public/PSC instances provisioned out-of-band. IpConfiguration: &sqladmin.IpConfiguration{ Ipv4Enabled: false, @@ -396,7 +396,7 @@ Cloud SQL is provisioned. Two steps remain: export ATE_API_POSTGRES_CLOUDSQL_INSTANCE=%s:%s:%s export ATE_API_POSTGRES_CLOUDSQL_GSA=%s - ./hack/install-ate.sh --deploy-ate-system --credential-provider='{"name":"k8s.io"}' + go run ./cmd/ate-setup deploy ate-system --credential-provider='{"name":"k8s.io"}' See tools/setup-gcp/cloud-sql.md for details and verification steps. `, cfg.ProjectID, cfg.Region, cfg.CloudSQLInstance, gsa) diff --git a/tools/setup-gcp/cmd/cloudsql_test.go b/tools/setup-gcp/cmd/cloudsql_test.go index 5b9a52594b..84040a7f6e 100644 --- a/tools/setup-gcp/cmd/cloudsql_test.go +++ b/tools/setup-gcp/cmd/cloudsql_test.go @@ -34,7 +34,7 @@ func TestCloudSQLIdentityDerivations(t *testing.T) { } // The IAM database username is the GSA email without the // .gserviceaccount.com suffix — this must match what operators GRANT to - // and what install-ate.sh synthesizes into the DSN. + // and what ate-setup synthesizes into the DSN. if got, want := cloudSQLDatabaseUser(cloudSQLGSAEmail(cfg)), "ate-api-server@my-proj.iam"; got != want { t.Errorf("cloudSQLDatabaseUser() = %q, want %q", got, want) } From 5c577d52a45f425fca4839494fb515b78bb2f701 Mon Sep 17 00:00:00 2001 From: Haven Xia Date: Wed, 28 Oct 2026 10:34:30 -0700 Subject: [PATCH 2/2] Make the demo READMEs independent of kind and GKE Signed-off-by: Haven Xia --- README.md | 8 ++++-- demos/claude-code-multiplex/README.md | 9 +++---- demos/counter/README.md | 11 +++++--- demos/egress/README.md | 27 +++++++------------ demos/egress/test-egress.sh | 7 ++++- demos/jupyter/README.md | 38 +++++---------------------- demos/multi-template/README.md | 4 +-- demos/parking/README.md | 8 +++--- demos/sandbox/README.md | 4 +-- 9 files changed, 45 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index c692069798..18d3fb512f 100644 --- a/README.md +++ b/README.md @@ -118,12 +118,16 @@ To quickly set up the complete environment: # create cluster and local registry hack/create-kind-cluster.sh +# make ate-setup target the kind cluster; set this in every shell that runs +# ate-setup, including for the demo walkthroughs +export ATE_INSTALL_KIND=true + # install Substrate -go run ./cmd/ate-setup --kind deploy ate-system --credential-provider='{"name":"k8s.io"}' \ +go run ./cmd/ate-setup deploy ate-system --credential-provider='{"name":"k8s.io"}' \ --ingress-allowed-spiffe-ids=spiffe://cluster.local/ns/ate-system/sa/atenet-client # install counter demo -go run ./cmd/ate-setup --kind deploy demo counter +go run ./cmd/ate-setup deploy demo counter # install kubectl-ate go install ./cmd/kubectl-ate diff --git a/demos/claude-code-multiplex/README.md b/demos/claude-code-multiplex/README.md index 2669a379ca..6c9598b5ad 100644 --- a/demos/claude-code-multiplex/README.md +++ b/demos/claude-code-multiplex/README.md @@ -26,7 +26,8 @@ This guide assumes you know Kubernetes and the general shape of agent runtimes ( ## Prerequisites -- A Kubernetes cluster with **Agent Substrate** installed. +- A k8s cluster with Agent Substrate installed as in the [Quickstart](../../README.md#quickstart-development) + (with `ATE_INSTALL_KIND=true` exported in your shell) or [GKE Quickstart](../../README.md#gke-quickstart-development). - `kubectl` configured against that cluster (the dashboard uses the operator's kubeconfig via [`client-go`](https://github.com/kubernetes/client-go) for pod-log reads). - Network reach to the substrate **api** gRPC service (`api.ate-system:443`). If you run the dashboard as a pod in the cluster, label its namespace `ate.dev/api-access=true`, because ate-system's NetworkPolicies admit API clients only from labeled namespaces (see [`ate-system-networkpolicies.yaml`](../../manifests/ate-install/ate-system-networkpolicies.yaml)). When running the dashboard from outside the cluster, port-forward it in a separate terminal (same convention as [`demos/sandbox/README.md`](../sandbox/README.md#3-port-forward-services)) and keep it running for the lifetime of the demo: ```bash @@ -34,8 +35,7 @@ This guide assumes you know Kubernetes and the general shape of agent runtimes ( kubectl port-forward svc/api 8080:443 -n ate-system ``` - An **Anthropic API key** (the agents call Claude). -- A GCS bucket for substrate state snapshots (configured during Substrate install). -- `KO_DOCKER_REPO` set to a registry you can push to (e.g. `gcr.io/${PROJECT_ID}/ate-images`, same as `hack/ate-dev-env.sh.example`). The deploy step builds and pushes the workload image there with a sha256-pinned reference. +- The snapshot bucket and image registry (`BUCKET_NAME`, `KO_DOCKER_REPO`) that your Substrate install uses. The deploy step builds and pushes the workload image to that registry with a sha256-pinned reference. - `docker buildx` (the deploy function builds the workload image — a Dockerfile-based Python + Claude Code wrapper, not a Go binary, so `ko` doesn't apply for the workload itself). ## Components @@ -52,11 +52,10 @@ This guide assumes you know Kubernetes and the general shape of agent runtimes ( ### 1. Deploy the demo -From the repo root, with your Anthropic key and substrate bucket name in the environment: +From the repo root, with your Anthropic key in the environment: ```bash ANTHROPIC_API_KEY=sk-ant-... \ -BUCKET_NAME=your-substrate-bucket \ go run ./cmd/ate-setup deploy demo claude-code-multiplex ``` diff --git a/demos/counter/README.md b/demos/counter/README.md index 712a0b0f1f..604b75dbe5 100644 --- a/demos/counter/README.md +++ b/demos/counter/README.md @@ -9,12 +9,14 @@ The demo uses two kinds of resources: the `WorkerPool` is a Kubernetes CRD, whil ## Prerequisites - A k8s cluster with Agent Substrate installed as in the [Quickstart](../../README.md#quickstart-development) - or [GKE Quickstart](../../README.md#gke-quickstart-development). -- `ko` installed for building images. -- A GCS bucket for storing snapshots (configured via `BUCKET_NAME` env var). + (with `ATE_INSTALL_KIND=true` exported in your shell) or [GKE Quickstart](../../README.md#gke-quickstart-development). ## How to Run on Agent Substrate +The [Quickstart](../../README.md#quickstart-development) already deploys this +demo, creates `my-counter-1` and starts its proxy on port `8000`. If you ran +it, skip to [How to Use](#how-to-use). + ### 1. Build and Deploy > [!NOTE] @@ -209,7 +211,8 @@ kubectl ate delete actor my-counter-1 -a ate-demo-counter `counter.go` also listens on a second, configurable port (`--extra-port=9090` in this demo's template) to demonstrate atenet-router's arbitrary-port ingress support. Pass `[local-port:]remote-port` arguments to `kubectl ate proxy actor` -to forward additional ports: +to forward additional ports. This proxy also takes port `8000`, so stop the +earlier one (such as the Quickstart's) first:
Non standard port with MicroVM diff --git a/demos/egress/README.md b/demos/egress/README.md index 381dc05def..98cb7809c5 100644 --- a/demos/egress/README.md +++ b/demos/egress/README.md @@ -53,18 +53,11 @@ intercepted and carried over mTLS to a gateway that verifies who is making the r ## Choose a dataplane -The dataplane is selected when installing `ate-system`, not when installing this demo. The Actor, -ActorTemplate, worker pool, test, and manual walkthrough are otherwise the same. - -```bash -# Envoy (default) -go run ./cmd/ate-setup --kind deploy ate-system --credential-provider='{"name":"k8s.io"}' \ - --ingress-allowed-spiffe-ids=spiffe://cluster.local/ns/ate-system/sa/atenet-client - -# agentgateway -go run ./cmd/ate-setup --kind deploy ate-system --atenet-dataplane=agentgateway --credential-provider='{"name":"k8s.io"}' \ - --ingress-allowed-spiffe-ids=spiffe://cluster.local/ns/ate-system/sa/atenet-client -``` +The dataplane is selected when installing `ate-system`, not when installing this demo. Install as +in the [Quickstart](../../README.md#quickstart-development) or +[GKE Quickstart](../../README.md#gke-quickstart-development); for agentgateway, add +`--atenet-dataplane=agentgateway` to `deploy ate-system`. The Actor, ActorTemplate, worker pool, +test, and manual walkthrough are otherwise the same. | | Envoy | agentgateway | | --- | --- | --- | @@ -99,15 +92,15 @@ rejects that option with agentgateway rather than silently omitting it. ## Prerequisites -- A kind cluster with Agent Substrate installed (`hack/create-kind-cluster.sh`, followed by one of - the [dataplane installation commands above](#choose-a-dataplane)). Egress is enabled by the - ateapi flag above. -- `ko`, `kubectl`, and `kubectl-ate` (`go install ./cmd/kubectl-ate`). +- A k8s cluster with Agent Substrate installed as in the [Quickstart](../../README.md#quickstart-development) + (with `ATE_INSTALL_KIND=true` exported in your shell) or [GKE Quickstart](../../README.md#gke-quickstart-development), with the dataplane + [chosen above](#choose-a-dataplane). Egress is enabled by the ateapi flag above. +- `kubectl` and `kubectl-ate` (`go install ./cmd/kubectl-ate`). ## Deploy the demo fixture ```bash -go run ./cmd/ate-setup --kind deploy demo egress +go run ./cmd/ate-setup deploy demo egress ``` The install applies the worker pool, creates the `ate-demo-egress` atespace and diff --git a/demos/egress/test-egress.sh b/demos/egress/test-egress.sh index 061289684e..d88e6169cd 100755 --- a/demos/egress/test-egress.sh +++ b/demos/egress/test-egress.sh @@ -33,7 +33,12 @@ set -o errexit -o nounset -o pipefail -CTX="${KUBECTL_CONTEXT:-kind-kind}" +# Target the cluster ate-setup deploys to: KUBECTL_CONTEXT, else the kind +# cluster when ATE_INSTALL_KIND=true, else the current context. +if [[ -z "${KUBECTL_CONTEXT:-}" && "${ATE_INSTALL_KIND:-}" == "true" ]]; then + KUBECTL_CONTEXT="kind-${KIND_CLUSTER_NAME:-kind}" +fi +CTX="${KUBECTL_CONTEXT:-$(kubectl config current-context)}" # The actor lives in the demo's atespace: --template resolves the # template by name within the actor's own atespace. ATESPACE="${ATESPACE:-ate-demo-egress}" diff --git a/demos/jupyter/README.md b/demos/jupyter/README.md index da6cd8fe87..2fdd7f5faf 100644 --- a/demos/jupyter/README.md +++ b/demos/jupyter/README.md @@ -4,33 +4,14 @@ This demo runs a Jupyter Notebook on Agent Substrate. It demonstrates how standa ## Prerequisites -- A local Kubernetes cluster via Kind (or GKE). -- `ko` installed for building images. -- A GCS bucket for storing snapshots, or an in-cluster snapshot repository (handled automatically by `ate-setup --kind`). +- A k8s cluster with Agent Substrate installed as in the [Quickstart](../../README.md#quickstart-development) + (with `ATE_INSTALL_KIND=true` exported in your shell) or [GKE Quickstart](../../README.md#gke-quickstart-development). -## Quickstart on Kind +## Deploy the Jupyter Notebook Demo -For local development, Agent Substrate provides helper scripts to get a Kind cluster running and configured. - -1. **Create the Kind cluster:** - - ```bash - ./hack/create-kind-cluster.sh - # This will create a local cluster named "ate-demo" and configure a local registry. - ``` - -2. **Install Agent Substrate core system to the Kind cluster:** - - ```bash - go run ./cmd/ate-setup --kind deploy ate-system --credential-provider='{"name":"k8s.io"}' \ - --ingress-allowed-spiffe-ids=spiffe://cluster.local/ns/ate-system/sa/atenet-client - ``` - -3. **Deploy the Jupyter Notebook Demo:** - - ```bash - go run ./cmd/ate-setup --kind deploy demo jupyter - ``` +```bash +go run ./cmd/ate-setup deploy demo jupyter +``` ## Creating and Accessing Your Jupyter Actor @@ -99,10 +80,5 @@ Or, even easier, you can rely on "transparent resume" — just refresh the page Uninstall the demo deployment — this deletes the demo's actors, the actor template, and the `ate-demo-jupyter` atespace: ```bash -go run ./cmd/ate-setup --kind delete demo jupyter -``` - -Uninstall the entire local Kind cluster: -```bash -./hack/delete-kind-cluster.sh +go run ./cmd/ate-setup delete demo jupyter ``` diff --git a/demos/multi-template/README.md b/demos/multi-template/README.md index 6fee8feba5..e92057b743 100644 --- a/demos/multi-template/README.md +++ b/demos/multi-template/README.md @@ -10,9 +10,7 @@ or namespace. ## Prerequisites - A k8s cluster with Agent Substrate installed as in the [Quickstart](../../README.md#quickstart-development) - or [GKE Quickstart](../../README.md#gke-quickstart-development). -- `ko` installed for building images. -- A GCS bucket for storing snapshots (configured via `BUCKET_NAME` env var). + (with `ATE_INSTALL_KIND=true` exported in your shell) or [GKE Quickstart](../../README.md#gke-quickstart-development). ## How to Run on Agent Substrate diff --git a/demos/parking/README.md b/demos/parking/README.md index fc0aa5c6b4..74b5c26487 100644 --- a/demos/parking/README.md +++ b/demos/parking/README.md @@ -14,17 +14,15 @@ See [docs/request-parking.md](../../docs/request-parking.md) for the design. ## Prerequisites - A k8s cluster with Agent Substrate installed as in the [Quickstart](../../README.md#quickstart-development) - or [GKE Quickstart](../../README.md#gke-quickstart-development). -- `ko` installed for building images. -- A GCS bucket for storing snapshots (configured via `BUCKET_NAME` env var). + (with `ATE_INSTALL_KIND=true` exported in your shell) or [GKE Quickstart](../../README.md#gke-quickstart-development). ## How to Run on Agent Substrate ### 1. Build and Deploy > [!NOTE] -> Do not manually edit the `demos/parking/*.yaml.tmpl` manifests. The installation -> script automatically injects your `${BUCKET_NAME}` environment variable during +> Do not manually edit the `demos/parking/*.yaml.tmpl` manifests. `ate-setup` +> automatically injects your `${BUCKET_NAME}` environment variable during > deployment. ```bash diff --git a/demos/sandbox/README.md b/demos/sandbox/README.md index a7635e3646..b4d87af47c 100644 --- a/demos/sandbox/README.md +++ b/demos/sandbox/README.md @@ -15,9 +15,7 @@ It allows you to run arbitrary commands in an sandboxed, isolated container (run ## Prerequisites - A k8s cluster with Agent Substrate installed as in the [Quickstart](../../README.md#quickstart-development) - or [GKE Quickstart](../../README.md#gke-quickstart-development). -- `ko` installed for building images. -- A GCS bucket for storing snapshots (configured in `demos/sandbox/sandbox-template.yaml.tmpl`). + (with `ATE_INSTALL_KIND=true` exported in your shell) or [GKE Quickstart](../../README.md#gke-quickstart-development). - `kubectl-ate` CLI installed (can be installed via `go install ./cmd/kubectl-ate`). ## How to Run on Agent Substrate