├── .gitignore ├── .github ├── workflows │ ├── .gitignore │ ├── release.yaml │ └── test.yaml └── dependabot.yml ├── src ├── act │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ └── install.sh ├── k6 │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ └── install.sh ├── aztfy │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ └── install.sh ├── mizu │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ └── install.sh ├── stern │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ └── install.sh ├── flyctl │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ └── install.sh ├── opa │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ └── install.sh ├── oras │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ └── install.sh ├── tfsec │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ └── install.sh ├── trivy │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ └── install.sh ├── hadolint │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ └── install.sh ├── conftest │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ └── install.sh ├── terraform-docs │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ └── install.sh ├── terraformer │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ └── install.sh ├── k9s │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ └── install.sh └── google-cloud-cli │ ├── README.md │ ├── devcontainer-feature.json │ └── install.sh ├── .devcontainer.json ├── test ├── k9s │ ├── scenarios.json │ ├── test.sh │ ├── after-0-27-0.sh │ └── before-0-27-0.sh ├── _global │ ├── scenarios.json │ └── all.sh ├── k6 │ └── test.sh ├── act │ └── test.sh ├── opa │ └── test.sh ├── mizu │ └── test.sh ├── oras │ └── test.sh ├── aztfy │ └── test.sh ├── flyctl │ └── test.sh ├── stern │ └── test.sh ├── tfsec │ └── test.sh ├── trivy │ └── test.sh ├── conftest │ └── test.sh ├── hadolint │ └── test.sh ├── google-cloud-cli │ └── test.sh ├── terraformer │ └── test.sh └── terraform-docs │ └── test.sh ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | output/ 2 | -------------------------------------------------------------------------------- /.github/workflows/.gitignore: -------------------------------------------------------------------------------- 1 | local-*.yaml -------------------------------------------------------------------------------- /src/act/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Reference 2 | 3 | act: https://github.com/nektos/act -------------------------------------------------------------------------------- /src/k6/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Reference 2 | 3 | k6: https://github.com/grafana/k6 -------------------------------------------------------------------------------- /src/aztfy/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Reference 2 | 3 | aztfy: https://github.com/Azure/aztfy -------------------------------------------------------------------------------- /src/mizu/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Reference 2 | 3 | mizu: https://github.com/up9inc/mizu -------------------------------------------------------------------------------- /src/stern/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Reference 2 | 3 | stern: https://github.com/stern/stern -------------------------------------------------------------------------------- /src/flyctl/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Reference 2 | 3 | flyctl: https://github.com/superfly/flyctl -------------------------------------------------------------------------------- /src/opa/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Reference 2 | 3 | opa: https://github.com/open-policy-agent/opa -------------------------------------------------------------------------------- /src/oras/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Reference 2 | 3 | oras: https://github.com/oras-project/oras -------------------------------------------------------------------------------- /src/tfsec/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Reference 2 | 3 | tfsec: https://github.com/aquasecurity/tfsec -------------------------------------------------------------------------------- /src/trivy/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Reference 2 | 3 | trivy: https://github.com/aquasecurity/trivy -------------------------------------------------------------------------------- /src/hadolint/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Reference 2 | 3 | hadolint: https://github.com/hadolint/hadolint -------------------------------------------------------------------------------- /src/conftest/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Reference 2 | 3 | conftest: https://github.com/open-policy-agent/conftest -------------------------------------------------------------------------------- /src/terraform-docs/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Reference 2 | 3 | terraform-docs: https://github.com/terraform-docs/terraform-docs -------------------------------------------------------------------------------- /src/terraformer/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Reference 2 | 3 | terraformer: https://github.com/GoogleCloudPlatform/terraformer 4 | -------------------------------------------------------------------------------- /src/k9s/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Changelog 2 | 3 | ### 1.0.1 4 | - Using amd64 when k9s >=0.27.0 (#14) 5 | 6 | ## Reference 7 | 8 | k9s-cli: https://github.com/derailed/k9s -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Set update schedule for GitHub Actions 2 | # ref: https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot#example-dependabotyml-file-for-github-actions 3 | 4 | version: 2 5 | updates: 6 | 7 | - package-ecosystem: "github-actions" 8 | directory: "/" 9 | schedule: 10 | # Check for updates to GitHub Actions every week 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "mcr.microsoft.com/devcontainers/javascript-node:0-18", 3 | "customizations": { 4 | "vscode": { 5 | "extensions": [ 6 | "mads-hartmann.bash-ide-vscode" 7 | ] 8 | } 9 | }, 10 | "features": { 11 | "ghcr.io/devcontainers/features/docker-in-docker:1": {}, 12 | }, 13 | "remoteUser": "node", 14 | "postCreateCommand": "npm install -g @devcontainers/cli" 15 | } 16 | -------------------------------------------------------------------------------- /test/k9s/scenarios.json: -------------------------------------------------------------------------------- 1 | { 2 | "before-0-27-0": { 3 | "image": "mcr.microsoft.com/devcontainers/base:ubuntu", 4 | "features": { 5 | "k9s": { 6 | "version": "0.26.0" 7 | } 8 | } 9 | }, 10 | "after-0-27-0": { 11 | "image": "mcr.microsoft.com/devcontainers/base:ubuntu", 12 | "features": { 13 | "k9s": { 14 | "version": "0.27.0" 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: "Release dev container features" 2 | on: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | deploy: 7 | if: ${{ github.ref == 'refs/heads/main' }} 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v3 11 | 12 | - name: "Publish Features" 13 | uses: devcontainers/action@v1 14 | with: 15 | publish-features: "true" 16 | base-path-to-features: "./src" 17 | 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | -------------------------------------------------------------------------------- /src/k6/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "k6", 3 | "id": "k6", 4 | "version": "1.0.0", 5 | "description": "Install [k6](https://k6.io/)", 6 | "documentationURL": "https://github.com/dhoeric/features/tree/main/src/k6", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "default": "latest", 11 | "description": "Select or enter a k6 version" 12 | } 13 | }, 14 | "installsAfter": [ 15 | "ghcr.io/devcontainers/features/common-utils" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/k9s/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "k9s-cli", 3 | "id": "k9s", 4 | "version": "1.0.1", 5 | "description": "Install [k9s](https://k9scli.io/)", 6 | "documentationURL": "https://github.com/dhoeric/features/tree/main/src/k9s", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "default": "latest", 11 | "description": "Select or enter k9s version" 12 | } 13 | }, 14 | "installsAfter": [ 15 | "ghcr.io/devcontainers/features/common-utils" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/trivy/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "trivy", 3 | "id": "trivy", 4 | "version": "1.0.0", 5 | "description": "Install [trivy](https://trivy.dev/)", 6 | "documentationURL": "https://github.com/dhoeric/features/tree/main/src/trivy", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "default": "latest", 11 | "description": "Select or enter trivy version" 12 | } 13 | }, 14 | "installsAfter": [ 15 | "ghcr.io/devcontainers/features/common-utils" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/mizu/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mizu", 3 | "id": "mizu", 4 | "version": "1.0.0", 5 | "description": "Install [mizu](https://github.com/up9inc/mizu)", 6 | "documentationURL": "https://github.com/dhoeric/features/tree/main/src/mizu", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "default": "latest", 11 | "description": "Select or enter mizu version" 12 | } 13 | }, 14 | "installsAfter": [ 15 | "ghcr.io/devcontainers/features/common-utils" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/aztfy/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aztfy", 3 | "id": "aztfy", 4 | "version": "1.0.0", 5 | "description": "Install [aztfy](https://github.com/Azure/aztfy)", 6 | "documentationURL": "https://github.com/dhoeric/features/tree/main/src/aztfy", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "default": "latest", 11 | "description": "Select or enter aztfy version" 12 | } 13 | }, 14 | "installsAfter": [ 15 | "ghcr.io/devcontainers/features/common-utils" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/tfsec/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tfsec", 3 | "id": "tfsec", 4 | "version": "1.0.0", 5 | "description": "Install [tfsec](https://aquasecurity.github.io/tfsec/)", 6 | "documentationURL": "https://github.com/dhoeric/features/tree/main/src/tfsec", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "default": "latest", 11 | "description": "Select or enter tfsec version" 12 | } 13 | }, 14 | "installsAfter": [ 15 | "ghcr.io/devcontainers/features/common-utils" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/conftest/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Conftest", 3 | "id": "conftest", 4 | "version": "1.0.0", 5 | "description": "Install [conftest](https://www.conftest.dev/)", 6 | "documentationURL": "https://github.com/dhoeric/features/tree/main/src/conftest", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "default": "latest", 11 | "description": "Select or enter a conftest version" 12 | } 13 | }, 14 | "installsAfter": [ 15 | "ghcr.io/devcontainers/features/common-utils" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/oras/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "oras-cli", 3 | "id": "oras", 4 | "version": "1.0.0", 5 | "description": "Install [oras](https://oras.land/cli/) - OCI Registry As Storage", 6 | "documentationURL": "https://github.com/dhoeric/features/tree/main/src/oras", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "default": "latest", 11 | "description": "Select or enter oras version" 12 | } 13 | }, 14 | "installsAfter": [ 15 | "ghcr.io/devcontainers/features/common-utils" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/act/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "act", 3 | "id": "act", 4 | "version": "1.0.0", 5 | "description": "Install [act](https://github.com/nektos/act) - run github action locally", 6 | "documentationURL": "https://github.com/dhoeric/features/tree/main/src/act", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "default": "latest", 11 | "description": "Select or enter a act version" 12 | } 13 | }, 14 | "installsAfter": [ 15 | "ghcr.io/devcontainers/features/common-utils" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/hadolint/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hadolint", 3 | "id": "hadolint", 4 | "version": "1.0.0", 5 | "description": "Install [hadolint](https://github.com/hadolint/hadolint)", 6 | "documentationURL": "https://github.com/dhoeric/features/tree/main/src/hadolint", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "default": "latest", 11 | "description": "Select or enter a hadolint version" 12 | } 13 | }, 14 | "installsAfter": [ 15 | "ghcr.io/devcontainers/features/common-utils" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/opa/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Open Policy Agent", 3 | "id": "opa", 4 | "version": "1.0.0", 5 | "description": "Install [Open Policy Agent (opa)](https://www.openpolicyagent.org/docs/latest/#running-opa)", 6 | "documentationURL": "https://github.com/dhoeric/features/tree/main/src/opa", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "default": "latest", 11 | "description": "Select or enter an opa version" 12 | } 13 | }, 14 | "installsAfter": [ 15 | "ghcr.io/devcontainers/features/common-utils" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/stern/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stern", 3 | "id": "stern", 4 | "version": "1.0.0", 5 | "description": "Install [stern](https://github.com/stern/stern) - Multi pod and container log tailing for Kubernetes", 6 | "documentationURL": "https://github.com/dhoeric/features/tree/main/src/stern", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "default": "latest", 11 | "description": "Select or enter stern version" 12 | } 13 | }, 14 | "installsAfter": [ 15 | "ghcr.io/devcontainers/features/common-utils" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/terraform-docs/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "terraform-docs", 3 | "id": "terraform-docs", 4 | "version": "1.0.0", 5 | "description": "Install [terraform-docs](https://terraform-docs.io/)", 6 | "documentationURL": "https://github.com/dhoeric/features/tree/main/src/terraform-docs", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "default": "latest", 11 | "description": "Select or enter a terraform-docs version" 12 | } 13 | }, 14 | "installsAfter": [ 15 | "ghcr.io/devcontainers/features/common-utils" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/terraformer/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "terraformer", 3 | "id": "terraformer", 4 | "version": "1.0.0", 5 | "description": "Install [terraformer](https://github.com/GoogleCloudPlatform/terraformer)", 6 | "documentationURL": "https://github.com/dhoeric/features/tree/main/src/terraformer", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "default": "latest", 11 | "description": "Select or enter a terraformer version" 12 | } 13 | }, 14 | "installsAfter": [ 15 | "ghcr.io/devcontainers/features/common-utils" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/flyctl/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Fly.io CLI", 3 | "id": "flyctl", 4 | "version": "1.0.0", 5 | "description": "Install [flyctl](https://github.com/superfly/flyctl) - Command line tools for [fly.io services](https://fly.io/)", 6 | "documentationURL": "https://github.com/dhoeric/features/tree/main/src/flyctl", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "default": "latest", 11 | "description": "Select or enter a flyctl version" 12 | } 13 | }, 14 | "installsAfter": [ 15 | "ghcr.io/devcontainers/features/common-utils" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /src/k6/README.md: -------------------------------------------------------------------------------- 1 | 2 | # k6 (k6) 3 | 4 | Install [k6](https://k6.io/) 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/dhoeric/features/k6:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter a k6 version | string | latest | 19 | 20 | ## Reference 21 | 22 | k6: https://github.com/grafana/k6 23 | 24 | --- 25 | 26 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dhoeric/features/blob/main/src/k6/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 27 | -------------------------------------------------------------------------------- /test/_global/scenarios.json: -------------------------------------------------------------------------------- 1 | { 2 | "all": { 3 | "image": "mcr.microsoft.com/devcontainers/base:ubuntu", 4 | "features": { 5 | "google-cloud-cli": {}, 6 | "opa": {}, 7 | "conftest": {}, 8 | "tfsec": {}, 9 | "trivy": {}, 10 | "act": {}, 11 | "k9s": {}, 12 | "flyctl": {}, 13 | "aztfy": {}, 14 | "terraformer": {}, 15 | "terraform-docs": {}, 16 | "k6": {}, 17 | "hadolint": {}, 18 | "mizu": {}, 19 | "oras": {}, 20 | "stern": {} 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/mizu/README.md: -------------------------------------------------------------------------------- 1 | 2 | # mizu (mizu) 3 | 4 | Install [mizu](https://github.com/up9inc/mizu) 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/dhoeric/features/mizu:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter mizu version | string | latest | 19 | 20 | ## Reference 21 | 22 | mizu: https://github.com/up9inc/mizu 23 | 24 | --- 25 | 26 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dhoeric/features/blob/main/src/mizu/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 27 | -------------------------------------------------------------------------------- /test/k6/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features k6 \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "k6 version" k6 version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /src/trivy/README.md: -------------------------------------------------------------------------------- 1 | 2 | # trivy (trivy) 3 | 4 | Install [trivy](https://trivy.dev/) 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/dhoeric/features/trivy:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter trivy version | string | latest | 19 | 20 | ## Reference 21 | 22 | trivy: https://github.com/aquasecurity/trivy 23 | 24 | --- 25 | 26 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dhoeric/features/blob/main/src/trivy/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 27 | -------------------------------------------------------------------------------- /test/act/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features act \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "act version" act --version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /test/k9s/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features k9s \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "k9s version" k9s version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /test/opa/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features opa \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "opa version" opa version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /src/aztfy/README.md: -------------------------------------------------------------------------------- 1 | 2 | # aztfy (aztfy) 3 | 4 | Install [aztfy](https://github.com/Azure/aztfy) 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/dhoeric/features/aztfy:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter aztfy version | string | latest | 19 | 20 | ## Reference 21 | 22 | aztfy: https://github.com/Azure/aztfy 23 | 24 | --- 25 | 26 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dhoeric/features/blob/main/src/aztfy/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 27 | -------------------------------------------------------------------------------- /test/k9s/after-0-27-0.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features k9s \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "k9s version" k9s version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /test/mizu/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features mizu \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "mizu version" mizu version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /test/oras/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features oras \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "oras version" oras version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /test/aztfy/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features aztfy \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "aztfy version" aztfy --version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /test/flyctl/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features flyctl \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "flyctl version" flyctl version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /test/k9s/before-0-27-0.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features k9s \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "k9s version" k9s version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /test/stern/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features stern \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "stern version" stern --version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /test/tfsec/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features tfsec \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "tfsec version" tfsec --version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /test/trivy/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features trivy \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "trivy version" trivy --version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /src/act/README.md: -------------------------------------------------------------------------------- 1 | 2 | # act (act) 3 | 4 | Install [act](https://github.com/nektos/act) - run github action locally 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/dhoeric/features/act:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter a act version | string | latest | 19 | 20 | ## Reference 21 | 22 | act: https://github.com/nektos/act 23 | 24 | --- 25 | 26 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dhoeric/features/blob/main/src/act/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 27 | -------------------------------------------------------------------------------- /src/tfsec/README.md: -------------------------------------------------------------------------------- 1 | 2 | # tfsec (tfsec) 3 | 4 | Install [tfsec](https://aquasecurity.github.io/tfsec/) 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/dhoeric/features/tfsec:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter tfsec version | string | latest | 19 | 20 | ## Reference 21 | 22 | tfsec: https://github.com/aquasecurity/tfsec 23 | 24 | --- 25 | 26 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dhoeric/features/blob/main/src/tfsec/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 27 | -------------------------------------------------------------------------------- /test/conftest/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features conftest \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "conftest version" conftest --version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /test/hadolint/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features hadolint \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "hadolint version" hadolint --version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /src/oras/README.md: -------------------------------------------------------------------------------- 1 | 2 | # oras-cli (oras) 3 | 4 | Install [oras](https://oras.land/cli/) - OCI Registry As Storage 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/dhoeric/features/oras:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter oras version | string | latest | 19 | 20 | ## Reference 21 | 22 | oras: https://github.com/oras-project/oras 23 | 24 | --- 25 | 26 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dhoeric/features/blob/main/src/oras/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 27 | -------------------------------------------------------------------------------- /test/google-cloud-cli/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features google-cloud-cli \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "gcloud version" gcloud --version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults -------------------------------------------------------------------------------- /test/terraformer/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features terraformer \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "terraformer version" terraformer --version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /src/conftest/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Conftest (conftest) 3 | 4 | Install [conftest](https://www.conftest.dev/) 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/dhoeric/features/conftest:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter a conftest version | string | latest | 19 | 20 | ## Reference 21 | 22 | conftest: https://github.com/open-policy-agent/conftest 23 | 24 | --- 25 | 26 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dhoeric/features/blob/main/src/conftest/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 27 | -------------------------------------------------------------------------------- /src/hadolint/README.md: -------------------------------------------------------------------------------- 1 | 2 | # hadolint (hadolint) 3 | 4 | Install [hadolint](https://github.com/hadolint/hadolint) 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/dhoeric/features/hadolint:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter a hadolint version | string | latest | 19 | 20 | ## Reference 21 | 22 | hadolint: https://github.com/hadolint/hadolint 23 | 24 | --- 25 | 26 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dhoeric/features/blob/main/src/hadolint/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 27 | -------------------------------------------------------------------------------- /test/terraform-docs/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This test can be run with the following command (from the root of this repo) 4 | # devcontainer features test \ 5 | # --features terraform-docs \ 6 | # --base-image mcr.microsoft.com/devcontainers/base:ubuntu . 7 | 8 | set -e 9 | 10 | # Optional: Import test library bundled with the devcontainer CLI 11 | source dev-container-features-test-lib 12 | 13 | # Feature-specific tests 14 | # The 'check' command comes from the dev-container-features-test-lib. 15 | check "terraform-docs version" terraform-docs --version 16 | 17 | # Report result 18 | # If any of the checks above exited with a non-zero exit code, the test will fail. 19 | reportResults 20 | -------------------------------------------------------------------------------- /src/stern/README.md: -------------------------------------------------------------------------------- 1 | 2 | # stern (stern) 3 | 4 | Install [stern](https://github.com/stern/stern) - Multi pod and container log tailing for Kubernetes 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/dhoeric/features/stern:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter stern version | string | latest | 19 | 20 | ## Reference 21 | 22 | stern: https://github.com/stern/stern 23 | 24 | --- 25 | 26 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dhoeric/features/blob/main/src/stern/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 27 | -------------------------------------------------------------------------------- /src/opa/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Open Policy Agent (opa) 3 | 4 | Install [Open Policy Agent (opa)](https://www.openpolicyagent.org/docs/latest/#running-opa) 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/dhoeric/features/opa:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter an opa version | string | latest | 19 | 20 | ## Reference 21 | 22 | opa: https://github.com/open-policy-agent/opa 23 | 24 | --- 25 | 26 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dhoeric/features/blob/main/src/opa/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 27 | -------------------------------------------------------------------------------- /src/k9s/README.md: -------------------------------------------------------------------------------- 1 | 2 | # k9s-cli (k9s) 3 | 4 | Install [k9s](https://k9scli.io/) 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/dhoeric/features/k9s:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter k9s version | string | latest | 19 | 20 | ## Changelog 21 | 22 | ### 1.0.1 23 | - Using amd64 when k9s >=0.27.0 (#14) 24 | 25 | ## Reference 26 | 27 | k9s-cli: https://github.com/derailed/k9s 28 | 29 | --- 30 | 31 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dhoeric/features/blob/main/src/k9s/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 32 | -------------------------------------------------------------------------------- /src/google-cloud-cli/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Google Cloud CLI (google-cloud-cli) 3 | 4 | Install google-cloud-cli 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/dhoeric/features/google-cloud-cli:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter a gcloud CLI version | string | latest | 19 | | installGkeGcloudAuthPlugin | Install 'gke-gcloud-auth-plugin' plugin? | boolean | false | 20 | 21 | 22 | 23 | --- 24 | 25 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dhoeric/features/blob/main/src/google-cloud-cli/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 26 | -------------------------------------------------------------------------------- /src/flyctl/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Fly.io CLI (flyctl) 3 | 4 | Install [flyctl](https://github.com/superfly/flyctl) - Command line tools for [fly.io services](https://fly.io/) 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/dhoeric/features/flyctl:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter a flyctl version | string | latest | 19 | 20 | ## Reference 21 | 22 | flyctl: https://github.com/superfly/flyctl 23 | 24 | --- 25 | 26 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dhoeric/features/blob/main/src/flyctl/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 27 | -------------------------------------------------------------------------------- /src/terraform-docs/README.md: -------------------------------------------------------------------------------- 1 | 2 | # terraform-docs (terraform-docs) 3 | 4 | Install [terraform-docs](https://terraform-docs.io/) 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/dhoeric/features/terraform-docs:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter a terraform-docs version | string | latest | 19 | 20 | ## Reference 21 | 22 | terraform-docs: https://github.com/terraform-docs/terraform-docs 23 | 24 | --- 25 | 26 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dhoeric/features/blob/main/src/terraform-docs/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 27 | -------------------------------------------------------------------------------- /src/terraformer/README.md: -------------------------------------------------------------------------------- 1 | 2 | # terraformer (terraformer) 3 | 4 | Install [terraformer](https://github.com/GoogleCloudPlatform/terraformer) 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/dhoeric/features/terraformer:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter a terraformer version | string | latest | 19 | 20 | ## Reference 21 | 22 | terraformer: https://github.com/GoogleCloudPlatform/terraformer 23 | 24 | 25 | --- 26 | 27 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dhoeric/features/blob/main/src/terraformer/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 28 | -------------------------------------------------------------------------------- /src/google-cloud-cli/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Google Cloud CLI", 3 | "id": "google-cloud-cli", 4 | "version": "1.0.1", 5 | "description": "Install google-cloud-cli", 6 | "documentationURL": "https://github.com/dhoeric/features/tree/main/src/google-cloud-cli", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "default": "latest", 11 | "description": "Select or enter a gcloud CLI version" 12 | }, 13 | "installGkeGcloudAuthPlugin": { 14 | "type": "boolean", 15 | "default": false, 16 | "description": "Install 'gke-gcloud-auth-plugin' plugin?" 17 | } 18 | }, 19 | "installsAfter": [ 20 | "ghcr.io/devcontainers/features/common-utils" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Microsoft Corporation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /test/_global/all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The 'test/_global' folder is a special test folder that is not tied to a single feature. 4 | # 5 | # This test file is executed against a running container constructed 6 | # from the value of 'color_and_hello' in the tests/_global/scenarios.json file. 7 | # 8 | # The value of a scenarios element is any properties available in the 'devcontainer.json'. 9 | # Scenarios are useful for testing specific options in a feature, or to test a combination of features. 10 | # 11 | # This test can be run with the following command (from the root of this repo) 12 | # devcontainer features test --global-scenarios-only . 13 | 14 | set -e 15 | 16 | # Optional: Import test library bundled with the devcontainer CLI 17 | source dev-container-features-test-lib 18 | 19 | # Feature-specific tests 20 | # The 'check' command comes from the dev-container-features-test-lib. 21 | check "gcloud version" gcloud --version 22 | check "opa version" opa version 23 | check "conftest version" conftest --version 24 | check "tfsec version" tfsec --version 25 | check "trivy version" trivy --version 26 | check "act version" act --version 27 | check "k9s version" k9s version 28 | check "flyctl version" flyctl version 29 | check "aztfy version" aztfy --version 30 | check "terraformer version" terraformer --version 31 | check "terraform-docs version" terraform-docs --version 32 | check "k6 version" k6 version 33 | check "hadolint version" hadolint --version 34 | check "mizu version" mizu version 35 | check "oras version" oras version 36 | check "stern version" stern --version 37 | 38 | # Report result 39 | # If any of the checks above exited with a non-zero exit code, the test will fail. 40 | reportResults 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dev Container Features 2 | 3 | ## Contents 4 | 5 | This repository contains following features: 6 | - [google-cloud-cli](./src/google-cloud-cli/README.md): Install Google Cloud CLI tools 7 | - [opa](./src/opa/README.md): Install Open Policy Agent (opa) 8 | - [conftest](./src/conftest/README.md): Install conftest 9 | - [tfsec](./src/tfsec/README.md): Install tfsec 10 | - [trivy](./src/trivy/README.md): Install trivy 11 | - [act](./src/act/README.md): Install act 12 | - [k9s](./src/k9s/README.md): Install k9s 13 | - [flyctl](./src/flyctl/README.md): Install flyctl 14 | - [aztfy](./src/aztfy/README.md): Install aztfy 15 | - [terraformer](./src/terraformer/README.md): Install terraformer 16 | - [terraform-docs](./src/terraform-docs/README.md): Install terraform-docs 17 | - [k6](./src/k6/README.md): Install k6 18 | - [hadolint](./src/hadolint/README.md): Install hadolint 19 | - [mizu](./src/mizu/README.md): Install mizu 20 | - [oras](./src/oras/README.md): Install oras 21 | - [stern](./src/stern/README.md): Install stern 22 | 23 | ## Usage 24 | 25 | To use the features from this repository, add the desired features to devcontainer.json. 26 | 27 | This example use google-cloud-cli feature on devcontainer. 28 | 29 | ```jsonc 30 | { 31 | "image": "mcr.microsoft.com/devcontainers/base:ubuntu", 32 | "features": { 33 | "ghcr.io/dhoeric/features/google-cloud-cli:1": { 34 | "version": "latest" 35 | } 36 | } 37 | } 38 | ``` 39 | 40 | ## Repo and Feature Structure 41 | 42 | Similar to the [`devcontainers/features`](https://github.com/devcontainers/features) repo, this repository has a `src` folder. Each feature has its own sub-folder, containing at least a `devcontainer-feature.json` and an entrypoint script `install.sh`. 43 | 44 | ``` 45 | ├── src 46 | │ ├── hello 47 | │ │ ├── devcontainer-feature.json 48 | │ │ └── install.sh 49 | │ ├── color 50 | │ │ ├── devcontainer-feature.json 51 | │ │ └── install.sh 52 | | ├── ... 53 | │ │ ├── devcontainer-feature.json 54 | │ │ └── install.sh 55 | ... 56 | ``` 57 | 58 | An [implementing tool](https://containers.dev/supporting#tools) will composite [the documented dev container properties](https://containers.dev/implementors/features/#devcontainer-feature-json-properties) from the feature's `devcontainer-feature.json` file, and execute in the `install.sh` entrypoint script in the container during build time. Implementing tools are also free to process attributes under the `customizations` property as desired. 59 | -------------------------------------------------------------------------------- /src/mizu/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Clean up 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | MIZU_VERSION=${VERSION:-"latest"} 9 | 10 | if [ "$(id -u)" -ne 0 ]; then 11 | echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 12 | exit 1 13 | fi 14 | 15 | apt_get_update() 16 | { 17 | echo "Running apt-get update..." 18 | apt-get update -y 19 | } 20 | 21 | # Checks if packages are installed and installs them if not 22 | check_packages() { 23 | if ! dpkg -s "$@" > /dev/null 2>&1; then 24 | if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then 25 | apt_get_update 26 | fi 27 | apt-get -y install --no-install-recommends "$@" 28 | fi 29 | } 30 | 31 | export DEBIAN_FRONTEND=noninteractive 32 | 33 | # Figure out correct version of a three part version number is not passed 34 | find_version_from_git_tags() { 35 | local variable_name=$1 36 | local requested_version=${!variable_name} 37 | if [ "${requested_version}" = "none" ]; then return; fi 38 | local repository=$2 39 | local prefix=${3:-"tags/v"} 40 | local separator=${4:-"."} 41 | local last_part_optional=${5:-"false"} 42 | if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then 43 | local escaped_separator=${separator//./\\.} 44 | local last_part 45 | if [ "${last_part_optional}" = "true" ]; then 46 | last_part="(${escaped_separator}[0-9]+)?" 47 | else 48 | last_part="${escaped_separator}[0-9]+" 49 | fi 50 | local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" 51 | local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" 52 | if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then 53 | declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" 54 | else 55 | set +e 56 | declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" 57 | set -e 58 | fi 59 | fi 60 | if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then 61 | echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 62 | exit 1 63 | fi 64 | echo "${variable_name}=${!variable_name}" 65 | } 66 | 67 | # Install dependencies 68 | check_packages curl git 69 | 70 | architecture="$(uname -m)" 71 | case $architecture in 72 | x86_64) architecture="amd64";; 73 | aarch64 | armv8* | arm64) architecture="arm64";; 74 | *) echo "(!) Architecture $architecture unsupported"; exit 1 ;; 75 | esac 76 | 77 | # Install mizu 78 | echo "(*) Installing mizu..." 79 | find_version_from_git_tags MIZU_VERSION https://github.com/up9inc/mizu "tags/" "." true 80 | 81 | MIZU_VERSION="${MIZU_VERSION#"v"}" 82 | curl -sSL --fail -o /usr/local/bin/mizu "https://github.com/up9inc/mizu/releases/download/${MIZU_VERSION}/mizu_linux_${architecture}" 83 | chmod 0755 /usr/local/bin/mizu 84 | 85 | # Clean up 86 | rm -rf /var/lib/apt/lists/* 87 | 88 | echo "Done!" 89 | -------------------------------------------------------------------------------- /src/hadolint/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Clean up 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | HADOLINT_VERSION=${VERSION:-"latest"} 9 | 10 | if [ "$(id -u)" -ne 0 ]; then 11 | echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 12 | exit 1 13 | fi 14 | 15 | apt_get_update() 16 | { 17 | echo "Running apt-get update..." 18 | apt-get update -y 19 | } 20 | 21 | # Checks if packages are installed and installs them if not 22 | check_packages() { 23 | if ! dpkg -s "$@" > /dev/null 2>&1; then 24 | if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then 25 | apt_get_update 26 | fi 27 | apt-get -y install --no-install-recommends "$@" 28 | fi 29 | } 30 | 31 | export DEBIAN_FRONTEND=noninteractive 32 | 33 | # Figure out correct version of a three part version number is not passed 34 | find_version_from_git_tags() { 35 | local variable_name=$1 36 | local requested_version=${!variable_name} 37 | if [ "${requested_version}" = "none" ]; then return; fi 38 | local repository=$2 39 | local prefix=${3:-"tags/v"} 40 | local separator=${4:-"."} 41 | local last_part_optional=${5:-"false"} 42 | if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then 43 | local escaped_separator=${separator//./\\.} 44 | local last_part 45 | if [ "${last_part_optional}" = "true" ]; then 46 | last_part="(${escaped_separator}[0-9]+)?" 47 | else 48 | last_part="${escaped_separator}[0-9]+" 49 | fi 50 | local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" 51 | local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" 52 | if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then 53 | declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" 54 | else 55 | set +e 56 | declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" 57 | set -e 58 | fi 59 | fi 60 | if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then 61 | echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 62 | exit 1 63 | fi 64 | echo "${variable_name}=${!variable_name}" 65 | } 66 | 67 | # Install dependencies 68 | check_packages curl git tar 69 | 70 | architecture="$(uname -m)" 71 | case $architecture in 72 | x86_64) architecture="x86_64";; 73 | aarch64 | armv8* | arm64) architecture="arm64";; 74 | *) echo "(!) Architecture $architecture unsupported"; exit 1 ;; 75 | esac 76 | 77 | # Install hadolint 78 | echo "(*) Installing hadolint..." 79 | find_version_from_git_tags HADOLINT_VERSION https://github.com/hadolint/hadolint 80 | 81 | HADOLINT_VERSION="${HADOLINT_VERSION#"v"}" 82 | curl -sSL -o /usr/local/bin/hadolint "https://github.com/hadolint/hadolint/releases/download/v${HADOLINT_VERSION}/hadolint-Linux-${architecture}" 83 | chmod 0755 /usr/local/bin/hadolint 84 | 85 | # Clean up 86 | rm -rf /var/lib/apt/lists/* 87 | 88 | echo "Done!" 89 | -------------------------------------------------------------------------------- /src/tfsec/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Clean up 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | TFSEC_VERSION=${VERSION:-"latest"} 9 | 10 | if [ "$(id -u)" -ne 0 ]; then 11 | echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 12 | exit 1 13 | fi 14 | 15 | apt_get_update() 16 | { 17 | echo "Running apt-get update..." 18 | apt-get update -y 19 | } 20 | 21 | # Checks if packages are installed and installs them if not 22 | check_packages() { 23 | if ! dpkg -s "$@" > /dev/null 2>&1; then 24 | if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then 25 | apt_get_update 26 | fi 27 | apt-get -y install --no-install-recommends "$@" 28 | fi 29 | } 30 | 31 | export DEBIAN_FRONTEND=noninteractive 32 | 33 | # Figure out correct version of a three part version number is not passed 34 | find_version_from_git_tags() { 35 | local variable_name=$1 36 | local requested_version=${!variable_name} 37 | if [ "${requested_version}" = "none" ]; then return; fi 38 | local repository=$2 39 | local prefix=${3:-"tags/v"} 40 | local separator=${4:-"."} 41 | local last_part_optional=${5:-"false"} 42 | if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then 43 | local escaped_separator=${separator//./\\.} 44 | local last_part 45 | if [ "${last_part_optional}" = "true" ]; then 46 | last_part="(${escaped_separator}[0-9]+)?" 47 | else 48 | last_part="${escaped_separator}[0-9]+" 49 | fi 50 | local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" 51 | local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" 52 | if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then 53 | declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" 54 | else 55 | set +e 56 | declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" 57 | set -e 58 | fi 59 | fi 60 | if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then 61 | echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 62 | exit 1 63 | fi 64 | echo "${variable_name}=${!variable_name}" 65 | } 66 | 67 | # Install dependencies 68 | check_packages curl git 69 | 70 | architecture="$(uname -m)" 71 | case $architecture in 72 | x86_64) architecture="amd64";; 73 | aarch64 | armv8* | arm64) architecture="arm64";; 74 | *) echo "(!) Architecture $architecture unsupported"; exit 1 ;; 75 | esac 76 | 77 | # Install tfsec 78 | echo "(*) Installing tfsec..." 79 | find_version_from_git_tags TFSEC_VERSION https://github.com/aquasecurity/tfsec 80 | 81 | if [ "${TFSEC_VERSION::1}" != 'v' ]; then 82 | TFSEC_VERSION="v${TFSEC_VERSION}" 83 | fi 84 | curl -sSL -o /usr/local/bin/tfsec "https://github.com/aquasecurity/tfsec/releases/download/${TFSEC_VERSION}/tfsec-linux-${architecture}" 85 | chmod 0755 /usr/local/bin/tfsec 86 | 87 | # Clean up 88 | rm -rf /var/lib/apt/lists/* 89 | 90 | echo "Done!" 91 | -------------------------------------------------------------------------------- /src/opa/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Clean up 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | OPA_VERSION=${VERSION:-"latest"} 9 | 10 | if [ "$(id -u)" -ne 0 ]; then 11 | echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 12 | exit 1 13 | fi 14 | 15 | apt_get_update() 16 | { 17 | echo "Running apt-get update..." 18 | apt-get update -y 19 | } 20 | 21 | # Checks if packages are installed and installs them if not 22 | check_packages() { 23 | if ! dpkg -s "$@" > /dev/null 2>&1; then 24 | if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then 25 | apt_get_update 26 | fi 27 | apt-get -y install --no-install-recommends "$@" 28 | fi 29 | } 30 | 31 | export DEBIAN_FRONTEND=noninteractive 32 | 33 | # Figure out correct version of a three part version number is not passed 34 | find_version_from_git_tags() { 35 | local variable_name=$1 36 | local requested_version=${!variable_name} 37 | if [ "${requested_version}" = "none" ]; then return; fi 38 | local repository=$2 39 | local prefix=${3:-"tags/v"} 40 | local separator=${4:-"."} 41 | local last_part_optional=${5:-"false"} 42 | if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then 43 | local escaped_separator=${separator//./\\.} 44 | local last_part 45 | if [ "${last_part_optional}" = "true" ]; then 46 | last_part="(${escaped_separator}[0-9]+)?" 47 | else 48 | last_part="${escaped_separator}[0-9]+" 49 | fi 50 | local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" 51 | local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" 52 | if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then 53 | declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" 54 | else 55 | set +e 56 | declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" 57 | set -e 58 | fi 59 | fi 60 | if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then 61 | echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 62 | exit 1 63 | fi 64 | echo "${variable_name}=${!variable_name}" 65 | } 66 | 67 | # Install dependencies 68 | check_packages curl git 69 | 70 | architecture="$(uname -m)" 71 | case $architecture in 72 | x86_64) architecture="amd64";; 73 | aarch64 | armv8* | arm64) architecture="arm64";; 74 | *) echo "(!) Architecture $architecture unsupported"; exit 1 ;; 75 | esac 76 | 77 | # Install OPA 78 | echo "(*) Installing Open Policy Agent (opa)..." 79 | find_version_from_git_tags OPA_VERSION https://github.com/open-policy-agent/opa 80 | 81 | if [ "${OPA_VERSION::1}" != 'v' ]; then 82 | OPA_VERSION="v${OPA_VERSION}" 83 | fi 84 | curl -sSL -o /usr/local/bin/opa "https://github.com/open-policy-agent/opa/releases/download/${OPA_VERSION}/opa_linux_${architecture}_static" 85 | chmod 0755 /usr/local/bin/opa 86 | 87 | # Clean up 88 | rm -rf /var/lib/apt/lists/* 89 | 90 | echo "Done!" 91 | -------------------------------------------------------------------------------- /src/terraformer/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Clean up 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | TERRAFORMER_VERSION=${VERSION:-"latest"} 9 | 10 | if [ "$(id -u)" -ne 0 ]; then 11 | echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 12 | exit 1 13 | fi 14 | 15 | apt_get_update() 16 | { 17 | echo "Running apt-get update..." 18 | apt-get update -y 19 | } 20 | 21 | # Checks if packages are installed and installs them if not 22 | check_packages() { 23 | if ! dpkg -s "$@" > /dev/null 2>&1; then 24 | if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then 25 | apt_get_update 26 | fi 27 | apt-get -y install --no-install-recommends "$@" 28 | fi 29 | } 30 | 31 | export DEBIAN_FRONTEND=noninteractive 32 | 33 | # Figure out correct version of a three part version number is not passed 34 | find_version_from_git_tags() { 35 | local variable_name=$1 36 | local requested_version=${!variable_name} 37 | if [ "${requested_version}" = "none" ]; then return; fi 38 | local repository=$2 39 | local prefix=${3:-"tags/v"} 40 | local separator=${4:-"."} 41 | local last_part_optional=${5:-"false"} 42 | if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then 43 | local escaped_separator=${separator//./\\.} 44 | local last_part 45 | if [ "${last_part_optional}" = "true" ]; then 46 | last_part="(${escaped_separator}[0-9]+)?" 47 | else 48 | last_part="${escaped_separator}[0-9]+" 49 | fi 50 | local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" 51 | local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" 52 | if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then 53 | declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" 54 | else 55 | set +e 56 | declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" 57 | set -e 58 | fi 59 | fi 60 | if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then 61 | echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 62 | exit 1 63 | fi 64 | echo "${variable_name}=${!variable_name}" 65 | } 66 | 67 | # Install dependencies 68 | check_packages curl git 69 | 70 | architecture="$(uname -m)" 71 | case $architecture in 72 | x86_64) architecture="amd64";; 73 | aarch64 | armv8* | arm64) architecture="arm64";; 74 | *) echo "(!) Architecture $architecture unsupported"; exit 1 ;; 75 | esac 76 | 77 | # Install terraformer 78 | echo "(*) Installing terraformer..." 79 | find_version_from_git_tags TERRAFORMER_VERSION https://github.com/GoogleCloudPlatform/terraformer "tags/" 80 | 81 | TERRAFORMER_VERSION="${TERRAFORMER_VERSION#"v"}" 82 | curl -sSL --fail -o /usr/local/bin/terraformer "https://github.com/GoogleCloudPlatform/terraformer/releases/download/${TERRAFORMER_VERSION}/terraformer-all-linux-${architecture}" 83 | chmod 0755 /usr/local/bin/terraformer 84 | 85 | # Clean up 86 | rm -rf /var/lib/apt/lists/* 87 | 88 | echo "Done!" 89 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: "CI - Test Features & Generate Documentation" 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | workflow_dispatch: 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | continue-on-error: true 13 | strategy: 14 | matrix: 15 | features: [ 16 | "google-cloud-cli", 17 | "opa", 18 | "conftest", 19 | "tfsec", 20 | "trivy", 21 | "act", 22 | "k9s", 23 | "flyctl", 24 | "aztfy", 25 | "terraformer", 26 | "terraform-docs", 27 | "k6", 28 | "hadolint", 29 | "mizu", 30 | "oras", 31 | "stern", 32 | ] 33 | baseImage: 34 | [ 35 | "mcr.microsoft.com/devcontainers/base:ubuntu" 36 | ] 37 | steps: 38 | - uses: actions/checkout@v3 39 | 40 | - name: "Install latest devcontainer CLI" 41 | run: npm install -g @devcontainers/cli 42 | 43 | - name: "Generating tests for '${{ matrix.features }}' against '${{ matrix.baseImage }}'" 44 | run: devcontainer features test -f ${{ matrix.features }} -i ${{ matrix.baseImage }} . 45 | 46 | test-global: 47 | runs-on: ubuntu-latest 48 | continue-on-error: true 49 | steps: 50 | - uses: actions/checkout@v3 51 | 52 | - name: "Install latest devcontainer CLI" 53 | run: npm install -g @devcontainers/cli 54 | 55 | - name: "Testing global scenarios" 56 | run: devcontainer features test --global-scenarios-only . 57 | 58 | update-readme: 59 | runs-on: ubuntu-latest 60 | steps: 61 | - uses: actions/checkout@v3 62 | with: 63 | ref: ${{ github.event.pull_request.head.ref }} 64 | 65 | - name: "Update Readme" 66 | uses: devcontainers/action@v1 67 | with: 68 | base-path-to-features: "./src" 69 | generate-docs: "true" 70 | 71 | env: 72 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 73 | 74 | - name: Commit 75 | id: push_image_info 76 | env: 77 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 78 | run: | 79 | set -e 80 | echo "Start." 81 | # Configure git and Push updates 82 | git config --global --add safe.directory /github/workspace 83 | git config --global user.email github-actions@github.com 84 | git config --global user.name github-actions 85 | git config pull.rebase false 86 | git fetch --depth=1 origin +refs/tags/*:refs/tags/* || true 87 | message='Automated documentation update' 88 | # Add / update and commit 89 | git add */**/README.md 90 | if [ "$(git status --porcelain | grep "$file" | grep -c -E '([MA]\W).+')" -eq 1 ]; then 91 | echo "::debug Added ${file} to git staging area" 92 | else 93 | echo "::debug No change in ${file} detected" 94 | fi 95 | 96 | echo "::debug Following files will be committed" 97 | git status -s 98 | 99 | git commit -m 'Automated documentation update [skip ci]' || export NO_UPDATES=true 100 | # Push 101 | if [ "$NO_UPDATES" != "true" ] ; then 102 | git push 103 | fi 104 | -------------------------------------------------------------------------------- /src/act/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Clean up 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | ACT_VERSION=${VERSION:-"latest"} 9 | 10 | if [ "$(id -u)" -ne 0 ]; then 11 | echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 12 | exit 1 13 | fi 14 | 15 | apt_get_update() 16 | { 17 | echo "Running apt-get update..." 18 | apt-get update -y 19 | } 20 | 21 | # Checks if packages are installed and installs them if not 22 | check_packages() { 23 | if ! dpkg -s "$@" > /dev/null 2>&1; then 24 | if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then 25 | apt_get_update 26 | fi 27 | apt-get -y install --no-install-recommends "$@" 28 | fi 29 | } 30 | 31 | export DEBIAN_FRONTEND=noninteractive 32 | 33 | # Figure out correct version of a three part version number is not passed 34 | find_version_from_git_tags() { 35 | local variable_name=$1 36 | local requested_version=${!variable_name} 37 | if [ "${requested_version}" = "none" ]; then return; fi 38 | local repository=$2 39 | local prefix=${3:-"tags/v"} 40 | local separator=${4:-"."} 41 | local last_part_optional=${5:-"false"} 42 | if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then 43 | local escaped_separator=${separator//./\\.} 44 | local last_part 45 | if [ "${last_part_optional}" = "true" ]; then 46 | last_part="(${escaped_separator}[0-9]+)?" 47 | else 48 | last_part="${escaped_separator}[0-9]+" 49 | fi 50 | local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" 51 | local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" 52 | if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then 53 | declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" 54 | else 55 | set +e 56 | declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" 57 | set -e 58 | fi 59 | fi 60 | if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then 61 | echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 62 | exit 1 63 | fi 64 | echo "${variable_name}=${!variable_name}" 65 | } 66 | 67 | # Install dependencies 68 | check_packages curl git tar 69 | 70 | architecture="$(uname -m)" 71 | case $architecture in 72 | x86_64) architecture="x86_64";; 73 | aarch64 | armv8* | arm64) architecture="arm64";; 74 | *) echo "(!) Architecture $architecture unsupported"; exit 1 ;; 75 | esac 76 | 77 | # Use a temporary locaiton for act archive 78 | export TMP_DIR="/tmp/tmp-act" 79 | mkdir -p ${TMP_DIR} 80 | chmod 700 ${TMP_DIR} 81 | 82 | # Install act 83 | echo "(*) Installing act..." 84 | find_version_from_git_tags ACT_VERSION https://github.com/nektos/act 85 | 86 | ACT_VERSION="${ACT_VERSION#"v"}" 87 | curl -sSL -o ${TMP_DIR}/act.tar.gz "https://github.com/nektos/act/releases/download/v${ACT_VERSION}/act_Linux_${architecture}.tar.gz" 88 | tar -xzf "${TMP_DIR}/act.tar.gz" -C "${TMP_DIR}" act 89 | mv ${TMP_DIR}/act /usr/local/bin/act 90 | chmod 0755 /usr/local/bin/act 91 | 92 | # Clean up 93 | rm -rf /var/lib/apt/lists/* 94 | 95 | echo "Done!" 96 | -------------------------------------------------------------------------------- /src/aztfy/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Clean up 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | AZTFY_VERSION=${VERSION:-"latest"} 9 | 10 | if [ "$(id -u)" -ne 0 ]; then 11 | echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 12 | exit 1 13 | fi 14 | 15 | apt_get_update() 16 | { 17 | echo "Running apt-get update..." 18 | apt-get update -y 19 | } 20 | 21 | # Checks if packages are installed and installs them if not 22 | check_packages() { 23 | if ! dpkg -s "$@" > /dev/null 2>&1; then 24 | if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then 25 | apt_get_update 26 | fi 27 | apt-get -y install --no-install-recommends "$@" 28 | fi 29 | } 30 | 31 | export DEBIAN_FRONTEND=noninteractive 32 | 33 | # Figure out correct version of a three part version number is not passed 34 | find_version_from_git_tags() { 35 | local variable_name=$1 36 | local requested_version=${!variable_name} 37 | if [ "${requested_version}" = "none" ]; then return; fi 38 | local repository=$2 39 | local prefix=${3:-"tags/v"} 40 | local separator=${4:-"."} 41 | local last_part_optional=${5:-"false"} 42 | if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then 43 | local escaped_separator=${separator//./\\.} 44 | local last_part 45 | if [ "${last_part_optional}" = "true" ]; then 46 | last_part="(${escaped_separator}[0-9]+)?" 47 | else 48 | last_part="${escaped_separator}[0-9]+" 49 | fi 50 | local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" 51 | local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" 52 | if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then 53 | declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" 54 | else 55 | set +e 56 | declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" 57 | set -e 58 | fi 59 | fi 60 | if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then 61 | echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 62 | exit 1 63 | fi 64 | echo "${variable_name}=${!variable_name}" 65 | } 66 | 67 | # Install dependencies 68 | check_packages curl git unzip 69 | 70 | architecture="$(uname -m)" 71 | case $architecture in 72 | x86_64) architecture="amd64";; 73 | aarch64 | armv8* | arm64) architecture="arm64";; 74 | *) echo "(!) Architecture $architecture unsupported"; exit 1 ;; 75 | esac 76 | 77 | # Use a temporary locaiton for aztfy archive 78 | export TMP_DIR="/tmp/tmp-aztfy" 79 | mkdir -p ${TMP_DIR} 80 | chmod 700 ${TMP_DIR} 81 | 82 | # Install aztfy 83 | echo "(*) Installing aztfy..." 84 | find_version_from_git_tags AZTFY_VERSION https://github.com/Azure/aztfy 85 | 86 | AZTFY_VERSION="${AZTFY_VERSION#"v"}" 87 | curl -sSL -o ${TMP_DIR}/aztfy.zip "https://github.com/Azure/aztfy/releases/download/v${AZTFY_VERSION}/aztfy_v${AZTFY_VERSION}_linux_${architecture}.zip" 88 | unzip ${TMP_DIR}/aztfy.zip 89 | mv -f aztfy /usr/local/bin/ 90 | chmod 0755 /usr/local/bin/aztfy 91 | 92 | # Clean up 93 | rm -rf /var/lib/apt/lists/* 94 | 95 | echo "Done!" 96 | -------------------------------------------------------------------------------- /src/oras/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Clean up 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | ORAS_VERSION=${VERSION:-"latest"} 9 | 10 | if [ "$(id -u)" -ne 0 ]; then 11 | echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 12 | exit 1 13 | fi 14 | 15 | apt_get_update() 16 | { 17 | echo "Running apt-get update..." 18 | apt-get update -y 19 | } 20 | 21 | # Checks if packages are installed and installs them if not 22 | check_packages() { 23 | if ! dpkg -s "$@" > /dev/null 2>&1; then 24 | if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then 25 | apt_get_update 26 | fi 27 | apt-get -y install --no-install-recommends "$@" 28 | fi 29 | } 30 | 31 | export DEBIAN_FRONTEND=noninteractive 32 | 33 | # Figure out correct version of a three part version number is not passed 34 | find_version_from_git_tags() { 35 | local variable_name=$1 36 | local requested_version=${!variable_name} 37 | if [ "${requested_version}" = "none" ]; then return; fi 38 | local repository=$2 39 | local prefix=${3:-"tags/v"} 40 | local separator=${4:-"."} 41 | local last_part_optional=${5:-"false"} 42 | if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then 43 | local escaped_separator=${separator//./\\.} 44 | local last_part 45 | if [ "${last_part_optional}" = "true" ]; then 46 | last_part="(${escaped_separator}[0-9]+)?" 47 | else 48 | last_part="${escaped_separator}[0-9]+" 49 | fi 50 | local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" 51 | local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" 52 | if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then 53 | declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" 54 | else 55 | set +e 56 | declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" 57 | set -e 58 | fi 59 | fi 60 | if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then 61 | echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 62 | exit 1 63 | fi 64 | echo "${variable_name}=${!variable_name}" 65 | } 66 | 67 | # Install dependencies 68 | check_packages curl git tar 69 | 70 | architecture="$(uname -m)" 71 | case $architecture in 72 | x86_64) architecture="amd64";; 73 | aarch64 | armv8* | arm64) architecture="arm64";; 74 | *) echo "(!) Architecture $architecture unsupported"; exit 1 ;; 75 | esac 76 | 77 | # Use a temporary locaiton for oras archive 78 | export TMP_DIR="/tmp/tmp-oras" 79 | mkdir -p ${TMP_DIR} 80 | chmod 700 ${TMP_DIR} 81 | 82 | # Install oras 83 | echo "(*) Installing oras..." 84 | find_version_from_git_tags ORAS_VERSION https://github.com/oras-project/oras 85 | 86 | ORAS_VERSION="${ORAS_VERSION#"v"}" 87 | curl -sSL -o ${TMP_DIR}/oras.tar.gz "https://github.com/oras-project/oras/releases/download/v${ORAS_VERSION}/oras_${ORAS_VERSION}_linux_${architecture}.tar.gz" 88 | tar -xzf "${TMP_DIR}/oras.tar.gz" -C "${TMP_DIR}" oras 89 | mv ${TMP_DIR}/oras /usr/local/bin/oras 90 | chmod 0755 /usr/local/bin/oras 91 | 92 | # Clean up 93 | rm -rf /var/lib/apt/lists/* 94 | 95 | echo "Done!" 96 | -------------------------------------------------------------------------------- /src/stern/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Clean up 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | STERN_VERSION=${VERSION:-"latest"} 9 | 10 | if [ "$(id -u)" -ne 0 ]; then 11 | echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 12 | exit 1 13 | fi 14 | 15 | apt_get_update() 16 | { 17 | echo "Running apt-get update..." 18 | apt-get update -y 19 | } 20 | 21 | # Checks if packages are installed and installs them if not 22 | check_packages() { 23 | if ! dpkg -s "$@" > /dev/null 2>&1; then 24 | if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then 25 | apt_get_update 26 | fi 27 | apt-get -y install --no-install-recommends "$@" 28 | fi 29 | } 30 | 31 | export DEBIAN_FRONTEND=noninteractive 32 | 33 | # Figure out correct version of a three part version number is not passed 34 | find_version_from_git_tags() { 35 | local variable_name=$1 36 | local requested_version=${!variable_name} 37 | if [ "${requested_version}" = "none" ]; then return; fi 38 | local repository=$2 39 | local prefix=${3:-"tags/v"} 40 | local separator=${4:-"."} 41 | local last_part_optional=${5:-"false"} 42 | if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then 43 | local escaped_separator=${separator//./\\.} 44 | local last_part 45 | if [ "${last_part_optional}" = "true" ]; then 46 | last_part="(${escaped_separator}[0-9]+)?" 47 | else 48 | last_part="${escaped_separator}[0-9]+" 49 | fi 50 | local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" 51 | local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" 52 | if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then 53 | declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" 54 | else 55 | set +e 56 | declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" 57 | set -e 58 | fi 59 | fi 60 | if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then 61 | echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 62 | exit 1 63 | fi 64 | echo "${variable_name}=${!variable_name}" 65 | } 66 | 67 | # Install dependencies 68 | check_packages curl git tar 69 | 70 | architecture="$(uname -m)" 71 | case $architecture in 72 | x86_64) architecture="amd64";; 73 | aarch64 | armv8* | arm64) architecture="arm64";; 74 | *) echo "(!) Architecture $architecture unsupported"; exit 1 ;; 75 | esac 76 | 77 | # Use a temporary locaiton for stern archive 78 | export TMP_DIR="/tmp/tmp-stern" 79 | mkdir -p ${TMP_DIR} 80 | chmod 700 ${TMP_DIR} 81 | 82 | # Install stern 83 | echo "(*) Installing stern..." 84 | find_version_from_git_tags STERN_VERSION https://github.com/stern/stern 85 | 86 | STERN_VERSION="${STERN_VERSION#"v"}" 87 | curl -sSL -o ${TMP_DIR}/stern.tar.gz "https://github.com/stern/stern/releases/download/v${STERN_VERSION}/stern_${STERN_VERSION}_linux_${architecture}.tar.gz" 88 | tar -xzf "${TMP_DIR}/stern.tar.gz" -C "${TMP_DIR}" stern 89 | mv ${TMP_DIR}/stern /usr/local/bin/stern 90 | chmod 0755 /usr/local/bin/stern 91 | 92 | # Clean up 93 | rm -rf /var/lib/apt/lists/* 94 | 95 | echo "Done!" 96 | -------------------------------------------------------------------------------- /src/trivy/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Clean up 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | TRIVY_VERSION=${VERSION:-"latest"} 9 | 10 | if [ "$(id -u)" -ne 0 ]; then 11 | echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 12 | exit 1 13 | fi 14 | 15 | apt_get_update() 16 | { 17 | echo "Running apt-get update..." 18 | apt-get update -y 19 | } 20 | 21 | # Checks if packages are installed and installs them if not 22 | check_packages() { 23 | if ! dpkg -s "$@" > /dev/null 2>&1; then 24 | if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then 25 | apt_get_update 26 | fi 27 | apt-get -y install --no-install-recommends "$@" 28 | fi 29 | } 30 | 31 | export DEBIAN_FRONTEND=noninteractive 32 | 33 | # Figure out correct version of a three part version number is not passed 34 | find_version_from_git_tags() { 35 | local variable_name=$1 36 | local requested_version=${!variable_name} 37 | if [ "${requested_version}" = "none" ]; then return; fi 38 | local repository=$2 39 | local prefix=${3:-"tags/v"} 40 | local separator=${4:-"."} 41 | local last_part_optional=${5:-"false"} 42 | if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then 43 | local escaped_separator=${separator//./\\.} 44 | local last_part 45 | if [ "${last_part_optional}" = "true" ]; then 46 | last_part="(${escaped_separator}[0-9]+)?" 47 | else 48 | last_part="${escaped_separator}[0-9]+" 49 | fi 50 | local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" 51 | local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" 52 | if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then 53 | declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" 54 | else 55 | set +e 56 | declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" 57 | set -e 58 | fi 59 | fi 60 | if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then 61 | echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 62 | exit 1 63 | fi 64 | echo "${variable_name}=${!variable_name}" 65 | } 66 | 67 | # Install dependencies 68 | check_packages curl git tar 69 | 70 | architecture="$(uname -m)" 71 | case $architecture in 72 | x86_64) architecture="64bit";; 73 | aarch64 | armv8* | arm64) architecture="ARM64";; 74 | *) echo "(!) Architecture $architecture unsupported"; exit 1 ;; 75 | esac 76 | 77 | # Use a temporary locaiton for trivy archive 78 | export TMP_DIR="/tmp/tmp-trivy" 79 | mkdir -p ${TMP_DIR} 80 | chmod 700 ${TMP_DIR} 81 | 82 | # Install trivy 83 | echo "(*) Installing trivy..." 84 | find_version_from_git_tags TRIVY_VERSION https://github.com/aquasecurity/trivy 85 | 86 | TRIVY_VERSION="${TRIVY_VERSION#"v"}" 87 | curl -sSL -o ${TMP_DIR}/trivy.tar.gz "https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-${architecture}.tar.gz" 88 | tar -xzf "${TMP_DIR}/trivy.tar.gz" -C "${TMP_DIR}" trivy 89 | mv ${TMP_DIR}/trivy /usr/local/bin/trivy 90 | chmod 0755 /usr/local/bin/trivy 91 | 92 | # Clean up 93 | rm -rf /var/lib/apt/lists/* 94 | 95 | echo "Done!" 96 | -------------------------------------------------------------------------------- /src/flyctl/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Clean up 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | FLYCTL_VERSION=${VERSION:-"latest"} 9 | 10 | if [ "$(id -u)" -ne 0 ]; then 11 | echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 12 | exit 1 13 | fi 14 | 15 | apt_get_update() 16 | { 17 | echo "Running apt-get update..." 18 | apt-get update -y 19 | } 20 | 21 | # Checks if packages are installed and installs them if not 22 | check_packages() { 23 | if ! dpkg -s "$@" > /dev/null 2>&1; then 24 | if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then 25 | apt_get_update 26 | fi 27 | apt-get -y install --no-install-recommends "$@" 28 | fi 29 | } 30 | 31 | export DEBIAN_FRONTEND=noninteractive 32 | 33 | # Figure out correct version of a three part version number is not passed 34 | find_version_from_git_tags() { 35 | local variable_name=$1 36 | local requested_version=${!variable_name} 37 | if [ "${requested_version}" = "none" ]; then return; fi 38 | local repository=$2 39 | local prefix=${3:-"tags/v"} 40 | local separator=${4:-"."} 41 | local last_part_optional=${5:-"false"} 42 | if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then 43 | local escaped_separator=${separator//./\\.} 44 | local last_part 45 | if [ "${last_part_optional}" = "true" ]; then 46 | last_part="(${escaped_separator}[0-9]+)?" 47 | else 48 | last_part="${escaped_separator}[0-9]+" 49 | fi 50 | local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" 51 | local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" 52 | if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then 53 | declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" 54 | else 55 | set +e 56 | declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" 57 | set -e 58 | fi 59 | fi 60 | if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then 61 | echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 62 | exit 1 63 | fi 64 | echo "${variable_name}=${!variable_name}" 65 | } 66 | 67 | # Install dependencies 68 | check_packages curl git tar 69 | 70 | architecture="$(uname -m)" 71 | case $architecture in 72 | x86_64) architecture="x86_64";; 73 | aarch64 | armv8* | arm64) architecture="arm64";; 74 | *) echo "(!) Architecture $architecture unsupported"; exit 1 ;; 75 | esac 76 | 77 | # Use a temporary locaiton for flyctl archive 78 | export TMP_DIR="/tmp/tmp-flyctl" 79 | mkdir -p ${TMP_DIR} 80 | chmod 700 ${TMP_DIR} 81 | 82 | # Install flyctl 83 | echo "(*) Installing flyctl..." 84 | find_version_from_git_tags FLYCTL_VERSION https://github.com/superfly/flyctl 85 | 86 | FLYCTL_VERSION="${FLYCTL_VERSION#"v"}" 87 | curl -sSL -o ${TMP_DIR}/flyctl.tar.gz "https://github.com/superfly/flyctl/releases/download/v${FLYCTL_VERSION}/flyctl_${FLYCTL_VERSION}_Linux_${architecture}.tar.gz" 88 | tar -xzf "${TMP_DIR}/flyctl.tar.gz" -C "${TMP_DIR}" flyctl 89 | mv ${TMP_DIR}/flyctl /usr/local/bin/flyctl 90 | chmod 0755 /usr/local/bin/flyctl 91 | 92 | # Clean up 93 | rm -rf /var/lib/apt/lists/* 94 | 95 | echo "Done!" 96 | -------------------------------------------------------------------------------- /src/k6/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Clean up 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | K6_VERSION=${VERSION:-"latest"} 9 | 10 | if [ "$(id -u)" -ne 0 ]; then 11 | echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 12 | exit 1 13 | fi 14 | 15 | apt_get_update() 16 | { 17 | echo "Running apt-get update..." 18 | apt-get update -y 19 | } 20 | 21 | # Checks if packages are installed and installs them if not 22 | check_packages() { 23 | if ! dpkg -s "$@" > /dev/null 2>&1; then 24 | if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then 25 | apt_get_update 26 | fi 27 | apt-get -y install --no-install-recommends "$@" 28 | fi 29 | } 30 | 31 | export DEBIAN_FRONTEND=noninteractive 32 | 33 | # Figure out correct version of a three part version number is not passed 34 | find_version_from_git_tags() { 35 | local variable_name=$1 36 | local requested_version=${!variable_name} 37 | if [ "${requested_version}" = "none" ]; then return; fi 38 | local repository=$2 39 | local prefix=${3:-"tags/v"} 40 | local separator=${4:-"."} 41 | local last_part_optional=${5:-"false"} 42 | if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then 43 | local escaped_separator=${separator//./\\.} 44 | local last_part 45 | if [ "${last_part_optional}" = "true" ]; then 46 | last_part="(${escaped_separator}[0-9]+)?" 47 | else 48 | last_part="${escaped_separator}[0-9]+" 49 | fi 50 | local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" 51 | local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" 52 | if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then 53 | declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" 54 | else 55 | set +e 56 | declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" 57 | set -e 58 | fi 59 | fi 60 | if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then 61 | echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 62 | exit 1 63 | fi 64 | echo "${variable_name}=${!variable_name}" 65 | } 66 | 67 | # Install dependencies 68 | check_packages curl git tar 69 | 70 | architecture="$(uname -m)" 71 | case $architecture in 72 | x86_64) architecture="amd64";; 73 | aarch64 | armv8* | arm64) architecture="arm64";; 74 | *) echo "(!) Architecture $architecture unsupported"; exit 1 ;; 75 | esac 76 | 77 | # Use a temporary locaiton for k6 archive 78 | export TMP_DIR="/tmp/tmp-k6" 79 | mkdir -p ${TMP_DIR} 80 | chmod 700 ${TMP_DIR} 81 | 82 | # Install k6 83 | echo "(*) Installing k6..." 84 | find_version_from_git_tags K6_VERSION https://github.com/grafana/k6 85 | 86 | K6_VERSION="${K6_VERSION#"v"}" 87 | curl -sSL --fail -o ${TMP_DIR}/k6.tar.gz "https://github.com/grafana/k6/releases/download/v${K6_VERSION}/k6-v${K6_VERSION}-linux-${architecture}.tar.gz" 88 | tar -xzf "${TMP_DIR}/k6.tar.gz" -C "${TMP_DIR}" k6-v${K6_VERSION}-linux-${architecture}/k6 89 | mv ${TMP_DIR}/k6-v${K6_VERSION}-linux-${architecture}/k6 /usr/local/bin/k6 90 | chmod 0755 /usr/local/bin/k6 91 | 92 | # Clean up 93 | rm -rf /var/lib/apt/lists/* 94 | 95 | echo "Done!" 96 | -------------------------------------------------------------------------------- /src/conftest/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Clean up 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | CONFTEST_VERSION=${VERSION:-"latest"} 9 | 10 | if [ "$(id -u)" -ne 0 ]; then 11 | echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 12 | exit 1 13 | fi 14 | 15 | apt_get_update() 16 | { 17 | echo "Running apt-get update..." 18 | apt-get update -y 19 | } 20 | 21 | # Checks if packages are installed and installs them if not 22 | check_packages() { 23 | if ! dpkg -s "$@" > /dev/null 2>&1; then 24 | if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then 25 | apt_get_update 26 | fi 27 | apt-get -y install --no-install-recommends "$@" 28 | fi 29 | } 30 | 31 | export DEBIAN_FRONTEND=noninteractive 32 | 33 | # Figure out correct version of a three part version number is not passed 34 | find_version_from_git_tags() { 35 | local variable_name=$1 36 | local requested_version=${!variable_name} 37 | if [ "${requested_version}" = "none" ]; then return; fi 38 | local repository=$2 39 | local prefix=${3:-"tags/v"} 40 | local separator=${4:-"."} 41 | local last_part_optional=${5:-"false"} 42 | if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then 43 | local escaped_separator=${separator//./\\.} 44 | local last_part 45 | if [ "${last_part_optional}" = "true" ]; then 46 | last_part="(${escaped_separator}[0-9]+)?" 47 | else 48 | last_part="${escaped_separator}[0-9]+" 49 | fi 50 | local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" 51 | local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" 52 | if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then 53 | declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" 54 | else 55 | set +e 56 | declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" 57 | set -e 58 | fi 59 | fi 60 | if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then 61 | echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 62 | exit 1 63 | fi 64 | echo "${variable_name}=${!variable_name}" 65 | } 66 | 67 | # Install dependencies 68 | check_packages curl git tar 69 | 70 | architecture="$(uname -m)" 71 | case $architecture in 72 | x86_64) architecture="x86_64";; 73 | aarch64 | armv8* | arm64) architecture="arm64";; 74 | *) echo "(!) Architecture $architecture unsupported"; exit 1 ;; 75 | esac 76 | 77 | # Use a temporary locaiton for conftest archive 78 | export TMP_DIR="/tmp/tmp-conftest" 79 | mkdir -p ${TMP_DIR} 80 | chmod 700 ${TMP_DIR} 81 | 82 | # Install OPA 83 | echo "(*) Installing conftest..." 84 | find_version_from_git_tags CONFTEST_VERSION https://github.com/open-policy-agent/conftest 85 | 86 | CONFTEST_VERSION="${CONFTEST_VERSION#"v"}" 87 | curl -sSL -o ${TMP_DIR}/conftest.tar.gz "https://github.com/open-policy-agent/conftest/releases/download/v${CONFTEST_VERSION}/conftest_${CONFTEST_VERSION}_Linux_${architecture}.tar.gz" 88 | tar -xzf "${TMP_DIR}/conftest.tar.gz" -C "${TMP_DIR}" conftest 89 | mv ${TMP_DIR}/conftest /usr/local/bin/conftest 90 | chmod 0755 /usr/local/bin/conftest 91 | 92 | # Clean up 93 | rm -rf /var/lib/apt/lists/* 94 | 95 | echo "Done!" 96 | -------------------------------------------------------------------------------- /src/terraform-docs/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Clean up 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | TF_DOCS_VERSION=${VERSION:-"latest"} 9 | 10 | if [ "$(id -u)" -ne 0 ]; then 11 | echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 12 | exit 1 13 | fi 14 | 15 | apt_get_update() 16 | { 17 | echo "Running apt-get update..." 18 | apt-get update -y 19 | } 20 | 21 | # Checks if packages are installed and installs them if not 22 | check_packages() { 23 | if ! dpkg -s "$@" > /dev/null 2>&1; then 24 | if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then 25 | apt_get_update 26 | fi 27 | apt-get -y install --no-install-recommends "$@" 28 | fi 29 | } 30 | 31 | export DEBIAN_FRONTEND=noninteractive 32 | 33 | # Figure out correct version of a three part version number is not passed 34 | find_version_from_git_tags() { 35 | local variable_name=$1 36 | local requested_version=${!variable_name} 37 | if [ "${requested_version}" = "none" ]; then return; fi 38 | local repository=$2 39 | local prefix=${3:-"tags/v"} 40 | local separator=${4:-"."} 41 | local last_part_optional=${5:-"false"} 42 | if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then 43 | local escaped_separator=${separator//./\\.} 44 | local last_part 45 | if [ "${last_part_optional}" = "true" ]; then 46 | last_part="(${escaped_separator}[0-9]+)?" 47 | else 48 | last_part="${escaped_separator}[0-9]+" 49 | fi 50 | local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" 51 | local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" 52 | if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then 53 | declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" 54 | else 55 | set +e 56 | declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" 57 | set -e 58 | fi 59 | fi 60 | if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then 61 | echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 62 | exit 1 63 | fi 64 | echo "${variable_name}=${!variable_name}" 65 | } 66 | 67 | # Install dependencies 68 | check_packages curl git tar 69 | 70 | architecture="$(uname -m)" 71 | case $architecture in 72 | x86_64) architecture="amd64";; 73 | aarch64 | armv8* | arm64) architecture="arm64";; 74 | *) echo "(!) Architecture $architecture unsupported"; exit 1 ;; 75 | esac 76 | 77 | # Use a temporary locaiton for conftest archive 78 | export TMP_DIR="/tmp/tmp-conftest" 79 | mkdir -p ${TMP_DIR} 80 | chmod 700 ${TMP_DIR} 81 | 82 | # Install terraform-docs 83 | echo "(*) Installing terraform-docs..." 84 | find_version_from_git_tags TF_DOCS_VERSION https://github.com/terraform-docs/terraform-docs 85 | 86 | TF_DOCS_VERSION="${TF_DOCS_VERSION#"v"}" 87 | curl -sSL -o ${TMP_DIR}/terraform-docs.tar.gz "https://github.com/terraform-docs/terraform-docs/releases/download/v${TF_DOCS_VERSION}/terraform-docs-v${TF_DOCS_VERSION}-linux-${architecture}.tar.gz" 88 | tar -xzf "${TMP_DIR}/terraform-docs.tar.gz" -C "${TMP_DIR}" terraform-docs 89 | mv ${TMP_DIR}/terraform-docs /usr/local/bin/terraform-docs 90 | chmod 0755 /usr/local/bin/terraform-docs 91 | 92 | # Clean up 93 | rm -rf /var/lib/apt/lists/* 94 | 95 | echo "Done!" 96 | -------------------------------------------------------------------------------- /src/google-cloud-cli/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Clean up 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | GCLOUD_VERSION=${VERSION:-"latest"} 9 | INSTALL_GKEGCLOUDAUTH_PLUGIN="${INSTALL_GKEGCLOUDAUTH_PLUGIN:-"false"}" 10 | 11 | if [ "$(id -u)" -ne 0 ]; then 12 | echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 13 | exit 1 14 | fi 15 | 16 | apt_get_update() 17 | { 18 | echo "Running apt-get update..." 19 | apt-get update -y 20 | } 21 | 22 | # Checks if packages are installed and installs them if not 23 | check_packages() { 24 | if ! dpkg -s "$@" > /dev/null 2>&1; then 25 | if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then 26 | apt_get_update 27 | fi 28 | apt-get -y install --no-install-recommends "$@" 29 | fi 30 | } 31 | 32 | export DEBIAN_FRONTEND=noninteractive 33 | 34 | # Soft version matching that resolves a version for a given package in the *current apt-cache* 35 | # Return value is stored in first argument (the unprocessed version) 36 | apt_cache_version_soft_match() { 37 | 38 | # Version 39 | local variable_name="$1" 40 | local requested_version=${!variable_name} 41 | # Package Name 42 | local package_name="$2" 43 | 44 | # Ensure we've exported useful variables 45 | . /etc/os-release 46 | local architecture="$(dpkg --print-architecture)" 47 | 48 | dot_escaped="${requested_version//./\\.}" 49 | dot_plus_escaped="${dot_escaped//+/\\+}" 50 | # Regex needs to handle debian package version number format: https://www.systutorials.com/docs/linux/man/5-deb-version/ 51 | version_regex="^(.+:)?${dot_plus_escaped}([\\.\\+ ~:-]|$)" 52 | set +e # Don't exit if finding version fails - handle gracefully 53 | fuzzy_version="$(apt-cache madison ${package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${version_regex}")" 54 | set -e 55 | if [ -z "${fuzzy_version}" ]; then 56 | echo "(!) No full or partial for package \"${package_name}\" match found in apt-cache for \"${requested_version}\" on OS ${ID} ${VERSION_CODENAME} (${architecture})." 57 | echo "Available versions:" 58 | apt-cache madison ${package_name} | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+' 59 | exit 1 # Fail entire script 60 | fi 61 | 62 | # Globally assign fuzzy_version to this value 63 | # Use this value as the return value of this function 64 | declare -g ${variable_name}="=${fuzzy_version}" 65 | echo "${variable_name} ${!variable_name}" 66 | } 67 | 68 | install_using_apt() { 69 | # Install dependencies 70 | check_packages apt-transport-https curl ca-certificates gnupg python3 71 | # Import key 72 | curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - 73 | echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list 74 | apt_get_update 75 | 76 | if [ "${GCLOUD_VERSION}" = "latest" ]; then 77 | # Empty, meaning grab the "latest" in the apt repo 78 | GCLOUD_VERSION="" 79 | else 80 | # Sets GCLOUD_VERSION to our desired version, if match found. 81 | apt_cache_version_soft_match GCLOUD_VERSION "google-cloud-cli" 82 | if [ "$?" != 0 ]; then 83 | return 1 84 | fi 85 | fi 86 | 87 | if ! (apt-get install -yq google-cloud-cli${GCLOUD_VERSION}); then 88 | rm -f /etc/apt/sources.list.d/google-cloud-sdk.list 89 | return 1 90 | fi 91 | 92 | # Install gke-gcloud-auth-plugin if needed 93 | if [ "${INSTALL_GKEGCLOUDAUTH_PLUGIN}" = "true" ]; then 94 | echo "(*) Installing 'gke-gcloud-auth-plugin' plugin..." 95 | check_packages google-cloud-sdk-gke-gcloud-auth-plugin 96 | fi 97 | } 98 | 99 | echo "(*) Installing google-cloud CLI..." 100 | . /etc/os-release 101 | 102 | # Install 103 | install_using_apt 104 | 105 | # Clean up 106 | rm -rf /var/lib/apt/lists/* 107 | 108 | echo "Done!" 109 | -------------------------------------------------------------------------------- /src/k9s/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | # Clean up 6 | rm -rf /var/lib/apt/lists/* 7 | 8 | K9S_VERSION=${VERSION:-"latest"} 9 | 10 | if [ "$(id -u)" -ne 0 ]; then 11 | echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 12 | exit 1 13 | fi 14 | 15 | apt_get_update() 16 | { 17 | echo "Running apt-get update..." 18 | apt-get update -y 19 | } 20 | 21 | # Checks if packages are installed and installs them if not 22 | check_packages() { 23 | if ! dpkg -s "$@" > /dev/null 2>&1; then 24 | if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then 25 | apt_get_update 26 | fi 27 | apt-get -y install --no-install-recommends "$@" 28 | fi 29 | } 30 | 31 | # from https://stackoverflow.com/questions/4023830/how-to-compare-two-strings-in-dot-separated-version-format-in-bash 32 | function vercomp() { 33 | if [[ "$1" == "$2" ]]; then 34 | return 0 35 | fi 36 | local IFS=. 37 | # shellcheck disable=SC2206 38 | local i ver1=($1) ver2=($2) 39 | # fill empty fields in ver1 with zeros 40 | for ((i = ${#ver1[@]}; i < ${#ver2[@]}; i++)); do 41 | ver1[i]=0 42 | done 43 | for ((i = 0; i < ${#ver1[@]}; i++)); do 44 | if [[ -z ${ver2[i]} ]]; then 45 | # fill empty fields in ver2 with zeros 46 | ver2[i]=0 47 | fi 48 | if ((10#${ver1[i]} > 10#${ver2[i]})); then 49 | return 1 50 | fi 51 | if ((10#${ver1[i]} < 10#${ver2[i]})); then 52 | return 2 53 | fi 54 | done 55 | return 0 56 | } 57 | 58 | get_architecture() { 59 | local version="$1" 60 | local architecture_ 61 | architecture="$(uname -m)" 62 | case $architecture in 63 | x86_64) architecture_="amd64";; 64 | aarch64 | armv8* | arm64) architecture_="arm64";; 65 | *) echo "(!) Architecture $architecture unsupported"; exit 1 ;; 66 | esac 67 | 68 | # x86_64 before 0.27.0 69 | vercomp "$version" "0.27.0" 70 | case $? in 71 | 0) op='=' ;; 72 | 1) op='>' ;; 73 | 2) op='<' ;; 74 | esac 75 | if [[ "$op" == '<' && "$architecture" == 'x86_64' ]]; then 76 | architecture_="x86_64" 77 | fi 78 | 79 | echo "${architecture_}" 80 | } 81 | 82 | export DEBIAN_FRONTEND=noninteractive 83 | 84 | # Figure out correct version of a three part version number is not passed 85 | find_version_from_git_tags() { 86 | local variable_name=$1 87 | local requested_version=${!variable_name} 88 | if [ "${requested_version}" = "none" ]; then return; fi 89 | local repository=$2 90 | local prefix=${3:-"tags/v"} 91 | local separator=${4:-"."} 92 | local last_part_optional=${5:-"false"} 93 | if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then 94 | local escaped_separator=${separator//./\\.} 95 | local last_part 96 | if [ "${last_part_optional}" = "true" ]; then 97 | last_part="(${escaped_separator}[0-9]+)?" 98 | else 99 | last_part="${escaped_separator}[0-9]+" 100 | fi 101 | local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" 102 | local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" 103 | if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then 104 | declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" 105 | else 106 | set +e 107 | declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" 108 | set -e 109 | fi 110 | fi 111 | if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then 112 | echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 113 | exit 1 114 | fi 115 | echo "${variable_name}=${!variable_name}" 116 | } 117 | 118 | # Install dependencies 119 | check_packages curl git tar 120 | 121 | # Use a temporary locaiton for k9s archive 122 | export TMP_DIR="/tmp/tmp-k9s" 123 | mkdir -p ${TMP_DIR} 124 | chmod 700 ${TMP_DIR} 125 | 126 | # Install k9s 127 | echo "(*) Installing k9s..." 128 | find_version_from_git_tags K9S_VERSION https://github.com/derailed/k9s 129 | K9S_VERSION="${K9S_VERSION#"v"}" 130 | 131 | architecture=$(get_architecture "$K9S_VERSION") 132 | 133 | curl -sSL -o ${TMP_DIR}/k9s.tar.gz "https://github.com/derailed/k9s/releases/download/v${K9S_VERSION}/k9s_Linux_${architecture}.tar.gz" 134 | tar -xzf "${TMP_DIR}/k9s.tar.gz" -C "${TMP_DIR}" k9s 135 | mv ${TMP_DIR}/k9s /usr/local/bin/k9s 136 | chmod 0755 /usr/local/bin/k9s 137 | 138 | # Clean up 139 | rm -rf /var/lib/apt/lists/* 140 | 141 | echo "Done!" 142 | --------------------------------------------------------------------------------