16 Commits

Author SHA1 Message Date
google-labs-jules[bot]
2e019b16ff fix: Correct Dockerfile lib path and add Helm dependency toggle
This commit includes two main changes:

1.  **Fix Dockerfile library path for amd64:**
    - I updated the `exporter/Dockerfile` to correctly determine the source path for `libiperf.so.0` when building for different architectures.
    - Specifically, for `TARGETARCH=amd64`, the path `/usr/lib/x86_64-linux-gnu/libiperf.so.0` is now used.
    - For `TARGETARCH=arm64`, the path `/usr/lib/aarch64-linux-gnu/libiperf.so.0` is used.
    - I achieved this by copying the library to a canonical temporary location in the builder stage based on `TARGETARCH`, and then copying it from this location into the final image. This resolves an issue where builds for `amd64` would fail to find the library.

2.  **Add Helm chart option to disable dependencies:**
    - I added a new option `dependencies.install` (default: `true`) to `charts/iperf3-monitor/values.yaml`.
    - This allows you to disable the installation of managed dependencies (i.e., Prometheus Operator via `kube-prometheus-stack` or `prometheus-operator` from TrueCharts) even if `serviceMonitor.enabled` is true.
    - I updated the `condition` for these dependencies in `charts/iperf3-monitor/Chart.yaml` to `dependencies.install, serviceMonitor.enabled, ...`.
    - This is useful for you if you manage your Prometheus Operator installation separately.
2025-06-20 13:25:34 +00:00
google-labs-jules[bot]
a00629af7a fix: Ensure multi-platform builds with Docker Buildx
This commit updates the GitHub Actions workflows to correctly set up
Docker Buildx for multi-platform (amd64, arm64) image builds.

Previously, the workflows were missing the `docker/setup-buildx-action`
step, which led to errors when attempting multi-platform builds as the
default Docker driver does not support this.

The following changes were made:
1.  **Added `docker/setup-buildx-action@v3`:**
    - This step is now included in both the CI (`.github/workflows/ci.yaml`) and Release (`.github/workflows/release.yml`) workflows before the QEMU setup and build/push actions.

2.  **Dockerfile (`exporter/Dockerfile`):**
    - Remains as per the previous commit, using `TARGETARCH` to correctly copy architecture-specific libraries. This part was already correct for multi-arch builds.

3.  **Helm Chart:**
    - No changes were required for the Helm chart.

This ensures that the CI/CD pipeline can successfully build and push
Docker images for both `linux/amd64` and `linux/arm64` architectures.
2025-06-20 13:13:46 +00:00
google-labs-jules[bot]
e1164a597e feat: Add support for arm64 architecture
This commit introduces support for the arm64 architecture by:

1.  **Updating the Dockerfile:**
    *   The `exporter/Dockerfile` now uses the `TARGETARCH` build argument to dynamically determine the correct path for `libiperf.so.0`. This allows the same Dockerfile to be used for building both `amd64` and `arm64` images.

2.  **Modifying GitHub Workflows:**
    *   The CI workflow (`.github/workflows/ci.yaml`) and the Release workflow (`.github/workflows/release.yml`) have been updated to build and push multi-architecture Docker images (`linux/amd64` and `linux/arm64`).
    *   This involves adding the `docker/setup-qemu-action` for cross-compilation and specifying the target platforms in the `docker/build-push-action`.

3.  **Helm Chart:**
    *   No changes were required for the Helm chart as the image tag will now point to a multi-arch manifest, and the default iperf3 server image (`networkstatic/iperf3:latest`) is assumed to be multi-arch. Node selectors in the chart are not architecture-specific.

These changes enable the deployment of the iperf3-monitor on Kubernetes clusters with arm64 nodes.
2025-06-20 13:00:09 +00:00
458b786ff4 Fix: Ignore packaged chart files and remove markdown files (#10)
Removes the outdated markdown files and fixes the .gitignore to ignore packaged chart files in the correct directories. This prevents them from being committed to
2025-06-20 17:42:17 +05:30
96be13a23c Fix: Use dependencies scope for truecharts prometheus-operator (#9)
Fixes an issue where truecharts prometheus operator version and
repository values where not accessible because they were not under the
`dependencies` scope.
2025-06-20 13:35:13 +05:30
8d51afc24e Feat: Add optional TrueCharts Prometheus Operator dependency (#8)
This commit introduces a configurable dependency for the Prometheus Operator,
allowing you to choose between the standard kube-prometheus-stack and
the TrueCharts version of prometheus-operator.

Changes include:

1.  **values.yaml:**
    *   Added a `dependencies` section with the following new values:
        *   `useTrueChartsPrometheusOperator` (boolean, default: false):
            Controls which operator dependency is enabled.
        *   `trueChartsPrometheusOperatorRepository` (string, default:
            "oci://tccr.io/truecharts"): Repository for the TrueCharts operator.
        *   `trueChartsPrometheusOperatorVersion` (string, default: "8.11.1"):
            Chart version for the TrueCharts operator.

2.  **Chart.yaml:**
    *   The `kube-prometheus-stack` dependency condition is updated to
        `"serviceMonitor.enabled, !values.dependencies.useTrueChartsPrometheusOperator"`.
    *   A new dependency for `prometheus-operator` (TrueCharts) is added:
        *   `name: prometheus-operator`
        *   `version: "{{ .Values.dependencies.trueChartsPrometheusOperatorVersion }}"`
        *   `repository: "{{ .Values.dependencies.trueChartsPrometheusOperatorRepository }}"`
        *   `condition: "serviceMonitor.enabled, values.dependencies.useTrueChartsPrometheusOperator"`

This provides you with more flexibility in choosing your Prometheus
Operator stack while using the iperf3-monitor chart.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2025-06-20 13:25:30 +05:30
a2d57908f6 Merge pull request #7 from malarinv/fix/readme-license-ci-helm
Fix: Final correction for yq command in release workflow
2025-06-20 03:07:58 +05:30
google-labs-jules[bot]
4298031a2d Fix: Final correction for yq command in release workflow
This commit implements a verified yq command syntax in the
`.github/workflows/release.yml` file to ensure correct and reliable
updating of Chart.yaml version and appVersion from Git tags.

The previous attempts faced issues with yq argument parsing and
environment variable substitution. The new commands:
  VERSION=$VERSION yq e -i '.version = strenv(VERSION)' ./charts/iperf3-monitor/Chart.yaml
  VERSION=$VERSION yq e -i '.appVersion = strenv(VERSION)' ./charts/iperf3-monitor/Chart.yaml
were tested and confirmed to correctly modify
the Chart.yaml file as intended.

This change should resolve the issues where chart versions were being
set incorrectly or to empty strings during the release process.
2025-06-19 21:36:48 +00:00
e6d1a8fb91 Merge pull request #6 from malarinv/fix/readme-license-ci-helm
Fix: Update README, license consistency, and Helm chart configurations
2025-06-20 02:44:04 +05:30
google-labs-jules[bot]
a9f2a49549 Fix: Update README, license consistency, and Helm chart configurations
This commit addresses several issues to improve repository accuracy and CI reliability:

1.  **README.md Updates:**
    *   I corrected the Helm repository URL to `https://malarinv.github.io/iperf3-monitor/`.
    *   I updated the default exporter image name to `ghcr.io/malarinv/iperf3-monitor` in examples.
    *   I revised the License section to accurately reflect the AGPLv3 license present in the `LICENSE` file, removing contradictory statements.

2.  **License Consistency:**
    *   I confirmed `LICENSE` file contains AGPLv3. README now correctly refers to it.

3.  **Helm Chart Adjustments:**
    *   `charts/iperf3-monitor/Chart.yaml`: I removed placeholder comments for clarity. Versioning is handled by the release workflow.
    *   `charts/iperf3-monitor/values.yaml`: I updated `exporter.image.repository` to `ghcr.io/malarinv/iperf3-monitor` to match the CI build image name.

4.  **CI Workflow Verification:**
    *   I verified that `.github/workflows/release.yml` correctly uses `yq` to set chart versions from Git tags and publishes to the correct GitHub Pages URL. This should prevent the previously noted `chart.metadata.version is required` error, which was associated with an older version of the release workflow.

These changes ensure that the documentation is up-to-date, the Helm chart defaults are correct, and the CI pipeline for chart publishing is robust.
2025-06-19 21:13:13 +00:00
7f0784d382 Merge pull request #5 from malarinv/fix_helm_add_devbox
feat: Add devbox configuration and lock files; clean up YAML files by…
2025-06-20 02:29:45 +05:30
050fbcbf3c feat: Add devbox configuration and lock files; clean up YAML files by removing trailing newlines 2025-06-20 02:28:10 +05:30
e22d2ff71d Merge pull request #4 from malarinv/fix-helm-lint-errors
I've fixed the Helm lint errors in the iperf3-monitor chart.
2025-06-20 02:18:11 +05:30
1487901337 Merge pull request #3 from malarinv/ci
feat: Add GitHub Actions CI workflow
2025-06-20 02:18:01 +05:30
fec4cf64b9 fix: Remove unnecessary dependency section from Chart.yaml and correct formatting in exporter-deployment.yaml 2025-06-20 02:17:27 +05:30
f6c26c02b1 feat: Add GitHub Actions CI workflow
Configure automated checks for pull requests including:

- Linting the Helm chart.
- Building the exporter Docker image.
- A placeholder for future tests.
2025-06-19 01:01:01 +05:30
15 changed files with 147 additions and 3291 deletions

64
.github/workflows/ci.yaml vendored Normal file
View File

@@ -0,0 +1,64 @@
name: CI
on:
pull_request:
branches: ["main"] # Or your main development branch
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
validate-chart:
name: Validate Helm Chart
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Set up Helm
uses: azure/setup-helm@v3
with:
version: v3.10.0
- name: Helm Lint
run: helm lint ./charts/iperf3-monitor
build:
name: Build Docker Image
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build Docker image
uses: docker/build-push-action@v4
with:
context: ./exporter
push: false # Do not push on PRs
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
test:
name: Run Tests
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3
# Replace this step with your actual test command(s)
- name: Placeholder Test Step
run: echo "No tests configured yet. Add your test commands here."

View File

@@ -36,6 +36,12 @@ jobs:
- name: Check out code - name: Check out code
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Log in to GitHub Container Registry - name: Log in to GitHub Container Registry
uses: docker/login-action@v2 uses: docker/login-action@v2
with: with:
@@ -56,6 +62,7 @@ jobs:
push: true push: true
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
package-and-publish-chart: package-and-publish-chart:
name: Package and Publish Helm Chart name: Package and Publish Helm Chart
@@ -82,8 +89,8 @@ jobs:
- name: Set Chart Version from Tag - name: Set Chart Version from Tag
run: | run: |
VERSION=$(echo "${{ github.ref_name }}" | sed 's/^v//') VERSION=$(echo "${{ github.ref_name }}" | sed 's/^v//')
yq e -i '.version = strenv(VERSION)' ./charts/iperf3-monitor/Chart.yaml VERSION=$VERSION yq e -i '.version = strenv(VERSION)' ./charts/iperf3-monitor/Chart.yaml
yq e -i '.appVersion = strenv(VERSION)' ./charts/iperf3-monitor/Chart.yaml VERSION=$VERSION yq e -i '.appVersion = strenv(VERSION)' ./charts/iperf3-monitor/Chart.yaml
cat ./charts/iperf3-monitor/Chart.yaml # Optional: print updated Chart.yaml cat ./charts/iperf3-monitor/Chart.yaml # Optional: print updated Chart.yaml
- name: Publish Helm chart - name: Publish Helm chart

2
.gitignore vendored
View File

@@ -36,4 +36,4 @@ Thumbs.db
# Helm # Helm
!charts/iperf3-monitor/.helmignore !charts/iperf3-monitor/.helmignore
charts/*.tgz # Ignore packaged chart files charts/iperf3-monitor/charts/

File diff suppressed because it is too large Load Diff

View File

@@ -37,7 +37,7 @@ This separation of concerns ensures scalability, resilience, and aligns with Kub
1. Add the Helm chart repository (replace with your actual repo URL once published): 1. Add the Helm chart repository (replace with your actual repo URL once published):
```/dev/null/helm-install.sh#L1-1 ```/dev/null/helm-install.sh#L1-1
helm repo add iperf3-monitor https://your-github-org.github.io/iperf3-monitor/ helm repo add iperf3-monitor https://malarinv.github.io/iperf3-monitor/
``` ```
2. Update your Helm repositories: 2. Update your Helm repositories:
@@ -78,7 +78,7 @@ exporter:
# -- Configuration for the exporter container image. # -- Configuration for the exporter container image.
image: image:
# -- The container image repository for the exporter. # -- The container image repository for the exporter.
repository: ghcr.io/my-org/iperf3-prometheus-exporter # Replace with your repo URL repository: ghcr.io/malarinv/iperf3-monitor
# -- The container image tag for the exporter. If not set, the chart's appVersion is used. # -- The container image tag for the exporter. If not set, the chart's appVersion is used.
tag: "" tag: ""
# -- The image pull policy for the exporter container. # -- The image pull policy for the exporter container.
@@ -430,8 +430,4 @@ The project includes a GitHub Actions workflow (`.github/workflows/release.yml`)
## License ## License
This project is licensed under the terms defined in the `LICENSE` file. This project is licensed under the GNU Affero General Public License v3. See the `LICENSE` file for details.
```iperf3-monitor/LICENSE
This project is currently unlicensed. Please see the project's documentation or repository for licensing information when it becomes available.
```

File diff suppressed because it is too large Load Diff

View File

@@ -2,5 +2,8 @@ dependencies:
- name: kube-prometheus-stack - name: kube-prometheus-stack
repository: https://prometheus-community.github.io/helm-charts repository: https://prometheus-community.github.io/helm-charts
version: 75.3.6 version: 75.3.6
digest: sha256:d15acd48bfc0b842654ae025e1bd1969e636a66508020312d555db84f381c379 - name: prometheus-operator
generated: "2025-06-19T20:40:53.415529365Z" repository: oci://tccr.io/truecharts
version: 11.5.1
digest: sha256:3000e63445f8ba8df601cb483f4f77d14c5c4662bff2d16ffcf5cf1f7def314b
generated: "2025-06-20T17:25:44.538372209+05:30"

View File

@@ -12,12 +12,12 @@ keywords:
- kubernetes - kubernetes
- prometheus - prometheus
- grafana - grafana
home: https://github.com/malarinv/iperf3-monitor # Replace with your repo URL home: https://github.com/malarinv/iperf3-monitor
sources: sources:
- https://github.com/malarinv/iperf3-monitor # Replace with your repo URL - https://github.com/malarinv/iperf3-monitor
maintainers: maintainers:
- name: Malar Invention # Replace with your name - name: Malar Invention
email: malarkannan.invention@gmail.com # Replace with your email email: malarkannan.invention@gmail.com
icon: https://raw.githubusercontent.com/malarinv/iperf3-monitor/main/icon.png # Optional icon URL icon: https://raw.githubusercontent.com/malarinv/iperf3-monitor/main/icon.png # Optional icon URL
annotations: annotations:
artifacthub.io/changes: | artifacthub.io/changes: |
@@ -27,4 +27,8 @@ dependencies:
- name: kube-prometheus-stack # Example dependency if you package the whole stack - name: kube-prometheus-stack # Example dependency if you package the whole stack
version: ">=30.0.0" # Specify a compatible version range version: ">=30.0.0" # Specify a compatible version range
repository: https://prometheus-community.github.io/helm-charts repository: https://prometheus-community.github.io/helm-charts
condition: serviceMonitor.enabled # Only include if ServiceMonitor is enabled (assuming Prometheus Operator) condition: "dependencies.install, serviceMonitor.enabled, !dependencies.useTrueChartsPrometheusOperator"
- name: prometheus-operator
version: ">=8.11.1"
repository: "oci://tccr.io/truecharts"
condition: "dependencies.install, serviceMonitor.enabled, dependencies.useTrueChartsPrometheusOperator"

View File

@@ -12,7 +12,7 @@ exporter:
# -- Configuration for the exporter container image. # -- Configuration for the exporter container image.
image: image:
# -- The container image repository for the exporter. # -- The container image repository for the exporter.
repository: ghcr.io/malarinv/iperf3-prometheus-exporter # Replace with your repo URL repository: ghcr.io/malarinv/iperf3-monitor
# -- The container image tag for the exporter. If not set, the chart's appVersion is used. # -- The container image tag for the exporter. If not set, the chart's appVersion is used.
tag: "" tag: ""
# -- The image pull policy for the exporter container. # -- The image pull policy for the exporter container.
@@ -118,3 +118,19 @@ networkPolicy:
namespaceSelector: {} namespaceSelector: {}
# -- Specify pod selectors if needed. # -- Specify pod selectors if needed.
podSelector: {} podSelector: {}
# -----------------------------------------------------------------------------
# Dependency Configuration
# -----------------------------------------------------------------------------
dependencies:
# -- Set to true to install Prometheus operator dependency if serviceMonitor.enabled is also true.
# -- Set to false to disable the installation of Prometheus operator dependency,
# -- regardless of serviceMonitor.enabled. This is useful if you have Prometheus
# -- Operator installed and managed separately in your cluster.
install: true
# -- Set to true to use the TrueCharts Prometheus Operator instead of kube-prometheus-stack.
# This chart's ServiceMonitor resources require a Prometheus Operator to be functional.
# If serviceMonitor.enabled is true and dependencies.install is true,
# one of these two dependencies will be pulled based on this flag.
useTrueChartsPrometheusOperator: false

14
devbox.json Normal file
View File

@@ -0,0 +1,14 @@
{
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.7/.schema/devbox.schema.json",
"packages": [],
"shell": {
"init_hook": [
"echo 'Welcome to devbox!' > /dev/null"
],
"scripts": {
"test": [
"echo \"Error: no test specified\" && exit 1"
]
}
}
}

4
devbox.lock Normal file
View File

@@ -0,0 +1,4 @@
{
"lockfile_version": "1",
"packages": {}
}

View File

@@ -1,6 +1,8 @@
# Stage 1: Build stage with dependencies # Stage 1: Build stage with dependencies
FROM python:3.9-slim as builder FROM python:3.9-slim as builder
# Declare TARGETARCH for use in this stage
ARG TARGETARCH
WORKDIR /app WORKDIR /app
# Install iperf3 and build dependencies # Install iperf3 and build dependencies
@@ -8,6 +10,20 @@ RUN apt-get update && \
apt-get install -y --no-install-recommends gcc iperf3 libiperf-dev && \ apt-get install -y --no-install-recommends gcc iperf3 libiperf-dev && \
rm -rf /var/lib/apt/lists/* rm -rf /var/lib/apt/lists/*
# Determine the correct libiperf source directory based on TARGETARCH
# and copy libiperf.so.0 to a canonical temporary location /tmp/lib/ within the builder stage.
RUN echo "Builder stage TARGETARCH: ${TARGETARCH}" && \
LIBIPERF_SRC_DIR_SEGMENT="" && \
if [ "${TARGETARCH}" = "amd64" ]; then \
LIBIPERF_SRC_DIR_SEGMENT="x86_64-linux-gnu"; \
elif [ "${TARGETARCH}" = "arm64" ]; then \
LIBIPERF_SRC_DIR_SEGMENT="aarch64-linux-gnu"; \
else \
echo "Unsupported TARGETARCH in builder: ${TARGETARCH}" && exit 1; \
fi && \
mkdir -p /tmp/lib && \
cp "/usr/lib/${LIBIPERF_SRC_DIR_SEGMENT}/libiperf.so.0" /tmp/lib/libiperf.so.0
# Install Python dependencies # Install Python dependencies
COPY requirements.txt . COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt RUN pip install --no-cache-dir -r requirements.txt
@@ -17,9 +33,11 @@ FROM python:3.9-slim
WORKDIR /app WORKDIR /app
# Copy iperf3 binary and library from the builder stage # Copy iperf3 binary from the builder stage
COPY --from=builder /usr/bin/iperf3 /usr/bin/iperf3 COPY --from=builder /usr/bin/iperf3 /usr/bin/iperf3
COPY --from=builder /usr/lib/x86_64-linux-gnu/libiperf.so.0 /usr/lib/x86_64-linux-gnu/libiperf.so.0 # Copy the prepared libiperf.so.0 from the builder's canonical temporary location
# into a standard library path in the final image.
COPY --from=builder /tmp/lib/libiperf.so.0 /usr/lib/libiperf.so.0
# Copy installed Python packages from the builder stage # Copy installed Python packages from the builder stage
COPY --from=builder /usr/local/lib/python3.9/site-packages /usr/local/lib/python3.9/site-packages COPY --from=builder /usr/local/lib/python3.9/site-packages /usr/local/lib/python3.9/site-packages

View File

@@ -1,347 +0,0 @@
#!/usr/bin/env bash
# Copyright The Helm Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# The install script is based off of the MIT-licensed script from glide,
# the package manager for Go: https://github.com/Masterminds/glide.sh/blob/master/get
: ${BINARY_NAME:="helm"}
: ${USE_SUDO:="true"}
: ${DEBUG:="false"}
: ${VERIFY_CHECKSUM:="true"}
: ${VERIFY_SIGNATURES:="false"}
: ${HELM_INSTALL_DIR:="/usr/local/bin"}
: ${GPG_PUBRING:="pubring.kbx"}
HAS_CURL="$(type "curl" &> /dev/null && echo true || echo false)"
HAS_WGET="$(type "wget" &> /dev/null && echo true || echo false)"
HAS_OPENSSL="$(type "openssl" &> /dev/null && echo true || echo false)"
HAS_GPG="$(type "gpg" &> /dev/null && echo true || echo false)"
HAS_GIT="$(type "git" &> /dev/null && echo true || echo false)"
HAS_TAR="$(type "tar" &> /dev/null && echo true || echo false)"
# initArch discovers the architecture for this system.
initArch() {
ARCH=$(uname -m)
case $ARCH in
armv5*) ARCH="armv5";;
armv6*) ARCH="armv6";;
armv7*) ARCH="arm";;
aarch64) ARCH="arm64";;
x86) ARCH="386";;
x86_64) ARCH="amd64";;
i686) ARCH="386";;
i386) ARCH="386";;
esac
}
# initOS discovers the operating system for this system.
initOS() {
OS=$(echo `uname`|tr '[:upper:]' '[:lower:]')
case "$OS" in
# Minimalist GNU for Windows
mingw*|cygwin*) OS='windows';;
esac
}
# runs the given command as root (detects if we are root already)
runAsRoot() {
if [ $EUID -ne 0 -a "$USE_SUDO" = "true" ]; then
sudo "${@}"
else
"${@}"
fi
}
# verifySupported checks that the os/arch combination is supported for
# binary builds, as well whether or not necessary tools are present.
verifySupported() {
local supported="darwin-amd64\ndarwin-arm64\nlinux-386\nlinux-amd64\nlinux-arm\nlinux-arm64\nlinux-ppc64le\nlinux-s390x\nlinux-riscv64\nwindows-amd64\nwindows-arm64"
if ! echo "${supported}" | grep -q "${OS}-${ARCH}"; then
echo "No prebuilt binary for ${OS}-${ARCH}."
echo "To build from source, go to https://github.com/helm/helm"
exit 1
fi
if [ "${HAS_CURL}" != "true" ] && [ "${HAS_WGET}" != "true" ]; then
echo "Either curl or wget is required"
exit 1
fi
if [ "${VERIFY_CHECKSUM}" == "true" ] && [ "${HAS_OPENSSL}" != "true" ]; then
echo "In order to verify checksum, openssl must first be installed."
echo "Please install openssl or set VERIFY_CHECKSUM=false in your environment."
exit 1
fi
if [ "${VERIFY_SIGNATURES}" == "true" ]; then
if [ "${HAS_GPG}" != "true" ]; then
echo "In order to verify signatures, gpg must first be installed."
echo "Please install gpg or set VERIFY_SIGNATURES=false in your environment."
exit 1
fi
if [ "${OS}" != "linux" ]; then
echo "Signature verification is currently only supported on Linux."
echo "Please set VERIFY_SIGNATURES=false or verify the signatures manually."
exit 1
fi
fi
if [ "${HAS_GIT}" != "true" ]; then
echo "[WARNING] Could not find git. It is required for plugin installation."
fi
if [ "${HAS_TAR}" != "true" ]; then
echo "[ERROR] Could not find tar. It is required to extract the helm binary archive."
exit 1
fi
}
# checkDesiredVersion checks if the desired version is available.
checkDesiredVersion() {
if [ "x$DESIRED_VERSION" == "x" ]; then
# Get tag from release URL
local latest_release_url="https://get.helm.sh/helm-latest-version"
local latest_release_response=""
if [ "${HAS_CURL}" == "true" ]; then
latest_release_response=$( curl -L --silent --show-error --fail "$latest_release_url" 2>&1 || true )
elif [ "${HAS_WGET}" == "true" ]; then
latest_release_response=$( wget "$latest_release_url" -q -O - 2>&1 || true )
fi
TAG=$( echo "$latest_release_response" | grep '^v[0-9]' )
if [ "x$TAG" == "x" ]; then
printf "Could not retrieve the latest release tag information from %s: %s\n" "${latest_release_url}" "${latest_release_response}"
exit 1
fi
else
TAG=$DESIRED_VERSION
fi
}
# checkHelmInstalledVersion checks which version of helm is installed and
# if it needs to be changed.
checkHelmInstalledVersion() {
if [[ -f "${HELM_INSTALL_DIR}/${BINARY_NAME}" ]]; then
local version=$("${HELM_INSTALL_DIR}/${BINARY_NAME}" version --template="{{ .Version }}")
if [[ "$version" == "$TAG" ]]; then
echo "Helm ${version} is already ${DESIRED_VERSION:-latest}"
return 0
else
echo "Helm ${TAG} is available. Changing from version ${version}."
return 1
fi
else
return 1
fi
}
# downloadFile downloads the latest binary package and also the checksum
# for that binary.
downloadFile() {
HELM_DIST="helm-$TAG-$OS-$ARCH.tar.gz"
DOWNLOAD_URL="https://get.helm.sh/$HELM_DIST"
CHECKSUM_URL="$DOWNLOAD_URL.sha256"
HELM_TMP_ROOT="$(mktemp -dt helm-installer-XXXXXX)"
HELM_TMP_FILE="$HELM_TMP_ROOT/$HELM_DIST"
HELM_SUM_FILE="$HELM_TMP_ROOT/$HELM_DIST.sha256"
echo "Downloading $DOWNLOAD_URL"
if [ "${HAS_CURL}" == "true" ]; then
curl -SsL "$CHECKSUM_URL" -o "$HELM_SUM_FILE"
curl -SsL "$DOWNLOAD_URL" -o "$HELM_TMP_FILE"
elif [ "${HAS_WGET}" == "true" ]; then
wget -q -O "$HELM_SUM_FILE" "$CHECKSUM_URL"
wget -q -O "$HELM_TMP_FILE" "$DOWNLOAD_URL"
fi
}
# verifyFile verifies the SHA256 checksum of the binary package
# and the GPG signatures for both the package and checksum file
# (depending on settings in environment).
verifyFile() {
if [ "${VERIFY_CHECKSUM}" == "true" ]; then
verifyChecksum
fi
if [ "${VERIFY_SIGNATURES}" == "true" ]; then
verifySignatures
fi
}
# installFile installs the Helm binary.
installFile() {
HELM_TMP="$HELM_TMP_ROOT/$BINARY_NAME"
mkdir -p "$HELM_TMP"
tar xf "$HELM_TMP_FILE" -C "$HELM_TMP"
HELM_TMP_BIN="$HELM_TMP/$OS-$ARCH/helm"
echo "Preparing to install $BINARY_NAME into ${HELM_INSTALL_DIR}"
runAsRoot cp "$HELM_TMP_BIN" "$HELM_INSTALL_DIR/$BINARY_NAME"
echo "$BINARY_NAME installed into $HELM_INSTALL_DIR/$BINARY_NAME"
}
# verifyChecksum verifies the SHA256 checksum of the binary package.
verifyChecksum() {
printf "Verifying checksum... "
local sum=$(openssl sha1 -sha256 ${HELM_TMP_FILE} | awk '{print $2}')
local expected_sum=$(cat ${HELM_SUM_FILE})
if [ "$sum" != "$expected_sum" ]; then
echo "SHA sum of ${HELM_TMP_FILE} does not match. Aborting."
exit 1
fi
echo "Done."
}
# verifySignatures obtains the latest KEYS file from GitHub main branch
# as well as the signature .asc files from the specific GitHub release,
# then verifies that the release artifacts were signed by a maintainer's key.
verifySignatures() {
printf "Verifying signatures... "
local keys_filename="KEYS"
local github_keys_url="https://raw.githubusercontent.com/helm/helm/main/${keys_filename}"
if [ "${HAS_CURL}" == "true" ]; then
curl -SsL "${github_keys_url}" -o "${HELM_TMP_ROOT}/${keys_filename}"
elif [ "${HAS_WGET}" == "true" ]; then
wget -q -O "${HELM_TMP_ROOT}/${keys_filename}" "${github_keys_url}"
fi
local gpg_keyring="${HELM_TMP_ROOT}/keyring.gpg"
local gpg_homedir="${HELM_TMP_ROOT}/gnupg"
mkdir -p -m 0700 "${gpg_homedir}"
local gpg_stderr_device="/dev/null"
if [ "${DEBUG}" == "true" ]; then
gpg_stderr_device="/dev/stderr"
fi
gpg --batch --quiet --homedir="${gpg_homedir}" --import "${HELM_TMP_ROOT}/${keys_filename}" 2> "${gpg_stderr_device}"
gpg --batch --no-default-keyring --keyring "${gpg_homedir}/${GPG_PUBRING}" --export > "${gpg_keyring}"
local github_release_url="https://github.com/helm/helm/releases/download/${TAG}"
if [ "${HAS_CURL}" == "true" ]; then
curl -SsL "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" -o "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc"
curl -SsL "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" -o "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc"
elif [ "${HAS_WGET}" == "true" ]; then
wget -q -O "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc"
wget -q -O "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc"
fi
local error_text="If you think this might be a potential security issue,"
error_text="${error_text}\nplease see here: https://github.com/helm/community/blob/master/SECURITY.md"
local num_goodlines_sha=$(gpg --verify --keyring="${gpg_keyring}" --status-fd=1 "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" 2> "${gpg_stderr_device}" | grep -c -E '^\[GNUPG:\] (GOODSIG|VALIDSIG)')
if [[ ${num_goodlines_sha} -lt 2 ]]; then
echo "Unable to verify the signature of helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256!"
echo -e "${error_text}"
exit 1
fi
local num_goodlines_tar=$(gpg --verify --keyring="${gpg_keyring}" --status-fd=1 "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" 2> "${gpg_stderr_device}" | grep -c -E '^\[GNUPG:\] (GOODSIG|VALIDSIG)')
if [[ ${num_goodlines_tar} -lt 2 ]]; then
echo "Unable to verify the signature of helm-${TAG}-${OS}-${ARCH}.tar.gz!"
echo -e "${error_text}"
exit 1
fi
echo "Done."
}
# fail_trap is executed if an error occurs.
fail_trap() {
result=$?
if [ "$result" != "0" ]; then
if [[ -n "$INPUT_ARGUMENTS" ]]; then
echo "Failed to install $BINARY_NAME with the arguments provided: $INPUT_ARGUMENTS"
help
else
echo "Failed to install $BINARY_NAME"
fi
echo -e "\tFor support, go to https://github.com/helm/helm."
fi
cleanup
exit $result
}
# testVersion tests the installed client to make sure it is working.
testVersion() {
set +e
HELM="$(command -v $BINARY_NAME)"
if [ "$?" = "1" ]; then
echo "$BINARY_NAME not found. Is $HELM_INSTALL_DIR on your "'$PATH?'
exit 1
fi
set -e
}
# help provides possible cli installation arguments
help () {
echo "Accepted cli arguments are:"
echo -e "\t[--help|-h ] ->> prints this help"
echo -e "\t[--version|-v <desired_version>] . When not defined it fetches the latest release tag from the Helm CDN"
echo -e "\te.g. --version v3.0.0 or -v canary"
echo -e "\t[--no-sudo] ->> install without sudo"
}
# cleanup temporary files to avoid https://github.com/helm/helm/issues/2977
cleanup() {
if [[ -d "${HELM_TMP_ROOT:-}" ]]; then
rm -rf "$HELM_TMP_ROOT"
fi
}
# Execution
#Stop execution on any error
trap "fail_trap" EXIT
set -e
# Set debug if desired
if [ "${DEBUG}" == "true" ]; then
set -x
fi
# Parsing input arguments (if any)
export INPUT_ARGUMENTS="${@}"
set -u
while [[ $# -gt 0 ]]; do
case $1 in
'--version'|-v)
shift
if [[ $# -ne 0 ]]; then
export DESIRED_VERSION="${1}"
if [[ "$1" != "v"* ]]; then
echo "Expected version arg ('${DESIRED_VERSION}') to begin with 'v', fixing..."
export DESIRED_VERSION="v${1}"
fi
else
echo -e "Please provide the desired version. e.g. --version v3.0.0 or -v canary"
exit 0
fi
;;
'--no-sudo')
USE_SUDO="false"
;;
'--help'|-h)
help
exit 0
;;
*) exit 1
;;
esac
shift
done
set +u
initArch
initOS
verifySupported
checkDesiredVersion
if ! checkHelmInstalledVersion; then
downloadFile
verifyFile
installFile
fi
testVersion
cleanup