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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/deb-s3-gems.sha256
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
116bf85c436200d1060811e6f5d2d40c88f65448f2125bc77ffce5121e6e183b aws-eventstream-1.4.0.gem
40bda996876a45a60c43fbf489b04b46216e98c1814c1ac6453b942e0df6501e aws-partitions-1.1277.0.gem
ee3e3220b8468a3c9e59daba18e6ec897bf5c7ce8adcc0670cfa2f1f092112fe aws-sdk-core-3.254.0.gem
a2e83662ca31b77a2a19c9aa2f40a98165a67270c18c718fe1c70d0cbd7cd749 aws-sdk-kms-1.130.0.gem
1217b878b554b45f2152115c5d2623e3497222f46a738e5a96e9767cbf41468b aws-sdk-s3-1.228.2.gem
6973ff95cb0fd0dc58ba26e90e9510a2219525d07620c8babeb70ef831826c00 aws-sigv4-1.12.1.gem
8beb36bd7d5f524644f2e4b947e9212bcb47cab0b50cd8ad459ce527f938b956 deb-s3-26.1.0.gem
238d774a58723d6c090494c8879b5e9918c19485f7e840f2c1c7532cf84ebcb1 jmespath-1.6.2.gem
e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73 thor-1.5.0.gem
65 changes: 65 additions & 0 deletions .github/scripts/install-deb-s3.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env bash
#
# Install deb-s3 and its full runtime dependency tree from a pinned, checksum
# verified manifest.
#
# deb-s3 runs with the package signing key and the pre-release AWS credentials
# in scope, so it must not be resolved at run time. Every gem is fetched at the
# exact version recorded in the manifest and verified against the SHA256 that
# RubyGems publishes for that release before anything is installed or executed.
#
# Usage: install-deb-s3.sh [manifest]
#
# Regenerating the manifest: fetch each gem and record
# "<sha256> <name>-<version>.gem", matching the checksum published at
# https://rubygems.org/api/v1/versions/<name>.json for that version.

set -euo pipefail

MANIFEST="${1:-.github/deb-s3-gems.sha256}"

if [[ ! -f "${MANIFEST}" ]]; then
echo "gem manifest not found: ${MANIFEST}" >&2
exit 1
fi

MANIFEST_ABS="$(cd "$(dirname "${MANIFEST}")" && pwd)/$(basename "${MANIFEST}")"

WORKDIR="$(mktemp -d)"
trap 'rm -rf "${WORKDIR}"' EXIT

cp "${MANIFEST_ABS}" "${WORKDIR}/gems.sha256"
cd "${WORKDIR}"

while read -r _sha file; do
[[ -n "${file:-}" ]] || continue
name="${file%-*}"
version="${file##*-}"
version="${version%.gem}"
echo "fetching ${name} ${version}"
gem fetch "${name}" --version "${version}" --platform ruby
done < gems.sha256

echo "verifying checksums"
sha256sum --check --strict gems.sha256

echo "installing"
${GEM_INSTALL_SUDO-sudo} gem install --local --no-document --ignore-dependencies ./*.gem

# RubyGems installs versioned binstubs on some distributions (deb-s3.ruby3.2,
# deb-s33.2), so a plain "deb-s3" on PATH is not guaranteed. publish_package.sh
# invokes it by bare name, so link the canonical executable when it is missing.
if ! command -v deb-s3 >/dev/null 2>&1; then
canonical="$(gem contents deb-s3 | grep -E '/bin/deb-s3$' | head -n 1)"
if [[ -z "${canonical}" ]]; then
echo "deb-s3 was installed but its executable could not be located" >&2
exit 1
fi
${GEM_INSTALL_SUDO-sudo} ln -sf "${canonical}" "${LINK_DIR:-/usr/local/bin}/deb-s3"
fi

# Smoke check: this activates the whole pinned dependency set, so a missing or
# incompatible gem fails here rather than midway through publishing.
echo "verifying deb-s3"
deb-s3 help >/dev/null
echo "deb-s3 ready: $(command -v deb-s3)"
120 changes: 117 additions & 3 deletions .github/workflows/build-binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ jobs:
runs-on: ${{ matrix.runner }}
timeout-minutes: 45
env:
LOCAL_IMAGE: stackstate-cluster-agent:ci-${{ matrix.arch }}
LOCAL_IMAGE: quay.io/stackstate/stackstate-k8s-cluster-agent:ci-${{ matrix.arch }}
steps:
- name: Check out repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand All @@ -209,8 +209,6 @@ jobs:
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
run: |
set -eo pipefail
# Dockerfiles/cluster-agent pulls its ubuntu builder stage through the
# proxy; the BCI stages come from registry.suse.com and need no auth.
printf '%s' "${REGISTRY_PASSWORD}" | docker login -u "${REGISTRY_USER}" --password-stdin "${REGISTRY_HOST}"

- name: Build cluster-agent image
Expand Down Expand Up @@ -239,6 +237,120 @@ jobs:
--entrypoint /opt/stackstate-agent/bin/stackstate-cluster-agent/stackstate-cluster-agent \
"${LOCAL_IMAGE}" version

- name: Scan cluster-agent image (Trivy and Grype vulnerabilities, VEX-aware, plus Trivy secrets)
uses: StackVista/image-pipeline/.github/actions/scan-image@6284a6fc006a7cc46a7f00d02c50d5f21b117b63
with:
image: ${{ env.LOCAL_IMAGE }}
mode: gate
severity: UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL
with-grype: true
exceptions-path: exceptions
upload-sarif: false
sarif-category: stackstate-k8s-cluster-agent-${{ matrix.arch }}

publish-cluster-agent-image:
name: Publish and sign cluster-agent image (${{ matrix.arch }})
if: github.event_name == 'push'
needs: build-cluster-agent-image
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
runner: docker-public
- arch: arm64
runner: arm64-xlarge-public
runs-on: ${{ matrix.runner }}
timeout-minutes: 45
permissions:
contents: read
id-token: write
env:
IMAGE: quay.io/stackstate/stackstate-k8s-cluster-agent
steps:
- name: Check out repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Download cluster-agent binary
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: cluster-agent-binary-${{ matrix.arch }}

- name: Stage the cluster-agent binary in the image build context
run: |
set -eo pipefail
chmod +x bin/stackstate-cluster-agent/stackstate-cluster-agent
cp -r bin/stackstate-cluster-agent Dockerfiles/cluster-agent/

- name: Resolve image tag
id: image
env:
SOURCE_SHA: ${{ github.sha }}
run: |
set -euo pipefail
echo "tag=$(printf '%s' "${SOURCE_SHA}" | cut -c1-8)" >> "${GITHUB_OUTPUT}"

- name: Resolve canonical OCI labels
id: oci
uses: StackVista/image-pipeline/.github/actions/apply-oci-labels@6284a6fc006a7cc46a7f00d02c50d5f21b117b63
with:
image-name: stackstate-k8s-cluster-agent
tag: ${{ steps.image.outputs.tag }}
title: SUSE Observability Cluster Agent
description: Cluster-level agent collecting Kubernetes topology and cluster checks for SUSE Observability.
component: stackstate-k8s-cluster-agent
dockerfile: Dockerfiles/cluster-agent/Dockerfile
base-name: registry.suse.com/bci/bci-micro:latest
registry-credentials: |
[{"registry": "${{ vars.REGISTRY_HOST }}", "username": "${{ vars.REGISTRY_USER }}", "password": "${{ secrets.REGISTRY_PASSWORD }}"}]

- name: Build, publish, and sign architecture image
uses: StackVista/image-pipeline/.github/actions/push-single-arch@6284a6fc006a7cc46a7f00d02c50d5f21b117b63
with:
image: ${{ env.IMAGE }}
tag: ${{ steps.image.outputs.tag }}
arch: ${{ matrix.arch }}
docker-context: Dockerfiles/cluster-agent
dockerfile: Dockerfiles/cluster-agent/Dockerfile
labels: |
${{ steps.oci.outputs.labels }}
org.opencontainers.image.revision=${{ github.sha }}
source-registry-credentials: |
[{"registry": "${{ vars.REGISTRY_HOST }}", "username": "${{ vars.REGISTRY_USER }}", "password": "${{ secrets.REGISTRY_PASSWORD }}"}]
target-registry: quay.io
target-registry-user: ${{ vars.QUAY_USER }}
target-registry-password: ${{ secrets.QUAY_PASSWORD }}

merge-cluster-agent-manifest:
name: Publish and sign multi-architecture cluster-agent image
if: github.event_name == 'push'
needs: publish-cluster-agent-image
runs-on: docker-public
timeout-minutes: 30
permissions:
contents: read
id-token: write
steps:
- name: Resolve image tag
id: image
env:
SOURCE_SHA: ${{ github.sha }}
run: |
set -euo pipefail
echo "tag=$(printf '%s' "${SOURCE_SHA}" | cut -c1-8)" >> "${GITHUB_OUTPUT}"

- name: Merge and sign multi-architecture manifest
uses: StackVista/image-pipeline/.github/actions/merge-multiarch@6284a6fc006a7cc46a7f00d02c50d5f21b117b63
with:
image: quay.io/stackstate/stackstate-k8s-cluster-agent
tag: ${{ steps.image.outputs.tag }}
arches: amd64,arm64
target-registry: quay.io
target-registry-user: ${{ vars.QUAY_USER }}
target-registry-password: ${{ secrets.QUAY_PASSWORD }}

cerberus-notify:
name: Report failure to Slack (Cerberus)
needs:
Expand All @@ -247,6 +359,8 @@ jobs:
- build-agent
- build-cluster-agent
- build-cluster-agent-image
- publish-cluster-agent-image
- merge-cluster-agent-manifest
if: >-
always()
&& github.event_name == 'push'
Expand Down
Loading
Loading