Skip to content

Commit

Permalink
feat: harden image using apko and wolfi (#297)
Browse files Browse the repository at this point in the history
* move cmd/*.go to cmd/kargo-render/ to make room for source for a second binary

Signed-off-by: Kent Rancourt <kent.rancourt@gmail.com>

* implement a very simple git credential helper

Signed-off-by: Kent Rancourt <kent.rancourt@gmail.com>

* update git package to use new credential helper

Signed-off-by: Kent Rancourt <kent.rancourt@gmail.com>

* harden image using apko and wolfi

Signed-off-by: Kent Rancourt <kent.rancourt@gmail.com>

* upgrade argo cd and dependencies

Signed-off-by: Kent Rancourt <kent.rancourt@gmail.com>

* fix broken unit test

Signed-off-by: Kent Rancourt <kent.rancourt@gmail.com>

* fix(build): avoid superfluous retagging

Signed-off-by: Hidde Beydals <hidde@hhh.computer>

---------

Signed-off-by: Kent Rancourt <kent.rancourt@gmail.com>
Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Co-authored-by: Hidde Beydals <hidde@hhh.computer>
  • Loading branch information
krancour and hiddeco authored Aug 5, 2024
1 parent 7c83687 commit c29c1fb
Show file tree
Hide file tree
Showing 19 changed files with 379 additions and 877 deletions.
42 changes: 28 additions & 14 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,40 +13,38 @@ jobs:
test-unit:
runs-on: ubuntu-latest
container:
image: golang:1.22.1-bookworm
image: golang:1.22.5-bookworm
steps:
- name: Checkout code
uses: actions/checkout@v3
- uses: actions/cache@v3
uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: /go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Run unit tests
env:
TEST_GIT_CLIENT_WITH_AUTH: true
run: make test-unit
- name: Upload coverage reports
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}

lint:
runs-on: ubuntu-latest
container:
image: golang:1.22.1-bookworm
image: golang:1.22.5-bookworm
steps:
- name: Checkout code
uses: actions/checkout@v3
- uses: actions/cache@v3
uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: /go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
uses: golangci/golangci-lint-action@v6
env:
GOFLAGS: -buildvcs=false
with:
Expand All @@ -55,14 +53,30 @@ jobs:
build-image:
needs: [test-unit, lint]
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build image
uses: docker/build-push-action@v5
uses: docker/setup-buildx-action@v3
with:
driver-opts: network=host
- name: Checkout code
uses: actions/checkout@v4
- name: Build base image
run: |
BASE_IMAGE=localhost:5000/kargo-render-base:latest make build-base-image
docker push localhost:5000/kargo-render-base:latest-arm64
docker push localhost:5000/kargo-render-base:latest-amd64
- name: Build final image
uses: docker/build-push-action@v6
with:
build-args: |
BASE_IMAGE=localhost:5000/kargo-render-base
platforms: linux/amd64,linux/arm64
push: false
cache-from: type=gha
Expand Down
29 changes: 22 additions & 7 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,48 @@ jobs:
packages: write # Used to push images to ghcr.io
contents: write # Used to upload assets
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- 5000:5000
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
with:
driver-opts: network=host
- name: Install Cosign
uses: sigstore/cosign-installer@v2
uses: sigstore/cosign-installer@v3.5.0
with:
cosign-release: 'v2.2.1'
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
uses: docker/metadata-action@v5
with:
images: ghcr.io/akuity/kargo-render
flavor: latest=false
tags: type=semver,pattern={{raw}}
- name: Build and push
uses: docker/build-push-action@v5
- name: Build base image
run: |
BASE_IMAGE=localhost:5000/kargo-render-base make build-base-image
docker push localhost:5000/kargo-render-base:latest-arm64
docker push localhost:5000/kargo-render-base:latest-amd64
- name: Build and push final image
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
build-args: |
BASE_IMAGE=localhost:5000/kargo-render-base
VERSION=${{ github.ref_name }}
GIT_COMMIT=${{ github.sha }}
GIT_TREE_STATE=clean
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.vscode/
bin/
build/
coverage.txt
37 changes: 9 additions & 28 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
FROM --platform=$BUILDPLATFORM golang:1.22.1-bookworm as builder
ARG BASE_IMAGE

FROM --platform=$BUILDPLATFORM golang:1.22.5-bookworm AS builder

ARG TARGETOS
ARG TARGETARCH

ARG HELM_VERSION=v3.12.3
RUN curl -L -o /tmp/helm.tar.gz \
https://get.helm.sh/helm-${HELM_VERSION}-linux-${TARGETARCH}.tar.gz \
&& tar xvfz /tmp/helm.tar.gz -C /usr/local/bin --strip-components 1

ARG KUSTOMIZE_VERSION=v5.4.1
RUN curl -L -o /tmp/kustomize.tar.gz \
https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2F${KUSTOMIZE_VERSION}/kustomize_${KUSTOMIZE_VERSION}_linux_${TARGETARCH}.tar.gz \
&& tar xvfz /tmp/kustomize.tar.gz -C /usr/local/bin

ARG YTT_VERSION=v0.46.0
RUN curl -L -o /usr/local/bin/ytt \
https://github.com/vmware-tanzu/carvel-ytt/releases/download/${YTT_VERSION}/ytt-linux-${TARGETARCH} \
&& chmod 755 /usr/local/bin/ytt

ARG VERSION_PACKAGE=github.com/akuity/kargo-render/internal/version
ARG CGO_ENABLED=0

Expand All @@ -31,26 +18,20 @@ ARG VERSION
ARG GIT_COMMIT
ARG GIT_TREE_STATE

RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build \
-o bin/credential-helper \
./cmd/credential-helper

RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build \
-ldflags "-w -X ${VERSION_PACKAGE}.version=${VERSION} -X ${VERSION_PACKAGE}.buildDate=$(date -u +'%Y-%m-%dT%H:%M:%SZ') -X ${VERSION_PACKAGE}.gitCommit=${GIT_COMMIT} -X ${VERSION_PACKAGE}.gitTreeState=${GIT_TREE_STATE}" \
-o bin/kargo-render \
./cmd \
./cmd/kargo-render \
&& bin/kargo-render version

FROM alpine:3.20.0 as final
FROM ${BASE_IMAGE}:latest-${TARGETARCH} AS final

RUN apk update \
&& apk add git openssh-client \
&& addgroup -S -g 65532 nonroot \
&& adduser -S -D -H -u 65532 -g nonroot -G nonroot nonroot

COPY --from=builder /usr/local/bin/helm /usr/local/bin/
COPY --from=builder /usr/local/bin/kustomize /usr/local/bin/
COPY --from=builder /usr/local/bin/ytt /usr/local/bin/
COPY --from=builder /kargo-render/bin/ /usr/local/bin/

USER nonroot

# Ensure that the XDG_*_HOME environment variables are set to a directory
# that is writable by the nonroot user. This is necessary because otherwise
# Helm fails to write cache files and is unable to download indexes and
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.22.1-bookworm
FROM golang:1.22.5-bookworm

ARG TARGETARCH

Expand Down
36 changes: 32 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
SHELL ?= /bin/bash

IMAGE ?= kargo-render
TAG ?= dev

BASE_IMAGE ?= $(IMAGE)-base

DEV_TOOLS_TAG ?= dev-tools

################################################################################
# Tests #
# #
Expand All @@ -25,6 +32,26 @@ test-unit:
-covermode=atomic \
./...

################################################################################
# Build: Targets to help build #
################################################################################

.PHONY: clean
clean:
rm -rf build

.PHONY: build-base-image
build-base-image:
mkdir -p build
cp kargo-render-base.apko.yaml build
docker run \
--rm \
-v $(dir $(realpath $(firstword $(MAKEFILE_LIST))))build:/build \
-w /build \
cgr.dev/chainguard/apko \
build kargo-render-base.apko.yaml $(BASE_IMAGE) kargo-render-base.tar.gz
docker image load -i build/kargo-render-base.tar.gz

################################################################################
# Hack: Targets to help you hack #
# #
Expand All @@ -38,11 +65,11 @@ DOCKER_CMD := docker run \
-v gomodcache:/go/pkg/mod \
-v $(dir $(realpath $(firstword $(MAKEFILE_LIST)))):/workspaces/kargo-render \
-w /workspaces/kargo-render \
kargo-render:dev-tools
$(IMAGE):$(DEV_TOOLS_TAG)

.PHONY: hack-build-dev-tools
hack-build-dev-tools:
docker build -f Dockerfile.dev -t kargo-render:dev-tools .
docker build -f Dockerfile.dev -t $(IMAGE):$(DEV_TOOLS_TAG) .

.PHONY: hack-lint
hack-lint: hack-build-dev-tools
Expand All @@ -53,9 +80,10 @@ hack-test-unit: hack-build-dev-tools
$(DOCKER_CMD) make test-unit

.PHONY: hack-build
hack-build:
hack-build: build-base-image
docker build \
--build-arg BASE_IMAGE=$(BASE_IMAGE) \
--build-arg GIT_COMMIT=$(shell git rev-parse HEAD) \
--build-arg GIT_TREE_STATE=$(shell if [ -z "`git status --porcelain`" ]; then echo "clean" ; else echo "dirty"; fi) \
--tag kargo-render:dev \
--tag $(IMAGE):$(TAG) \
.
15 changes: 15 additions & 0 deletions cmd/credential-helper/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package main

import (
"fmt"
"os"
)

func main() {
password := os.Getenv("GIT_PASSWORD")
if password == "" {
fmt.Fprintln(os.Stderr, "GIT_PASSWORD must be set")
os.Exit(1)
}
fmt.Println(password)
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit c29c1fb

Please sign in to comment.