github.com/lafolle/docker@v1.6.0/hack/make.sh (about)

     1  #!/usr/bin/env bash
     2  set -e
     3  
     4  # This script builds various binary artifacts from a checkout of the docker
     5  # source code.
     6  #
     7  # Requirements:
     8  # - The current directory should be a checkout of the docker source code
     9  #   (http://github.com/docker/docker). Whatever version is checked out
    10  #   will be built.
    11  # - The VERSION file, at the root of the repository, should exist, and
    12  #   will be used as Docker binary version and package version.
    13  # - The hash of the git commit will also be included in the Docker binary,
    14  #   with the suffix -dirty if the repository isn't clean.
    15  # - The script is intented to be run inside the docker container specified
    16  #   in the Dockerfile at the root of the source. In other words:
    17  #   DO NOT CALL THIS SCRIPT DIRECTLY.
    18  # - The right way to call this script is to invoke "make" from
    19  #   your checkout of the Docker repository.
    20  #   the Makefile will do a "docker build -t docker ." and then
    21  #   "docker run hack/make.sh" in the resulting image.
    22  #
    23  
    24  set -o pipefail
    25  
    26  export DOCKER_PKG='github.com/docker/docker'
    27  
    28  # We're a nice, sexy, little shell script, and people might try to run us;
    29  # but really, they shouldn't. We want to be in a container!
    30  if [ "$(pwd)" != "/go/src/$DOCKER_PKG" ] || [ -z "$DOCKER_CROSSPLATFORMS" ]; then
    31  	{
    32  		echo "# WARNING! I don't seem to be running in the Docker container."
    33  		echo "# The result of this command might be an incorrect build, and will not be"
    34  		echo "#   officially supported."
    35  		echo "#"
    36  		echo "# Try this instead: make all"
    37  		echo "#"
    38  	} >&2
    39  fi
    40  
    41  echo
    42  
    43  # List of bundles to create when no argument is passed
    44  DEFAULT_BUNDLES=(
    45  	validate-dco
    46  	validate-gofmt
    47  	validate-toml
    48  
    49  	binary
    50  
    51  	test-unit
    52  	test-integration-cli
    53  	test-docker-py
    54  
    55  	dynbinary
    56  	test-integration
    57  
    58  	cover
    59  	cross
    60  	tgz
    61  	ubuntu
    62  )
    63  
    64  VERSION=$(cat ./VERSION)
    65  if command -v git &> /dev/null && git rev-parse &> /dev/null; then
    66  	GITCOMMIT=$(git rev-parse --short HEAD)
    67  	if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
    68  		GITCOMMIT="$GITCOMMIT-dirty"
    69  	fi
    70  elif [ "$DOCKER_GITCOMMIT" ]; then
    71  	GITCOMMIT="$DOCKER_GITCOMMIT"
    72  else
    73  	echo >&2 'error: .git directory missing and DOCKER_GITCOMMIT not specified'
    74  	echo >&2 '  Please either build with the .git directory accessible, or specify the'
    75  	echo >&2 '  exact (--short) commit hash you are building using DOCKER_GITCOMMIT for'
    76  	echo >&2 '  future accountability in diagnosing build issues.  Thanks!'
    77  	exit 1
    78  fi
    79  
    80  if [ "$AUTO_GOPATH" ]; then
    81  	rm -rf .gopath
    82  	mkdir -p .gopath/src/"$(dirname "${DOCKER_PKG}")"
    83  	ln -sf ../../../.. .gopath/src/"${DOCKER_PKG}"
    84  	export GOPATH="$(pwd)/.gopath:$(pwd)/vendor"
    85  fi
    86  
    87  if [ ! "$GOPATH" ]; then
    88  	echo >&2 'error: missing GOPATH; please see http://golang.org/doc/code.html#GOPATH'
    89  	echo >&2 '  alternatively, set AUTO_GOPATH=1'
    90  	exit 1
    91  fi
    92  
    93  if [ -z "$DOCKER_CLIENTONLY" ]; then
    94  	DOCKER_BUILDTAGS+=" daemon"
    95  fi
    96  
    97  if [ "$DOCKER_EXECDRIVER" = 'lxc' ]; then
    98  	DOCKER_BUILDTAGS+=' test_no_exec'
    99  fi
   100  
   101  # Use these flags when compiling the tests and final binary
   102  
   103  IAMSTATIC='true'
   104  source "$(dirname "$BASH_SOURCE")/make/.go-autogen"
   105  LDFLAGS='-w'
   106  
   107  LDFLAGS_STATIC='-linkmode external'
   108  # Cgo -H windows is incompatible with -linkmode external.
   109  if [ "$(go env GOOS)" == 'windows' ]; then
   110  	LDFLAGS_STATIC=''
   111  fi
   112  EXTLDFLAGS_STATIC='-static'
   113  # ORIG_BUILDFLAGS is necessary for the cross target which cannot always build
   114  # with options like -race.
   115  ORIG_BUILDFLAGS=( -a -tags "netgo static_build $DOCKER_BUILDTAGS" -installsuffix netgo )
   116  # see https://github.com/golang/go/issues/9369#issuecomment-69864440 for why -installsuffix is necessary here
   117  BUILDFLAGS=( $BUILDFLAGS "${ORIG_BUILDFLAGS[@]}" )
   118  # Test timeout.
   119  : ${TIMEOUT:=30m}
   120  TESTFLAGS+=" -test.timeout=${TIMEOUT}"
   121  
   122  # A few more flags that are specific just to building a completely-static binary (see hack/make/binary)
   123  # PLEASE do not use these anywhere else.
   124  EXTLDFLAGS_STATIC_DOCKER="$EXTLDFLAGS_STATIC -lpthread -Wl,--unresolved-symbols=ignore-in-object-files"
   125  LDFLAGS_STATIC_DOCKER="
   126  	$LDFLAGS_STATIC
   127  	-extldflags \"$EXTLDFLAGS_STATIC_DOCKER\"
   128  "
   129  
   130  if [ "$(uname -s)" = 'FreeBSD' ]; then
   131  	# Tell cgo the compiler is Clang, not GCC
   132  	# https://code.google.com/p/go/source/browse/src/cmd/cgo/gcc.go?spec=svne77e74371f2340ee08622ce602e9f7b15f29d8d3&r=e6794866ebeba2bf8818b9261b54e2eef1c9e588#752
   133  	export CC=clang
   134  
   135  	# "-extld clang" is a workaround for
   136  	# https://code.google.com/p/go/issues/detail?id=6845
   137  	LDFLAGS="$LDFLAGS -extld clang"
   138  fi
   139  
   140  # If sqlite3.h doesn't exist under /usr/include,
   141  # check /usr/local/include also just in case
   142  # (e.g. FreeBSD Ports installs it under the directory)
   143  if [ ! -e /usr/include/sqlite3.h ] && [ -e /usr/local/include/sqlite3.h ]; then
   144  	export CGO_CFLAGS='-I/usr/local/include'
   145  	export CGO_LDFLAGS='-L/usr/local/lib'
   146  fi
   147  
   148  HAVE_GO_TEST_COVER=
   149  if \
   150  	go help testflag | grep -- -cover > /dev/null \
   151  	&& go tool -n cover > /dev/null 2>&1 \
   152  ; then
   153  	HAVE_GO_TEST_COVER=1
   154  fi
   155  
   156  # If $TESTFLAGS is set in the environment, it is passed as extra arguments to 'go test'.
   157  # You can use this to select certain tests to run, eg.
   158  #
   159  #   TESTFLAGS='-run ^TestBuild$' ./hack/make.sh test
   160  #
   161  go_test_dir() {
   162  	dir=$1
   163  	coverpkg=$2
   164  	testcover=()
   165  	if [ "$HAVE_GO_TEST_COVER" ]; then
   166  		# if our current go install has -cover, we want to use it :)
   167  		mkdir -p "$DEST/coverprofiles"
   168  		coverprofile="docker${dir#.}"
   169  		coverprofile="$DEST/coverprofiles/${coverprofile//\//-}"
   170  		testcover=( -cover -coverprofile "$coverprofile" $coverpkg )
   171  	fi
   172  	(
   173  		export DEST
   174  		echo '+ go test' $TESTFLAGS "${DOCKER_PKG}${dir#.}"
   175  		cd "$dir"
   176  		test_env go test ${testcover[@]} -ldflags "$LDFLAGS" "${BUILDFLAGS[@]}" $TESTFLAGS
   177  	)
   178  }
   179  test_env() {
   180  	# use "env -i" to tightly control the environment variables that bleed into the tests
   181  	env -i \
   182  		DEST="$DEST" \
   183  		DOCKER_EXECDRIVER="$DOCKER_EXECDRIVER" \
   184  		DOCKER_GRAPHDRIVER="$DOCKER_GRAPHDRIVER" \
   185  		DOCKER_HOST="$DOCKER_HOST" \
   186  		GOPATH="$GOPATH" \
   187  		HOME="$DEST/fake-HOME" \
   188  		PATH="$PATH" \
   189  		TEST_DOCKERINIT_PATH="$TEST_DOCKERINIT_PATH" \
   190  		"$@"
   191  }
   192  
   193  # a helper to provide ".exe" when it's appropriate
   194  binary_extension() {
   195  	if [ "$(go env GOOS)" = 'windows' ]; then
   196  		echo -n '.exe'
   197  	fi
   198  }
   199  
   200  # This helper function walks the current directory looking for directories
   201  # holding certain files ($1 parameter), and prints their paths on standard
   202  # output, one per line.
   203  find_dirs() {
   204  	find . -not \( \
   205  		\( \
   206  			-path './vendor/*' \
   207  			-o -path './integration/*' \
   208  			-o -path './integration-cli/*' \
   209  			-o -path './contrib/*' \
   210  			-o -path './pkg/mflag/example/*' \
   211  			-o -path './.git/*' \
   212  			-o -path './bundles/*' \
   213  			-o -path './docs/*' \
   214  			-o -path './pkg/libcontainer/nsinit/*' \
   215  		\) \
   216  		-prune \
   217  	\) -name "$1" -print0 | xargs -0n1 dirname | sort -u
   218  }
   219  
   220  hash_files() {
   221  	while [ $# -gt 0 ]; do
   222  		f="$1"
   223  		shift
   224  		dir="$(dirname "$f")"
   225  		base="$(basename "$f")"
   226  		for hashAlgo in md5 sha256; do
   227  			if command -v "${hashAlgo}sum" &> /dev/null; then
   228  				(
   229  					# subshell and cd so that we get output files like:
   230  					#   $HASH docker-$VERSION
   231  					# instead of:
   232  					#   $HASH /go/src/github.com/.../$VERSION/binary/docker-$VERSION
   233  					cd "$dir"
   234  					"${hashAlgo}sum" "$base" > "$base.$hashAlgo"
   235  				)
   236  			fi
   237  		done
   238  	done
   239  }
   240  
   241  bundle() {
   242  	bundlescript=$1
   243  	bundle=$(basename $bundlescript)
   244  	echo "---> Making bundle: $bundle (in bundles/$VERSION/$bundle)"
   245  	mkdir -p bundles/$VERSION/$bundle
   246  	source "$bundlescript" "$(pwd)/bundles/$VERSION/$bundle"
   247  }
   248  
   249  main() {
   250  	# We want this to fail if the bundles already exist and cannot be removed.
   251  	# This is to avoid mixing bundles from different versions of the code.
   252  	mkdir -p bundles
   253  	if [ -e "bundles/$VERSION" ]; then
   254  		echo "bundles/$VERSION already exists. Removing."
   255  		rm -fr bundles/$VERSION && mkdir bundles/$VERSION || exit 1
   256  		echo
   257  	fi
   258  	SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
   259  	if [ $# -lt 1 ]; then
   260  		bundles=(${DEFAULT_BUNDLES[@]})
   261  	else
   262  		bundles=($@)
   263  	fi
   264  	for bundle in ${bundles[@]}; do
   265  		bundle $SCRIPTDIR/make/$bundle
   266  		echo
   267  	done
   268  }
   269  
   270  main "$@"