diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..74083c1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,24 @@ +# vim: se syn=dockerfile: +FROM golang:1.13-alpine AS build +ENV CGO_ENABLED 0 + +RUN apk add --no-cache --update make git perl-utils dep shadow + +ENV PATH "/go/bin:${PATH}" + +RUN go get honnef.co/go/tools/cmd/staticcheck + +RUN mkdir -p /go/src/github.com/joyent/kosh +WORKDIR /go/src/github.com/joyent/kosh + +COPY . /go/src/github.com/joyent/kosh/ + +RUN make + +FROM scratch +COPY --from=build /go/src/github.com/joyent/kosh/bin/kosh /bin/kosh +COPY --from=build /etc/ssl /etc/ssl + +ENV KOSH_TOKEN "broken" +ENTRYPOINT [ "/bin/kosh" ] +CMD ["version"] diff --git a/Dockerfile.release b/Dockerfile.release new file mode 100644 index 0000000..98eb80a --- /dev/null +++ b/Dockerfile.release @@ -0,0 +1,38 @@ +# vim: se syn=dockerfile: +FROM golang:1.13-alpine AS build +ENV CGO_ENABLED 0 + +RUN apk add --no-cache --update make git perl-utils dep shadow + +ARG UID="1000" +ARG BRANCH="master" + +ENV GOPATH "/home/app/go" +ENV PATH "${GOPATH}/bin:${PATH}" +ENV GOCACHE "/home/app/.cache" + +RUN mkdir -p "${GOPATH}/src/github.com/joyent/" +RUN chown -R $UID /home/app + + +USER $UID +ENV HOME "/home/app" + +RUN rm -rf release +RUN rm -rf vendor + +RUN mkdir -p "${GOPATH}/src/github.com/joyent" +WORKDIR "${GOPATH}/src/github.com/joyent/" +RUN git clone --branch $BRANCH https://github.com/joyent/kosh kosh + +WORKDIR "${GOPATH}/src/github.com/joyent/kosh" +RUN go get honnef.co/go/tools/cmd/staticcheck + +RUN id +RUN env + +ENTRYPOINT ["make" ] +CMD [ "release" ] + + + diff --git a/Makefile b/Makefile index 9082264..675be55 100644 --- a/Makefile +++ b/Makefile @@ -1,19 +1,13 @@ VERSION ?= v0.0.0 #VERSION ?= $(shell git describe --tags --abbrev=0 | sed 's/^v//') -GIT_REV := $(shell git describe --always --abbrev --dirty --long) -LD_FLAGS = -ldflags="-X main.Version=$(VERSION) -X main.GitRev=$(GIT_REV)" -BUILD := CGO_ENABLED=0 go build $(LD_FLAGS) - -build: vendor clean test kosh ## Clean, test, and build all the things. You probably want this target +build: vendor clean test all ## Test and build binaries for local architecture first: tools .PHONY: clean -clean: ## Clean up the local environment - rm -f kosh - -kosh: ## Build kosh - $(BUILD) -o kosh ./... +clean: ## Remove build products from bin/ and release/ + rm -rf bin + rm -rf release .PHONY: tools tools: ## Download and install all dev/code tools @@ -37,4 +31,60 @@ help: ## Display this help message @echo "GNU make(1) targets:" @grep -E '^[a-zA-Z_.-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}' +.PHONY: docker_test +docker_test: ## run a test build in docker + docker/test.bash + +.PHONY: docker_release +docker_release: ## Build all release binaries and checksums in docker + docker/release.bash + + +################################ +# Dynamic Fanciness # +# aka Why GNU make Is Required # +################################ + +PLATFORMS := darwin-amd64 linux-amd64 solaris-amd64 freebsd-amd64 openbsd-amd64 linux-arm +BINARIES := kosh +RELEASE_BINARIES := kosh + +BINS := $(foreach bin,$(BINARIES),bin/$(bin)) +RELEASES := $(foreach bin,$(RELEASE_BINARIES),release/$(bin)) + +GIT_REV := $(shell git describe --always --abbrev --dirty --long) +LD_FLAGS := -ldflags="-X main.Version=$(VERSION) -X main.GitRev=$(GIT_REV)" +BUILD := CGO_ENABLED=0 go build $(LD_FLAGS) + +#### + +all: $(BINS) ## Build all binaries + +.PHONY: release +release: vendor test $(RELEASES) ## Build release binaries with checksums + +bin/%: + @mkdir -p bin + @echo "> Building bin/$(subst bin/,,$@)" + @$(BUILD) -o bin/$(subst bin/,,$@) *.go + +os = $(firstword $(subst -, ,$1)) +arch = $(lastword $(subst -, ,$1)) + +define release_me + $(eval BIN:=$(subst release/,,$@)) + $(eval GOOS:=$(call os, $(platform))) + $(eval GOARCH:=$(call arch, $(platform))) + $(eval RPATH:=release/$(BIN)-$(GOOS)-$(GOARCH)) + + @echo "> Building $(RPATH)" + @GOOS=$(GOOS) GOARCH=$(GOARCH) $(BUILD) -o $(RPATH) *.go + shasum -a 256 $(RPATH) > $(RPATH).sha256 +endef + + +release/%: + @mkdir -p release + $(foreach platform,$(PLATFORMS),$(call release_me)) + diff --git a/docker/release.bash b/docker/release.bash new file mode 100755 index 0000000..8452cbb --- /dev/null +++ b/docker/release.bash @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +PWD=$(pwd) + +PREFIX="joyentbuildops" +NAME="kosh" + +: ${BUILDNUMBER:=0} + +: ${BUILDER:=${USER}} +BUILDER=$(echo "${BUILDER}" | sed 's/\//_/g' | sed 's/-/_/g') + +: ${LABEL:="latest"} +LABEL=$(echo "${LABEL}" | sed 's/\//_/g') + +if test $LABEL == "master"; then + LABEL="latest" +fi + +: ${BRANCH:="master"} + +IMAGE_NAME="${PREFIX}/${NAME}:${LABEL}" + +mkdir -p release + +docker build \ + -t ${IMAGE_NAME} \ + --build-arg BRANCH=${BRANCH} \ + --build-arg UID=$(id -u) \ + --file Dockerfile.release . \ +&& \ +docker run --rm \ + --name ${BUILDER}_${BUILDNUMBER} \ + -u $(id -u):$(id -g) \ + --mount type=bind,source="${PWD}/release",target="/home/app/go/src/github.com/joyent/kosh/release" \ + ${IMAGE_NAME} \ +&& \ +docker rmi ${IMAGE_NAME} diff --git a/docker/test.bash b/docker/test.bash new file mode 100755 index 0000000..0fcd2e7 --- /dev/null +++ b/docker/test.bash @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +: ${PREFIX:=$USER} +: ${NAME:="kosh"} + +: ${BUILDNUMBER:=0} + +: ${BUILDER:=${USER}} +BUILDER=$(echo "${BUILDER}" | sed 's/\//_/g' | sed 's/-/_/g') + +: ${LABEL:="latest"} +LABEL=$(echo "${LABEL}" | sed 's/\//_/g') + +IMAGE_NAME="${PREFIX}/${NAME}:${LABEL}" + +docker build \ + -t ${IMAGE_NAME} \ + --file Dockerfile . \ +&& \ +docker run \ + --rm \ + --name ${BUILDER}_${BUILDNUMBER} \ + ${IMAGE_NAME} + diff --git a/main.go b/main.go index d8aa8cc..a7a1a3b 100644 --- a/main.go +++ b/main.go @@ -183,6 +183,25 @@ func init() { API.StrictParsing = *strictParseOpt API.DevelMode = *develOpt } + + App.Version("version", Version) + + App.Command( + "version", + "Get more detailed version info than --version", + func(cmd *cli.Cmd) { + + cmd.Action = func() { + fmt.Printf( + "Kosh %s\n"+ + " Git Revision: %s\n", + Version, + GitRev, + ) + } + }, + ) + } func main() {