diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..2930303 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,19 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + # Workflow files stored in the + # default location of `.github/workflows` + directory: "/" + schedule: + interval: "daily" + commit-message: + # Prefix all commit messages with "[gha] " + prefix: "[gha] " + + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "daily" + commit-message: + # Prefix all commit messages with "[docker] " + prefix: "[docker] " diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e6a4e0f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,147 @@ +name: ci + +on: + push: + branches: [ "master" ] + # Publish pep440 tags as releases. + tags: [ '*.*.*' ] + +env: + # Use docker.io for Docker Hub if empty + REGISTRY: ghcr.io + # github.repository as / + IMAGE_NAME: ${{ github.repository }} + +jobs: + prepare: + runs-on: ubuntu-latest + steps: + - name: Convert repository name to lowercase + id: set-variables + run: | + echo "image=${{ env.REGISTRY }}/${IMAGE_NAME,,}" >>${GITHUB_OUTPUT} + # Only enable push on push events (already covered above, but this is a safeguard) + echo "push=${{ github.event_name != 'pull_request' }}" >>${GITHUB_OUTPUT} + + # Extract metadata (tags, labels) for Docker + # https://github.com/docker/metadata-action + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ steps.set-variables.outputs.image }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=pep440,pattern={{version}} + type=pep440,pattern={{major}} + type=pep440,pattern={{major}}.{{minor}} + outputs: + image: ${{ steps.set-variables.outputs.image }} + push: ${{ steps.set-variables.outputs.push }} + meta-json: ${{ steps.meta.outputs.json }} + meta-labels: ${{ steps.meta.outputs.labels }} + meta-version: ${{ steps.meta.outputs.version }} + + build: + needs: + - prepare + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + strategy: + matrix: + platform: + - linux/amd64 + - linux/arm/v6 + - linux/arm/v7 + - linux/arm64 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up QEMU + if: matrix.platform != 'linux/amd64' + uses: docker/setup-qemu-action@v3 + + - name: Setup Docker buildx + uses: docker/setup-buildx-action@v3 + + - name: Log into registry ${{ env.REGISTRY }} + if: needs.prepare.outputs.push == 'true' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Build and push the Docker image with Buildx (don't tag it yet) + # https://github.com/docker/build-push-action + - name: Build and push Docker image by digest + id: build + uses: docker/build-push-action@v5 + with: + context: . + platforms: ${{ matrix.platform }} + build-args: | + GIT_REPOSITORY=${{ github.repository }} + "SSH_DEPLOY_KEY=${{ secrets.DOCKER_DEPLOY_KEY }}" + outputs: type=image,name=${{ needs.prepare.outputs.image }},push-by-digest=true,name-canonical=true,push=${{ needs.prepare.outputs.push }} + labels: ${{ needs.prepare.outputs.meta-labels }} + + - name: Export digest + run: | + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}" + + - name: Upload digest + if: needs.prepare.outputs.push == 'true' + uses: actions/upload-artifact@v3 + with: + name: digests + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + push: + needs: + - prepare + - build + if: needs.prepare.outputs.push == 'true' + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests + path: /tmp/digests + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + + - name: Log into registry ${{ env.REGISTRY }} + if: needs.prepare.outputs.push == 'true' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + if: needs.prepare.outputs.push == 'true' + working-directory: /tmp/digests + run: | + docker buildx imagetools create $(jq -r '"-t " + (.tags | join(" -t "))' <<< '${{ needs.prepare.outputs.meta-json }}') \ + $(printf '${{ needs.prepare.outputs.image }}@sha256:%s ' *) + + - name: Inspect image + if: needs.prepare.outputs.push == 'true' + run: | + docker buildx imagetools inspect '${{ needs.prepare.outputs.image }}:${{ needs.prepare.outputs.meta-version }}' diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..231f26b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,40 @@ +ARG SSACLI_VERSION=6.15-11.0 + +FROM golang:1.21.1-bookworm as builder + +ARG GIT_REPOSITORY +ARG SSH_DEPLOY_KEY + +RUN \ + apt-get update && \ + apt-get upgrade -y && \ + wget https://downloads.linux.hpe.com/SDR/repo/mcp/Debian/pool/non-free/ssacli-${SSACLI_VERSION}_amd64.deb && \ + mkdir /root/.ssh/ && \ + echo "${SSH_DEPLOY_KEY}" > /root/.ssh/id_rsa && \ + chmod 600 /root/.ssh/id_rsa && \ + ssh-keyscan github.com >> /root/.ssh/known_hosts && \ + git clone git@github.com:${GIT_REPOSITORY}.git app && \ + cd app && \ + go mod init smartctl_ssacli_exporter && \ + go get && \ + go build -o smartctl_ssacli_exporter + +FROM debian:12.1-slim +LABEL maintainer="Patrick Baus " +ARG SSACLI_VERSION + +COPY --from=builder /go/app/smartctl_ssacli_exporter /sbin/smartctl_ssacli_exporter +COPY --from=builder /go/ssacli-${SSACLI_VERSION}_amd64.deb / + +# Upgrade installed packages +RUN apt-get update && \ + apt-get upgrade -y && \ + apt-get install -y --no-install-recommends \ + smartmontools \ + procps && \ + dpkg -i ssacli-${SSACLI_VERSION}_amd64.deb && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* && \ + rm ssacli-${SSACLI_VERSION}_amd64.deb + +ENTRYPOINT ["/sbin/smartctl_ssacli_exporter"]