diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 24d7369..82349d6 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,13 +2,14 @@ "name": "TheDiveO's devcontainer features", "image": "mcr.microsoft.com/devcontainers/base:ubuntu", "features": { + "ghcr.io/thediveo/devcontainer-features/pinact:0": {}, "ghcr.io/devcontainers/features/node:2": {}, "./devcontainers-cli": {}, "ghcr.io/devcontainers/features/docker-in-docker:3": { "version": "latest", "moby": false // go for the upstream Docker-CE }, - "ghcr.io/thediveo/devcontainer-features/pull-through-cache-registry:0": { + "ghcr.io/thediveo/devcontainer-features/pull-through-cache-registry:1": { "port": "9999" } }, diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 3525c8c..ade3c12 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -14,10 +14,10 @@ jobs: packages: write steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: "publish Features" - uses: devcontainers/action@1082abd5d2bf3a11abccba70eef98df068277772 # pin@v1 + uses: devcontainers/action@1082abd5d2bf3a11abccba70eef98df068277772 # v1.4.3 with: publish-features: "true" base-path-to-features: "./src" diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e8d26db..c7a9a49 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -17,6 +17,7 @@ jobs: - bpftool - cni-plugins - docsify + - gcx - go-ebpf - go-mod-upgrade - gocover @@ -31,7 +32,7 @@ jobs: baseImage: - mcr.microsoft.com/devcontainers/base:ubuntu steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: "install latest devcontainer CLI" run: npm install -g @devcontainers/cli@0.84.1 diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index afc4e29..2f0b7d3 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -8,10 +8,10 @@ jobs: validate: runs-on: ubuntu-latest steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: "validate devcontainer-feature.json files" - uses: devcontainers/action@1082abd5d2bf3a11abccba70eef98df068277772 # pin@v1 + uses: devcontainers/action@1082abd5d2bf3a11abccba70eef98df068277772 # v1.4.3 with: validate-only: "true" base-path-to-features: "./src" diff --git a/README.md b/README.md index 311fd6d..6354425 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Container feature that also doesn't support Alpine. | bpftool | ✅ | ✅ | ✅ | ✅ | ✅ | | cni-plugins | | ✅ | ✅ | ✅ | ✅ | | docsify | | ✅ | ✅ | ✅ | ✅ | +| gcx | ✅ | ✅ | ✅ | ✅ | ✅ | | go-ebpf | | ✅ | ✅ | ✅ | ✅ | | go-mod-upgrade | | ✅ | ✅ | ✅ | ✅ | | gocover | | ✅ | ✅ | ✅ | ✅ | @@ -42,6 +43,9 @@ Container feature that also doesn't support Alpine. directory via `docsify serve` in the background (with the specific workspace location being configurable). +- [gcx](src/gcx/README.md) – installs `gcx` directly from upstream + https://github.com/grafana/gcx binary releases. + - [grafanactl](src/grafanactl/README.md) – installs `grafanactl` directly from upstream https://github.com/grafana/grafanactl binary releases. diff --git a/src/gcx/NOTES.md b/src/gcx/NOTES.md new file mode 100644 index 0000000..1297ecb --- /dev/null +++ b/src/gcx/NOTES.md @@ -0,0 +1,11 @@ +## OS Support + +Tested with: +- [ghcr.io/almalinux/almalinux](https://ghcr.io/almalinux/almalinux), +- [mcr.microsoft.com/devcontainers/base:debian](https://mcr.microsoft.com/en-us/artifact/mar/devcontainers/base/about#about:_debian), +- [fedora](https://hub.docker.com/_/fedora), +- [mcr.microsoft.com/devcontainers/base:ubuntu](https://mcr.microsoft.com/en-us/artifact/mar/devcontainers/base/about#about:_ubuntu). + +## Acknowledgement + +[@gcx](https://github.com/grafana/gcx) diff --git a/src/gcx/README.md b/src/gcx/README.md new file mode 100644 index 0000000..7eafd59 --- /dev/null +++ b/src/gcx/README.md @@ -0,0 +1,35 @@ + +# gcx (gcx) + +Installs Grafana gcx CLI from upstream https://github.com/grafana/gcx binary releases. + +## Example Usage + +```json +"features": { + "ghcr.io/thediveo/devcontainer-features/gcx:0": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| version | version of gcx to install from upstream | string | latest | + +## OS Support + +Tested with: +- [ghcr.io/almalinux/almalinux](https://ghcr.io/almalinux/almalinux), +- [mcr.microsoft.com/devcontainers/base:debian](https://mcr.microsoft.com/en-us/artifact/mar/devcontainers/base/about#about:_debian), +- [fedora](https://hub.docker.com/_/fedora), +- [mcr.microsoft.com/devcontainers/base:ubuntu](https://mcr.microsoft.com/en-us/artifact/mar/devcontainers/base/about#about:_ubuntu). + +## Acknowledgement + +[@gcx](https://github.com/grafana/gcx) + + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/thediveo/devcontainer-features/blob/main/src/gcx/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/gcx/devcontainer-feature.json b/src/gcx/devcontainer-feature.json new file mode 100644 index 0000000..05bcef6 --- /dev/null +++ b/src/gcx/devcontainer-feature.json @@ -0,0 +1,13 @@ +{ + "name": "gcx", + "id": "gcx", + "version": "0.0.1", + "description": "Installs Grafana gcx CLI from upstream https://github.com/grafana/gcx binary releases.", + "options": { + "version": { + "type": "string", + "default": "latest", + "description": "version of gcx to install from upstream" + } + } +} \ No newline at end of file diff --git a/src/gcx/install.sh b/src/gcx/install.sh new file mode 100755 index 0000000..c0c4aaf --- /dev/null +++ b/src/gcx/install.sh @@ -0,0 +1,178 @@ +#!/usr/bin/env bash + +# Distribution and package manager detection are licensed by Microsoft +# Corporation under the MIT License, please refer to: +# https://github.com/devcontainers/features/blob/main/src/go/install.sh: +# +# Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the +# MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license +# information + +set -e + +GCX_VERSION="${VERSION:-"latest"}" + +REPOSLUG="grafana/gcx" +QUERYLATEST_URL="https://api.github.com/repos/${REPOSLUG}/releases/latest" +RELEASE_URL="https://github.com/${REPOSLUG}/releases/download/" + +echo "installing feature gcx..." + +if [ "$(id -u)" -ne 0 ]; then + echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' + exit 1 +fi + +# Bring in ID, ID_LIKE, VERSION_ID, VERSION_CODENAME +. /etc/os-release +# Get an adjusted ID independent of distro variants +MAJOR_VERSION_ID=$(echo ${VERSION_ID} | cut -d . -f 1) +if [ "${ID}" = "debian" ] || [ "${ID_LIKE}" = "debian" ]; then + ADJUSTED_ID="debian" +elif [ "${ID}" = "alpine" ]; then + ADJUSTED_ID="alpine" +elif [[ "${ID}" = "rhel" || "${ID}" = "fedora" || "${ID}" = "mariner" || "${ID_LIKE}" = *"rhel"* || "${ID_LIKE}" = *"fedora"* || "${ID_LIKE}" = *"mariner"* ]]; then + ADJUSTED_ID="rhel" + if [[ "${ID}" = "rhel" ]] || [[ "${ID}" = *"alma"* ]] || [[ "${ID}" = *"rocky"* ]]; then + VERSION_CODENAME="rhel${MAJOR_VERSION_ID}" + else + VERSION_CODENAME="${ID}${MAJOR_VERSION_ID}" + fi +else + echo "Linux distro ${ID} not supported." + exit 1 +fi + +if [ "${ADJUSTED_ID}" = "rhel" ] && [ "${VERSION_CODENAME-}" = "centos7" ]; then + # As of 1 July 2024, mirrorlist.centos.org no longer exists. + # Update the repo files to reference vault.centos.org. + sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo + sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo + sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo +fi + +# Setup INSTALL_CMD & PKG_MGR_CMD +if type apt-get > /dev/null 2>&1; then + PKG_MGR_CMD=apt-get + INSTALL_CMD="${PKG_MGR_CMD} -y install --no-install-recommends" +elif type apk > /dev/null 2>&1; then + PKG_MGR_CMD=apk + INSTALL_CMD="${PKG_MGR_CMD} add --no-interactive" +elif type microdnf > /dev/null 2>&1; then + PKG_MGR_CMD=microdnf + INSTALL_CMD="${PKG_MGR_CMD} ${INSTALL_CMD_ADDL_REPOS} -y install --refresh --best --nodocs --noplugins --setopt=install_weak_deps=0" +elif type dnf > /dev/null 2>&1; then + PKG_MGR_CMD=dnf + INSTALL_CMD="${PKG_MGR_CMD} ${INSTALL_CMD_ADDL_REPOS} -y install --refresh --best --nodocs --noplugins --setopt=install_weak_deps=0" +else + PKG_MGR_CMD=yum + INSTALL_CMD="${PKG_MGR_CMD} ${INSTALL_CMD_ADDL_REPOS} -y install --noplugins --setopt=install_weak_deps=0" +fi + +# Clean up +clean_up() { + case ${ADJUSTED_ID} in + alpine) + rm -rf /var/cache/apk/* + ;; + debian) + rm -rf /var/lib/apt/lists/* + ;; + rhel) + rm -rf /var/cache/dnf/* /var/cache/yum/* + rm -rf /tmp/yum.log + rm -rf ${GPG_INSTALL_PATH} + ;; + esac +} +clean_up + +pkg_mgr_update() { + case $ADJUSTED_ID in + alpine) + if [ "$(find /var/cache/apk/* | wc -l)" = "0" ]; then + echo "Running apk update..." + ${PKG_MGR_CMD} update + fi + ;; + debian) + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + echo "Running apt-get update..." + ${PKG_MGR_CMD} update -y + fi + ;; + rhel) + if [ ${PKG_MGR_CMD} = "microdnf" ]; then + if [ "$(ls /var/cache/yum/* 2>/dev/null | wc -l)" = 0 ]; then + echo "Running ${PKG_MGR_CMD} makecache ..." + ${PKG_MGR_CMD} makecache + fi + else + if [ "$(ls /var/cache/${PKG_MGR_CMD}/* 2>/dev/null | wc -l)" = 0 ]; then + echo "Running ${PKG_MGR_CMD} check-update ..." + set +e + ${PKG_MGR_CMD} check-update + rc=$? + if [ $rc != 0 ] && [ $rc != 100 ]; then + exit 1 + fi + set -e + fi + fi + ;; + esac +} + +# Checks if packages are installed and installs them if not +check_packages() { + case ${ADJUSTED_ID} in + alpine) + ${INSTALL_CMD} "$@" + ;; + debian) + if ! dpkg -s "$@" > /dev/null 2>&1; then + pkg_mgr_update + ${INSTALL_CMD} "$@" + fi + ;; + rhel) + if ! rpm -q "$@" > /dev/null 2>&1; then + pkg_mgr_update + ${INSTALL_CMD} "$@" + fi + ;; + esac +} + +case $(uname -m) in + x86_64) ARCH="amd64";; + aarch64 | armv8*) ARCH="arm64";; + *) echo "Unsupported architecture: $(uname -m)"; exit 1;; +esac + +export DEBIAN_FRONTEND=noninteractive + +if ! type curl > /dev/null 2>&1; then + check_packages curl +fi + +if [ "$GCX_VERSION" = "latest" ]; then + # get latest release + GCX_VERSION=$(curl -s ${QUERYLATEST_URL} | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') +fi + +echo "installing gcx version: ${GCX_VERSION}" +echo "for architecture: ${ARCH}" + +URL="${RELEASE_URL}${GCX_VERSION}/gcx_${GCX_VERSION#v}_linux_${ARCH}.tar.gz" +echo "from: ${URL}" + +curl -sSL -o /tmp/gcx.tar.gz "${URL}" +ls -lH /tmp/gcx.tar.gz +tar xzof /tmp/gcx.tar.gz -C /usr/local/bin/ gcx +chmod 0755 /usr/local/bin/gcx +rm /tmp/gcx.tar.gz + +clean_up + +echo "Done!" diff --git a/test/gcx/almalinux.sh b/test/gcx/almalinux.sh new file mode 100644 index 0000000..d4e56d7 --- /dev/null +++ b/test/gcx/almalinux.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e + +. ./test.sh diff --git a/test/gcx/alpine.sh b/test/gcx/alpine.sh new file mode 100644 index 0000000..d4e56d7 --- /dev/null +++ b/test/gcx/alpine.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e + +. ./test.sh diff --git a/test/gcx/debian.sh b/test/gcx/debian.sh new file mode 100644 index 0000000..d4e56d7 --- /dev/null +++ b/test/gcx/debian.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e + +. ./test.sh diff --git a/test/gcx/fedora.sh b/test/gcx/fedora.sh new file mode 100644 index 0000000..d4e56d7 --- /dev/null +++ b/test/gcx/fedora.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e + +. ./test.sh diff --git a/test/gcx/scenarios.json b/test/gcx/scenarios.json new file mode 100644 index 0000000..999923f --- /dev/null +++ b/test/gcx/scenarios.json @@ -0,0 +1,34 @@ +{ + "v0.0.5": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04", + "features": { + "grafanactl": { + "version": "v0.0.5" + } + } + }, + "almalinux": { + "image": "ghcr.io/almalinux/almalinux:9", + "features": { + "grafanactl": {} + } + }, + "alpine": { + "image": "mcr.microsoft.com/devcontainers/base:alpine", + "features": { + "grafanactl": {} + } + }, + "debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian-12", + "features": { + "grafanactl": {} + } + }, + "fedora": { + "image": "fedora", + "features": { + "grafanactl": {} + } + } +} \ No newline at end of file diff --git a/test/gcx/test.sh b/test/gcx/test.sh new file mode 100755 index 0000000..1f0ecb6 --- /dev/null +++ b/test/gcx/test.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -e + +source dev-container-features-test-lib + +check "grafanactl" bash -c "grafanactl --version | grep -E 'grafanactl version [0-9]+\.[0-9]+\.[0-9]+ built from'" + +reportResults diff --git a/test/grafanactl/v0.0.5.sh b/test/gcx/v0.0.5.sh similarity index 100% rename from test/grafanactl/v0.0.5.sh rename to test/gcx/v0.0.5.sh diff --git a/test/grafanactl/scenarios.json b/test/grafanactl/scenarios.json index 999923f..b233a26 100644 --- a/test/grafanactl/scenarios.json +++ b/test/grafanactl/scenarios.json @@ -1,34 +1,34 @@ { - "v0.0.5": { + "v0.4.0": { "image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04", "features": { - "grafanactl": { - "version": "v0.0.5" + "gcx": { + "version": "v0.4.0" } } }, "almalinux": { - "image": "ghcr.io/almalinux/almalinux:9", + "image": "ghcr.io/almalinux/almalinux:10", "features": { - "grafanactl": {} + "gcx": {} } }, "alpine": { "image": "mcr.microsoft.com/devcontainers/base:alpine", "features": { - "grafanactl": {} + "gcx": {} } }, "debian": { - "image": "mcr.microsoft.com/devcontainers/base:debian-12", + "image": "mcr.microsoft.com/devcontainers/base:debian-13", "features": { - "grafanactl": {} + "gcx": {} } }, "fedora": { "image": "fedora", "features": { - "grafanactl": {} + "gcx": {} } } } \ No newline at end of file diff --git a/test/grafanactl/test.sh b/test/grafanactl/test.sh index 1f0ecb6..95d146b 100755 --- a/test/grafanactl/test.sh +++ b/test/grafanactl/test.sh @@ -3,6 +3,6 @@ set -e source dev-container-features-test-lib -check "grafanactl" bash -c "grafanactl --version | grep -E 'grafanactl version [0-9]+\.[0-9]+\.[0-9]+ built from'" +check "gcx" bash -c "gcx --version | grep -E 'gcx version [0-9]+\.[0-9]+\.[0-9]+ built from'" reportResults diff --git a/test/grafanactl/v0.4.0.sh b/test/grafanactl/v0.4.0.sh new file mode 100644 index 0000000..0132d9b --- /dev/null +++ b/test/grafanactl/v0.4.0.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -e + +source dev-container-features-test-lib + +check "gcx 0.4.0" bash -c "gcx --version | grep -E 'gcx version 0.4.0 built from'" + +reportResults