container-superposition 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -15
- package/dist/scripts/init.js +1 -1534
- package/dist/scripts/init.js.map +1 -1
- package/dist/tool/cli/args.d.ts +20 -0
- package/dist/tool/cli/args.d.ts.map +1 -0
- package/dist/tool/cli/args.js +325 -0
- package/dist/tool/cli/args.js.map +1 -0
- package/dist/tool/cli/run.d.ts +2 -0
- package/dist/tool/cli/run.d.ts.map +1 -0
- package/dist/tool/cli/run.js +318 -0
- package/dist/tool/cli/run.js.map +1 -0
- package/dist/tool/commands/adopt.d.ts.map +1 -1
- package/dist/tool/commands/adopt.js +1 -27
- package/dist/tool/commands/adopt.js.map +1 -1
- package/dist/tool/commands/doctor.d.ts +3 -0
- package/dist/tool/commands/doctor.d.ts.map +1 -1
- package/dist/tool/commands/doctor.js +1068 -70
- package/dist/tool/commands/doctor.js.map +1 -1
- package/dist/tool/commands/explain.d.ts.map +1 -1
- package/dist/tool/commands/explain.js +18 -0
- package/dist/tool/commands/explain.js.map +1 -1
- package/dist/tool/commands/migrate.d.ts +7 -0
- package/dist/tool/commands/migrate.d.ts.map +1 -0
- package/dist/tool/commands/migrate.js +52 -0
- package/dist/tool/commands/migrate.js.map +1 -0
- package/dist/tool/questionnaire/answers.d.ts +16 -0
- package/dist/tool/questionnaire/answers.d.ts.map +1 -0
- package/dist/tool/questionnaire/answers.js +102 -0
- package/dist/tool/questionnaire/answers.js.map +1 -0
- package/dist/tool/questionnaire/composer.d.ts +3 -3
- package/dist/tool/questionnaire/composer.d.ts.map +1 -1
- package/dist/tool/questionnaire/composer.js +902 -37
- package/dist/tool/questionnaire/composer.js.map +1 -1
- package/dist/tool/questionnaire/presets.d.ts +60 -0
- package/dist/tool/questionnaire/presets.d.ts.map +1 -0
- package/dist/tool/questionnaire/presets.js +164 -0
- package/dist/tool/questionnaire/presets.js.map +1 -0
- package/dist/tool/questionnaire/questionnaire.d.ts +10 -0
- package/dist/tool/questionnaire/questionnaire.d.ts.map +1 -0
- package/dist/tool/questionnaire/questionnaire.js +580 -0
- package/dist/tool/questionnaire/questionnaire.js.map +1 -0
- package/dist/tool/schema/manifest-migrations.d.ts +5 -0
- package/dist/tool/schema/manifest-migrations.d.ts.map +1 -1
- package/dist/tool/schema/manifest-migrations.js +45 -0
- package/dist/tool/schema/manifest-migrations.js.map +1 -1
- package/dist/tool/schema/overlay-loader.d.ts.map +1 -1
- package/dist/tool/schema/overlay-loader.js +25 -0
- package/dist/tool/schema/overlay-loader.js.map +1 -1
- package/dist/tool/schema/project-config.d.ts +14 -2
- package/dist/tool/schema/project-config.d.ts.map +1 -1
- package/dist/tool/schema/project-config.js +277 -34
- package/dist/tool/schema/project-config.js.map +1 -1
- package/dist/tool/schema/target-rules.d.ts +78 -0
- package/dist/tool/schema/target-rules.d.ts.map +1 -0
- package/dist/tool/schema/target-rules.js +367 -0
- package/dist/tool/schema/target-rules.js.map +1 -0
- package/dist/tool/schema/types.d.ts +123 -12
- package/dist/tool/schema/types.d.ts.map +1 -1
- package/dist/tool/utils/merge.d.ts.map +1 -1
- package/dist/tool/utils/merge.js +9 -0
- package/dist/tool/utils/merge.js.map +1 -1
- package/dist/tool/utils/parameters.d.ts +76 -0
- package/dist/tool/utils/parameters.d.ts.map +1 -0
- package/dist/tool/utils/parameters.js +125 -0
- package/dist/tool/utils/parameters.js.map +1 -0
- package/dist/tool/utils/paths.d.ts +2 -0
- package/dist/tool/utils/paths.d.ts.map +1 -0
- package/dist/tool/utils/paths.js +31 -0
- package/dist/tool/utils/paths.js.map +1 -0
- package/docs/creating-overlays.md +151 -2
- package/docs/deployment-targets.md +88 -56
- package/docs/examples.md +20 -17
- package/docs/filesystem-contract.md +5 -0
- package/docs/minimal-and-editor.md +65 -5
- package/docs/overlay-imports.md +202 -101
- package/docs/overlays.md +162 -34
- package/docs/quick-reference.md +99 -0
- package/docs/specs/003-mkdocs2-overlay/spec.md +114 -0
- package/docs/specs/004-doctor-fix/spec.md +70 -0
- package/docs/specs/005-cuda-overlay/spec.md +101 -0
- package/docs/specs/006-rocm-overlay/spec.md +109 -0
- package/docs/specs/007-init-project-file/spec.md +66 -0
- package/docs/specs/007-target-aware-generation/spec.md +126 -0
- package/docs/specs/008-project-file-canonical/spec.md +83 -0
- package/docs/specs/009-project-env/spec.md +147 -0
- package/docs/specs/010-compose-env-materialization/spec.md +130 -0
- package/docs/specs/011-overlay-parameters/spec.md +235 -0
- package/overlays/.shared/README.md +105 -21
- package/overlays/.shared/compose/common-healthchecks.md +60 -0
- package/overlays/.shared/compose/nvidia-gpu-devcontainer.yml +22 -0
- package/overlays/.shared/vscode/recommended-extensions.json +15 -11
- package/overlays/alertmanager/setup.sh +4 -19
- package/overlays/alertmanager/verify.sh +8 -9
- package/overlays/all/README.md +43 -0
- package/overlays/all/devcontainer.patch.json +6 -0
- package/overlays/all/overlay.yml +14 -0
- package/overlays/amp/setup.sh +5 -0
- package/overlays/bun/setup.sh +10 -1
- package/overlays/bun/verify.sh +6 -1
- package/overlays/claude-code/setup.sh +5 -0
- package/overlays/cloudflared/setup.sh +9 -12
- package/overlays/codex/README.md +9 -6
- package/overlays/codex/devcontainer.patch.json +7 -1
- package/overlays/codex/setup.sh +5 -0
- package/overlays/codex/verify.sh +8 -0
- package/overlays/comfyui/.env.example +34 -0
- package/overlays/comfyui/README.md +342 -0
- package/overlays/comfyui/devcontainer.patch.json +15 -0
- package/overlays/comfyui/docker-compose.yml +39 -0
- package/overlays/comfyui/overlay.yml +20 -0
- package/overlays/comfyui/setup.sh +36 -0
- package/overlays/comfyui/verify.sh +103 -0
- package/overlays/commitlint/setup.sh +5 -0
- package/overlays/cuda/README.md +179 -0
- package/overlays/cuda/devcontainer.patch.json +7 -0
- package/overlays/cuda/overlay.yml +17 -0
- package/overlays/cuda/setup.sh +32 -0
- package/overlays/cuda/verify.sh +38 -0
- package/overlays/devcontainer-cli/README.md +50 -0
- package/overlays/devcontainer-cli/devcontainer.patch.json +13 -0
- package/overlays/devcontainer-cli/overlay.yml +16 -0
- package/overlays/devcontainer-cli/setup.sh +14 -0
- package/overlays/direnv/devcontainer.patch.json +6 -0
- package/overlays/direnv/setup.sh +7 -6
- package/overlays/dotnet/setup.sh +14 -7
- package/overlays/duckdb/devcontainer.patch.json +1 -2
- package/overlays/gcloud/devcontainer.patch.json +0 -6
- package/overlays/gcloud/setup.sh +51 -0
- package/overlays/gemini-cli/setup.sh +5 -0
- package/overlays/git-helpers/devcontainer.patch.json +2 -1
- package/overlays/go/setup.sh +15 -14
- package/overlays/jaeger/overlay.yml +2 -0
- package/overlays/just/setup.sh +5 -17
- package/overlays/k3d/README.md +201 -0
- package/overlays/k3d/devcontainer.patch.json +9 -0
- package/overlays/k3d/overlay.yml +19 -0
- package/overlays/k3d/setup.sh +34 -0
- package/overlays/k3d/verify.sh +38 -0
- package/overlays/keycloak/docker-compose.yml +6 -4
- package/overlays/keycloak/verify.sh +4 -3
- package/overlays/kind/devcontainer.patch.json +1 -2
- package/overlays/kind/setup.sh +8 -17
- package/overlays/minio/setup.sh +10 -18
- package/overlays/mkdocs/overlay.yml +2 -1
- package/overlays/mkdocs2/README.md +135 -0
- package/overlays/mkdocs2/devcontainer.patch.json +19 -0
- package/overlays/mkdocs2/overlay.yml +17 -0
- package/overlays/mkdocs2/setup.sh +67 -0
- package/overlays/mkdocs2/verify.sh +35 -0
- package/overlays/modern-cli-tools/devcontainer.patch.json +7 -1
- package/overlays/modern-cli-tools/setup.sh +21 -71
- package/overlays/mongodb/devcontainer.patch.json +0 -6
- package/overlays/mongodb/setup.sh +59 -0
- package/overlays/mysql/verify.sh +4 -3
- package/overlays/nats/.env.example +1 -1
- package/overlays/nats/README.md +1 -1
- package/overlays/nats/docker-compose.yml +1 -1
- package/overlays/ngrok/setup.sh +9 -6
- package/overlays/nodejs/setup.sh +5 -0
- package/overlays/ollama/.env.example +14 -0
- package/overlays/ollama/README.md +325 -0
- package/overlays/ollama/devcontainer.patch.json +14 -0
- package/overlays/ollama/docker-compose.yml +24 -0
- package/overlays/ollama/overlay.yml +22 -0
- package/overlays/ollama/setup.sh +106 -0
- package/overlays/ollama/verify.sh +99 -0
- package/overlays/open-webui/.env.example +5 -0
- package/overlays/open-webui/README.md +162 -0
- package/overlays/open-webui/devcontainer.patch.json +14 -0
- package/overlays/open-webui/docker-compose.yml +23 -0
- package/overlays/open-webui/overlay.yml +38 -0
- package/overlays/openapi-tools/devcontainer.patch.json +1 -2
- package/overlays/openapi-tools/setup.sh +9 -8
- package/overlays/opencode/setup.sh +5 -0
- package/overlays/otel-collector/overlay.yml +2 -0
- package/overlays/otel-collector/setup.sh +3 -16
- package/overlays/otel-demo-nodejs/verify.sh +8 -9
- package/overlays/otel-demo-python/verify.sh +16 -10
- package/overlays/pandoc/README.md +22 -15
- package/overlays/pandoc/devcontainer.patch.json +6 -2
- package/overlays/pandoc/setup.sh +217 -18
- package/overlays/pandoc/verify.sh +16 -4
- package/overlays/pgvector/.env.example +6 -0
- package/overlays/pgvector/README.md +215 -0
- package/overlays/pgvector/devcontainer.patch.json +23 -0
- package/overlays/pgvector/docker-compose.yml +32 -0
- package/overlays/pgvector/overlay.yml +44 -0
- package/overlays/playwright/devcontainer.patch.json +3 -1
- package/overlays/playwright/setup.sh +37 -0
- package/overlays/postgres/.env.example +5 -5
- package/overlays/postgres/devcontainer.patch.json +4 -4
- package/overlays/postgres/docker-compose.yml +15 -5
- package/overlays/postgres/overlay.yml +19 -1
- package/overlays/powershell/setup.sh +49 -13
- package/overlays/pre-commit/setup.sh +12 -3
- package/overlays/prometheus/overlay.yml +2 -0
- package/overlays/promtail/verify.sh +16 -10
- package/overlays/pulumi/devcontainer.patch.json +1 -1
- package/overlays/python/setup.sh +28 -9
- package/overlays/python/verify.sh +4 -2
- package/overlays/qdrant/.env.example +4 -0
- package/overlays/qdrant/README.md +216 -0
- package/overlays/qdrant/devcontainer.patch.json +20 -0
- package/overlays/qdrant/docker-compose.yml +25 -0
- package/overlays/qdrant/overlay.yml +40 -0
- package/overlays/redpanda/docker-compose.yml +3 -5
- package/overlays/rocm/README.md +227 -0
- package/overlays/rocm/devcontainer.patch.json +4 -0
- package/overlays/rocm/overlay.yml +17 -0
- package/overlays/rocm/setup.sh +45 -0
- package/overlays/rocm/verify.sh +47 -0
- package/overlays/rust/setup.sh +11 -18
- package/overlays/skaffold/README.md +256 -0
- package/overlays/skaffold/devcontainer.patch.json +9 -0
- package/overlays/skaffold/overlay.yml +20 -0
- package/overlays/skaffold/setup.sh +33 -0
- package/overlays/skaffold/verify.sh +24 -0
- package/overlays/spec-kit/setup.sh +7 -3
- package/overlays/sqlite/setup.sh +14 -14
- package/overlays/sqlserver/docker-compose.yml +3 -3
- package/overlays/sqlserver/verify.sh +22 -5
- package/overlays/tempo/verify.sh +16 -10
- package/overlays/tilt/devcontainer.patch.json +1 -2
- package/overlays/tilt/setup.sh +14 -4
- package/overlays/windsurf-cli/setup.sh +27 -4
- package/overlays/windsurf-cli/verify.sh +13 -3
- package/package.json +4 -2
- package/templates/scripts/setup-utils.sh +228 -0
- package/tool/schema/config.schema.json +141 -9
- package/tool/schema/overlay-manifest.schema.json +38 -0
- package/overlays/.shared/compose/common-healthchecks.yml +0 -38
- /package/overlays/otel-demo-nodejs/{Dockerfile-otel-demo-nodejs → Dockerfile} +0 -0
- /package/overlays/otel-demo-nodejs/{package-otel-demo-nodejs.json → package.json} +0 -0
- /package/overlays/otel-demo-nodejs/{server-otel-demo-nodejs.js → server.js} +0 -0
- /package/overlays/otel-demo-nodejs/{tracing-otel-demo-nodejs.js → tracing.js} +0 -0
- /package/overlays/otel-demo-python/{Dockerfile-otel-demo-python → Dockerfile} +0 -0
- /package/overlays/otel-demo-python/{app-otel-demo-python.py → app.py} +0 -0
- /package/overlays/otel-demo-python/{requirements-otel-demo-python.txt → requirements.txt} +0 -0
package/overlays/dotnet/setup.sh
CHANGED
|
@@ -3,6 +3,15 @@
|
|
|
3
3
|
|
|
4
4
|
set -e
|
|
5
5
|
|
|
6
|
+
# Source shared setup utilities (provides run_spinner)
|
|
7
|
+
# shellcheck source=setup-utils.sh
|
|
8
|
+
source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
|
|
9
|
+
|
|
10
|
+
# Suppress the .NET SDK first-run welcome banner and telemetry noise
|
|
11
|
+
export DOTNET_NOLOGO=1
|
|
12
|
+
export DOTNET_CLI_TELEMETRY_OPTOUT=1
|
|
13
|
+
export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
|
|
14
|
+
|
|
6
15
|
# Extract overlay name from script filename (setup-<overlay>.sh -> <overlay>)
|
|
7
16
|
OVERLAY_NAME=$(basename "$0" | sed 's/setup-//;s/\.sh$//')
|
|
8
17
|
|
|
@@ -21,20 +30,18 @@ if [ -f ".devcontainer/global-tools-${OVERLAY_NAME}.txt" ]; then
|
|
|
21
30
|
if [[ "$line" =~ ^(.+)::(.+)$ ]]; then
|
|
22
31
|
tool="${BASH_REMATCH[1]}"
|
|
23
32
|
version="${BASH_REMATCH[2]}"
|
|
24
|
-
|
|
25
|
-
dotnet tool install --global "$tool" --version "$version" || echo " ⚠️ $tool already installed or failed"
|
|
33
|
+
run_spinner "$tool@$version" dotnet tool install --global "$tool" --version "$version" || true
|
|
26
34
|
else
|
|
27
35
|
tool="$line"
|
|
28
|
-
|
|
29
|
-
dotnet tool install --global "$tool" || echo " ⚠️ $tool already installed or failed"
|
|
36
|
+
run_spinner "$tool" dotnet tool install --global "$tool" || true
|
|
30
37
|
fi
|
|
31
38
|
done < ".devcontainer/global-tools-${OVERLAY_NAME}.txt"
|
|
32
39
|
else
|
|
33
40
|
# Fallback to hardcoded list
|
|
34
41
|
echo "📦 Installing default .NET global tools..."
|
|
35
|
-
dotnet tool install --global dotnet-ef ||
|
|
36
|
-
dotnet tool install --global dotnet-format ||
|
|
37
|
-
dotnet tool install --global dotnet-outdated-tool ||
|
|
42
|
+
run_spinner "dotnet-ef" dotnet tool install --global dotnet-ef || true
|
|
43
|
+
run_spinner "dotnet-format" dotnet tool install --global dotnet-format || true
|
|
44
|
+
run_spinner "dotnet-outdated-tool" dotnet tool install --global dotnet-outdated-tool || true
|
|
38
45
|
fi
|
|
39
46
|
|
|
40
47
|
# Verify installations
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
|
|
3
|
-
"features": {
|
|
4
|
-
"ghcr.io/devcontainers/features/google-cloud-cli:1": {
|
|
5
|
-
"version": "latest",
|
|
6
|
-
"installGkeGcloudAuthPlugin": true
|
|
7
|
-
}
|
|
8
|
-
},
|
|
9
3
|
"customizations": {
|
|
10
4
|
"vscode": {
|
|
11
5
|
"extensions": ["googlecloudtools.cloudcode"]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Google Cloud CLI setup script
|
|
3
|
+
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
echo "☁️ Setting up Google Cloud CLI..."
|
|
7
|
+
|
|
8
|
+
# Source shared setup utilities
|
|
9
|
+
# shellcheck source=setup-utils.sh
|
|
10
|
+
source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
|
|
11
|
+
|
|
12
|
+
if command -v apk >/dev/null 2>&1; then
|
|
13
|
+
# Alpine Linux — no official gcloud apt repo; install via tarball
|
|
14
|
+
apk add --no-cache python3 curl
|
|
15
|
+
curl -sSL https://sdk.cloud.google.com | CLOUDSDK_CORE_DISABLE_PROMPTS=1 bash -s -- --disable-prompts --install-dir=/usr/local
|
|
16
|
+
ln -sf /usr/local/google-cloud-sdk/bin/gcloud /usr/local/bin/gcloud
|
|
17
|
+
ln -sf /usr/local/google-cloud-sdk/bin/gsutil /usr/local/bin/gsutil
|
|
18
|
+
elif command -v apt-get >/dev/null 2>&1; then
|
|
19
|
+
# Debian/Ubuntu — add Google Cloud apt repo using modern signed-by method
|
|
20
|
+
# The Google Cloud key is already in binary (non-armored) format — write directly.
|
|
21
|
+
sudo mkdir -p /usr/share/keyrings /etc/apt/sources.list.d
|
|
22
|
+
curl -fsSL "https://packages.cloud.google.com/apt/doc/apt-key.gpg" \
|
|
23
|
+
| sudo tee /usr/share/keyrings/cloud.google.gpg >/dev/null
|
|
24
|
+
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" \
|
|
25
|
+
| sudo tee /etc/apt/sources.list.d/google-cloud-sdk.list >/dev/null
|
|
26
|
+
|
|
27
|
+
# Single lock acquisition: install prereqs + add repo + install gcloud in one pass
|
|
28
|
+
acquire_apt_lock
|
|
29
|
+
# Pass env vars explicitly — sudo strips them by default.
|
|
30
|
+
sudo DEBIAN_FRONTEND=noninteractive TERM=dumb apt-get update -qq
|
|
31
|
+
sudo DEBIAN_FRONTEND=noninteractive TERM=dumb apt-get install -y -qq --no-install-recommends apt-transport-https ca-certificates gnupg curl
|
|
32
|
+
# apt index already fresh — install gcloud packages without a second apt-get update
|
|
33
|
+
sudo DEBIAN_FRONTEND=noninteractive TERM=dumb apt-get install -y -qq --no-install-recommends \
|
|
34
|
+
google-cloud-cli \
|
|
35
|
+
google-cloud-cli-gke-gcloud-auth-plugin
|
|
36
|
+
sudo apt-get clean
|
|
37
|
+
sudo rm -rf /var/lib/apt/lists/*
|
|
38
|
+
release_apt_lock
|
|
39
|
+
else
|
|
40
|
+
echo "⚠️ Unsupported package manager, skipping gcloud installation"
|
|
41
|
+
exit 0
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
if command -v gcloud >/dev/null 2>&1; then
|
|
45
|
+
echo "✓ gcloud installed: $(gcloud --version | head -1)"
|
|
46
|
+
else
|
|
47
|
+
echo "✗ gcloud installation failed"
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
echo "✓ gcloud setup complete"
|
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
set -e
|
|
5
5
|
|
|
6
|
+
# Source shared setup utilities (provides load_nvm)
|
|
7
|
+
# shellcheck source=setup-utils.sh
|
|
8
|
+
source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
|
|
9
|
+
load_nvm
|
|
10
|
+
|
|
6
11
|
echo "📦 Installing Google Gemini CLI..."
|
|
7
12
|
|
|
8
13
|
# Install @google/gemini-cli globally
|
package/overlays/go/setup.sh
CHANGED
|
@@ -3,25 +3,26 @@
|
|
|
3
3
|
|
|
4
4
|
set -e
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
# Source shared setup utilities
|
|
7
|
+
# shellcheck source=setup-utils.sh
|
|
8
|
+
source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
echo "🔧 Setting up Go development environment..."
|
|
9
11
|
echo "📦 Installing Go development tools..."
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
go install
|
|
13
|
-
|
|
14
|
-
# delve (Debugger)
|
|
15
|
-
go install github.com/go-delve/delve/cmd/dlv@latest || echo "⚠️ delve installation failed"
|
|
13
|
+
run_spinner "gopls (language server)" go install golang.org/x/tools/gopls@latest
|
|
14
|
+
run_spinner "delve (debugger)" go install github.com/go-delve/delve/cmd/dlv@latest
|
|
16
15
|
|
|
17
|
-
# golangci-lint
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
# golangci-lint — use official installer to avoid gold linker issues on arm64
|
|
17
|
+
if ! command -v golangci-lint &>/dev/null; then
|
|
18
|
+
run_spinner "golangci-lint" \
|
|
19
|
+
bash -c 'curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "$(go env GOPATH)/bin"'
|
|
20
|
+
else
|
|
21
|
+
echo " ℹ️ golangci-lint already installed: $(golangci-lint version --short 2>/dev/null || true)"
|
|
22
|
+
fi
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
go install honnef.co/go/tools/cmd/staticcheck@latest
|
|
24
|
+
run_spinner "gofumpt (formatter)" go install mvdan.cc/gofumpt@latest
|
|
25
|
+
run_spinner "staticcheck (analyzer)" go install honnef.co/go/tools/cmd/staticcheck@latest
|
|
25
26
|
|
|
26
27
|
# Install project dependencies if go.mod exists
|
|
27
28
|
if [ -f "go.mod" ]; then
|
package/overlays/just/setup.sh
CHANGED
|
@@ -9,31 +9,19 @@ echo "⚡ Setting up just task runner..."
|
|
|
9
9
|
JUST_VERSION="1.25.2"
|
|
10
10
|
ARCH=$(uname -m)
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
if [ "$ARCH" = "x86_64" ]; then
|
|
14
|
-
ARCH="x86_64"
|
|
15
|
-
CHECKSUM="6804798c3744fd1ce563840ee9fe14ae53c74b3cc7b8536da3f87751d7f85501"
|
|
16
|
-
elif [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
|
|
12
|
+
if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
|
|
17
13
|
ARCH="aarch64"
|
|
18
|
-
|
|
14
|
+
elif [ "$ARCH" = "x86_64" ]; then
|
|
15
|
+
ARCH="x86_64"
|
|
19
16
|
else
|
|
20
|
-
echo "⚠️ Unsupported architecture: $ARCH"
|
|
17
|
+
echo "⚠️ Unsupported architecture: $ARCH, falling back to x86_64"
|
|
21
18
|
ARCH="x86_64"
|
|
22
|
-
CHECKSUM="6804798c3744fd1ce563840ee9fe14ae53c74b3cc7b8536da3f87751d7f85501"
|
|
23
19
|
fi
|
|
24
20
|
|
|
25
21
|
echo "📦 Downloading just v${JUST_VERSION} for ${ARCH}..."
|
|
26
|
-
curl -
|
|
22
|
+
curl -fsSL "https://github.com/casey/just/releases/download/${JUST_VERSION}/just-${JUST_VERSION}-${ARCH}-unknown-linux-musl.tar.gz" \
|
|
27
23
|
-o /tmp/just.tar.gz
|
|
28
24
|
|
|
29
|
-
# Verify checksum
|
|
30
|
-
echo "🔐 Verifying checksum..."
|
|
31
|
-
echo "${CHECKSUM} /tmp/just.tar.gz" | sha256sum -c - || {
|
|
32
|
-
echo "✗ Checksum verification failed"
|
|
33
|
-
rm /tmp/just.tar.gz
|
|
34
|
-
exit 1
|
|
35
|
-
}
|
|
36
|
-
|
|
37
25
|
# Extract and install
|
|
38
26
|
tar -xzf /tmp/just.tar.gz -C /tmp
|
|
39
27
|
sudo mv /tmp/just /usr/local/bin/
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# k3d Overlay
|
|
2
|
+
|
|
3
|
+
Installs [k3d](https://k3d.io), a lightweight wrapper that runs [k3s](https://k3s.io) (Rancher's minimal Kubernetes distribution) in Docker containers, enabling fast local Kubernetes clusters for development.
|
|
4
|
+
|
|
5
|
+
> **Note:** This overlay conflicts with `kind` because both tools create local Kubernetes clusters using Docker containers. Choose `k3d` for faster startup and lower resource usage, or `kind` for full Kubernetes conformance.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **k3d CLI** — Create, manage, and delete local k3s clusters from the terminal
|
|
10
|
+
- **Fast cluster startup** — Clusters spin up in seconds, compared to heavier alternatives
|
|
11
|
+
- **Low resource usage** — k3s has a smaller memory and CPU footprint than full Kubernetes
|
|
12
|
+
- **Multi-node clusters** — Simulate multi-node topologies with server and agent nodes
|
|
13
|
+
- **Load balancer included** — Built-in k3s service load balancer for `LoadBalancer` services
|
|
14
|
+
- **Port and volume mapping** — Map host ports and directories into the cluster easily
|
|
15
|
+
|
|
16
|
+
## How It Works
|
|
17
|
+
|
|
18
|
+
k3d is installed as a static binary in the devcontainer during `setup.sh`. It requires Docker (provided by the `docker-in-docker` dependency) to create k3s nodes as Docker containers.
|
|
19
|
+
|
|
20
|
+
**Dependencies:**
|
|
21
|
+
|
|
22
|
+
- `docker-in-docker` (required) — Provides the Docker daemon that k3d uses to launch k3s nodes
|
|
23
|
+
|
|
24
|
+
**Suggested overlays:**
|
|
25
|
+
|
|
26
|
+
- `kubectl-helm` — Kubernetes CLI and Helm for interacting with k3d clusters
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
k3d is installed automatically during devcontainer creation via `setup.sh`:
|
|
31
|
+
|
|
32
|
+
- Downloads the k3d binary for your architecture (amd64/arm64)
|
|
33
|
+
- Installs to `/usr/local/bin/k3d`
|
|
34
|
+
- Verifies Docker access
|
|
35
|
+
|
|
36
|
+
## Common Commands
|
|
37
|
+
|
|
38
|
+
### Cluster Management
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Create a single-node cluster (control plane + agent in one node)
|
|
42
|
+
k3d cluster create dev
|
|
43
|
+
|
|
44
|
+
# Create a cluster with multiple agents
|
|
45
|
+
k3d cluster create dev --agents 2
|
|
46
|
+
|
|
47
|
+
# Create with a specific k3s version
|
|
48
|
+
k3d cluster create dev --image rancher/k3s:v1.30.0-k3s1
|
|
49
|
+
|
|
50
|
+
# Create with port mapping (host 8080 → cluster LoadBalancer 80)
|
|
51
|
+
k3d cluster create dev -p "8080:80@loadbalancer"
|
|
52
|
+
|
|
53
|
+
# List all clusters
|
|
54
|
+
k3d cluster list
|
|
55
|
+
|
|
56
|
+
# Start/stop a cluster
|
|
57
|
+
k3d cluster start dev
|
|
58
|
+
k3d cluster stop dev
|
|
59
|
+
|
|
60
|
+
# Delete a cluster
|
|
61
|
+
k3d cluster delete dev
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Working with Clusters
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Merge k3d kubeconfig into default kubeconfig
|
|
68
|
+
k3d kubeconfig merge dev --kubeconfig-merge-default
|
|
69
|
+
|
|
70
|
+
# Get kubeconfig for a specific cluster
|
|
71
|
+
k3d kubeconfig get dev
|
|
72
|
+
|
|
73
|
+
# Import a Docker image into the cluster (avoids registry push/pull)
|
|
74
|
+
docker build -t myapp:dev .
|
|
75
|
+
k3d image import myapp:dev --cluster dev
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### kubectl Integration
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Use kubectl with the k3d cluster
|
|
82
|
+
kubectl cluster-info --context k3d-dev
|
|
83
|
+
|
|
84
|
+
# Deploy a workload
|
|
85
|
+
kubectl create deployment nginx --image=nginx
|
|
86
|
+
kubectl expose deployment nginx --port=80 --type=LoadBalancer
|
|
87
|
+
|
|
88
|
+
# Port-forward for direct access
|
|
89
|
+
kubectl port-forward service/nginx 8080:80
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Configuration
|
|
93
|
+
|
|
94
|
+
### Multi-Node Cluster
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
k3d cluster create dev \
|
|
98
|
+
--servers 1 \
|
|
99
|
+
--agents 3 \
|
|
100
|
+
--k3s-arg "--disable=traefik@server:*"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Volume Mounts
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Mount a local directory into all nodes
|
|
107
|
+
k3d cluster create dev \
|
|
108
|
+
--volume "${PWD}:/app@all"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Port Mapping
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Expose ports 80 and 443 through the cluster load balancer
|
|
115
|
+
k3d cluster create dev \
|
|
116
|
+
-p "80:80@loadbalancer" \
|
|
117
|
+
-p "443:443@loadbalancer"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Benefits vs kind
|
|
121
|
+
|
|
122
|
+
| Feature | k3d (this overlay) | kind |
|
|
123
|
+
| --------------------- | --------------------------- | ---------------------------- |
|
|
124
|
+
| **Distribution** | k3s (lightweight variant) | ✅ Full Kubernetes |
|
|
125
|
+
| **Startup speed** | ✅ Faster (~15–30 s) | Moderate (~30–60 s) |
|
|
126
|
+
| **Resource usage** | ✅ Lower (~256 MB RAM/node) | Higher (~512 MB+ RAM/node) |
|
|
127
|
+
| **Conformance** | High (not 100%) | ✅ 100% CNCF conformant |
|
|
128
|
+
| **Port mapping** | ✅ Built-in load balancer | Manual NodePort/port-forward |
|
|
129
|
+
| **Production parity** | Sufficient for most apps | ✅ Identical to production |
|
|
130
|
+
|
|
131
|
+
**Choose k3d when:**
|
|
132
|
+
|
|
133
|
+
- Fast iteration cycles are more important than 100% conformance
|
|
134
|
+
- System resources are limited
|
|
135
|
+
- You want built-in load balancer for easy port mapping
|
|
136
|
+
|
|
137
|
+
**Choose kind when:**
|
|
138
|
+
|
|
139
|
+
- You need guaranteed Kubernetes API compatibility
|
|
140
|
+
- Developing Kubernetes operators or controllers
|
|
141
|
+
- Testing for production environments
|
|
142
|
+
|
|
143
|
+
## Use Cases
|
|
144
|
+
|
|
145
|
+
- **Rapid Kubernetes development** — Fast cluster creation and teardown for iterative development
|
|
146
|
+
- **Helm chart testing** — Deploy and test Helm charts locally before pushing
|
|
147
|
+
- **CI/CD prototyping** — Simulate cluster deployments in low-resource environments
|
|
148
|
+
- **Multi-node testing** — Test workloads across multiple nodes on a single machine
|
|
149
|
+
- **Learning Kubernetes** — Explore Kubernetes concepts with minimal overhead
|
|
150
|
+
|
|
151
|
+
**Integrates well with:**
|
|
152
|
+
|
|
153
|
+
- `kubectl-helm` — Kubernetes CLI and Helm package manager
|
|
154
|
+
- `tilt` — Live reload for Kubernetes workloads
|
|
155
|
+
- `skaffold` — Build/deploy automation for Kubernetes
|
|
156
|
+
- `terraform` — IaC for cluster configuration
|
|
157
|
+
|
|
158
|
+
## Troubleshooting
|
|
159
|
+
|
|
160
|
+
### Cluster Creation Fails
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
# Ensure Docker daemon is running
|
|
164
|
+
docker info
|
|
165
|
+
|
|
166
|
+
# Check Docker has sufficient resources
|
|
167
|
+
docker system df
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### `kubectl` Cannot Connect
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
# Ensure kubeconfig is merged
|
|
174
|
+
k3d kubeconfig merge dev --kubeconfig-merge-default
|
|
175
|
+
|
|
176
|
+
# Verify cluster is running
|
|
177
|
+
k3d cluster list
|
|
178
|
+
kubectl cluster-info --context k3d-dev
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Image Not Found in Cluster
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# Import local images directly (avoids registry round-trip)
|
|
185
|
+
k3d image import myapp:latest --cluster dev
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## References
|
|
189
|
+
|
|
190
|
+
- [k3d Documentation](https://k3d.io)
|
|
191
|
+
- [k3d GitHub](https://github.com/k3d-io/k3d)
|
|
192
|
+
- [k3s Documentation](https://docs.k3s.io)
|
|
193
|
+
- [Kubernetes Documentation](https://kubernetes.io/docs/)
|
|
194
|
+
|
|
195
|
+
**Related Overlays:**
|
|
196
|
+
|
|
197
|
+
- `docker-in-docker` — Required: provides the Docker daemon for k3d
|
|
198
|
+
- [`kubectl-helm`](../kubectl-helm/README.md) — Kubernetes CLI and Helm
|
|
199
|
+
- [`kind`](../kind/README.md) — Full-conformance K8s alternative (conflicts)
|
|
200
|
+
- [`tilt`](../tilt/README.md) — Live reload for Kubernetes development
|
|
201
|
+
- [`skaffold`](../skaffold/README.md) — K8s build and deploy automation
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
id: k3d
|
|
2
|
+
name: k3d
|
|
3
|
+
description: Lightweight local Kubernetes clusters using k3s in Docker
|
|
4
|
+
category: cloud
|
|
5
|
+
supports: []
|
|
6
|
+
requires:
|
|
7
|
+
- docker-in-docker
|
|
8
|
+
suggests:
|
|
9
|
+
- kubectl-helm
|
|
10
|
+
conflicts:
|
|
11
|
+
- kind
|
|
12
|
+
tags:
|
|
13
|
+
- cloud
|
|
14
|
+
- kubernetes
|
|
15
|
+
- k8s
|
|
16
|
+
- k3d
|
|
17
|
+
- k3s
|
|
18
|
+
- testing
|
|
19
|
+
ports: []
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Setup script for k3d
|
|
3
|
+
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
echo "🔧 Setting up k3d..."
|
|
7
|
+
|
|
8
|
+
# Source shared setup utilities
|
|
9
|
+
# shellcheck source=setup-utils.sh
|
|
10
|
+
source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
|
|
11
|
+
|
|
12
|
+
detect_arch
|
|
13
|
+
|
|
14
|
+
# Install k3d
|
|
15
|
+
K3D_VERSION="${K3D_VERSION:-v5.7.4}"
|
|
16
|
+
echo "📦 Installing k3d ${K3D_VERSION}..."
|
|
17
|
+
|
|
18
|
+
install_binary \
|
|
19
|
+
"https://github.com/k3d-io/k3d/releases/download/${K3D_VERSION}/k3d-linux-${CS_ARCH}" \
|
|
20
|
+
"k3d"
|
|
21
|
+
|
|
22
|
+
# Verify installation
|
|
23
|
+
if command -v k3d &>/dev/null; then
|
|
24
|
+
echo "✅ k3d installed successfully"
|
|
25
|
+
k3d version
|
|
26
|
+
else
|
|
27
|
+
echo "❌ k3d installation failed"
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
echo "✅ k3d setup complete"
|
|
32
|
+
echo ""
|
|
33
|
+
echo "ℹ️ To create a cluster, run:"
|
|
34
|
+
echo " k3d cluster create dev"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Verification script for k3d overlay
|
|
3
|
+
# Confirms k3d is installed
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
echo "🔍 Verifying k3d overlay..."
|
|
8
|
+
echo ""
|
|
9
|
+
|
|
10
|
+
# Check k3d is installed
|
|
11
|
+
echo "1️⃣ Checking k3d installation..."
|
|
12
|
+
if command -v k3d &>/dev/null; then
|
|
13
|
+
k3d version
|
|
14
|
+
echo " ✅ k3d is installed"
|
|
15
|
+
else
|
|
16
|
+
echo " ❌ k3d is not installed"
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# Check Docker is available (required for k3d)
|
|
21
|
+
echo ""
|
|
22
|
+
echo "2️⃣ Checking Docker availability..."
|
|
23
|
+
if ! command -v docker &>/dev/null; then
|
|
24
|
+
echo " ❌ Docker CLI not found"
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
if docker version --format '{{.Server.Version}}' &>/dev/null; then
|
|
28
|
+
echo " ✅ Docker is available"
|
|
29
|
+
else
|
|
30
|
+
echo " ❌ Docker daemon not accessible"
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
echo ""
|
|
35
|
+
echo "✅ k3d overlay verification complete"
|
|
36
|
+
echo ""
|
|
37
|
+
echo "ℹ️ To create a cluster, run:"
|
|
38
|
+
echo " k3d cluster create dev"
|
|
@@ -15,18 +15,20 @@ services:
|
|
|
15
15
|
KC_HTTP_PORT: 8180
|
|
16
16
|
KC_HOSTNAME_STRICT: 'false'
|
|
17
17
|
KC_HTTP_ENABLED: 'true'
|
|
18
|
+
KC_HEALTH_ENABLED: 'true'
|
|
18
19
|
ports:
|
|
19
20
|
- '${KEYCLOAK_PORT:-8180}:8180'
|
|
20
21
|
depends_on:
|
|
21
|
-
|
|
22
|
+
postgres:
|
|
23
|
+
condition: service_healthy
|
|
22
24
|
networks:
|
|
23
25
|
- devnet
|
|
24
26
|
healthcheck:
|
|
25
|
-
test: ['CMD-SHELL', 'curl -sf http://localhost:
|
|
27
|
+
test: ['CMD-SHELL', 'curl -sf http://localhost:9000/health/ready || exit 1']
|
|
26
28
|
interval: 15s
|
|
27
29
|
timeout: 10s
|
|
28
|
-
retries:
|
|
29
|
-
start_period:
|
|
30
|
+
retries: 15
|
|
31
|
+
start_period: 90s
|
|
30
32
|
|
|
31
33
|
networks:
|
|
32
34
|
devnet:
|
|
@@ -20,10 +20,11 @@ echo ""
|
|
|
20
20
|
echo "2️⃣ Checking Keycloak service..."
|
|
21
21
|
KEYCLOAK_HOST="${KEYCLOAK_HOST:-keycloak}"
|
|
22
22
|
KEYCLOAK_PORT="${KEYCLOAK_PORT:-8180}"
|
|
23
|
+
KEYCLOAK_MGMT_PORT="${KEYCLOAK_MGMT_PORT:-9000}"
|
|
23
24
|
KEYCLOAK_READY=false
|
|
24
25
|
|
|
25
|
-
for i in {1..
|
|
26
|
-
if curl -sf "http://${KEYCLOAK_HOST}:${
|
|
26
|
+
for i in {1..80}; do
|
|
27
|
+
if curl -sf "http://${KEYCLOAK_HOST}:${KEYCLOAK_MGMT_PORT}/health/ready" &> /dev/null; then
|
|
27
28
|
echo " ✅ Keycloak service is ready"
|
|
28
29
|
KEYCLOAK_READY=true
|
|
29
30
|
break
|
|
@@ -32,7 +33,7 @@ for i in {1..40}; do
|
|
|
32
33
|
done
|
|
33
34
|
|
|
34
35
|
if [ "$KEYCLOAK_READY" = false ]; then
|
|
35
|
-
echo " ❌ Keycloak service not ready after
|
|
36
|
+
echo " ❌ Keycloak service not ready after 4 minutes"
|
|
36
37
|
echo " ℹ️ Keycloak can take a while to start on first run"
|
|
37
38
|
exit 1
|
|
38
39
|
fi
|
package/overlays/kind/setup.sh
CHANGED
|
@@ -5,28 +5,19 @@ set -e
|
|
|
5
5
|
|
|
6
6
|
echo "🔧 Setting up kind (Kubernetes in Docker)..."
|
|
7
7
|
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
;;
|
|
14
|
-
aarch64|arm64)
|
|
15
|
-
KIND_ARCH="arm64"
|
|
16
|
-
;;
|
|
17
|
-
*)
|
|
18
|
-
echo "❌ Unsupported architecture: $ARCH"
|
|
19
|
-
exit 1
|
|
20
|
-
;;
|
|
21
|
-
esac
|
|
8
|
+
# Source shared setup utilities
|
|
9
|
+
# shellcheck source=setup-utils.sh
|
|
10
|
+
source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
|
|
11
|
+
|
|
12
|
+
detect_arch
|
|
22
13
|
|
|
23
14
|
# Install kind
|
|
24
15
|
KIND_VERSION="${KIND_VERSION:-v0.22.0}"
|
|
25
16
|
echo "📦 Installing kind ${KIND_VERSION}..."
|
|
26
17
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
18
|
+
install_binary \
|
|
19
|
+
"https://kind.sigs.k8s.io/dl/${KIND_VERSION}/kind-linux-${CS_ARCH}" \
|
|
20
|
+
"kind"
|
|
30
21
|
|
|
31
22
|
# Verify installation
|
|
32
23
|
if command -v kind &> /dev/null; then
|
package/overlays/minio/setup.sh
CHANGED
|
@@ -7,25 +7,17 @@ echo "🔧 Setting up MinIO client..."
|
|
|
7
7
|
|
|
8
8
|
# Install MinIO client (mc)
|
|
9
9
|
echo "📦 Installing MinIO client (mc)..."
|
|
10
|
+
# Source shared setup utilities
|
|
11
|
+
# shellcheck source=setup-utils.sh
|
|
12
|
+
source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
|
|
13
|
+
|
|
10
14
|
if ! command -v mc &> /dev/null; then
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
wget -q "${MC_URL}" -O /tmp/mc
|
|
18
|
-
|
|
19
|
-
# Verify checksum
|
|
20
|
-
echo " Verifying checksum..."
|
|
21
|
-
echo "${MC_CHECKSUM} /tmp/mc" | sha256sum -c - || {
|
|
22
|
-
echo " ❌ Checksum verification failed!"
|
|
23
|
-
rm -f /tmp/mc
|
|
24
|
-
exit 1
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
sudo install /tmp/mc /usr/local/bin/
|
|
28
|
-
rm /tmp/mc
|
|
15
|
+
MC_VERSION="${MC_VERSION:-RELEASE.2024-11-17T19-35-25Z}"
|
|
16
|
+
detect_arch
|
|
17
|
+
echo " Downloading MinIO client version ${MC_VERSION} for ${CS_ARCH}..."
|
|
18
|
+
install_binary \
|
|
19
|
+
"https://dl.min.io/client/mc/release/linux-${CS_ARCH}/archive/mc.${MC_VERSION}" \
|
|
20
|
+
"mc"
|
|
29
21
|
echo " ✅ MinIO client installed (${MC_VERSION})"
|
|
30
22
|
else
|
|
31
23
|
echo " ✅ MinIO client already installed"
|