Browse Source

Good-bye, ugly mega-Makefile. Docker can now be built with docker, with the help of a simple very simple shell script.

Solomon Hykes 12 years ago
parent
commit
89ee524229
3 changed files with 111 additions and 105 deletions
  1. 11 10
      Dockerfile
  2. 0 95
      Makefile
  3. 100 0
      make.sh

+ 11 - 10
Dockerfile

@@ -3,6 +3,8 @@ docker-version 0.4.2
 from	ubuntu:12.04
 maintainer	Solomon Hykes <solomon@dotcloud.com>
 # Build dependencies
+run	echo 'deb http://archive.ubuntu.com/ubuntu precise main universe' > /etc/apt/sources.list
+run	apt-get update
 run	apt-get install -y -q curl
 run	apt-get install -y -q git
 # Install Go
@@ -11,24 +13,23 @@ env	PATH	/usr/local/go/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bi
 env	GOPATH	/go
 env	CGO_ENABLED 0
 run	cd /tmp && echo 'package main' > t.go && go test -a -i -v
+# Ubuntu stuff
+run	apt-get install -y -q ruby1.9.3 rubygems
+run	gem install fpm
+run	apt-get install -y -q reprepro
+# Install s3cmd 1.0.1 (earlier versions don't support env variables in the config)
+run	apt-get install -y -q python-pip
+run	pip install s3cmd
+run	/bin/echo -e '[default]\naccess_key=$AWS_ID\nsecret_key=$AWS_KEY\n' > /.s3cfg
 # Download dependencies
 run	PKG=github.com/kr/pty REV=27435c699;		 git clone http://$PKG /go/src/$PKG && cd /go/src/$PKG && git checkout -f $REV
 run	PKG=github.com/gorilla/context/ REV=708054d61e5; git clone http://$PKG /go/src/$PKG && cd /go/src/$PKG && git checkout -f $REV
 run	PKG=github.com/gorilla/mux/ REV=9b36453141c;	 git clone http://$PKG /go/src/$PKG && cd /go/src/$PKG && git checkout -f $REV
 run	PKG=github.com/dotcloud/tar/ REV=d06045a6d9;	 git clone http://$PKG /go/src/$PKG && cd /go/src/$PKG && git checkout -f $REV
-# Run dependencies
-run	apt-get install -y iptables
-# lxc requires updating ubuntu sources
-run	echo 'deb http://archive.ubuntu.com/ubuntu precise main universe' > /etc/apt/sources.list
-run	apt-get update
-run	apt-get install -y lxc
-run	apt-get install -y aufs-tools
 # Docker requires code.google.com/p/go.net/websocket
 run	apt-get install -y -q mercurial
 run	PKG=code.google.com/p/go.net REV=78ad7f42aa2e;	 hg clone https://$PKG /go/src/$PKG && cd /go/src/$PKG && hg checkout -r $REV
 # Upload docker source
 add	.       /go/src/github.com/dotcloud/docker
 # Build the binary
-run	cd /go/src/github.com/dotcloud/docker/docker && go install -ldflags "-X main.GITCOMMIT '??' -d -w"
-env	PATH	/usr/local/go/bin:/go/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
-cmd	["docker"]
+run	cd /go/src/github.com/dotcloud/docker && ./make.sh

+ 0 - 95
Makefile

@@ -1,95 +0,0 @@
-DOCKER_PACKAGE := github.com/dotcloud/docker
-RELEASE_VERSION := $(shell git tag | grep -E "v[0-9\.]+$$" | sort -nr | head -n 1)
-SRCRELEASE := docker-$(RELEASE_VERSION)
-BINRELEASE := docker-$(RELEASE_VERSION).tgz
-BUILD_SRC := build_src
-BUILD_PATH := ${BUILD_SRC}/src/${DOCKER_PACKAGE}
-
-GIT_ROOT := $(shell git rev-parse --show-toplevel)
-BUILD_DIR := $(CURDIR)/.gopath
-
-GOPATH ?= $(BUILD_DIR)
-export GOPATH
-
-GO_OPTIONS ?= -a -ldflags='-w -d'
-ifeq ($(VERBOSE), 1)
-GO_OPTIONS += -v
-endif
-
-GIT_COMMIT = $(shell git rev-parse --short HEAD)
-GIT_STATUS = $(shell test -n "`git status --porcelain`" && echo "+CHANGES")
-
-BUILD_OPTIONS = -a -ldflags "-X main.GITCOMMIT $(GIT_COMMIT)$(GIT_STATUS) -d -w"
-
-SRC_DIR := $(GOPATH)/src
-
-DOCKER_DIR := $(SRC_DIR)/$(DOCKER_PACKAGE)
-DOCKER_MAIN := $(DOCKER_DIR)/docker
-
-DOCKER_BIN_RELATIVE := bin/docker
-DOCKER_BIN := $(CURDIR)/$(DOCKER_BIN_RELATIVE)
-
-.PHONY: all clean test hack release srcrelease $(BINRELEASE) $(SRCRELEASE) $(DOCKER_BIN) $(DOCKER_DIR)
-
-all: $(DOCKER_BIN)
-
-$(DOCKER_BIN): $(DOCKER_DIR)
-	@mkdir -p  $(dir $@)
-	@(cd $(DOCKER_MAIN); CGO_ENABLED=0 go build $(GO_OPTIONS) $(BUILD_OPTIONS) -o $@)
-	@echo $(DOCKER_BIN_RELATIVE) is created.
-
-$(DOCKER_DIR):
-	@mkdir -p $(dir $@)
-	@if [ -h $@ ]; then rm -f $@; fi; ln -sf $(CURDIR)/ $@
-	@(cd $(DOCKER_MAIN); go get -d $(GO_OPTIONS))
-
-whichrelease:
-	echo $(RELEASE_VERSION)
-
-release: $(BINRELEASE)
-	s3cmd -P put $(BINRELEASE) s3://get.docker.io/builds/`uname -s`/`uname -m`/docker-$(RELEASE_VERSION).tgz
-	s3cmd -P put docker-latest.tgz s3://get.docker.io/builds/`uname -s`/`uname -m`/docker-latest.tgz
-	s3cmd -P put $(SRCRELEASE)/bin/docker s3://get.docker.io/builds/`uname -s`/`uname -m`/docker
-	echo $(RELEASE_VERSION) > latest ; s3cmd -P put latest s3://get.docker.io/latest ; rm latest
-
-srcrelease: $(SRCRELEASE)
-deps: $(DOCKER_DIR)
-
-# A clean checkout of $RELEASE_VERSION, with vendored dependencies
-$(SRCRELEASE):
-	rm -fr $(SRCRELEASE)
-	git clone $(GIT_ROOT) $(SRCRELEASE)
-	cd $(SRCRELEASE); git checkout -q $(RELEASE_VERSION)
-
-# A binary release ready to be uploaded to a mirror
-$(BINRELEASE): $(SRCRELEASE)
-	rm -f $(BINRELEASE)
-	cd $(SRCRELEASE); make; cp -R bin docker-$(RELEASE_VERSION); tar -f ../$(BINRELEASE) -zv -c docker-$(RELEASE_VERSION)
-	cd $(SRCRELEASE); cp -R bin docker-latest; tar -f ../docker-latest.tgz -zv -c docker-latest
-clean:
-	@rm -rf $(dir $(DOCKER_BIN))
-ifeq ($(GOPATH), $(BUILD_DIR))
-	@rm -rf $(BUILD_DIR)
-else ifneq ($(DOCKER_DIR), $(realpath $(DOCKER_DIR)))
-	@rm -f $(DOCKER_DIR)
-endif
-
-test:
-	# Copy docker source and dependencies for testing
-	rm -rf ${BUILD_SRC}; mkdir -p ${BUILD_PATH}
-	tar --exclude=${BUILD_SRC} -cz . | tar -xz -C ${BUILD_PATH}
-	GOPATH=${CURDIR}/${BUILD_SRC} go get -d
-	# Do the test
-	sudo -E GOPATH=${CURDIR}/${BUILD_SRC} CGO_ENABLED=0 go test ${GO_OPTIONS}
-
-testall: all
-	@(cd $(DOCKER_DIR); CGO_ENABLED=0 sudo -E go test ./... $(GO_OPTIONS))
-
-fmt:
-	@gofmt -s -l -w .
-
-hack:
-	cd $(CURDIR)/hack && vagrant up
-
-ssh-dev:
-	cd $(CURDIR)/hack && vagrant ssh

+ 100 - 0
make.sh

@@ -0,0 +1,100 @@
+#!/bin/sh
+
+# This script builds various binary artifacts from a checkout of the docker source code.
+#
+# Requirements:
+# - The current directory should be a checkout of the docker source code (http://github.com/dotcloud/docker). Whatever version is checked out will be built.
+# - The script is intented to be run as part of a docker build, as defined in the Dockerfile at the root of the source.
+# - If you don't call this script from the official Dockerfile, or a container built by the official Dockerfile, you're probably doing it wrong.
+# 
+
+set -e
+set -x
+
+VERSION=`cat ./VERSION`
+GIT_COMMIT=$(git rev-parse --short HEAD)
+GIT_CHANGES=$(test -n "`git status --porcelain`" && echo "+CHANGES")
+
+# "bundles" indicate the different types of build artifacts: static binary, ubuntu package, etc.
+
+# Build docker as a static binary file
+bundle_binary() {
+	mkdir -p bundles/$VERSION/binary
+	go build -o bundles/$VERSION/binary/docker-$VERSION -ldflags "-X main.GITCOMMIT $GIT_COMMIT$GIT_CHANGES -X main.VERSION $VERSION -d -w" ./docker
+}
+
+
+# Build docker's test suite as a collection of binary files (one per sub-package to test)
+bundle_test() {
+	mkdir -p bundles/$VERSION/test
+	for test_dir in `find_test_dirs`; do
+		test_binary=`
+			cd $test_dir
+			go test -c -v -ldflags "-X main.GITCOMMIT $GIT_COMMIT$GIT_CHANGES -X main.VERSION $VERSION -d -w" >&2
+			find . -maxdepth 1 -type f -name '*.test' -executable
+		`
+		cp $test_dir/$test_binary bundles/$VERSION/test/
+	done
+
+}
+
+# Build docker as an ubuntu package using FPM and REPREPRO (sue me).
+# bundle_binary must be called first.
+bundle_ubuntu() {
+	mkdir -p bundles/$VERSION/ubuntu
+
+	DIR=$(mktemp -d)
+
+	# Generate an upstart config file (ubuntu-specific)
+	mkdir -p $DIR/etc/init
+	cat > $DIR/etc/init/docker.conf <<EOF
+description     "Run docker"
+
+start on filesystem or runlevel [2345]
+stop on runlevel [!2345]
+
+respawn
+
+exec docker -d
+EOF
+
+	# Copy the binary
+	mkdir -p $DIR/usr/bin
+	cp bundles/$VERSION/binary/docker-$VERSION $DIR/usr/bin/docker
+
+	(
+		cd bundles/$VERSION/ubuntu
+		fpm -s dir -t deb -n lxc-docker -v $VERSION -a all --prefix / -C $DIR .
+	)
+	rm -fr $DIR
+
+
+	# Setup the APT repo
+	APTDIR=bundles/$VERSION/ubuntu/apt
+	mkdir -p $APTDIR/conf
+	cat > $APTDIR/conf/distributions <<EOF
+Codename: docker
+Components: main
+Architectures: amd64
+EOF
+
+	# Add the DEB package to the APT repo
+	DEBFILE=bundles/$VERSION/ubuntu/lxc-docker*.deb
+	reprepro -b $APTDIR includedeb docker $DEBFILE
+}
+
+
+# This helper function walks the current directory looking for directories holding Go test files,
+# and prints their paths on standard output, one per line.
+find_test_dirs() {
+	find . -name '*_test.go' | { while read f; do dirname $f; done; } | sort -u
+}
+
+
+main() {
+	bundle_binary
+	bundle_ubuntu
+	#bundle_test
+}
+
+main