Browse Source

Combining build.sh with push.sh

Joe Ferguson 11 years ago
parent
commit
6426164142
1 changed files with 132 additions and 93 deletions
  1. 132 93
      bashbrew/bashbrew.sh

+ 132 - 93
bashbrew/build.sh → bashbrew/bashbrew.sh

@@ -16,42 +16,63 @@ library="$(readlink -f "$library")"
 src="$(readlink -f "$src")"
 logs="$(readlink -f "$logs")"
 
-# arg handling: all args are [repo|repo:tag]
 usage() {
 	cat <<EOUSAGE
 
-usage: $0 [options] [repo[:tag] ...]
-   ie: $0 --all
-       $0 debian ubuntu:12.04
+usage: $0 [build|push] [options] [repo[:tag] ...]
+   ie: $0 build --all
+       $0 push debian ubuntu:12.04
 
-   This script builds the Docker images specified using the Git repositories
-   specified in the library files.
+   This script builds or pushes the Docker images specified using the Git
+   repositories specified in the library files in the namespaces.
 
-options:
+common options:
   --help, -h, -?     Print this help message
   --all              Builds all Docker repos specified in library
-  --no-clone         Don't pull the Git repos
-  --no-build         Don't build, just echo what would have built
   --library="$library"
                      Where to find repository manifest files
-  --src="$src"
-                     Where to store the cloned Git repositories
-  --logs="$logs"
-                     Where to store the build logs
   --namespaces="$namespaces"
                      Space separated list of namespaces to tag images in after
                      building
   --docker="$docker"
                      Use a custom Docker binary.
 
+build options:
+  --no-clone         Don't pull the Git repos
+  --no-build         Don't build, just echo what would have built
+  --src="$src"
+                     Where to store the cloned Git repositories
+  --logs="$logs"
+                     Where to store the build logs
+
+push options:
+  --no-push          Don't actually push the images to the Docker Hub
+
 EOUSAGE
 }
 
-opts="$(getopt -o 'h?' --long 'help,all,no-clone,no-build,library:,src:,logs:,namespaces:,docker:' -- "$@" || { usage >&2 && false; })"
+# which subcommand
+subcommand=$1
+case "$subcommand" in
+	build|push)
+		shift
+		;;
+	*)
+		{
+			echo "error: unknown subcommand: $1"
+			usage
+		} >&2
+		exit 1
+		;;
+esac
+
+# arg handling
+opts="$(getopt -o 'h?' --long 'help,all,no-clone,no-build,no-push,library:,src:,logs:,namespaces:,docker:' -- "$@" || { usage >&2 && false; })"
 eval set -- "$opts"
 
 doClone=1
 doBuild=1
+doPush=1
 buildAll=
 while true; do
 	flag=$1
@@ -64,6 +85,7 @@ while true; do
 		--all) buildAll=1 ;;
 		--no-clone) doClone= ;;
 		--no-build) doBuild= ;;
+		--no-push) doPush= ;;
 		--library) library="$1" && shift ;;
 		--src) src="$1" && shift ;;
 		--logs) logs="$1" && shift ;;
@@ -102,7 +124,7 @@ declare -A repoGitRepo=()
 declare -A repoGitRef=()
 declare -A repoGitDir=()
 
-logDir="$logs/build-$(date +'%Y-%m-%d--%H-%M-%S')"
+logDir="$logs/$subcommand-$(date +'%Y-%m-%d--%H-%M-%S')"
 mkdir -p "$logDir"
 
 latestLogDir="$logs/latest" # this gets shiny symlinks to the latest buildlog for each repo we've seen since the creation of the logs dir
@@ -174,33 +196,35 @@ for repoTag in "${repos[@]}"; do
 		gitRepo="${gitRepo%/}"
 		gitRepo="$src/$gitRepo"
 		
-		if [ -z "$doClone" ]; then
-			if [ "$doBuild" -a ! -d "$gitRepo" ]; then
-				echo >&2 "error: directory not found: $gitRepo"
-				exit 1
-			fi
-		else
-			if [ ! -d "$gitRepo" ]; then
-				mkdir -p "$(dirname "$gitRepo")"
-				echo "Cloning $repo ($gitUrl) ..."
-				git clone -q "$gitUrl" "$gitRepo"
+		if [ "$subcommand" == 'build' ]; then
+			if [ -z "$doClone" ]; then
+				if [ "$doBuild" -a ! -d "$gitRepo" ]; then
+					echo >&2 "error: directory not found: $gitRepo"
+					exit 1
+				fi
 			else
-				# if we don't have the "ref" specified, "git fetch" in the hopes that we get it
-				if ! (
-					cd "$gitRepo"
-					git rev-parse --verify "${gitRef}^{commit}" &> /dev/null
-				); then
-					echo "Fetching $repo ($gitUrl) ..."
-					(
+				if [ ! -d "$gitRepo" ]; then
+					mkdir -p "$(dirname "$gitRepo")"
+					echo "Cloning $repo ($gitUrl) ..."
+					git clone -q "$gitUrl" "$gitRepo"
+				else
+					# if we don't have the "ref" specified, "git fetch" in the hopes that we get it
+					if ! (
 						cd "$gitRepo"
-						git fetch -q --all
-						git fetch -q --tags
-					)
+						git rev-parse --verify "${gitRef}^{commit}" &> /dev/null
+					); then
+						echo "Fetching $repo ($gitUrl) ..."
+						(
+							cd "$gitRepo"
+							git fetch -q --all
+							git fetch -q --tags
+						)
+					fi
 				fi
+				
+				# disable any automatic garbage collection too, just to help make sure we keep our dangling commit objects
+				( cd "$gitRepo" && git config gc.auto 0 )
 			fi
-			
-			# disable any automatic garbage collection too, just to help make sure we keep our dangling commit objects
-			( cd "$gitRepo" && git config gc.auto 0 )
 		fi
 		
 		repoGitRepo[$repo:$tag]="$gitRepo"
@@ -232,65 +256,80 @@ while [ "$#" -gt 0 ]; do
 	
 	echo "Processing $repoTag ..."
 	
-	thisLog="$logDir/build-$repoTag.log"
+	thisLog="$logDir/$subcommand-$repoTag.log"
 	touch "$thisLog"
 	ln -sf "$thisLog" "$latestLogDir/$(basename "$thisLog")"
 	
-	if ! ( cd "$gitRepo" && git rev-parse --verify "${gitRef}^{commit}" &> /dev/null ); then
-		echo "- failed; invalid ref: $gitRef"
-		didFail=1
-		continue
-	fi
-	
-	dockerfilePath="$gitDir/Dockerfile"
-	dockerfilePath="${dockerfilePath#/}" # strip leading "/" (for when gitDir is '') because "git show" doesn't like it
-	
-	if ! dockerfile="$(cd "$gitRepo" && git show "$gitRef":"$dockerfilePath")"; then
-		echo "- failed; missing '$dockerfilePath' at '$gitRef' ?"
-		didFail=1
-		continue
-	fi
-	
-	IFS=$'\n'
-	froms=( $(echo "$dockerfile" | awk 'toupper($1) == "FROM" { print $2 ~ /:/ ? $2 : $2":latest" }') )
-	unset IFS
-	
-	for from in "${froms[@]}"; do
-		for queuedRepoTag in "$@"; do
-			if [ "$from" = "$queuedRepoTag" ]; then
-				# a "FROM" in this image is being built later in our queue, so let's bail on this image for now and come back later
-				echo "- deferred; FROM $from"
-				set -- "$@" "$repoTag"
-				continue 3
+	case "$subcommand" in
+		build)
+			if ! ( cd "$gitRepo" && git rev-parse --verify "${gitRef}^{commit}" &> /dev/null ); then
+				echo "- failed; invalid ref: $gitRef"
+				didFail=1
+				continue
 			fi
-		done
-	done
-	
-	if [ "$doBuild" ]; then
-		(
-			set -x
-			cd "$gitRepo"
-			git reset -q HEAD
-			git checkout -q -- .
-			git clean -dfxq
-			git checkout -q "$gitRef" --
-			cd "$gitRepo/$gitDir"
-			"$dir/git-set-mtimes"
-		) &>> "$thisLog"
-		
-		if ! (
-			set -x
-			"$docker" build -t "$repoTag" "$gitRepo/$gitDir"
-		) &>> "$thisLog"; then
-			echo "- failed; see $thisLog"
-			didFail=1
-			continue
-		fi
-		
-		for namespace in $namespaces; do
-			( set -x; "$docker" tag "$repoTag" "$namespace/$repoTag" ) &>> "$thisLog"
-		done
-	fi
+			
+			dockerfilePath="$gitDir/Dockerfile"
+			dockerfilePath="${dockerfilePath#/}" # strip leading "/" (for when gitDir is '') because "git show" doesn't like it
+			
+			if ! dockerfile="$(cd "$gitRepo" && git show "$gitRef":"$dockerfilePath")"; then
+				echo "- failed; missing '$dockerfilePath' at '$gitRef' ?"
+				didFail=1
+				continue
+			fi
+			
+			IFS=$'\n'
+			froms=( $(echo "$dockerfile" | awk 'toupper($1) == "FROM" { print $2 ~ /:/ ? $2 : $2":latest" }') )
+			unset IFS
+			
+			for from in "${froms[@]}"; do
+				for queuedRepoTag in "$@"; do
+					if [ "$from" = "$queuedRepoTag" ]; then
+						# a "FROM" in this image is being built later in our queue, so let's bail on this image for now and come back later
+						echo "- deferred; FROM $from"
+						set -- "$@" "$repoTag"
+						continue 3
+					fi
+				done
+			done
+			
+			if [ "$doBuild" ]; then
+				(
+					set -x
+					cd "$gitRepo"
+					git reset -q HEAD
+					git checkout -q -- .
+					git clean -dfxq
+					git checkout -q "$gitRef" --
+					cd "$gitRepo/$gitDir"
+					"$dir/git-set-mtimes"
+				) &>> "$thisLog"
+				
+				if ! (
+					set -x
+					"$docker" build -t "$repoTag" "$gitRepo/$gitDir"
+				) &>> "$thisLog"; then
+					echo "- failed; see $thisLog"
+					didFail=1
+					continue
+				fi
+				
+				for namespace in $namespaces; do
+					( set -x; "$docker" tag "$repoTag" "$namespace/$repoTag" ) &>> "$thisLog"
+				done
+			fi
+			;;
+		push)
+			for namespace in $namespaces; do
+				if [ "$doPush" ]; then
+					if ! "$docker" push "$namespace/$repoTag"; then
+						echo >&2 "- $namespace/$repoTag failed to push!"
+					fi
+				else
+					echo "$docker push" "$namespace/$repoTag"
+				fi
+			done
+			;;
+	esac
 done
 
 [ -z "$didFail" ]