Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/clis/nvcf-cli/cmd/self_hosted_compute_plane.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func runSelfHostedComputePlaneInstall(c *cobra.Command, _ []string) error {
Stdout: c.OutOrStdout(),
Stderr: c.ErrOrStderr(),
Ctx: c.Context(),
ExtraEnv: computePlaneInstallEnv(clusterName, ncaID),
ExtraEnv: computePlaneInstallEnv(clusterName, ncaID, filepath.Dir(valuesPath)),
Comment thread
coderabbitai[bot] marked this conversation as resolved.
})
}

Expand Down Expand Up @@ -234,10 +234,14 @@ func inferClusterNameFromValuesPath(path string) string {
return ""
}

func computePlaneInstallEnv(clusterName, ncaID string) []string {
func computePlaneInstallEnv(clusterName, ncaID, outputDir string) []string {
return []string{
"CLUSTER_NAME=" + clusterName,
"NCA_ID=" + ncaID,
// The worker helmfile resolves the registration values at
// $OUTPUT_DIR/$CLUSTER_NAME-register-values.yaml via requiredEnv, so
// point it at the directory holding the --values file.
"OUTPUT_DIR=" + outputDir,
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/clis/nvcf-cli/cmd/self_hosted_compute_plane_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ func TestComputePlaneInstallTemplatesUserValuesFile(t *testing.T) {
assert.Contains(t, out, "arg=--kube-context=gpu-context")
assert.Contains(t, out, "env:CLUSTER_NAME=gpu-from-values")
assert.Contains(t, out, "env:NCA_ID=nca-from-values")
// The worker helmfile reads $OUTPUT_DIR/$CLUSTER_NAME-register-values.yaml,
// so install must point OUTPUT_DIR at the directory of --values.
assert.Contains(t, out, "env:OUTPUT_DIR="+filepath.Dir(valuesFile))
assert.Contains(t, out, "arg="+stackDir)
assert.FileExists(t, fakeBin)
}
Expand Down Expand Up @@ -928,6 +931,7 @@ done
printf 'verb=%s\n' "$last"
printf 'env:CLUSTER_NAME=%s\n' "$CLUSTER_NAME"
printf 'env:NCA_ID=%s\n' "$NCA_ID"
printf 'env:OUTPUT_DIR=%s\n' "$OUTPUT_DIR"
`
require.NoError(t, os.WriteFile(fakeBin, []byte(body), 0o755))
t.Setenv("PATH", filepath.Dir(fakeBin)+":"+os.Getenv("PATH"))
Expand Down
4 changes: 4 additions & 0 deletions src/clis/nvcf-cli/cmd/self_hosted_down.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ func runDownComputePlaneForCluster(c *cobra.Command, ctx context.Context, sink p
extra := []string{
"CLUSTER_NAME=" + clusterName,
"NCA_ID=" + downNCAID,
// The worker helmfile also requires OUTPUT_DIR to resolve
// $OUTPUT_DIR/$CLUSTER_NAME-register-values.yaml, the same
// directory readRegisterValuesYAML reads from below.
"OUTPUT_DIR=" + filepath.Join(resolved.Path, "out"),
}
unregisterClusterID := clusterName
if rv, err := readRegisterValuesYAML(resolved.Path, clusterName); err == nil {
Expand Down
5 changes: 4 additions & 1 deletion src/clis/nvcf-cli/cmd/self_hosted_down_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ func installFakeHelmfile(t *testing.T) string {
logPath := filepath.Join(dir, "helmfile.log")
binPath := filepath.Join(dir, "helmfile")
script := `#!/bin/sh
printf '%s\n' "$PWD|$*|CLUSTER_NAME=${CLUSTER_NAME}" >> "$NVCF_TEST_HELMFILE_LOG"
printf '%s\n' "$PWD|$*|CLUSTER_NAME=${CLUSTER_NAME}|OUTPUT_DIR=${OUTPUT_DIR}" >> "$NVCF_TEST_HELMFILE_LOG"
`
require.NoError(t, os.WriteFile(binPath, []byte(script), 0o755))
t.Setenv("NVCF_TEST_HELMFILE_LOG", logPath)
Expand Down Expand Up @@ -348,6 +348,9 @@ func TestDown_ClusterNameCleansControlPlaneWhenLastClusterRemoved(t *testing.T)
require.Len(t, invocations, 2, "last cluster removal must destroy compute and control planes")
assert.Contains(t, invocations[0], filepath.Join(computePlaneStack, "helmfile.d")+"/")
assert.Contains(t, invocations[0], "CLUSTER_NAME=test-cluster")
// The worker helmfile reads $OUTPUT_DIR/$CLUSTER_NAME-register-values.yaml
// at render time, so destroy must export it like install does.
assert.Contains(t, invocations[0], "OUTPUT_DIR="+filepath.Join(computePlaneStack, "out"))
assert.Contains(t, invocations[1], filepath.Join(controlPlaneStack, "helmfile.d")+"/")
assert.Contains(t, invocations[1], "--sequential-helmfiles")
}
Expand Down
22 changes: 22 additions & 0 deletions tests/bdd/features/multi-cluster-up.feature
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,28 @@ Feature: Bring up a local multi-cluster NVCF stack with the CLI
# teardown.
And I copy the file "deploy/stacks/self-managed/secrets/secrets.yaml.template" to "deploy/stacks/self-managed/secrets/local-secrets.yaml"
And I substitute "REPLACE_WITH_BASE64_DOCKER_CREDENTIAL" in file "deploy/stacks/self-managed/secrets/local-secrets.yaml" with base64 of "$oauthtoken:${NGC_API_KEY}"
# --env local also reads operator-authored environment values from
# both split stacks: deploy/stacks/<stack>/environments/local.yaml.
# Neither file is tracked, so author both from the BDD multi-cluster
# fixtures (they carry the alias-service URL shape the split
# topology needs). observability.profile is disabled because this
# workflow runs 'helmfile apply', whose diff phase validates
# rendered manifests against the live cluster (--dry-run=server);
# on a fresh cluster the ServiceMonitor CRDs do not exist yet and
# the diff fails before anything installs. The Helmfile workflow
# (helmfile sync) has no diff phase and keeps the default profile.
And I copy the file "tests/bdd/fixtures/self-managed-local-bdd-multi.yaml" to "deploy/stacks/self-managed/environments/local.yaml"
And I update yaml file "deploy/stacks/self-managed/environments/local.yaml" with keys:
| global.imagePullSecrets[0].name | nvcr-pull-secret |
| global.helm.sources.repository | ${SAMPLE_NGC_ORG}/${SAMPLE_NGC_TEAM} |
| global.image.repository | ${SAMPLE_NGC_ORG}/${SAMPLE_NGC_TEAM} |
| observability.profile | disabled |
And I copy the file "tests/bdd/fixtures/nvcf-compute-plane-local-bdd-multi.yaml" to "deploy/stacks/nvcf-compute-plane/environments/local.yaml"
And I update yaml file "deploy/stacks/nvcf-compute-plane/environments/local.yaml" with keys:
| global.imagePullSecrets[0].name | nvcr-pull-secret |
| global.helm.sources.repository | ${SAMPLE_NGC_ORG}/${SAMPLE_NGC_TEAM} |
| global.image.repository | ${SAMPLE_NGC_ORG}/${SAMPLE_NGC_TEAM} |
| observability.profile | disabled |
# Conflict precheck: single-cluster ncp-local's k3d serverlb
# claims 0.0.0.0:8080/8443/10081, and ncp-local-cp also
# needs NATS on 4222 plus the worker callback port 10086.
Expand Down
21 changes: 21 additions & 0 deletions tests/bdd/features/single-cluster-up.feature
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,27 @@ Feature: Bring up a local single-cluster NVCF stack with the CLI
# teardown, so the working tree stays clean.
And I copy the file "deploy/stacks/self-managed/secrets/secrets.yaml.template" to "deploy/stacks/self-managed/secrets/local-secrets.yaml"
And I substitute "REPLACE_WITH_BASE64_DOCKER_CREDENTIAL" in file "deploy/stacks/self-managed/secrets/local-secrets.yaml" with base64 of "$oauthtoken:${NGC_API_KEY}"
# --env local also reads operator-authored environment values from
# both split stacks: deploy/stacks/<stack>/environments/local.yaml.
# Neither file is tracked, so author both from the BDD fixtures.
# observability.profile is disabled because this workflow runs
# 'helmfile apply', whose diff phase validates rendered manifests
# against the live cluster (--dry-run=server); on a fresh cluster
# the ServiceMonitor CRDs do not exist yet and the diff fails
# before anything installs. The Helmfile workflow (helmfile sync)
# has no diff phase and keeps the default profile.
And I copy the file "tests/bdd/fixtures/self-managed-local-bdd.yaml" to "deploy/stacks/self-managed/environments/local.yaml"
And I update yaml file "deploy/stacks/self-managed/environments/local.yaml" with keys:
| global.imagePullSecrets[0].name | nvcr-pull-secret |
| global.helm.sources.repository | ${SAMPLE_NGC_ORG}/${SAMPLE_NGC_TEAM} |
| global.image.repository | ${SAMPLE_NGC_ORG}/${SAMPLE_NGC_TEAM} |
| observability.profile | disabled |
And I copy the file "tests/bdd/fixtures/nvcf-compute-plane-local-bdd.yaml" to "deploy/stacks/nvcf-compute-plane/environments/local.yaml"
And I update yaml file "deploy/stacks/nvcf-compute-plane/environments/local.yaml" with keys:
| global.imagePullSecrets[0].name | nvcr-pull-secret |
| global.helm.sources.repository | ${SAMPLE_NGC_ORG}/${SAMPLE_NGC_TEAM} |
| global.image.repository | ${SAMPLE_NGC_ORG}/${SAMPLE_NGC_TEAM} |
| observability.profile | disabled |
# Conflict precheck: ncp-local-cp's k3d serverlb claims
# 0.0.0.0:8080/8443/10081, NATS on 4222, and the worker
# callback port 10086, overlapping host ports single-cluster
Expand Down
2 changes: 1 addition & 1 deletion tests/bdd/fixtures/nvcf-cli-local.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: Apache-2.0

base_http_url: "http://api.localhost:8080"
base_grpc_url: "localhost:10081"
base_grpc_url: "grpc.localhost:10081"
invoke_url: "http://invocation.localhost:8080"
api_keys_service_url: "http://api-keys.localhost:8080"
icms_url: "http://sis.localhost:8080"
Expand Down
2 changes: 1 addition & 1 deletion tests/bdd/fixtures_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ func TestNVCFCLILocalFixtureTargetsLocalGRPCGateway(t *testing.T) {
if err := yaml.Unmarshal(fixtureBytes, &fixture); err != nil {
t.Fatalf("parse local CLI fixture: %v", err)
}
if got, want := fixture["base_grpc_url"], "localhost:10081"; got != want {
if got, want := fixture["base_grpc_url"], "grpc.localhost:10081"; got != want {
t.Fatalf("base_grpc_url = %v, want %q", got, want)
}
}
Expand Down
4 changes: 4 additions & 0 deletions tests/bdd/godog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,8 @@ func TestSingleClusterUpFeatureFileWiresToSteps(t *testing.T) {
writeProfileHandoffArtifact(t, suite.Config.RepoRoot)
writeSingleClusterComputeRegisterValues(t, suite.Config.RepoRoot)
seedStackSecretsTemplate(t, suite.Config.RepoRoot)
seedHelmfileLocalBDDFixture(t, suite.Config.RepoRoot)
seedComputePlaneLocalBDDFixture(t, suite.Config.RepoRoot)

sc := steps.NewScenarioContext(suite)
featurePath := mustResolveFeaturePath(t, "single-cluster-up.feature")
Expand Down Expand Up @@ -361,6 +363,8 @@ func TestMultiClusterUpFeatureFileWiresToSteps(t *testing.T) {
writeMulticlusterProfileHandoffArtifact(t, suite.Config.RepoRoot)
writeMulticlusterComputeRegisterValues(t, suite.Config.RepoRoot, "nvcf-compute-plane", "ncp-local-compute-1")
seedStackSecretsTemplate(t, suite.Config.RepoRoot)
seedHelmfileLocalBDDMultiFixture(t, suite.Config.RepoRoot)
seedComputePlaneLocalBDDMultiFixture(t, suite.Config.RepoRoot)

sc := steps.NewScenarioContext(suite)
featurePath := mustResolveFeaturePath(t, "multi-cluster-up.feature")
Expand Down
Loading