Skip to content

Commit

Permalink
Use docker bake to build development image (#31)
Browse files Browse the repository at this point in the history
Related to: #30

Using the image building infrastructure added in #30, this moves the
build configuration of the development tooling image into docker bake.

Additionally, this removes vestigial configuration and targets from
the `Makefile`. This also normalizes the `Makefile` target names; for
easier discover-ability of alike tasks. For example, all testing
related targets now start with `test-`; `test-unit` for unit tests,
`tests-helm` for chart tests, etc. The project's developer
documentation is also updated to reflect these changes.
  • Loading branch information
indiebrain authored Dec 21, 2023
1 parent 82e1345 commit 2233e9c
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 144 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
- uses: actions/setup-go@v4
with:
go-version-file: go.mod
- run: make ci-unit-test
- run: make test-unit-ci

integration-test:
name: Integration test
Expand Down Expand Up @@ -68,7 +68,7 @@ jobs:
driver: none
- name: Add redisfailover CRD
run: kubectl create -f manifests/databases.spotahome.com_redisfailovers.yaml
- run: make ci-integration-test
- run: make test-integration-ci

chart-test:
name: Chart testing
Expand All @@ -84,7 +84,7 @@ jobs:
version: v3.7.2

- name: Helm test
run: make helm-test
run: make test-helm-ci

dockerhub-image:
needs:
Expand Down
20 changes: 19 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,34 @@
# Changelog

Check [releases](https://github.com/powerhome/redis-operator/releases) section for Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Also check this project's [releases](https://github.com/powerhome/redis-operator/releases) for official release notes.

## Unreleased

### Changed
- [Use the new docker bake tooling to build the developer tools image and remove vestigial development targets from the Makefile](https://github.com/powerhome/redis-operator/pull/31).

## [v1.8.0-rc2] - 2023-12-20

### Changed
- [Automate image publishing to the public image repository](https://github.com/powerhome/redis-operator/pull/30)
- [Run CI on the master branch](https://github.com/powerhome/redis-operator/pull/29)

## [v1.8.0-rc1] - 2023-12-15

### Added
- [Add public image repository](https://github.com/powerhome/redis-operator/pull/28)

## [v1.7.1] - 2023-12-14

### Changed
- [Use finer grained NetworkPolicies](https://github.com/powerhome/redis-operator/pull/25)

### Fixed
- [Fix PodDisruptionBudget deprecation warnings on kube 1.21+](https://github.com/powerhome/redis-operator/pull/19)

## [v1.1.0-rc.3] - 2022-01-19
Expand Down
207 changes: 92 additions & 115 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,154 +9,108 @@ IMAGE_NAME := powerhome/$(SERVICE_NAME)
# Repository url for this project
REPOSITORY := $(IMAGE_NAME)

# Shell to use for running scripts
SHELL := $(shell which bash)

# Get docker path or an empty string
DOCKER := $(shell command -v docker)

# Get the main unix group for the user running make (to be used by docker-compose later)
GID := $(shell id -g)

# Get the unix user id for the user running make (to be used by docker-compose later)
# Get the unix user id for the user running make (to be used by docker bake)
UID := $(shell id -u)

# Commit hash from git
COMMIT=$(shell git rev-parse HEAD)
GITTAG_COMMIT := $(shell git rev-list --tags --max-count=1)
GITTAG := $(shell git describe --abbrev=0 --tags ${GITTAG_COMMIT} 2>/dev/null || true)

# Branch from git
BRANCH=$(shell git rev-parse --abbrev-ref HEAD)

TAG := $(GITTAG)
ifneq ($(COMMIT), $(GITTAG_COMMIT))
TAG := $(COMMIT)
endif

GIT_COMMIT=$(shell git rev-parse HEAD)
IMAGE_TAG := $(GIT_COMMIT)
ifneq ($(shell git status --porcelain),)
TAG := $(TAG)-dirty
IMAGE_TAG := $(IMAGE_TAG)-dirty
endif


PROJECT_PACKAGE := github.com/spotahome/redis-operator
CODEGEN_IMAGE := ghcr.io/slok/kube-code-generator:v1.27.0
PORT := 9710

# workdir
WORKDIR := /go/src/github.com/spotahome/redis-operator

# CMDs
UNIT_TEST_CMD := go test `go list ./... | grep -v /vendor/` -v
HELM_TEST_CMD := ./scripts/helm-tests.sh
GO_GENERATE_CMD := go generate `go list ./... | grep -v /vendor/`
GO_INTEGRATION_TEST_CMD := go test `go list ./... | grep test/integration` -v -tags='integration'
GET_DEPS_CMD := dep ensure
UPDATE_DEPS_CMD := dep ensure
MOCKS_CMD := go generate ./mocks

# environment dirs
DEV_DIR := docker/development
APP_DIR := docker/app

# workdir
WORKDIR := /go/src/github.com/spotahome/redis-operator
DOCKER_RUN_CMD := $(DOCKER) run -ti --rm \
-v $(PWD):$(WORKDIR) \
-u $(UID):$(UID) \
--name $(SERVICE_NAME) \
-p $(PORT):$(PORT) \
$(REPOSITORY)-dev

# The default action of this Makefile is to build the development docker image
.PHONY: default
default: build

# Run the development environment in non-daemonized mode (foreground)
.PHONY: docker-build
docker-build: deps-development
docker build \
--build-arg uid=$(UID) \
-t $(REPOSITORY)-dev:latest \
-t $(REPOSITORY)-dev:$(COMMIT) \
-f $(DEV_DIR)/Dockerfile \
.

# Run a shell into the development docker image
default: test

.PHONY: ensure-docker
# Test if the dependencies we need to run this Makefile are installed
ensure-docker:
ifndef DOCKER
@echo "Docker is not available. Please install docker"
@exit 1
endif

# Build the operator image for local, end-to-end testing purposes
.PHONY: image-local
image-local: ensure-docker
docker buildx bake \
--set build-local.tags="$(IMAGE_NAME):latest" \
--set build-local.tags="$(IMAGE_NAME):$(IMAGE_TAG)" \
build-local

# Build the development environment docker image
.PHONY: image-dev-tools
image-dev-tools: ensure-docker
docker buildx bake \
--set dev.args.uid=$(UID) \
--set dev.tags="$(IMAGE_NAME)-dev:latest" \
dev

# Connect to a BASH shell the development docker image
.PHONY: shell
shell: docker-build
docker run -ti --rm -v ~/.kube:/.kube:ro -v $(PWD):$(WORKDIR) -u $(UID):$(UID) --name $(SERVICE_NAME) -p $(PORT):$(PORT) $(REPOSITORY)-dev /bin/bash

# Build redis-failover executable file
.PHONY: build
build: docker-build
docker run -ti --rm -v $(PWD):$(WORKDIR) -u $(UID):$(UID) --name $(SERVICE_NAME) $(REPOSITORY)-dev ./scripts/build.sh

# Run the development environment in the background
.PHONY: run
run: docker-build
docker run -ti --rm -v ~/.kube:/.kube:ro -v $(PWD):$(WORKDIR) -u $(UID):$(UID) --name $(SERVICE_NAME) -p $(PORT):$(PORT) $(REPOSITORY)-dev ./scripts/run.sh

# Build the production image based on the public one
.PHONY: image
image: deps-development
docker build \
-t $(SERVICE_NAME) \
-t $(REPOSITORY):latest \
-t $(REPOSITORY):$(COMMIT) \
-t $(REPOSITORY):$(BRANCH) \
-f $(APP_DIR)/Dockerfile \
.
shell: image-dev-tools
$(DOCKER_RUN_CMD) /bin/bash

# Create a git tag using the VERSION
.PHONY: tag
tag:
git tag $(VERSION)

# Test stuff in dev
.PHONY: unit-test
unit-test: docker-build
docker run -ti --rm -v $(PWD):$(WORKDIR) -u $(UID):$(UID) --name $(SERVICE_NAME) $(REPOSITORY)-dev /bin/sh -c '$(UNIT_TEST_CMD)'

.PHONY: ci-unit-test
ci-unit-test:
$(UNIT_TEST_CMD)

.PHONY: ci-integration-test
ci-integration-test:
$(GO_INTEGRATION_TEST_CMD)

.PHONY: integration-test
integration-test:
./scripts/integration-tests.sh
# Run unit tests in the development docker container (DEV)
.PHONY: test-unit
test-unit: image-dev-tools
$(DOCKER_RUN_CMD) /bin/sh -c '$(UNIT_TEST_CMD)'

.PHONY: helm-test
helm-test:
./scripts/helm-tests.sh
# Run helm tests in the development docker container (DEV)
.PHONY: test-helm
test-helm:
$(DOCKER_RUN_CMD) $(HELM_TEST_CMD)

# Run all tests
# Run all (DEV) tests
.PHONY: test
test: ci-unit-test ci-integration-test helm-test

.PHONY: go-generate
go-generate: docker-build
docker run -ti --rm -v $(PWD):$(WORKDIR) -u $(UID):$(UID) --name $(SERVICE_NAME) $(REPOSITORY)-dev /bin/sh -c '$(GO_GENERATE_CMD)'

.PHONY: generate
generate: go-generate

.PHONY: get-deps
get-deps: docker-build
docker run -ti --rm -v $(PWD):$(WORKDIR) -u $(UID):$(UID) --name $(SERVICE_NAME) $(REPOSITORY)-dev /bin/sh -c '$(GET_DEPS_CMD)'
test: test-unit test-helm

.PHONY: update-deps
update-deps: docker-build
docker run -ti --rm -v $(PWD):$(WORKDIR) -u $(UID):$(UID) --name $(SERVICE_NAME) $(REPOSITORY)-dev /bin/sh -c '$(UPDATE_DEPS_CMD)'
# Run unit tests on the host (CI)
.PHONY: test-unit-ci
test-unit-ci:
$(UNIT_TEST_CMD)

.PHONY: mocks
mocks: docker-build
docker run -ti --rm -v $(PWD):$(WORKDIR) -u $(UID):$(UID) --name $(SERVICE_NAME) $(REPOSITORY)-dev /bin/sh -c '$(MOCKS_CMD)'
# Run integration tests on the host (CI)
.PHONY: test-integration-ci
test-integration-ci:
$(GO_INTEGRATION_TEST_CMD)

.PHONY: deps-development
# Test if the dependencies we need to run this Makefile are installed
deps-development:
ifndef DOCKER
@echo "Docker is not available. Please install docker"
@exit 1
endif
# Run helm tests on the host (CI)
.PHONY: test-helm-ci
test-helm-ci:
$(HELM_TEST_CMD)

# Generate kubernetes code for types..
.PHONY: update-codegen
update-codegen:
# Generate kubernetes client
.PHONY: generate-client
generate-client:
@echo ">> Generating code for Kubernetes CRD types..."
docker run --rm -it \
-v $(PWD):/go/src/$(PROJECT_PACKAGE) \
Expand All @@ -167,6 +121,8 @@ update-codegen:
-e GENERATION_TARGETS="deepcopy,client" \
$(CODEGEN_IMAGE)

# Generate kubernetes Custom Resource Definitions
.PHONY: generate-crd
generate-crd:
docker run -it --rm \
-v $(PWD):/go/src/$(PROJECT_PACKAGE) \
Expand All @@ -175,3 +131,24 @@ generate-crd:
-e CRD_OUT_PATH=/go/src/$(PROJECT_PACKAGE)/manifests \
$(CODEGEN_IMAGE) update-crd.sh
cp -f manifests/databases.spotahome.com_redisfailovers.yaml manifests/kustomize/base

.PHONY: generate-go
generate-go: image-dev-tools
docker run -ti --rm \
-v $(PWD):$(WORKDIR) \
-u $(UID):$(UID) \
--name $(SERVICE_NAME) $(REPOSITORY)-dev \
/bin/sh -c '$(GO_GENERATE_CMD)'

# Generate testing mocks
.PHONY: generate-mocks
generate-mocks: image-dev-tools
docker run -ti --rm \
-v $(PWD):$(WORKDIR) \
-u $(UID):$(UID) \
--name $(SERVICE_NAME) \
$(REPOSITORY)-dev /bin/sh -c '$(MOCKS_CMD)'

# Run all code generators
.PHONY: generate
generate: generate-go generate-mocks generate-client generate-crd
13 changes: 12 additions & 1 deletion docker-bake.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ target "build" {
"linux/arm/v6",
"linux/arm/v7",
"linux/arm64",
"linux/386"
"linux/386",
]
}

variable UID { default = 1000 }
variable GID { default = 1000 }
target "dev" {
dockerfile = "docker/development/Dockerfile"
output = ["type=docker"]
args = {
uid: "${UID}",
gid: "${GID}",
}
}
15 changes: 9 additions & 6 deletions docker/development/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
FROM golang:1.20-alpine

ENV CODEGEN_VERSION="1.11.9"
ARG TARGETOS
ARG TARGETARCH

RUN apk --no-cache add \
bash \
git \
g++ \
openssl

# Helm for running helm template tests locally
ENV HELM_VERSION="v3.12.0"
RUN wget -c https://get.helm.sh/helm-${HELM_VERSION}-${TARGETOS}-${TARGETARCH}.tar.gz -O - | tar zxv -C /tmp && \
mv /tmp/${TARGETOS}-${TARGETARCH}/helm /go/bin/helm

# Code generator stuff
# Check: https://github.com/kubernetes/kubernetes/pull/57656
ENV CODEGEN_VERSION="1.11.9"
RUN wget http://github.com/kubernetes/code-generator/archive/kubernetes-${CODEGEN_VERSION}.tar.gz && \
mkdir -p /go/src/k8s.io/code-generator/ && \
tar zxvf kubernetes-${CODEGEN_VERSION}.tar.gz --strip 1 -C /go/src/k8s.io/code-generator/ && \
mkdir -p /go/src/k8s.io/kubernetes/hack/boilerplate/ && \
touch /go/src/k8s.io/kubernetes/hack/boilerplate/boilerplate.go.txt

# Mock creator
# Alpine labels ARM architectures differently than Mockery: https://wiki.alpinelinux.org/wiki/Architecture
ARG MOCKERY_VERSION="2.32.0"
RUN export ARCH="$(uname -m)" \
&& if [[ "${ARCH}" == "aarch64" ]]; then export ARCH="arm64"; fi \
&& wget -c https://github.com/vektra/mockery/releases/download/v${MOCKERY_VERSION}/mockery_${MOCKERY_VERSION}_$(uname -o)_${ARCH}.tar.gz -O - | tar -xz -C /go/bin/
RUN wget -c https://github.com/vektra/mockery/releases/download/v${MOCKERY_VERSION}/mockery_${MOCKERY_VERSION}_$(uname -o)_${TARGETARCH}.tar.gz -O - | tar -xz -C /go/bin/

# Create user
ARG uid=1000
Expand All @@ -30,6 +34,5 @@ RUN addgroup -g $gid rf && \
adduser -D -u $uid -G rf rf && \
chown rf:rf -R /go


USER rf
WORKDIR /go/src/github.com/spotahome/redis-operator
Loading

0 comments on commit 2233e9c

Please sign in to comment.