github.com/yuanlv/docker@v1.8.1/hack/release.sh (about) 1 #!/usr/bin/env bash 2 set -e 3 4 # This script looks for bundles built by make.sh, and releases them on a 5 # public S3 bucket. 6 # 7 # Bundles should be available for the VERSION string passed as argument. 8 # 9 # The correct way to call this script is inside a container built by the 10 # official Dockerfile at the root of the Docker source code. The Dockerfile, 11 # make.sh and release.sh should all be from the same source code revision. 12 13 set -o pipefail 14 15 # Print a usage message and exit. 16 usage() { 17 cat >&2 <<'EOF' 18 To run, I need: 19 - to be in a container generated by the Dockerfile at the top of the Docker 20 repository; 21 - to be provided with the name of an S3 bucket, in environment variable 22 AWS_S3_BUCKET; 23 - to be provided with AWS credentials for this S3 bucket, in environment 24 variables AWS_ACCESS_KEY and AWS_SECRET_KEY; 25 - the passphrase to unlock the GPG key which will sign the deb packages 26 (passed as environment variable GPG_PASSPHRASE); 27 - a generous amount of good will and nice manners. 28 The canonical way to run me is to run the image produced by the Dockerfile: e.g.:" 29 30 docker run -e AWS_S3_BUCKET=test.docker.com \ 31 -e AWS_ACCESS_KEY=... \ 32 -e AWS_SECRET_KEY=... \ 33 -e GPG_PASSPHRASE=... \ 34 -i -t --privileged \ 35 docker ./hack/release.sh 36 EOF 37 exit 1 38 } 39 40 [ "$AWS_S3_BUCKET" ] || usage 41 [ "$AWS_ACCESS_KEY" ] || usage 42 [ "$AWS_SECRET_KEY" ] || usage 43 [ "$GPG_PASSPHRASE" ] || usage 44 [ -d /go/src/github.com/docker/docker ] || usage 45 cd /go/src/github.com/docker/docker 46 [ -x hack/make.sh ] || usage 47 48 RELEASE_BUNDLES=( 49 binary 50 cross 51 tgz 52 ubuntu 53 ) 54 55 if [ "$1" != '--release-regardless-of-test-failure' ]; then 56 RELEASE_BUNDLES=( 57 test-unit 58 "${RELEASE_BUNDLES[@]}" 59 test-integration-cli 60 ) 61 fi 62 63 VERSION=$(< VERSION) 64 BUCKET=$AWS_S3_BUCKET 65 66 # These are the 2 keys we've used to sign the deb's 67 # release (get.docker.com) 68 # GPG_KEY="36A1D7869245C8950F966E92D8576A8BA88D21E9" 69 # test (test.docker.com) 70 # GPG_KEY="740B314AE3941731B942C66ADF4FD13717AAD7D6" 71 72 setup_s3() { 73 echo "Setting up S3" 74 # Try creating the bucket. Ignore errors (it might already exist). 75 s3cmd mb "s3://$BUCKET" 2>/dev/null || true 76 # Check access to the bucket. 77 # s3cmd has no useful exit status, so we cannot check that. 78 # Instead, we check if it outputs anything on standard output. 79 # (When there are problems, it uses standard error instead.) 80 s3cmd info "s3://$BUCKET" | grep -q . 81 # Make the bucket accessible through website endpoints. 82 s3cmd ws-create --ws-index index --ws-error error "s3://$BUCKET" 83 } 84 85 # write_to_s3 uploads the contents of standard input to the specified S3 url. 86 write_to_s3() { 87 DEST=$1 88 F=`mktemp` 89 cat > "$F" 90 s3cmd --acl-public --mime-type='text/plain' put "$F" "$DEST" 91 rm -f "$F" 92 } 93 94 s3_url() { 95 case "$BUCKET" in 96 get.docker.com|test.docker.com|experimental.docker.com) 97 echo "https://$BUCKET" 98 ;; 99 *) 100 s3cmd ws-info s3://$BUCKET | awk -v 'FS=: +' '/http:\/\/'$BUCKET'/ { gsub(/\/+$/, "", $2); print $2 }' 101 ;; 102 esac 103 } 104 105 build_all() { 106 echo "Building release" 107 if ! ./hack/make.sh "${RELEASE_BUNDLES[@]}"; then 108 echo >&2 109 echo >&2 'The build or tests appear to have failed.' 110 echo >&2 111 echo >&2 'You, as the release maintainer, now have a couple options:' 112 echo >&2 '- delay release and fix issues' 113 echo >&2 '- delay release and fix issues' 114 echo >&2 '- did we mention how important this is? issues need fixing :)' 115 echo >&2 116 echo >&2 'As a final LAST RESORT, you (because only you, the release maintainer,' 117 echo >&2 ' really knows all the hairy problems at hand with the current release' 118 echo >&2 ' issues) may bypass this checking by running this script again with the' 119 echo >&2 ' single argument of "--release-regardless-of-test-failure", which will skip' 120 echo >&2 ' running the test suite, and will only build the binaries and packages. Please' 121 echo >&2 ' avoid using this if at all possible.' 122 echo >&2 123 echo >&2 'Regardless, we cannot stress enough the scarcity with which this bypass' 124 echo >&2 ' should be used. If there are release issues, we should always err on the' 125 echo >&2 ' side of caution.' 126 echo >&2 127 exit 1 128 fi 129 } 130 131 upload_release_build() { 132 src="$1" 133 dst="$2" 134 latest="$3" 135 136 echo 137 echo "Uploading $src" 138 echo " to $dst" 139 echo 140 s3cmd --follow-symlinks --preserve --acl-public put "$src" "$dst" 141 if [ "$latest" ]; then 142 echo 143 echo "Copying to $latest" 144 echo 145 s3cmd --acl-public cp "$dst" "$latest" 146 fi 147 148 # get hash files too (see hash_files() in hack/make.sh) 149 for hashAlgo in md5 sha256; do 150 if [ -e "$src.$hashAlgo" ]; then 151 echo 152 echo "Uploading $src.$hashAlgo" 153 echo " to $dst.$hashAlgo" 154 echo 155 s3cmd --follow-symlinks --preserve --acl-public --mime-type='text/plain' put "$src.$hashAlgo" "$dst.$hashAlgo" 156 if [ "$latest" ]; then 157 echo 158 echo "Copying to $latest.$hashAlgo" 159 echo 160 s3cmd --acl-public cp "$dst.$hashAlgo" "$latest.$hashAlgo" 161 fi 162 fi 163 done 164 } 165 166 release_build() { 167 echo "Releasing binaries" 168 GOOS=$1 169 GOARCH=$2 170 171 binDir=bundles/$VERSION/cross/$GOOS/$GOARCH 172 tgzDir=bundles/$VERSION/tgz/$GOOS/$GOARCH 173 binary=docker-$VERSION 174 tgz=docker-$VERSION.tgz 175 176 latestBase= 177 if [ -z "$NOLATEST" ]; then 178 latestBase=docker-latest 179 fi 180 181 # we need to map our GOOS and GOARCH to uname values 182 # see https://en.wikipedia.org/wiki/Uname 183 # ie, GOOS=linux -> "uname -s"=Linux 184 185 s3Os=$GOOS 186 case "$s3Os" in 187 darwin) 188 s3Os=Darwin 189 ;; 190 freebsd) 191 s3Os=FreeBSD 192 ;; 193 linux) 194 s3Os=Linux 195 ;; 196 windows) 197 s3Os=Windows 198 binary+='.exe' 199 if [ "$latestBase" ]; then 200 latestBase+='.exe' 201 fi 202 ;; 203 *) 204 echo >&2 "error: can't convert $s3Os to an appropriate value for 'uname -s'" 205 exit 1 206 ;; 207 esac 208 209 s3Arch=$GOARCH 210 case "$s3Arch" in 211 amd64) 212 s3Arch=x86_64 213 ;; 214 386) 215 s3Arch=i386 216 ;; 217 arm) 218 s3Arch=armel 219 # someday, we might potentially support mutliple GOARM values, in which case we might get armhf here too 220 ;; 221 *) 222 echo >&2 "error: can't convert $s3Arch to an appropriate value for 'uname -m'" 223 exit 1 224 ;; 225 esac 226 227 s3Dir=s3://$BUCKET/builds/$s3Os/$s3Arch 228 latest= 229 latestTgz= 230 if [ "$latestBase" ]; then 231 latest="$s3Dir/$latestBase" 232 latestTgz="$s3Dir/$latestBase.tgz" 233 fi 234 235 if [ ! -x "$binDir/$binary" ]; then 236 echo >&2 "error: can't find $binDir/$binary - was it compiled properly?" 237 exit 1 238 fi 239 if [ ! -f "$tgzDir/$tgz" ]; then 240 echo >&2 "error: can't find $tgzDir/$tgz - was it packaged properly?" 241 exit 1 242 fi 243 244 upload_release_build "$binDir/$binary" "$s3Dir/$binary" "$latest" 245 upload_release_build "$tgzDir/$tgz" "$s3Dir/$tgz" "$latestTgz" 246 } 247 248 # Upload the 'ubuntu' bundle to S3: 249 # 1. A full APT repository is published at $BUCKET/ubuntu/ 250 # 2. Instructions for using the APT repository are uploaded at $BUCKET/ubuntu/index 251 release_ubuntu() { 252 echo "Releasing ubuntu" 253 [ -e "bundles/$VERSION/ubuntu" ] || { 254 echo >&2 './hack/make.sh must be run before release_ubuntu' 255 exit 1 256 } 257 258 local debfiles=( "bundles/$VERSION/ubuntu/"*.deb ) 259 260 # Sign our packages 261 dpkg-sig -g "--passphrase $GPG_PASSPHRASE" -k releasedocker --sign builder "${debfiles[@]}" 262 263 # Setup the APT repo 264 APTDIR=bundles/$VERSION/ubuntu/apt 265 mkdir -p "$APTDIR/conf" "$APTDIR/db" 266 s3cmd sync "s3://$BUCKET/ubuntu/db/" "$APTDIR/db/" || true 267 cat > "$APTDIR/conf/distributions" <<EOF 268 Codename: docker 269 Components: main 270 Architectures: amd64 i386 271 EOF 272 273 # Add the DEB package to the APT repo 274 reprepro -b "$APTDIR" includedeb docker "${debfiles[@]}" 275 276 # Sign 277 for F in $(find $APTDIR -name Release); do 278 gpg -u releasedocker --passphrase "$GPG_PASSPHRASE" \ 279 --armor --sign --detach-sign \ 280 --output "$F.gpg" "$F" 281 done 282 283 # Upload keys 284 s3cmd sync "$HOME/.gnupg/" "s3://$BUCKET/ubuntu/.gnupg/" 285 gpg --armor --export releasedocker > "bundles/$VERSION/ubuntu/gpg" 286 s3cmd --acl-public put "bundles/$VERSION/ubuntu/gpg" "s3://$BUCKET/gpg" 287 288 local gpgFingerprint=36A1D7869245C8950F966E92D8576A8BA88D21E9 289 local s3Headers= 290 if [[ $BUCKET == test* ]]; then 291 gpgFingerprint=740B314AE3941731B942C66ADF4FD13717AAD7D6 292 elif [[ $BUCKET == experimental* ]]; then 293 gpgFingerprint=E33FF7BF5C91D50A6F91FFFD4CC38D40F9A96B49 294 s3Headers='--add-header=Cache-Control:no-cache' 295 fi 296 297 # Upload repo 298 s3cmd --acl-public "$s3Headers" sync "$APTDIR/" "s3://$BUCKET/ubuntu/" 299 cat <<EOF | write_to_s3 s3://$BUCKET/ubuntu/index 300 echo "# WARNING! This script is deprecated. Please use the script" 301 echo "# at https://get.docker.com/" 302 EOF 303 304 # Add redirect at /ubuntu/info for URL-backwards-compatibility 305 rm -rf /tmp/emptyfile && touch /tmp/emptyfile 306 s3cmd --acl-public --add-header='x-amz-website-redirect-location:/ubuntu/' --mime-type='text/plain' put /tmp/emptyfile "s3://$BUCKET/ubuntu/info" 307 308 echo "APT repository uploaded. Instructions available at $(s3_url)/ubuntu" 309 } 310 311 # Upload binaries and tgz files to S3 312 release_binaries() { 313 [ -e "bundles/$VERSION/cross/linux/amd64/docker-$VERSION" ] || { 314 echo >&2 './hack/make.sh must be run before release_binaries' 315 exit 1 316 } 317 318 for d in bundles/$VERSION/cross/*/*; do 319 GOARCH="$(basename "$d")" 320 GOOS="$(basename "$(dirname "$d")")" 321 release_build "$GOOS" "$GOARCH" 322 done 323 324 # TODO create redirect from builds/*/i686 to builds/*/i386 325 326 cat <<EOF | write_to_s3 s3://$BUCKET/builds/index 327 # To install, run the following command as root: 328 curl -sSL -O $(s3_url)/builds/Linux/x86_64/docker-$VERSION && chmod +x docker-$VERSION && sudo mv docker-$VERSION /usr/local/bin/docker 329 # Then start docker in daemon mode: 330 sudo /usr/local/bin/docker -d 331 EOF 332 333 # Add redirect at /builds/info for URL-backwards-compatibility 334 rm -rf /tmp/emptyfile && touch /tmp/emptyfile 335 s3cmd --acl-public --add-header='x-amz-website-redirect-location:/builds/' --mime-type='text/plain' put /tmp/emptyfile "s3://$BUCKET/builds/info" 336 337 if [ -z "$NOLATEST" ]; then 338 echo "Advertising $VERSION on $BUCKET as most recent version" 339 echo "$VERSION" | write_to_s3 "s3://$BUCKET/latest" 340 fi 341 } 342 343 # Upload the index script 344 release_index() { 345 echo "Releasing index" 346 sed "s,url='https://get.docker.com/',url='$(s3_url)/'," hack/install.sh | write_to_s3 "s3://$BUCKET/index" 347 } 348 349 release_test() { 350 echo "Releasing tests" 351 if [ -e "bundles/$VERSION/test" ]; then 352 s3cmd --acl-public sync "bundles/$VERSION/test/" "s3://$BUCKET/test/" 353 fi 354 } 355 356 setup_gpg() { 357 echo "Setting up GPG" 358 # Make sure that we have our keys 359 mkdir -p "$HOME/.gnupg/" 360 s3cmd sync "s3://$BUCKET/ubuntu/.gnupg/" "$HOME/.gnupg/" || true 361 gpg --list-keys releasedocker >/dev/null || { 362 gpg --gen-key --batch <<EOF 363 Key-Type: RSA 364 Key-Length: 4096 365 Passphrase: $GPG_PASSPHRASE 366 Name-Real: Docker Release Tool 367 Name-Email: docker@docker.com 368 Name-Comment: releasedocker 369 Expire-Date: 0 370 %commit 371 EOF 372 } 373 } 374 375 main() { 376 build_all 377 setup_s3 378 setup_gpg 379 release_binaries 380 release_ubuntu 381 release_index 382 release_test 383 } 384 385 main 386 387 echo 388 echo 389 echo "Release complete; see $(s3_url)" 390 echo "Use the following text to announce the release:" 391 echo 392 echo "We have just pushed $VERSION to $(s3_url). You can download it with the following:" 393 echo 394 echo "Ubuntu/Debian: curl -sSL $(s3_url) | sh" 395 echo "Linux 64bit binary: $(s3_url)/builds/Linux/x86_64/docker-$VERSION" 396 echo "Darwin/OSX 64bit client binary: $(s3_url)/builds/Darwin/x86_64/docker-$VERSION" 397 echo "Darwin/OSX 32bit client binary: $(s3_url)/builds/Darwin/i386/docker-$VERSION" 398 echo "Linux 64bit tgz: $(s3_url)/builds/Linux/x86_64/docker-$VERSION.tgz" 399 echo "Windows 64bit client binary: $(s3_url)/builds/Windows/x86_64/docker-$VERSION.exe" 400 echo "Windows 32bit client binary: $(s3_url)/builds/Windows/i386/docker-$VERSION.exe" 401 echo