diff --git a/.gitignore b/.gitignore index 30944692f3..896ffb3ad8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ .DS_Store -build +./build diff --git a/Makefile b/Makefile index 932568bf73..4b9a71eae8 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,7 @@ # github.com/docker/cli # -# build the CLI -.PHONY: build -build: clean - @./scripts/build/binary +all: binary # remove build artifacts .PHONY: clean @@ -18,24 +15,32 @@ clean: test: @go test -tags daemon -v $(shell go list ./... | grep -v /vendor/) -# run linters .PHONY: lint lint: @gometalinter --config gometalinter.json ./... + +.PHONY: binary +binary: + @./scripts/build/binary + # build the CLI for multiple architectures .PHONY: cross -cross: clean +cross: @./scripts/build/cross +.PHONY: dynbinary +dynbinary: + @./scripts/build/dynbinary + # download dependencies (vendor/) listed in vendor.conf .PHONY: vendor vendor: vendor.conf @vndr 2> /dev/null - @script/validate/check-git-diff vendor + @scripts/validate/check-git-diff vendor cli/compose/schema/bindata.go: cli/compose/schema/data/*.json go generate github.com/docker/cli/cli/compose/schema compose-jsonschema: cli/compose/schema/bindata.go - @script/validate/check-git-diff cli/compose/schema/bindata.go + @scripts/validate/check-git-diff cli/compose/schema/bindata.go diff --git a/README.md b/README.md index 66db952beb..fcf49495ce 100644 --- a/README.md +++ b/README.md @@ -6,60 +6,42 @@ docker/cli This repository is the home of the cli used in the Docker CE and Docker EE products. -It's composed of 3 main folders - -* `/cli` - all the commands code. -* `/cmd/docker` - the entrypoint of the cli, aka the main. - Development =========== -### Build locally +`docker/cli` is developed using Docker. + +Build a linux binary: ``` -$ make build +$ make -f docker.Makefile binary ``` -``` -$ make clean -``` - -You will need [gox](https://github.com/mitchellh/gox) for this one: - -``` -$ make cross -``` - -If you don't have [gox](https://github.com/mitchellh/gox), you can use the "in-container" version of `make cross`, listed below. - -### Build inside container - -``` -$ make -f docker.Makefile build -``` - -``` -$ make -f docker.Makefile clean -``` +Build binaries for all supported platforms: ``` $ make -f docker.Makefile cross ``` +Run all linting: + +``` +$ make -f docker.Makefile lint +``` +` + ### In-container development environment -``` -$ make -f docker.Makefile dev -``` - -Then you can use the [build locally](#build-locally) commands: +Start an interactive development environment: ``` -$ make build +$ make -f docker.Makefile shell ``` +In the development environment you can run many tasks, including build binaries: + ``` -$ make clean +$ make binary ``` Legal diff --git a/circle.yml b/circle.yml index 5635fd5f74..e791bb93bf 100644 --- a/circle.yml +++ b/circle.yml @@ -15,26 +15,34 @@ jobs: name: "Lint" command: | if [ "$CIRCLE_NODE_INDEX" != "0" ]; then exit; fi - docker build -f dockerfiles/Dockerfile.lint --tag cli-linter . + dockerfile=dockerfiles/Dockerfile.lint + echo "COPY . ." >> $dockerfile + docker build -f $dockerfile --tag cli-linter . docker run cli-linter - run: name: "Cross" command: | if [ "$CIRCLE_NODE_INDEX" != "1" ]; then exit; fi - docker build -f dockerfiles/Dockerfile.ci --tag cli-builder . + dockerfile=dockerfiles/Dockerfile.cross + echo "COPY . ." >> $dockerfile + docker build -f $dockerfile --tag cli-builder . docker run --name cross cli-builder make cross docker cp cross:/go/src/github.com/docker/cli/build /work/build - run: name: "Unit Test" command: | if [ "$CIRCLE_NODE_INDEX" != "2" ]; then exit; fi - docker build -f dockerfiles/Dockerfile.ci --tag cli-builder . + dockerfile=dockerfiles/Dockerfile.dev + echo "COPY . ." >> $dockerfile + docker build -f $dockerfile --tag cli-builder . docker run cli-builder make test - run: name: "Validate Vendor and Code Generation" command: | if [ "$CIRCLE_NODE_INDEX" != "3" ]; then exit; fi - docker build -f dockerfiles/Dockerfile.ci --tag cli-builder . + dockerfile=dockerfiles/Dockerfile.dev + echo "COPY . ." >> $dockerfile + docker build -f $dockerfile --tag cli-builder . docker run cli-builder make -B vendor compose-jsonschema - store_artifacts: diff --git a/docker.Makefile b/docker.Makefile index e0d8643da7..5fde78e470 100644 --- a/docker.Makefile +++ b/docker.Makefile @@ -6,23 +6,30 @@ DEV_DOCKER_IMAGE_NAME = docker-cli-dev LINTER_IMAGE_NAME = docker-cli-lint +CROSS_IMAGE_NAME = docker-cli-cross MOUNTS = -v `pwd`:/go/src/github.com/docker/cli # build docker image (dockerfiles/Dockerfile.build) .PHONY: build_docker_image build_docker_image: - @docker build -q -t $(DEV_DOCKER_IMAGE_NAME) -f ./dockerfiles/Dockerfile.build . + @docker build -t $(DEV_DOCKER_IMAGE_NAME) -f ./dockerfiles/Dockerfile.dev . # build docker image having the linting tools (dockerfiles/Dockerfile.lint) .PHONY: build_linter_image build_linter_image: - @docker build -q -t $(LINTER_IMAGE_NAME) -f ./dockerfiles/Dockerfile.lint . + @docker build -t $(LINTER_IMAGE_NAME) -f ./dockerfiles/Dockerfile.lint . + +.PHONY: build_cross_image +build_cross_image: + @docker build -t $(CROSS_IMAGE_NAME) -f ./dockerfiles/Dockerfile.cross . + # build executable using a container -.PHONY: build -build: build_docker_image +binary: build_docker_image @echo "WARNING: this will drop a Linux executable on your host (not a macOS or Windows one)" - @docker run --rm $(MOUNTS) $(DEV_DOCKER_IMAGE_NAME) make build + @docker run --rm $(MOUNTS) $(DEV_DOCKER_IMAGE_NAME) make binary + +build: binary # clean build artifacts using a container .PHONY: clean @@ -36,14 +43,16 @@ test: build_docker_image # build the CLI for multiple architectures using a container .PHONY: cross -cross: build_docker_image - @docker run --rm $(MOUNTS) $(DEV_DOCKER_IMAGE_NAME) make cross +cross: build_cross_image + @docker run --rm $(MOUNTS) $(CROSS_IMAGE_NAME) make cross # start container in interactive mode for in-container development .PHONY: dev dev: build_docker_image @docker run -ti $(MOUNTS) -v /var/run/docker.sock:/var/run/docker.sock $(DEV_DOCKER_IMAGE_NAME) ash +shell: dev + # run linters in a container .PHONY: lint lint: build_linter_image @@ -53,3 +62,6 @@ lint: build_linter_image .PHONY: vendor vendor: build_docker_image vendor.conf @docker run -ti --rm $(MOUNTS) $(DEV_DOCKER_IMAGE_NAME) make vendor + +dynbinary: build_cross_image + @docker run -ti --rm $(MOUNTS) $(CROSS_IMAGE_NAME) make dynbinary diff --git a/dockerfiles/Dockerfile.ci b/dockerfiles/Dockerfile.ci deleted file mode 100644 index 166239e617..0000000000 --- a/dockerfiles/Dockerfile.ci +++ /dev/null @@ -1,29 +0,0 @@ -# -# This Dockerfile makes the docker builder run the tests. -# It means that if this Dockerfile can be built successfully, -# the tests passed. -# -# From the repo root dir: -# $ docker build -f dockerfiles/Dockerfile.ci . -# - -FROM golang:1.8-alpine - -RUN apk add -U git make - -RUN go get github.com/LK4D4/vndr && \ - cp /go/bin/vndr /usr/bin && \ - rm -rf /go/src/* /go/pkg/* /go/bin/* - -RUN go get github.com/mitchellh/gox && \ - cp /go/bin/gox /usr/bin && \ - rm -rf /go/src/* /go/pkg/* /go/bin/* - -RUN go get github.com/jteeuwen/go-bindata/go-bindata && \ - cp /go/bin/go-bindata /usr/bin && \ - rm -rf /go/src/* /go/pkg/* /go/bin/* - -COPY . /go/src/github.com/docker/cli - -ENV CGO_ENABLED=0 -WORKDIR /go/src/github.com/docker/cli diff --git a/dockerfiles/Dockerfile.cross b/dockerfiles/Dockerfile.cross new file mode 100644 index 0000000000..7e9aaacc24 --- /dev/null +++ b/dockerfiles/Dockerfile.cross @@ -0,0 +1,22 @@ + +FROM golang:1.8.1 + +# allow replacing httpredir or deb mirror +ARG APT_MIRROR=deb.debian.org +RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list + +RUN apt-get update -qq && apt-get install -y -q \ + libltdl-dev \ + gcc-mingw-w64 \ + parallel \ + ; + +RUN go get github.com/mitchellh/gox && \ + cp /go/bin/gox /usr/bin && \ + rm -rf /go/src/* /go/pkg/* /go/bin/* + +COPY dockerfiles/osx-cross.sh /tmp/ +RUN /tmp/osx-cross.sh +ENV PATH /osxcross/target/bin:$PATH + +WORKDIR /go/src/github.com/docker/cli diff --git a/dockerfiles/Dockerfile.build b/dockerfiles/Dockerfile.dev similarity index 92% rename from dockerfiles/Dockerfile.build rename to dockerfiles/Dockerfile.dev index 13ee07f252..d1887e85ef 100644 --- a/dockerfiles/Dockerfile.build +++ b/dockerfiles/Dockerfile.dev @@ -1,7 +1,7 @@ FROM golang:1.8-alpine -RUN apk add -U git make +RUN apk add -U git make bash coreutils RUN go get github.com/LK4D4/vndr && \ cp /go/bin/vndr /usr/bin && \ diff --git a/dockerfiles/Dockerfile.lint b/dockerfiles/Dockerfile.lint index 9050e05325..2bba9595e5 100644 --- a/dockerfiles/Dockerfile.lint +++ b/dockerfiles/Dockerfile.lint @@ -7,6 +7,5 @@ RUN go get -u gopkg.in/alecthomas/gometalinter.v1 && \ gometalinter --install WORKDIR /go/src/github.com/docker/cli -COPY . . ENTRYPOINT ["/usr/local/bin/gometalinter"] CMD ["--config=gometalinter.json", "./..."] diff --git a/dockerfiles/osx-cross.sh b/dockerfiles/osx-cross.sh new file mode 100755 index 0000000000..07f6542fcc --- /dev/null +++ b/dockerfiles/osx-cross.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# +# Install dependencies required to cross compile osx, then cleanup +# +# TODO: this should be a separate build stage when CI supports it + + +set -eu -o pipefail + +PKG_DEPS="patch xz-utils clang" + +apt-get update -qq +apt-get install -y -q $PKG_DEPS + +OSX_SDK=MacOSX10.11.sdk +OSX_CROSS_COMMIT=a9317c18a3a457ca0a657f08cc4d0d43c6cf8953 +OSXCROSS_PATH="/osxcross" + +echo "Cloning osxcross" +time git clone https://github.com/tpoechtrager/osxcross.git $OSXCROSS_PATH +cd $OSXCROSS_PATH +git checkout -q $OSX_CROSS_COMMIT + +echo "Downloading OSX SDK" +time curl -sSL https://s3.dockerproject.org/darwin/v2/${OSX_SDK}.tar.xz \ + -o "${OSXCROSS_PATH}/tarballs/${OSX_SDK}.tar.xz" + +echo "Buidling osxcross" +UNATTENDED=yes OSX_VERSION_MIN=10.6 ${OSXCROSS_PATH}/build.sh > /dev/null diff --git a/scripts/build/.variables b/scripts/build/.variables new file mode 100755 index 0000000000..12ca95e7d1 --- /dev/null +++ b/scripts/build/.variables @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +set -eu + +VERSION=${VERSION:-"unknown-version"} +GITCOMMIT=${GITCOMMIT:-$(git rev-parse --short HEAD 2> /dev/null || true)} +BUILDTIME=${BUILDTIME:-$(date --utc --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/')} + +export LDFLAGS="\ + -w \ + -X github.com/docker/cli/cli.GitCommit=${GITCOMMIT} \ + -X github.com/docker/cli/cli.BuildTime=${BUILDTIME} \ + -X github.com/docker/cli/cli.Version=${VERSION} \ + ${LDFLAGS:-} \ +" + +export TARGET="build/docker-$(go env GOHOSTOS)-$(go env GOHOSTARCH)" +export SOURCE="github.com/docker/cli/cmd/docker" diff --git a/scripts/build/binary b/scripts/build/binary index 9f6f472812..b40f9d5f9d 100755 --- a/scripts/build/binary +++ b/scripts/build/binary @@ -1,5 +1,14 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash +# +# Build a static binary for the host OS/ARCH +# -source ./scripts/build/ldflags +set -eu -o pipefail -go build -o ./build/docker --ldflags "${LDFLAGS}" github.com/docker/cli/cmd/docker +source ./scripts/build/.variables + +echo "Building statically linked $TARGET" +export CGO_ENABLED=0 +go build -o "${TARGET}" --ldflags "${LDFLAGS}" "${SOURCE}" + +ln -sf "$(basename ${TARGET})" build/docker diff --git a/scripts/build/cross b/scripts/build/cross index 4e113943a4..b9df606fca 100755 --- a/scripts/build/cross +++ b/scripts/build/cross @@ -1,8 +1,12 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash -source ./scripts/build/ldflags +set -eu -o pipefail -gox -output build/docker-{{.OS}}-{{.Arch}} \ - -osarch="linux/arm linux/amd64 darwin/amd64 windows/amd64" \ - --ldflags "${LDFLAGS}" \ - github.com/docker/cli/cmd/docker +export BUILDDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +echo "Building all binaries" +SHELL=/bin/bash parallel ::: \ + "$BUILDDIR/linux-cross" \ + "$BUILDDIR/windows" \ + "$BUILDDIR/osx" \ + ; diff --git a/scripts/build/dynbinary b/scripts/build/dynbinary new file mode 100755 index 0000000000..d1107338ab --- /dev/null +++ b/scripts/build/dynbinary @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# +# Build a dynamically linked binary for the host OS/ARCH +# + +set -eu -o pipefail + +source ./scripts/build/.variables + +echo "Building dynamically linked $TARGET" +export CGO_ENABLED=1 +go build -o "${TARGET}" -tags pkcs11 --ldflags "${LDFLAGS}" "${SOURCE}" + +ln -sf "$(basename ${TARGET})" build/docker diff --git a/scripts/build/ldflags b/scripts/build/ldflags deleted file mode 100755 index a0c5e1f9e6..0000000000 --- a/scripts/build/ldflags +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -VERSION=${VERSION:-"unknown-version"} -GITCOMMIT=${GITCOMMIT:-$(git rev-parse --short HEAD 2> /dev/null || true)} -BUILDTIME=${BUILDTIME:-$(date --utc --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/')} - -export LDFLAGS="-X github.com/docker/cli/cli.GitCommit=${GITCOMMIT} \ - -X github.com/docker/cli/cli.BuildTime=${BUILDTIME} \ - -X github.com/docker/cli/cli.Version=${VERSION} ${LDFLAGS}" diff --git a/scripts/build/linux-cross b/scripts/build/linux-cross new file mode 100755 index 0000000000..4a43e4b396 --- /dev/null +++ b/scripts/build/linux-cross @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# +# Build static linux binary for multiple architectures +# + +set -eu -o pipefail + +source ./scripts/build/.variables + +CROSS_OSARCH="linux/amd64 linux/arm" + +# Compile is broken +# linux/ppc64le + +# Not yet supported by gox +# linux/s390x + +echo "Building all linux binaries" +gox -output build/docker-{{.OS}}-{{.Arch}} \ + -osarch "${CROSS_OSARCH}" \ + --ldflags "${LDFLAGS}" \ + "${SOURCE}" diff --git a/scripts/build/osx b/scripts/build/osx new file mode 100755 index 0000000000..b993a8e0c8 --- /dev/null +++ b/scripts/build/osx @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# +# Build an osx binary from linux +# + +set -eu -o pipefail + +source ./scripts/build/.variables + +export CGO_ENABLED=1 +export GOOS=darwin +export GOARCH=amd64 +export CC=o64-clang +export LDFLAGS='-linkmode external -s' +export LDFLAGS_STATIC_DOCKER='-extld='${CC} + +# Override TARGET +TARGET="build/docker-$GOOS-$GOARCH" + +echo "Building $TARGET" +go build -o "${TARGET}" -tags pkcs11 --ldflags "${LDFLAGS}" "${SOURCE}" diff --git a/scripts/build/windows b/scripts/build/windows new file mode 100755 index 0000000000..eccf6d1e57 --- /dev/null +++ b/scripts/build/windows @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# +# Build a windows binary from linux +# + +set -eu -o pipefail + +source ./scripts/build/.variables + +export CC=x86_64-w64-mingw32-gcc +export CGO_ENABLED=1 +export GOOS=windows +export GOARCH=amd64 + +# Override TARGET +TARGET="build/docker-$GOOS-$GOARCH" + +echo "Building $TARGET" +# TODO: -tags pkcs11 +go build -o "${TARGET}" --ldflags "${LDFLAGS}" "${SOURCE}" diff --git a/script/validate/check-git-diff b/scripts/validate/check-git-diff similarity index 100% rename from script/validate/check-git-diff rename to scripts/validate/check-git-diff