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
12 changes: 7 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ _testmain.go
*.exe
*.test
*.prof
.idea/
dist/
/.idea
/dist
**/junit.xml
**/.env
.vscode/
apiserver.local.config/
coverage.txt
/.vscode
/coverage.txt

/bin
/.go
26 changes: 26 additions & 0 deletions Dockerfile.dbg
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM debian:stretch

ENV DEBIAN_FRONTEND noninteractive
ENV DEBCONF_NONINTERACTIVE_SEEN true

RUN set -x \
&& apt-get update \
&& apt-get install -y --no-install-recommends apt-transport-https ca-certificates curl bzip2

RUN set -x \
&& curl -Lo restic.bz2 https://github.com/restic/restic/releases/download/v{RESTIC_VER}/restic_{RESTIC_VER}_{ARG_OS}_{ARG_ARCH}.bz2 \
&& bzip2 -d restic.bz2 \
&& chmod 755 restic \
&& curl -Lo restic_{NEW_RESTIC_VER}.bz2 https://github.com/restic/restic/releases/download/v{NEW_RESTIC_VER}/restic_{NEW_RESTIC_VER}_{ARG_OS}_{ARG_ARCH}.bz2 \
&& bzip2 -d restic_{NEW_RESTIC_VER}.bz2 \
&& chmod 755 restic_{NEW_RESTIC_VER}



FROM {ARG_FROM}

COPY --from=0 restic /bin/restic
COPY --from=0 restic_{NEW_RESTIC_VER} /bin/restic_{NEW_RESTIC_VER}
COPY bin/{ARG_OS}_{ARG_ARCH}/{ARG_BIN} /{ARG_BIN}

ENTRYPOINT ["/{ARG_BIN}"]
28 changes: 28 additions & 0 deletions Dockerfile.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FROM debian:stretch

ENV DEBIAN_FRONTEND noninteractive
ENV DEBCONF_NONINTERACTIVE_SEEN true

RUN set -x \
&& apt-get update \
&& apt-get install -y --no-install-recommends apt-transport-https ca-certificates curl bzip2

RUN set -x \
&& curl -Lo restic.bz2 https://github.com/restic/restic/releases/download/v{RESTIC_VER}/restic_{RESTIC_VER}_{ARG_OS}_{ARG_ARCH}.bz2 \
&& bzip2 -d restic.bz2 \
&& chmod 755 restic \
&& curl -Lo restic_{NEW_RESTIC_VER}.bz2 https://github.com/restic/restic/releases/download/v{NEW_RESTIC_VER}/restic_{NEW_RESTIC_VER}_{ARG_OS}_{ARG_ARCH}.bz2 \
&& bzip2 -d restic_{NEW_RESTIC_VER}.bz2 \
&& chmod 755 restic_{NEW_RESTIC_VER}


FROM {ARG_FROM}

COPY --from=0 /restic /bin/restic
COPY --from=0 /restic_{NEW_RESTIC_VER} /bin/restic_{NEW_RESTIC_VER}
COPY bin/{ARG_OS}_{ARG_ARCH}/{ARG_BIN} /{ARG_BIN}

# This would be nicer as `nobody:nobody` but distroless has no such entries.
USER 65535:65535

ENTRYPOINT ["/{ARG_BIN}"]
290 changes: 290 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,290 @@
SHELL=/bin/bash -o pipefail

# The binary to build (just the basename).
BIN := stash
COMPRESS ?=no

# Where to push the docker image.
REGISTRY ?= appscode

# This version-strategy uses git tags to set the version string
git_branch := $(shell git rev-parse --abbrev-ref HEAD)
git_tag := $(shell git describe --exact-match --abbrev=0 2>/dev/null || echo "")
commit_hash := $(shell git rev-parse --verify HEAD)
commit_timestamp := $(shell date --date="@$$(git show -s --format=%ct)" --utc +%FT%T)

VERSION := $(shell git describe --tags --always --dirty)
version_strategy := commit_hash
ifdef git_tag
VERSION := $(git_tag)
version_strategy := tag
else
ifeq (,$(findstring $(git_branch),master HEAD))
ifneq (,$(patsubst release-%,,$(git_branch)))
VERSION := $(git_branch)
version_strategy := branch
endif
endif
endif

RESTIC_VER := 0.8.3
# also update in restic wrapper library
NEW_RESTIC_VER := 0.9.5

###
### These variables should not need tweaking.
###

SRC_DIRS := apis client *.go pkg test # directories which hold app source (not vendored)

DOCKER_PLATFORMS := linux/amd64 linux/arm linux/arm64
BIN_PLATFORMS := $(DOCKER_PLATFORMS) windows/amd64 darwin/amd64

# Used internally. Users should pass GOOS and/or GOARCH.
OS := $(if $(GOOS),$(GOOS),$(shell go env GOOS))
ARCH := $(if $(GOARCH),$(GOARCH),$(shell go env GOARCH))

BASEIMAGE_PROD ?= gcr.io/distroless/static
BASEIMAGE_DBG ?= debian:stretch

IMAGE := $(REGISTRY)/$(BIN)
VERSION_PROD := $(VERSION)
VERSION_DBG := $(VERSION)-dbg
TAG := $(VERSION)_$(OS)_$(ARCH)
TAG_PROD := $(TAG)
TAG_DBG := $(VERSION)-dbg_$(OS)_$(ARCH)
CANARY_TAG_PROD := canary_$(OS)_$(ARCH)
CANARY_TAG_DBG := canary-dbg_$(OS)_$(ARCH)

GO_VERSION ?= 1.12.5
BUILD_IMAGE ?= appscode/golang-dev:$(GO_VERSION)-stretch

OUTBIN = bin/$(OS)_$(ARCH)/$(BIN)
ifeq ($(OS),windows)
OUTBIN = bin/$(OS)_$(ARCH)/$(BIN).exe
endif

# Directories that we need created to build/test.
BUILD_DIRS := bin/$(OS)_$(ARCH) \
.go/bin/$(OS)_$(ARCH) \
.go/cache

DOCKERFILE_PROD = Dockerfile.in
DOCKERFILE_DBG = Dockerfile.dbg

# If you want to build all binaries, see the 'all-build' rule.
# If you want to build all containers, see the 'all-container' rule.
# If you want to build AND push all containers, see the 'all-push' rule.
all: fmt build

# For the following OS/ARCH expansions, we transform OS/ARCH into OS_ARCH
# because make pattern rules don't match with embedded '/' characters.

build-%:
@$(MAKE) build \
--no-print-directory \
GOOS=$(firstword $(subst _, ,$*)) \
GOARCH=$(lastword $(subst _, ,$*))

container-%:
@$(MAKE) container \
--no-print-directory \
GOOS=$(firstword $(subst _, ,$*)) \
GOARCH=$(lastword $(subst _, ,$*))

push-%:
@$(MAKE) push \
--no-print-directory \
GOOS=$(firstword $(subst _, ,$*)) \
GOARCH=$(lastword $(subst _, ,$*))

all-build: $(addprefix build-, $(subst /,_, $(BIN_PLATFORMS)))

all-container: $(addprefix container-, $(subst /,_, $(DOCKER_PLATFORMS)))

all-push: $(addprefix push-, $(subst /,_, $(DOCKER_PLATFORMS)))

version:
@echo version=$(VERSION)
@echo version_strategy=$(version_strategy)
@echo git_tag=$(git_tag)
@echo git_branch=$(git_branch)
@echo commit_hash=$(commit_hash)
@echo commit_timestamp=$(commit_timestamp)

gen:
./hack/codegen.sh

fmt: $(BUILD_DIRS)
@docker run \
-i \
--rm \
-u $$(id -u):$$(id -g) \
-v $$(pwd):/src \
-w /src \
-v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin \
-v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin/$(OS)_$(ARCH) \
-v $$(pwd)/.go/cache:/.cache \
--env HTTP_PROXY=$(HTTP_PROXY) \
--env HTTPS_PROXY=$(HTTPS_PROXY) \
$(BUILD_IMAGE) \
./hack/fmt.sh $(SRC_DIRS)

build: $(OUTBIN)

# The following structure defeats Go's (intentional) behavior to always touch
# result files, even if they have not changed. This will still run `go` but
# will not trigger further work if nothing has actually changed.

$(OUTBIN): .go/$(OUTBIN).stamp
@true

# This will build the binary under ./.go and update the real binary iff needed.
.PHONY: .go/$(OUTBIN).stamp
.go/$(OUTBIN).stamp: $(BUILD_DIRS)
@echo "making $(OUTBIN)"
@docker run \
-i \
--rm \
-u $$(id -u):$$(id -g) \
-v $$(pwd):/src \
-w /src \
-v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin \
-v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin/$(OS)_$(ARCH) \
-v $$(pwd)/.go/cache:/.cache \
--env HTTP_PROXY=$(HTTP_PROXY) \
--env HTTPS_PROXY=$(HTTPS_PROXY) \
$(BUILD_IMAGE) \
/bin/bash -c " \
ARCH=$(ARCH) \
OS=$(OS) \
VERSION=$(VERSION) \
version_strategy=$(version_strategy) \
git_branch=$(git_branch) \
git_tag=$(git_tag) \
commit_hash=$(commit_hash) \
commit_timestamp=$(commit_timestamp) \
./hack/build.sh \
"
@if [ $(COMPRESS) = yes ] && [ $(OS) != windows ]; then \
echo "compressing $(OUTBIN)"; \
upx --brute .go/$(OUTBIN); \
fi
@if ! cmp -s .go/$(OUTBIN) $(OUTBIN); then \
mv .go/$(OUTBIN) $(OUTBIN); \
date >$@; \
fi
@echo

# Used to track state in hidden files.
DOTFILE_IMAGE = $(subst /,_,$(IMAGE))-$(TAG)

container: bin/.container-$(DOTFILE_IMAGE)-PROD bin/.container-$(DOTFILE_IMAGE)-DBG
bin/.container-$(DOTFILE_IMAGE)-%: bin/$(OS)_$(ARCH)/$(BIN) $(DOCKERFILE_%)
@echo "container: $(IMAGE):$(TAG_$*)"
@sed \
-e 's|{ARG_BIN}|$(BIN)|g' \
-e 's|{ARG_ARCH}|$(ARCH)|g' \
-e 's|{ARG_OS}|$(OS)|g' \
-e 's|{ARG_FROM}|$(BASEIMAGE_$*)|g' \
-e 's|{RESTIC_VER}|$(RESTIC_VER)|g' \
-e 's|{NEW_RESTIC_VER}|$(NEW_RESTIC_VER)|g' \
$(DOCKERFILE_$*) > bin/.dockerfile-$*-$(OS)_$(ARCH)
@docker build -t $(IMAGE):$(TAG_$*) -f bin/.dockerfile-$*-$(OS)_$(ARCH) .
@docker images -q $(IMAGE):$(TAG_$*) > $@
@if [ $(version_strategy) = commit_hash ] && [ $(git_branch) = master ]; then \
docker tag $(IMAGE):$(TAG_$*) $(IMAGE):$(CANARY_TAG_$*); \
fi
@echo

push: bin/.push-$(DOTFILE_IMAGE)-PROD bin/.push-$(DOTFILE_IMAGE)-DBG
bin/.push-$(DOTFILE_IMAGE)-%: bin/.container-$(DOTFILE_IMAGE)-%
@docker push $(IMAGE):$(TAG_$*)
@echo "pushed: $(IMAGE):$(TAG_$*)"
@if [ $(version_strategy) = commit_hash ] && [ $(git_branch) = master ]; then \
docker push $(IMAGE):$(CANARY_TAG_$*); \
echo "pushed: $(IMAGE):$(TAG_$*)"; \
fi
@echo

.PHONY: docker-manifest
docker-manifest: docker-manifest-PROD docker-manifest-DBG
docker-manifest-%:
DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a $(IMAGE):$(VERSION_$*) $(foreach PLATFORM,$(DOCKER_PLATFORMS),$(IMAGE):$(VERSION_$*)_$(subst /,_,$(PLATFORM)))
DOCKER_CLI_EXPERIMENTAL=enabled docker manifest push $(IMAGE):$(VERSION_$*)

test: $(BUILD_DIRS)
@docker run \
-i \
--rm \
-u $$(id -u):$$(id -g) \
-v $$(pwd):/src \
-w /src \
-v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin \
-v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin/$(OS)_$(ARCH) \
-v $$(pwd)/.go/cache:/.cache \
--env HTTP_PROXY=$(HTTP_PROXY) \
--env HTTPS_PROXY=$(HTTPS_PROXY) \
$(BUILD_IMAGE) \
/bin/bash -c " \
ARCH=$(ARCH) \
OS=$(OS) \
VERSION=$(VERSION) \
./hack/test.sh $(SRC_DIRS) \
"

ADDTL_LINTERS := goconst,gofmt,goimports,unparam

.PHONY: lint
lint: $(BUILD_DIRS)
@echo "running linter"
@docker run \
-i \
--rm \
-u $$(id -u):$$(id -g) \
-v $$(pwd):/src \
-w /src \
-v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin \
-v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin/$(OS)_$(ARCH) \
-v $$(pwd)/.go/cache:/.cache \
--env HTTP_PROXY=$(HTTP_PROXY) \
--env HTTPS_PROXY=$(HTTPS_PROXY) \
$(BUILD_IMAGE) \
golangci-lint run --enable $(ADDTL_LINTERS)

$(BUILD_DIRS):
@mkdir -p $@

.PHONY: dev
dev: gen fmt push

.PHONY: ci
ci: lint test build #cover

.PHONY: qa
qa: docker-manifest
@if [ "$$APPSCODE_ENV" = "prod" ]; then \
echo "Nothing to do in prod env. Are you trying to 'release' binaries to prod?"; \
exit 1; \
fi
@if [ "$(version_strategy)" = "git_tag" ]; then \
echo "Are you trying to 'release' binaries to prod?"; \
exit 1; \
fi
@$(MAKE) clean all-push --no-print-directory

.PHONY: release
release: docker-manifest
@if [ "$$APPSCODE_ENV" != "prod" ]; then \
echo "'release' only works in PROD env."; \
exit 1; \
fi
@if [ "$(version_strategy)" != "git_tag" ]; then \
echo "'apply_tag' to release binaries and/or docker images."; \
exit 1; \
fi
@$(MAKE) clean all-push --no-print-directory

.PHONY: clean
clean:
rm -rf .go bin
Loading