github.com/ph/moby@v1.13.1/hack/Jenkins/W2L/setup.sh (about)

     1  # Jenkins CI script for Windows to Linux CI.
     2  # Heavily modified by John Howard (@jhowardmsft) December 2015 to try to make it more reliable.
     3  set +xe
     4  SCRIPT_VER="Wed Apr 20 18:30:19 UTC 2016"
     5  
     6  # TODO to make (even) more resilient: 
     7  #  - Wait for daemon to be running before executing docker commands
     8  #  - Check if jq is installed
     9  #  - Make sure bash is v4.3 or later. Can't do until all Azure nodes on the latest version
    10  #  - Make sure we are not running as local system. Can't do until all Azure nodes are updated.
    11  #  - Error if docker versions are not equal. Can't do until all Azure nodes are updated
    12  #  - Error if go versions are not equal. Can't do until all Azure nodes are updated.
    13  #  - Error if running 32-bit posix tools. Probably can take from bash --version and check contains "x86_64"
    14  #  - Warn if the CI directory cannot be deleted afterwards. Otherwise turdlets are left behind
    15  #  - Use %systemdrive% ($SYSTEMDRIVE) rather than hard code to c: for TEMP
    16  #  - Consider cross builing the Windows binary and copy across. That's a bit of a heavy lift. Only reason
    17  #    for doing that is that it mirrors the actual release process for docker.exe which is cross-built.
    18  #    However, should absolutely not be a problem if built natively, so nit-picking.
    19  #  - Tidy up of images and containers. Either here, or in the teardown script.
    20  
    21  ec=0
    22  uniques=1
    23  echo INFO: Started at `date`. Script version $SCRIPT_VER
    24  
    25  
    26  # !README!
    27  # There are two daemons running on the remote Linux host:
    28  # 	- outer: specified by DOCKER_HOST, this is the daemon that will build and run the inner docker daemon
    29  #			from the sources matching the PR.
    30  #	- inner: runs on the host network, on a port number similar to that of DOCKER_HOST but the last two digits are inverted
    31  #			(2357 if DOCKER_HOST had port 2375; and 2367 if DOCKER_HOST had port 2376).
    32  #			The windows integration tests are run against this inner daemon.
    33  
    34  # get the ip, inner and outer ports.
    35  ip="${DOCKER_HOST#*://}"
    36  port_outer="${ip#*:}"
    37  # inner port is like outer port with last two digits inverted.
    38  port_inner=$(echo "$port_outer" | sed -E 's/(.)(.)$/\2\1/')
    39  ip="${ip%%:*}"
    40  
    41  echo "INFO: IP=$ip PORT_OUTER=$port_outer PORT_INNER=$port_inner"
    42  
    43  # If TLS is enabled
    44  if [ -n "$DOCKER_TLS_VERIFY" ]; then
    45  	protocol=https
    46  	if [ -z "$DOCKER_MACHINE_NAME" ]; then
    47  		ec=1
    48  		echo "ERROR: DOCKER_MACHINE_NAME is undefined"
    49  	fi
    50  	certs=$(echo ~/.docker/machine/machines/$DOCKER_MACHINE_NAME)
    51  	curlopts="--cacert $certs/ca.pem --cert $certs/cert.pem --key $certs/key.pem"
    52  	run_extra_args="-v tlscerts:/etc/docker"
    53  	daemon_extra_args="--tlsverify --tlscacert /etc/docker/ca.pem --tlscert /etc/docker/server.pem --tlskey /etc/docker/server-key.pem"
    54  else
    55  	protocol=http
    56  fi
    57  
    58  # Save for use by make.sh and scripts it invokes
    59  export MAIN_DOCKER_HOST="tcp://$ip:$port_inner"
    60  
    61  # Verify we can get the remote node to respond to _ping
    62  if [ $ec -eq 0 ]; then
    63  	reply=`curl -s $curlopts $protocol://$ip:$port_outer/_ping`
    64  	if [ "$reply" != "OK" ]; then
    65  		ec=1
    66  		echo "ERROR: Failed to get an 'OK' response from the docker daemon on the Linux node"
    67  		echo "       at $ip:$port_outer when called with an http request for '_ping'. This implies that"
    68  		echo "       either the daemon has crashed/is not running, or the Linux node is unavailable."
    69  		echo
    70  		echo "       A regular ping to the remote Linux node is below. It should reply. If not, the"
    71  		echo "       machine cannot be reached at all and may have crashed. If it does reply, it is"
    72  		echo "       likely a case of the Linux daemon not running or having crashed, which requires"
    73  		echo "       further investigation."
    74  		echo
    75  		echo "       Try re-running this CI job, or ask on #docker-dev or #docker-maintainers"
    76  		echo "       for someone to perform further diagnostics, or take this node out of rotation."
    77  		echo
    78  		ping $ip
    79  	else
    80  		echo "INFO: The Linux nodes outer daemon replied to a ping. Good!"
    81  	fi 
    82  fi
    83  
    84  # Get the version from the remote node. Note this may fail if jq is not installed.
    85  # That's probably worth checking to make sure, just in case.
    86  if [ $ec -eq 0 ]; then
    87  	remoteVersion=`curl -s $curlopts $protocol://$ip:$port_outer/version | jq -c '.Version'`
    88  	echo "INFO: Remote daemon is running docker version $remoteVersion"
    89  fi
    90  
    91  # Compare versions. We should really fail if result is no 1. Output at end of script.
    92  if [ $ec -eq 0 ]; then
    93  	uniques=`docker version | grep Version | /usr/bin/sort -u | wc -l`
    94  fi
    95  
    96  # Make sure we are in repo
    97  if [ $ec -eq 0 ]; then
    98  	if [ ! -d hack ]; then
    99  		echo "ERROR: Are you sure this is being launched from a the root of docker repository?"
   100  		echo "       If this is a Windows CI machine, it should be c:\jenkins\gopath\src\github.com\docker\docker."
   101                  echo "       Current directory is `pwd`"
   102  		ec=1
   103  	fi
   104  fi
   105  
   106  # Are we in split binary mode?
   107  if [ `grep DOCKER_CLIENTONLY Makefile | wc -l` -gt 0 ]; then
   108      splitBinary=0
   109  	echo "INFO: Running in single binary mode"
   110  else
   111      splitBinary=1
   112  	echo "INFO: Running in split binary mode"
   113  fi
   114  
   115  
   116  # Get the commit has and verify we have something
   117  if [ $ec -eq 0 ]; then
   118  	export COMMITHASH=$(git rev-parse --short HEAD)
   119  	echo INFO: Commmit hash is $COMMITHASH
   120  	if [ -z $COMMITHASH ]; then
   121  		echo "ERROR: Failed to get commit hash. Are you sure this is a docker repository?"
   122  		ec=1
   123  	fi
   124  fi
   125  
   126  # Redirect to a temporary location. Check is here for local runs from Jenkins machines just in case not
   127  # in the right directory where the repo is cloned. We also redirect TEMP to not use the environment
   128  # TEMP as when running as a standard user (not local system), it otherwise exposes a bug in posix tar which
   129  # will cause CI to fail from Windows to Linux. Obviously it's not best practice to ever run as local system...
   130  if [ $ec -eq 0 ]; then
   131  	export TEMP=/c/CI/CI-$COMMITHASH
   132  	export TMP=$TEMP
   133  	/usr/bin/mkdir -p $TEMP  # Make sure Linux mkdir for -p
   134  fi
   135  
   136  # Tidy up time
   137  if [ $ec -eq 0 ]; then
   138  	echo INFO: Deleting pre-existing containers and images...
   139      
   140  	# Force remove all containers based on a previously built image with this commit
   141  	! docker rm -f $(docker ps -aq --filter "ancestor=docker:$COMMITHASH") &>/dev/null
   142      
   143  	# Force remove any container with this commithash as a name
   144  	! docker rm -f $(docker ps -aq --filter "name=docker-$COMMITHASH") &>/dev/null
   145  
   146  	# This SHOULD never happen, but just in case, also blow away any containers
   147  	# that might be around.
   148  	! if [ ! $(docker ps -aq | wc -l) -eq 0 ]; then
   149  		echo WARN: There were some leftover containers. Cleaning them up.
   150  		! docker rm -f $(docker ps -aq)
   151  	fi
   152  	
   153      # Force remove the image if it exists
   154  	! docker rmi -f "docker-$COMMITHASH" &>/dev/null
   155  fi
   156  
   157  # Provide the docker version for debugging purposes. If these fail, game over. 
   158  # as the Linux box isn't responding for some reason.
   159  if [ $ec -eq 0 ]; then
   160  	echo INFO: Docker version and info of the outer daemon on the Linux node
   161  	echo
   162  	docker version
   163  	ec=$?
   164  	if [ 0 -ne $ec ]; then
   165  		echo "ERROR: The main linux daemon does not appear to be running. Has the Linux node crashed?"
   166  	fi
   167  	echo
   168  fi
   169  
   170  # Same as above, but docker info
   171  if [ $ec -eq 0 ]; then
   172  	echo
   173  	docker info
   174  	ec=$?
   175  	if [ 0 -ne $ec ]; then
   176  		echo "ERROR: The main linux daemon does not appear to be running. Has the Linux node crashed?"
   177  	fi
   178  	echo
   179  fi
   180  
   181  # build the daemon image
   182  if [ $ec -eq 0 ]; then
   183  	echo "INFO: Running docker build on Linux host at $DOCKER_HOST"
   184  	if [ $splitBinary -eq 0 ]; then
   185  		set -x
   186  		docker build --rm --force-rm --build-arg APT_MIRROR=cdn-fastly.deb.debian.org -t "docker:$COMMITHASH" .
   187      cat <<EOF | docker build --rm --force-rm -t "docker:$COMMITHASH" -
   188  FROM docker:$COMMITHASH
   189  RUN hack/make.sh binary
   190  RUN cp bundles/latest/binary/docker /bin/docker 
   191  CMD docker daemon -D -H tcp://0.0.0.0:$port_inner $daemon_extra_args
   192  EOF
   193  	else
   194  		set -x
   195  		docker build --rm --force-rm --build-arg APT_MIRROR=cdn-fastly.deb.debian.org -t "docker:$COMMITHASH" .
   196      cat <<EOF | docker build --rm --force-rm -t "docker:$COMMITHASH" -
   197  FROM docker:$COMMITHASH
   198  RUN hack/make.sh binary
   199  RUN cp bundles/latest/binary-daemon/dockerd /bin/dockerd 
   200  CMD dockerd -D -H tcp://0.0.0.0:$port_inner $daemon_extra_args
   201  EOF
   202  
   203  	fi
   204  	ec=$?
   205  	set +x
   206  	if [ 0 -ne $ec ]; then
   207  		echo "ERROR: docker build failed"
   208  	fi
   209  fi
   210  
   211  # Start the docker-in-docker daemon from the image we just built
   212  if [ $ec -eq 0 ]; then
   213  	echo "INFO: Starting build of a Linux daemon to test against, and starting it..."
   214  	set -x
   215  	# aufs in aufs is faster than vfs in aufs
   216  	docker run -d $run_extra_args -e DOCKER_GRAPHDRIVER=aufs --pid host --privileged --name "docker-$COMMITHASH" --net host "docker:$COMMITHASH"
   217  	ec=$?
   218  	set +x
   219  	if [ 0 -ne $ec ]; then
   220  	    	echo "ERROR: Failed to compile and start the linux daemon"
   221  	fi
   222  fi
   223  
   224  # Build locally.
   225  if [ $ec -eq 0 ]; then
   226  	echo "INFO: Starting local build of Windows binary..."
   227  	set -x
   228  	export TIMEOUT="120m"
   229  	export DOCKER_HOST="tcp://$ip:$port_inner"
   230      # This can be removed
   231  	export DOCKER_TEST_HOST="tcp://$ip:$port_inner"
   232  	unset DOCKER_CLIENTONLY
   233  	export DOCKER_REMOTE_DAEMON=1
   234  	hack/make.sh binary 
   235  	ec=$?
   236  	set +x
   237  	if [ 0 -ne $ec ]; then
   238  	    echo "ERROR: Build of binary on Windows failed"
   239  	fi
   240  fi
   241  
   242  # Make a local copy of the built binary and ensure that is first in our path
   243  if [ $ec -eq 0 ]; then
   244  	VERSION=$(< ./VERSION)
   245  	if [ $splitBinary -eq 0 ]; then
   246  		cp bundles/$VERSION/binary/docker.exe $TEMP
   247  	else
   248  		cp bundles/$VERSION/binary-client/docker.exe $TEMP
   249  	fi
   250  	ec=$?
   251  	if [ 0 -ne $ec ]; then
   252  		echo "ERROR: Failed to copy built binary to $TEMP"
   253  	fi
   254  	export PATH=$TEMP:$PATH
   255  fi
   256  
   257  # Run the integration tests
   258  if [ $ec -eq 0 ]; then	
   259  	echo "INFO: Running Integration tests..."
   260  	set -x
   261  	export DOCKER_TEST_TLS_VERIFY="$DOCKER_TLS_VERIFY"
   262  	export DOCKER_TEST_CERT_PATH="$DOCKER_CERT_PATH"
   263  	#export TESTFLAGS='-check.vv'
   264  	hack/make.sh test-integration-cli
   265  	ec=$?
   266  	set +x
   267  	if [ 0 -ne $ec ]; then
   268  		echo "ERROR: CLI test failed."
   269  		# Next line is useful, but very long winded if included
   270  		docker -H=$MAIN_DOCKER_HOST logs --tail 100 "docker-$COMMITHASH"
   271      fi
   272  fi
   273  
   274  # Tidy up any temporary files from the CI run
   275  if [ ! -z $COMMITHASH ]; then
   276  	rm -rf $TEMP
   277  fi
   278  
   279  # CI Integrity check - ensure we are using the same version of go as present in the Dockerfile
   280  GOVER_DOCKERFILE=`grep 'ENV GO_VERSION' Dockerfile | awk '{print $3}'`
   281  GOVER_INSTALLED=`go version | awk '{print $3}'`
   282  if [ "${GOVER_INSTALLED:2}" != "$GOVER_DOCKERFILE" ]; then
   283  	#ec=1  # Uncomment to make CI fail once all nodes are updated.
   284  	echo
   285  	echo "---------------------------------------------------------------------------"
   286  	echo "WARN: CI should be using go version $GOVER_DOCKERFILE, but is using ${GOVER_INSTALLED:2}"
   287  	echo "      Please ping #docker-maintainers on IRC to get this CI server updated."
   288  	echo "---------------------------------------------------------------------------"
   289  	echo
   290  fi
   291  
   292  # Check the Linux box is running a matching version of docker
   293  if [ "$uniques" -ne 1 ]; then
   294      ec=0  # Uncomment to make CI fail once all nodes are updated.
   295  	echo
   296  	echo "---------------------------------------------------------------------------"
   297  	echo "ERROR: This CI node is not running the same version of docker as the daemon."
   298  	echo "       This is a CI configuration issue."
   299  	echo "---------------------------------------------------------------------------"
   300  	echo
   301  fi
   302  
   303  # Tell the user how we did.
   304  if [ $ec -eq 0 ]; then
   305  	echo INFO: Completed successfully at `date`. 
   306  else
   307  	echo ERROR: Failed with exitcode $ec at `date`.
   308  fi
   309  exit $ec