github.com/raychaser/docker@v1.5.0/project/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  # Use these flags when compiling the tests and final binary
    98  LDFLAGS='
    99  	-X '$DOCKER_PKG'/dockerversion.GITCOMMIT "'$GITCOMMIT'"
   100  	-X '$DOCKER_PKG'/dockerversion.VERSION "'$VERSION'"
   101  '
   102  
   103  if [ -z "$DEBUG" ]; then
   104  	LDFLAGS="-w $LDFLAGS"
   105  fi
   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  	-X $DOCKER_PKG/dockerversion.IAMSTATIC true
   128  	-extldflags \"$EXTLDFLAGS_STATIC_DOCKER\"
   129  "
   130  
   131  if [ "$(uname -s)" = 'FreeBSD' ]; then
   132  	# Tell cgo the compiler is Clang, not GCC
   133  	# https://code.google.com/p/go/source/browse/src/cmd/cgo/gcc.go?spec=svne77e74371f2340ee08622ce602e9f7b15f29d8d3&r=e6794866ebeba2bf8818b9261b54e2eef1c9e588#752
   134  	export CC=clang
   135  
   136  	# "-extld clang" is a workaround for
   137  	# https://code.google.com/p/go/issues/detail?id=6845
   138  	LDFLAGS="$LDFLAGS -extld clang"
   139  fi
   140  
   141  # If sqlite3.h doesn't exist under /usr/include,
   142  # check /usr/local/include also just in case
   143  # (e.g. FreeBSD Ports installs it under the directory)
   144  if [ ! -e /usr/include/sqlite3.h ] && [ -e /usr/local/include/sqlite3.h ]; then
   145  	export CGO_CFLAGS='-I/usr/local/include'
   146  	export CGO_LDFLAGS='-L/usr/local/lib'
   147  fi
   148  
   149  HAVE_GO_TEST_COVER=
   150  if \
   151  	go help testflag | grep -- -cover > /dev/null \
   152  	&& go tool -n cover > /dev/null 2>&1 \
   153  ; then
   154  	HAVE_GO_TEST_COVER=1
   155  fi
   156  
   157  # If $TESTFLAGS is set in the environment, it is passed as extra arguments to 'go test'.
   158  # You can use this to select certain tests to run, eg.
   159  #
   160  #   TESTFLAGS='-run ^TestBuild$' ./hack/make.sh test
   161  #
   162  go_test_dir() {
   163  	dir=$1
   164  	coverpkg=$2
   165  	testcover=()
   166  	if [ "$HAVE_GO_TEST_COVER" ]; then
   167  		# if our current go install has -cover, we want to use it :)
   168  		mkdir -p "$DEST/coverprofiles"
   169  		coverprofile="docker${dir#.}"
   170  		coverprofile="$DEST/coverprofiles/${coverprofile//\//-}"
   171  		testcover=( -cover -coverprofile "$coverprofile" $coverpkg )
   172  	fi
   173  	(
   174  		export DEST
   175  		echo '+ go test' $TESTFLAGS "${DOCKER_PKG}${dir#.}"
   176  		cd "$dir"
   177  		go test ${testcover[@]} -ldflags "$LDFLAGS" "${BUILDFLAGS[@]}" $TESTFLAGS
   178  	)
   179  }
   180  
   181  # a helper to provide ".exe" when it's appropriate
   182  binary_extension() {
   183  	if [ "$(go env GOOS)" = 'windows' ]; then
   184  		echo -n '.exe'
   185  	fi
   186  }
   187  
   188  # This helper function walks the current directory looking for directories
   189  # holding certain files ($1 parameter), and prints their paths on standard
   190  # output, one per line.
   191  find_dirs() {
   192  	find . -not \( \
   193  		\( \
   194  			-path './vendor/*' \
   195  			-o -path './integration/*' \
   196  			-o -path './integration-cli/*' \
   197  			-o -path './contrib/*' \
   198  			-o -path './pkg/mflag/example/*' \
   199  			-o -path './.git/*' \
   200  			-o -path './bundles/*' \
   201  			-o -path './docs/*' \
   202  			-o -path './pkg/libcontainer/nsinit/*' \
   203  		\) \
   204  		-prune \
   205  	\) -name "$1" -print0 | xargs -0n1 dirname | sort -u
   206  }
   207  
   208  hash_files() {
   209  	while [ $# -gt 0 ]; do
   210  		f="$1"
   211  		shift
   212  		dir="$(dirname "$f")"
   213  		base="$(basename "$f")"
   214  		for hashAlgo in md5 sha256; do
   215  			if command -v "${hashAlgo}sum" &> /dev/null; then
   216  				(
   217  					# subshell and cd so that we get output files like:
   218  					#   $HASH docker-$VERSION
   219  					# instead of:
   220  					#   $HASH /go/src/github.com/.../$VERSION/binary/docker-$VERSION
   221  					cd "$dir"
   222  					"${hashAlgo}sum" "$base" > "$base.$hashAlgo"
   223  				)
   224  			fi
   225  		done
   226  	done
   227  }
   228  
   229  bundle() {
   230  	bundlescript=$1
   231  	bundle=$(basename $bundlescript)
   232  	echo "---> Making bundle: $bundle (in bundles/$VERSION/$bundle)"
   233  	mkdir -p bundles/$VERSION/$bundle
   234  	source "$bundlescript" "$(pwd)/bundles/$VERSION/$bundle"
   235  }
   236  
   237  main() {
   238  	# We want this to fail if the bundles already exist and cannot be removed.
   239  	# This is to avoid mixing bundles from different versions of the code.
   240  	mkdir -p bundles
   241  	if [ -e "bundles/$VERSION" ]; then
   242  		echo "bundles/$VERSION already exists. Removing."
   243  		rm -fr bundles/$VERSION && mkdir bundles/$VERSION || exit 1
   244  		echo
   245  	fi
   246  	SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
   247  	if [ $# -lt 1 ]; then
   248  		bundles=(${DEFAULT_BUNDLES[@]})
   249  	else
   250  		bundles=($@)
   251  	fi
   252  	for bundle in ${bundles[@]}; do
   253  		bundle $SCRIPTDIR/make/$bundle
   254  		echo
   255  	done
   256  }
   257  
   258  main "$@"