From 878dcb89f38e8eb7bb07ccd4a4e5ce622252ff30 Mon Sep 17 00:00:00 2001 From: Patrick Devine Date: Tue, 31 Mar 2015 13:58:17 -0700 Subject: [PATCH 1/2] Make a docker-in-docker dynamic binary and add RPM target This change adds a new docker-in-docker dynamic binary make target which builds a centos container for creating the dynamically linked binary. To use it, you first must create the static binary and then call the dind-dynbinary target. You can call it like: $ hack/make.sh binary dind-dynbinary rpm This would then package the dynamic binary into the rpm after having created it in the centos build container. Unfortunately with this approach you can't create the rpms and the debs with the same command. They have to be created separately otherwise the wrong version (static vs. dynamic) gets packaged. Various RPM fixes including: - Adding missing RPM dependencies. - Add sysconfig configuration files to the RPM. - Add an epoch to silence the fpm warning. - Remove unnecessary empty package. Signed-off-by: Patrick Devine Signed-off-by: Chad Metcalf --- Dockerfile | 1 + Dockerfile.centos | 36 ++++++ hack/make.sh | 2 +- hack/make/.integration-daemon-start | 2 +- hack/make/dind-dynbinary | 23 ++++ hack/make/rpm | 193 ++++++++++++++++++++++++++++ 6 files changed, 255 insertions(+), 2 deletions(-) create mode 100644 Dockerfile.centos create mode 100644 hack/make/dind-dynbinary create mode 100644 hack/make/rpm diff --git a/Dockerfile b/Dockerfile index 2b49fc1e0b..0c85a86331 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,6 +47,7 @@ RUN apt-get update && apt-get install -y \ python-pip \ python-websocket \ reprepro \ + rpm \ ruby1.9.1 \ ruby1.9.1-dev \ s3cmd=1.1.0* \ diff --git a/Dockerfile.centos b/Dockerfile.centos new file mode 100644 index 0000000000..0d11f2f2f7 --- /dev/null +++ b/Dockerfile.centos @@ -0,0 +1,36 @@ +# This file creates a CentOS docker container which can be used to create the Docker +# RPMs, however it shouldn't be called directly. +# + +FROM centos:7.0.1406 +MAINTAINER Patrick Devine (@pdev110) + +RUN rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 + +# Packaged dependencies +RUN yum groupinstall -y "Development Tools" + +RUN yum install -y \ + btrfs-progs-devel \ + device-mapper-devel \ + glibc-static \ + libselinux-devel \ + sqlite-devel + +VOLUME /go + +ENV LXC_VERSION 1.0.7 +ENV GO_VERSION 1.4.2 +ENV PATH /go/bin:/usr/local/go/bin:$PATH +ENV GOPATH /go:/go/src/github.com/docker/docker/vendor +ENV GOFMT_VERSION 1.3.3 + +# Add an unprivileged user to be used for tests which need it +RUN groupadd -r docker +RUN useradd --create-home --gid docker unprivilegeduser + +WORKDIR /go/src/github.com/docker/docker +ENV DOCKER_BUILDTAGS selinux btrfs_noversion + +# Wrap all commands in the "docker-in-docker" script to allow nested containers +#ENTRYPOINT ["hack/dind"] diff --git a/hack/make.sh b/hack/make.sh index 699bedb379..96ca5902bc 100755 --- a/hack/make.sh +++ b/hack/make.sh @@ -274,7 +274,7 @@ main() { # We want this to fail if the bundles already exist and cannot be removed. # This is to avoid mixing bundles from different versions of the code. mkdir -p bundles - if [ -e "bundles/$VERSION" ]; then + if [ -e "bundles/$VERSION" ] && [ -z ${KEEPBUNDLE} ]; then echo "bundles/$VERSION already exists. Removing." rm -fr "bundles/$VERSION" && mkdir "bundles/$VERSION" || exit 1 echo diff --git a/hack/make/.integration-daemon-start b/hack/make/.integration-daemon-start index 57fd525028..0a889ae7a2 100644 --- a/hack/make/.integration-daemon-start +++ b/hack/make/.integration-daemon-start @@ -2,7 +2,7 @@ # see test-integration-cli for example usage of this script -export PATH="$DEST/../binary:$DEST/../dynbinary:$DEST/../gccgo:$DEST/../dyngccgo:$PATH" +export PATH="$DEST/../dynbinary:$DEST/../binary:$DEST/../gccgo:$DEST/../dyngccgo:$PATH" if ! command -v docker &> /dev/null; then echo >&2 'error: binary or dynbinary must be run before .integration-daemon-start' diff --git a/hack/make/dind-dynbinary b/hack/make/dind-dynbinary new file mode 100644 index 0000000000..a577ca0763 --- /dev/null +++ b/hack/make/dind-dynbinary @@ -0,0 +1,23 @@ +#!/bin/bash + +DEST=$1 +DOCKERBIN=$DEST/../binary/docker +BUILDDIR=$DEST/../dynbinary/ +RPM_PATH=$DEST/../rpm/ + +build_rpm() { + if [ ! -x $DOCKERBIN ]; then + echo "No docker binary was found to execute. This step requires 'binary' to be run first." + exit 1 + fi + + $DOCKERBIN -d 2>/dev/null & + $DOCKERBIN build -t centos-build -f Dockerfile.centos ./ + $DOCKERBIN run -it --rm --privileged -v /go:/go -v /usr/local:/usr/local -e "KEEPBUNDLE=true" --name centos-build-container centos-build hack/make.sh dynbinary + + # turn off the docker daemon + $DOCKERBIN rmi centos-build + cat /var/run/docker.pid | xargs kill +} + +build_rpm diff --git a/hack/make/rpm b/hack/make/rpm new file mode 100644 index 0000000000..6340f79131 --- /dev/null +++ b/hack/make/rpm @@ -0,0 +1,193 @@ +#!/bin/bash + +DEST=$1 +PACKAGE_NAME=${PACKAGE_NAME:-docker-engine} + +# XXX - The package version in CentOS gets messed up and inserts a '~' +# (including the single quote) if we use the same package +# version scheme as the deb packages. This doesn't work with +# rpmbuild. +PKGVERSION="${VERSION}" +# if we have a "-dev" suffix or have change in Git, let's make this package version more complex so it works better +if [[ "$VERSION" == *-dev ]] || [ -n "$(git status --porcelain)" ]; then + GIT_UNIX="$(git log -1 --pretty='%at')" + GIT_DATE="$(date --date "@$GIT_UNIX" +'%Y%m%d.%H%M%S')" + GIT_COMMIT="$(git log -1 --pretty='%h')" + GIT_VERSION="git${GIT_DATE}.0.${GIT_COMMIT}" + # GIT_VERSION is now something like 'git20150128.112847.0.17e840a' + PKGVERSION="$PKGVERSION~$GIT_VERSION" +fi + +# $ dpkg --compare-versions 1.5.0 gt 1.5.0~rc1 && echo true || echo false +# true +# $ dpkg --compare-versions 1.5.0~rc1 gt 1.5.0~git20150128.112847.17e840a && echo true || echo false +# true +# $ dpkg --compare-versions 1.5.0~git20150128.112847.17e840a gt 1.5.0~dev~git20150128.112847.17e840a && echo true || echo false +# true + +# ie, 1.5.0 > 1.5.0~rc1 > 1.5.0~git20150128.112847.17e840a > 1.5.0~dev~git20150128.112847.17e840a + +PACKAGE_ARCHITECTURE=`uname -i` + +PACKAGE_URL="http://www.docker.com/" +PACKAGE_MAINTAINER="support@docker.com" +PACKAGE_DESCRIPTION="Linux container runtime +Docker complements LXC with a high-level API which operates at the process +level. It runs unix processes with strong guarantees of isolation and +repeatability across servers. +Docker is a great building block for automating distributed systems: +large-scale web deployments, database clusters, continuous deployment systems, +private PaaS, service-oriented architectures, etc." +PACKAGE_LICENSE="Apache-2.0" + +# bundle the RPM using FPM -- we may want to change this to rpmbuild at some point +bundle_rpm() { + DIR=$DEST/build + + # Include our udev rules + mkdir -p $DIR/etc/udev/rules.d + cp contrib/udev/80-docker.rules $DIR/etc/udev/rules.d/ + + mkdir -p $DIR/usr/lib/systemd/system + cp contrib/init/systemd/docker.{service,socket} $DIR/usr/lib/systemd/system + + cat > $DIR/usr/lib/systemd/system/docker.service <<'EOF' +[Unit] +Description=Docker Application Container Engine +Documentation=http://docs.docker.com +After=network.target docker.socket +Requires=docker.socket + +[Service] +Type=notify +EnvironmentFile=-/etc/sysconfig/docker +EnvironmentFile=-/etc/sysconfig/docker-storage +ExecStart=/usr/bin/docker -d $OPTIONS $DOCKER_STORAGE_OPTIONS +LimitNOFILE=1048576 +LimitNPROC=1048576 +MountFlags=private + +[Install] +WantedBy=multi-user.target +EOF + + mkdir -p $DIR/etc/sysconfig + cat > $DIR/etc/sysconfig/docker <<'EOF' +# /etc/sysconfig/docker + +# Modify these options if you want to change the way the docker daemon runs +OPTIONS=--selinux-enabled -H fd:// + +# Location used for temporary files, such as those created by +# docker load and build operations. Default is /var/lib/docker/tmp +# Can be overriden by setting the following environment variable. +# DOCKER_TMPDIR=/var/tmp +EOF + +cat > $DIR/etc/sysconfig/docker-storage <<'EOF' +# By default, Docker uses a loopback-mounted sparse file in +# /var/lib/docker. The loopback makes it slower, and there are some +# restrictive defaults, such as 100GB max storage. + +# If your installation did not set a custom storage for Docker, you +# may do it below. + +# Example: Use a custom pair of raw logical volumes (one for metadata, +# one for data). +# DOCKER_STORAGE_OPTIONS = --storage-opt dm.metadatadev=/dev/mylogvol/my-docker-metadata --storage-opt dm.datadev=/dev/mylogvol/my-docker-data + +DOCKER_STORAGE_OPTIONS= +EOF + + # Include contributed completions + mkdir -p $DIR/etc/bash_completion.d + cp contrib/completion/bash/docker $DIR/etc/bash_completion.d/ + mkdir -p $DIR/usr/share/zsh/vendor-completions + cp contrib/completion/zsh/_docker $DIR/usr/share/zsh/vendor-completions/ + mkdir -p $DIR/etc/fish/completions + cp contrib/completion/fish/docker.fish $DIR/etc/fish/completions/ + + # Include contributed man pages + docs/man/md2man-all.sh -q + manRoot="$DIR/usr/share/man" + mkdir -p "$manRoot" + for manDir in docs/man/man?; do + manBase="$(basename "$manDir")" # "man1" + for manFile in "$manDir"/*; do + manName="$(basename "$manFile")" # "docker-build.1" + mkdir -p "$manRoot/$manBase" + gzip -c "$manFile" > "$manRoot/$manBase/$manName.gz" + done + done + + # Copy the binary + # This will fail if the dynbinary bundle hasn't been built + mkdir -p $DIR/usr/bin + cp $DEST/../dynbinary/docker-$VERSION $DIR/usr/bin/docker + cp $DEST/../dynbinary/dockerinit-$VERSION $DIR/usr/bin/dockerinit + + # Generate postinst/prerm/postrm scripts + cat > $DEST/postinst <<'EOF' +EOF + + cat > $DEST/preinst <<'EOF' +if ! getent group docker > /dev/null; then + groupadd --system docker +fi +EOF + + cat > $DEST/prerm <<'EOF' +EOF + + cat > $DEST/postrm <<'EOF' +## In case this system is running systemd, we make systemd reload the unit files +## to pick up changes. +#if [ -d /run/systemd/system ] ; then +# systemctl --system daemon-reload > /dev/null || true +#fi +EOF + + chmod +x $DEST/postinst $DEST/prerm $DEST/postrm $DEST/preinst + + ( + # switch directories so we create *.deb in the right folder + cd $DEST + + # create PACKAGE_NAME-VERSION package + fpm -s dir -C $DIR \ + --name $PACKAGE_NAME-$VERSION --version "$PKGVERSION" \ + --epoch 7 \ + --before-install $DEST/preinst \ + --after-install $DEST/postinst \ + --before-remove $DEST/prerm \ + --after-remove $DEST/postrm \ + --architecture "$PACKAGE_ARCHITECTURE" \ + --prefix / \ + --depends iptables \ + --depends xz \ + --depends "systemd >= 208-20" \ + --depends "device-mapper-libs >= 7:1.02.90-1" \ + --depends "device-mapper-event-libs >= 7:1.02.90-1" \ + --depends libselinux \ + --depends libsepol \ + --depends sqlite \ + --description "$PACKAGE_DESCRIPTION" \ + --maintainer "$PACKAGE_MAINTAINER" \ + --conflicts docker \ + --conflicts docker-io \ + --conflicts lxc-docker-virtual-package \ + --conflicts lxc-docker \ + --url "$PACKAGE_URL" \ + --license "$PACKAGE_LICENSE" \ + --config-files etc/sysconfig \ + --config-files etc/udev/rules.d/80-docker.rules \ + --rpm-compression gzip \ + -t rpm . + ) + + # clean up after ourselves so we have a clean output directory + rm $DEST/postinst $DEST/prerm $DEST/postrm $DEST/preinst + rm -r $DIR +} + +bundle_rpm From 18beb5561140aaa950f00391a87bb332fb2b6aea Mon Sep 17 00:00:00 2001 From: Jessica Frazelle Date: Thu, 30 Apr 2015 15:30:42 -0700 Subject: [PATCH 2/2] Add rpm for centos-6, centos-7, fedora-20, fedora-21 Signed-off-by: Jessica Frazelle --- Dockerfile | 1 - Dockerfile.centos | 36 ----- contrib/builder/rpm/README.md | 5 + contrib/builder/rpm/build.sh | 10 ++ contrib/builder/rpm/centos-6/Dockerfile | 15 ++ contrib/builder/rpm/centos-7/Dockerfile | 15 ++ contrib/builder/rpm/fedora-20/Dockerfile | 15 ++ contrib/builder/rpm/fedora-21/Dockerfile | 15 ++ contrib/builder/rpm/generate.sh | 73 +++++++++ hack/make.sh | 2 +- hack/make/.build-rpm/docker-engine.spec | 180 +++++++++++++++++++++ hack/make/.integration-daemon-start | 2 +- hack/make/build-rpm | 73 +++++++++ hack/make/dind-dynbinary | 23 --- hack/make/rpm | 193 ----------------------- 15 files changed, 403 insertions(+), 255 deletions(-) delete mode 100644 Dockerfile.centos create mode 100644 contrib/builder/rpm/README.md create mode 100755 contrib/builder/rpm/build.sh create mode 100644 contrib/builder/rpm/centos-6/Dockerfile create mode 100644 contrib/builder/rpm/centos-7/Dockerfile create mode 100644 contrib/builder/rpm/fedora-20/Dockerfile create mode 100644 contrib/builder/rpm/fedora-21/Dockerfile create mode 100755 contrib/builder/rpm/generate.sh create mode 100644 hack/make/.build-rpm/docker-engine.spec create mode 100644 hack/make/build-rpm delete mode 100644 hack/make/dind-dynbinary delete mode 100644 hack/make/rpm diff --git a/Dockerfile b/Dockerfile index 0c85a86331..2b49fc1e0b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,7 +47,6 @@ RUN apt-get update && apt-get install -y \ python-pip \ python-websocket \ reprepro \ - rpm \ ruby1.9.1 \ ruby1.9.1-dev \ s3cmd=1.1.0* \ diff --git a/Dockerfile.centos b/Dockerfile.centos deleted file mode 100644 index 0d11f2f2f7..0000000000 --- a/Dockerfile.centos +++ /dev/null @@ -1,36 +0,0 @@ -# This file creates a CentOS docker container which can be used to create the Docker -# RPMs, however it shouldn't be called directly. -# - -FROM centos:7.0.1406 -MAINTAINER Patrick Devine (@pdev110) - -RUN rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 - -# Packaged dependencies -RUN yum groupinstall -y "Development Tools" - -RUN yum install -y \ - btrfs-progs-devel \ - device-mapper-devel \ - glibc-static \ - libselinux-devel \ - sqlite-devel - -VOLUME /go - -ENV LXC_VERSION 1.0.7 -ENV GO_VERSION 1.4.2 -ENV PATH /go/bin:/usr/local/go/bin:$PATH -ENV GOPATH /go:/go/src/github.com/docker/docker/vendor -ENV GOFMT_VERSION 1.3.3 - -# Add an unprivileged user to be used for tests which need it -RUN groupadd -r docker -RUN useradd --create-home --gid docker unprivilegeduser - -WORKDIR /go/src/github.com/docker/docker -ENV DOCKER_BUILDTAGS selinux btrfs_noversion - -# Wrap all commands in the "docker-in-docker" script to allow nested containers -#ENTRYPOINT ["hack/dind"] diff --git a/contrib/builder/rpm/README.md b/contrib/builder/rpm/README.md new file mode 100644 index 0000000000..153fbceb6a --- /dev/null +++ b/contrib/builder/rpm/README.md @@ -0,0 +1,5 @@ +# `dockercore/builder-rpm` + +This image's tags contain the dependencies for building Docker `.rpm`s for each of the RPM-based platforms Docker targets. + +To add new tags, see [`contrib/builder/rpm` in https://github.com/docker/docker](https://github.com/docker/docker/tree/master/contrib/builder/rpm), specifically the `generate.sh` script, whose usage is described in a comment at the top of the file. diff --git a/contrib/builder/rpm/build.sh b/contrib/builder/rpm/build.sh new file mode 100755 index 0000000000..558f7ee0db --- /dev/null +++ b/contrib/builder/rpm/build.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e + +cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" + +set -x +./generate.sh +for d in */; do + docker build -t "dockercore/builder-rpm:$(basename "$d")" "$d" +done diff --git a/contrib/builder/rpm/centos-6/Dockerfile b/contrib/builder/rpm/centos-6/Dockerfile new file mode 100644 index 0000000000..d248142270 --- /dev/null +++ b/contrib/builder/rpm/centos-6/Dockerfile @@ -0,0 +1,15 @@ +# +# THIS FILE IS AUTOGENERATED; SEE "contrib/builder/rpm/generate.sh"! +# + +FROM centos:6 + +RUN yum groupinstall -y "Development Tools" +RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libselinux-devel sqlite-devel tar + +ENV GO_VERSION 1.4.2 +RUN curl -fsSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xvzC /usr/local +ENV PATH $PATH:/usr/local/go/bin + +ENV AUTO_GOPATH 1 +ENV DOCKER_BUILDTAGS selinux exclude_graphdriver_btrfs diff --git a/contrib/builder/rpm/centos-7/Dockerfile b/contrib/builder/rpm/centos-7/Dockerfile new file mode 100644 index 0000000000..a58c9f58bd --- /dev/null +++ b/contrib/builder/rpm/centos-7/Dockerfile @@ -0,0 +1,15 @@ +# +# THIS FILE IS AUTOGENERATED; SEE "contrib/builder/rpm/generate.sh"! +# + +FROM centos:7 + +RUN yum groupinstall -y "Development Tools" +RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libselinux-devel sqlite-devel tar + +ENV GO_VERSION 1.4.2 +RUN curl -fsSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xvzC /usr/local +ENV PATH $PATH:/usr/local/go/bin + +ENV AUTO_GOPATH 1 +ENV DOCKER_BUILDTAGS selinux diff --git a/contrib/builder/rpm/fedora-20/Dockerfile b/contrib/builder/rpm/fedora-20/Dockerfile new file mode 100644 index 0000000000..f5642cdf03 --- /dev/null +++ b/contrib/builder/rpm/fedora-20/Dockerfile @@ -0,0 +1,15 @@ +# +# THIS FILE IS AUTOGENERATED; SEE "contrib/builder/rpm/generate.sh"! +# + +FROM fedora:20 + +RUN yum install -y @development-tools fedora-packager +RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libselinux-devel sqlite-devel tar + +ENV GO_VERSION 1.4.2 +RUN curl -fsSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xvzC /usr/local +ENV PATH $PATH:/usr/local/go/bin + +ENV AUTO_GOPATH 1 +ENV DOCKER_BUILDTAGS selinux diff --git a/contrib/builder/rpm/fedora-21/Dockerfile b/contrib/builder/rpm/fedora-21/Dockerfile new file mode 100644 index 0000000000..18e7837c75 --- /dev/null +++ b/contrib/builder/rpm/fedora-21/Dockerfile @@ -0,0 +1,15 @@ +# +# THIS FILE IS AUTOGENERATED; SEE "contrib/builder/rpm/generate.sh"! +# + +FROM fedora:21 + +RUN yum install -y @development-tools fedora-packager +RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libselinux-devel sqlite-devel tar + +ENV GO_VERSION 1.4.2 +RUN curl -fsSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xvzC /usr/local +ENV PATH $PATH:/usr/local/go/bin + +ENV AUTO_GOPATH 1 +ENV DOCKER_BUILDTAGS selinux diff --git a/contrib/builder/rpm/generate.sh b/contrib/builder/rpm/generate.sh new file mode 100755 index 0000000000..7bfd06f678 --- /dev/null +++ b/contrib/builder/rpm/generate.sh @@ -0,0 +1,73 @@ +#!/bin/bash +set -e + +# usage: ./generate.sh [versions] +# ie: ./generate.sh +# to update all Dockerfiles in this directory +# or: ./generate.sh +# to only update fedora-20/Dockerfile +# or: ./generate.sh fedora-newversion +# to create a new folder and a Dockerfile within it + +cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" + +versions=( "$@" ) +if [ ${#versions[@]} -eq 0 ]; then + versions=( */ ) +fi +versions=( "${versions[@]%/}" ) + +for version in "${versions[@]}"; do + distro="${version%-*}" + suite="${version##*-}" + from="${distro}:${suite}" + + mkdir -p "$version" + echo "$version -> FROM $from" + cat > "$version/Dockerfile" <<-EOF + # + # THIS FILE IS AUTOGENERATED; SEE "contrib/builder/rpm/generate.sh"! + # + + FROM $from + EOF + + echo >> "$version/Dockerfile" + + case "$from" in + centos:*) + # get "Development Tools" packages dependencies + echo 'RUN yum groupinstall -y "Development Tools"' >> "$version/Dockerfile" + ;; + *) + echo 'RUN yum install -y @development-tools fedora-packager' >> "$version/Dockerfile" + ;; + esac + + # this list is sorted alphabetically; please keep it that way + packages=( + btrfs-progs-devel # for "btrfs/ioctl.h" (and "version.h" if possible) + device-mapper-devel # for "libdevmapper.h" + glibc-static + libselinux-devel # for "libselinux.so" + sqlite-devel # for "sqlite3.h" + tar # older versions of dev-tools don't have tar + ) + echo "RUN yum install -y ${packages[*]}" >> "$version/Dockerfile" + + echo >> "$version/Dockerfile" + + awk '$1 == "ENV" && $2 == "GO_VERSION" { print; exit }' ../../../Dockerfile >> "$version/Dockerfile" + echo 'RUN curl -fsSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xvzC /usr/local' >> "$version/Dockerfile" + echo 'ENV PATH $PATH:/usr/local/go/bin' >> "$version/Dockerfile" + + echo >> "$version/Dockerfile" + + echo 'ENV AUTO_GOPATH 1' >> "$version/Dockerfile" + + if [ "$from" == "centos:6" ]; then + echo 'ENV DOCKER_BUILDTAGS selinux exclude_graphdriver_btrfs' >> "$version/Dockerfile" + else + echo 'ENV DOCKER_BUILDTAGS selinux' >> "$version/Dockerfile" + fi +done diff --git a/hack/make.sh b/hack/make.sh index 96ca5902bc..699bedb379 100755 --- a/hack/make.sh +++ b/hack/make.sh @@ -274,7 +274,7 @@ main() { # We want this to fail if the bundles already exist and cannot be removed. # This is to avoid mixing bundles from different versions of the code. mkdir -p bundles - if [ -e "bundles/$VERSION" ] && [ -z ${KEEPBUNDLE} ]; then + if [ -e "bundles/$VERSION" ]; then echo "bundles/$VERSION already exists. Removing." rm -fr "bundles/$VERSION" && mkdir "bundles/$VERSION" || exit 1 echo diff --git a/hack/make/.build-rpm/docker-engine.spec b/hack/make/.build-rpm/docker-engine.spec new file mode 100644 index 0000000000..1bb654df80 --- /dev/null +++ b/hack/make/.build-rpm/docker-engine.spec @@ -0,0 +1,180 @@ +Name: docker-engine +Version: %{_version} +Release: %{_release}%{?dist} +Summary: The open-source application container engine + +License: ASL 2.0 +Source: %{name}.tar.gz + +URL: https://dockerproject.com +Vendor: Docker +Packager: Docker + +# docker builds in a checksum of dockerinit into docker, +# # so stripping the binaries breaks docker +%global __os_install_post %{_rpmconfigdir}/brp-compress +%global debug_package %{nil} + +# is_systemd conditional +%if 0%{?fedora} >= 21 || 0%{?centos} >= 7 || 0%{?rhel} >= 7 +%global is_systemd 1 +%endif + +# required packages for build +# most are already in the container (see contrib/builder/rpm/generate.sh) +# only require systemd on those systems +%if 0%{?is_systemd} +BuildRequires: pkgconfig(systemd) +Requires: systemd-units +%else +Requires(post): chkconfig +Requires(preun): chkconfig +# This is for /sbin/service +Requires(preun): initscripts +%endif + +# required packages on install +Requires: /bin/sh +Requires: iptables +Requires: libc.so.6 +Requires: libcgroup +Requires: libpthread.so.0 +Requires: libsqlite3.so.0 +Requires: tar +Requires: xz +%if 0%{?fedora} >= 21 +# Resolves: rhbz#1165615 +Requires: device-mapper-libs >= 1.02.90-1 +%endif + +# conflicting packages +Conflicts: docker +Conflicts: docker-io + +%description +Docker is an open source project to pack, ship and run any application as a +lightweight container + +Docker containers are both hardware-agnostic and platform-agnostic. This means +they can run anywhere, from your laptop to the largest EC2 compute instance and +everything in between - and they don't require you to use a particular +language, framework or packaging system. That makes them great building blocks +for deploying and scaling web apps, databases, and backend services without +depending on a particular stack or provider. + +%prep +%if 0%{?centos} <= 6 +%setup -n %{name} +%else +%autosetup -n %{name} +%endif + +%build +./hack/make.sh dynbinary +# ./docs/man/md2man-all.sh runs outside the build container (if at all), since we don't have go-md2man here + +%check +./bundles/%{_origversion}/dynbinary/docker -v + +%install +# install binary +install -d $RPM_BUILD_ROOT/%{_bindir} +install -p -m 755 bundles/%{_origversion}/dynbinary/docker-%{_origversion} $RPM_BUILD_ROOT/%{_bindir}/docker + +# install dockerinit +install -d $RPM_BUILD_ROOT/%{_libexecdir}/docker +install -p -m 755 bundles/%{_origversion}/dynbinary/dockerinit-%{_origversion} $RPM_BUILD_ROOT/%{_libexecdir}/docker/dockerinit + +# install udev rules +install -d $RPM_BUILD_ROOT/%{_sysconfdir}/udev/rules.d +install -p -m 755 contrib/udev/80-docker.rules $RPM_BUILD_ROOT/%{_sysconfdir}/udev/rules.d/80-docker.rules + +# add init scripts +install -d $RPM_BUILD_ROOT/etc/sysconfig +install -d $RPM_BUILD_ROOT/%{_initddir} + + +%if 0%{?is_systemd} +install -d $RPM_BUILD_ROOT/%{_unitdir} +install -p -m 644 contrib/init/systemd/docker.service $RPM_BUILD_ROOT/%{_unitdir}/docker.service +install -p -m 644 contrib/init/systemd/docker.socket $RPM_BUILD_ROOT/%{_unitdir}/docker.socket +%endif + +install -p -m 644 contrib/init/sysvinit-redhat/docker.sysconfig $RPM_BUILD_ROOT/etc/sysconfig/docker +install -p -m 755 contrib/init/sysvinit-redhat/docker $RPM_BUILD_ROOT/%{_initddir}/docker + +# add bash completions +install -d $RPM_BUILD_ROOT/usr/share/bash-completion/completions +install -d $RPM_BUILD_ROOT/usr/share/zsh/vendor-completions +install -d $RPM_BUILD_ROOT/usr/share/fish/completions +install -p -m 644 contrib/completion/bash/docker $RPM_BUILD_ROOT/usr/share/bash-completion/completions/docker +install -p -m 644 contrib/completion/zsh/_docker $RPM_BUILD_ROOT/usr/share/zsh/vendor-completions/_docker +install -p -m 644 contrib/completion/fish/docker.fish $RPM_BUILD_ROOT/usr/share/fish/completions/docker.fish + +# install manpages +install -d %{buildroot}%{_mandir}/man1 +install -p -m 644 docs/man/man1/*.1 $RPM_BUILD_ROOT/%{_mandir}/man1 +install -d %{buildroot}%{_mandir}/man5 +install -p -m 644 docs/man/man5/*.5 $RPM_BUILD_ROOT/%{_mandir}/man5 + +# add vimfiles +install -d $RPM_BUILD_ROOT/usr/share/vim/vimfiles/doc +install -d $RPM_BUILD_ROOT/usr/share/vim/vimfiles/ftdetect +install -d $RPM_BUILD_ROOT/usr/share/vim/vimfiles/syntax +install -p -m 644 contrib/syntax/vim/doc/dockerfile.txt $RPM_BUILD_ROOT/usr/share/vim/vimfiles/doc/dockerfile.txt +install -p -m 644 contrib/syntax/vim/ftdetect/dockerfile.vim $RPM_BUILD_ROOT/usr/share/vim/vimfiles/ftdetect/dockerfile.vim +install -p -m 644 contrib/syntax/vim/syntax/dockerfile.vim $RPM_BUILD_ROOT/usr/share/vim/vimfiles/syntax/dockerfile.vim + + +# list files owned by the package here +%files +/%{_bindir}/docker +/%{_libexecdir}/docker/dockerinit +/%{_sysconfdir}/udev/rules.d/80-docker.rules +%if 0%{?is_systemd} +/%{_unitdir}/docker.service +/%{_unitdir}/docker.socket +%endif +/etc/sysconfig/docker +/%{_initddir}/docker +/usr/share/bash-completion/completions/docker +/usr/share/zsh/vendor-completions/_docker +/usr/share/fish/completions/docker.fish +%doc +/%{_mandir}/man1/* +/%{_mandir}/man5/* +/usr/share/vim/vimfiles/doc/dockerfile.txt +/usr/share/vim/vimfiles/ftdetect/dockerfile.vim +/usr/share/vim/vimfiles/syntax/dockerfile.vim + +%post +%if 0%{?is_systemd} +%systemd_post docker +%else +# This adds the proper /etc/rc*.d links for the script +/sbin/chkconfig --add docker +%endif +if ! getent group docker > /dev/null; then + groupadd --system docker +fi + +%preun +%if 0%{?is_systemd} +%systemd_preun docker +%else +if [ $1 -eq 0 ] ; then + /sbin/service docker stop >/dev/null 2>&1 + /sbin/chkconfig --del docker +fi +%endif + +%postun +%if 0%{?is_systemd} +%systemd_postun_with_restart docker +%else +if [ "$1" -ge "1" ] ; then + /sbin/service docker condrestart >/dev/null 2>&1 || : +fi +%endif + +%changelog diff --git a/hack/make/.integration-daemon-start b/hack/make/.integration-daemon-start index 0a889ae7a2..57fd525028 100644 --- a/hack/make/.integration-daemon-start +++ b/hack/make/.integration-daemon-start @@ -2,7 +2,7 @@ # see test-integration-cli for example usage of this script -export PATH="$DEST/../dynbinary:$DEST/../binary:$DEST/../gccgo:$DEST/../dyngccgo:$PATH" +export PATH="$DEST/../binary:$DEST/../dynbinary:$DEST/../gccgo:$DEST/../dyngccgo:$PATH" if ! command -v docker &> /dev/null; then echo >&2 'error: binary or dynbinary must be run before .integration-daemon-start' diff --git a/hack/make/build-rpm b/hack/make/build-rpm new file mode 100644 index 0000000000..0f3ff6d00e --- /dev/null +++ b/hack/make/build-rpm @@ -0,0 +1,73 @@ +#!/bin/bash +set -e + +DEST=$1 + +# subshell so that we can export PATH without breaking other things +( + source "$(dirname "$BASH_SOURCE")/.integration-daemon-start" + + # TODO consider using frozen images for the dockercore/builder-rpm tags + + rpmName=docker-engine + rpmVersion="${VERSION%%-*}" + rpmRelease=1 + + # rpmRelease versioning is as follows + # Docker 1.7.0: version=1.7.0, release=1 + # Docker 1.7.0-rc1: version=1.7.0, release=0.1.rc1 + # Docker 1.7.0-dev nightly: version=1.7.0, release=0.0.YYYYMMDD.HHMMSS.gitHASH + + # if we have a "-rc*" suffix, set appropriate release + if [[ "$VERSION" == *-rc* ]]; then + rcVersion=${VERSION#*-rc} + rpmRelease="0.${rcVersion}.rc${rcVersion}" + fi + + # if we have a "-dev" suffix or have change in Git, let's make this package version more complex so it works better + if [[ "$VERSION" == *-dev ]] || [ -n "$(git status --porcelain)" ]; then + gitUnix="$(git log -1 --pretty='%at')" + gitDate="$(date --date "@$gitUnix" +'%Y%m%d.%H%M%S')" + gitCommit="$(git log -1 --pretty='%h')" + gitVersion="${gitDate}.git${gitCommit}" + # gitVersion is now something like '20150128.112847.17e840a' + rpmRelease="0.0.$gitVersion" + fi + + rpmPackager="$(awk -F ': ' '$1 == "Packager" { print $2; exit }' hack/make/.build-rpm/${rpmName}.spec)" + rpmDate="$(date +'%a %b %d %Y')" + + # if go-md2man is available, pre-generate the man pages + ./docs/man/md2man-all.sh -q || true + # TODO decide if it's worth getting go-md2man in _each_ builder environment to avoid this + + # TODO add a configurable knob for _which_ rpms to build so we don't have to modify the file or build all of them every time we need to test + for dir in contrib/builder/rpm/*/; do + version="$(basename "$dir")" + suite="${version##*-}" + + image="dockercore/builder-rpm:$version" + if ! docker inspect "$image" &> /dev/null; then + ( set -x && docker build -t "$image" "$dir" ) + fi + + mkdir -p "$DEST/$version" + cat > "$DEST/$version/Dockerfile.build" <<-EOF + FROM $image + COPY . /usr/src/${rpmName} + RUN mkdir -p /root/rpmbuild/SOURCES + WORKDIR /root/rpmbuild + RUN ln -sfv /usr/src/${rpmName}/hack/make/.build-rpm SPECS + RUN tar -cz -C /usr/src -f /root/rpmbuild/SOURCES/${rpmName}.tar.gz ${rpmName} + WORKDIR /root/rpmbuild/SPECS + RUN { echo '* $rpmDate $rpmPackager $rpmVersion-$rpmRelease'; echo '* Version: $VERSION'; } >> ${rpmName}.spec && tail >&2 ${rpmName}.spec + RUN rpmbuild -ba --define '_release $rpmRelease' --define '_version $rpmVersion' --define '_origversion $VERSION' ${rpmName}.spec + EOF + tempImage="docker-temp/build-rpm:$version" + ( set -x && docker build -t "$tempImage" -f $DEST/$version/Dockerfile.build . ) + docker run --rm "$tempImage" bash -c 'cd /root/rpmbuild && tar -c *RPMS' | tar -xvC "$DEST/$version" + docker rmi "$tempImage" + done + + source "$(dirname "$BASH_SOURCE")/.integration-daemon-stop" +) 2>&1 | tee -a $DEST/test.log diff --git a/hack/make/dind-dynbinary b/hack/make/dind-dynbinary deleted file mode 100644 index a577ca0763..0000000000 --- a/hack/make/dind-dynbinary +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -DEST=$1 -DOCKERBIN=$DEST/../binary/docker -BUILDDIR=$DEST/../dynbinary/ -RPM_PATH=$DEST/../rpm/ - -build_rpm() { - if [ ! -x $DOCKERBIN ]; then - echo "No docker binary was found to execute. This step requires 'binary' to be run first." - exit 1 - fi - - $DOCKERBIN -d 2>/dev/null & - $DOCKERBIN build -t centos-build -f Dockerfile.centos ./ - $DOCKERBIN run -it --rm --privileged -v /go:/go -v /usr/local:/usr/local -e "KEEPBUNDLE=true" --name centos-build-container centos-build hack/make.sh dynbinary - - # turn off the docker daemon - $DOCKERBIN rmi centos-build - cat /var/run/docker.pid | xargs kill -} - -build_rpm diff --git a/hack/make/rpm b/hack/make/rpm deleted file mode 100644 index 6340f79131..0000000000 --- a/hack/make/rpm +++ /dev/null @@ -1,193 +0,0 @@ -#!/bin/bash - -DEST=$1 -PACKAGE_NAME=${PACKAGE_NAME:-docker-engine} - -# XXX - The package version in CentOS gets messed up and inserts a '~' -# (including the single quote) if we use the same package -# version scheme as the deb packages. This doesn't work with -# rpmbuild. -PKGVERSION="${VERSION}" -# if we have a "-dev" suffix or have change in Git, let's make this package version more complex so it works better -if [[ "$VERSION" == *-dev ]] || [ -n "$(git status --porcelain)" ]; then - GIT_UNIX="$(git log -1 --pretty='%at')" - GIT_DATE="$(date --date "@$GIT_UNIX" +'%Y%m%d.%H%M%S')" - GIT_COMMIT="$(git log -1 --pretty='%h')" - GIT_VERSION="git${GIT_DATE}.0.${GIT_COMMIT}" - # GIT_VERSION is now something like 'git20150128.112847.0.17e840a' - PKGVERSION="$PKGVERSION~$GIT_VERSION" -fi - -# $ dpkg --compare-versions 1.5.0 gt 1.5.0~rc1 && echo true || echo false -# true -# $ dpkg --compare-versions 1.5.0~rc1 gt 1.5.0~git20150128.112847.17e840a && echo true || echo false -# true -# $ dpkg --compare-versions 1.5.0~git20150128.112847.17e840a gt 1.5.0~dev~git20150128.112847.17e840a && echo true || echo false -# true - -# ie, 1.5.0 > 1.5.0~rc1 > 1.5.0~git20150128.112847.17e840a > 1.5.0~dev~git20150128.112847.17e840a - -PACKAGE_ARCHITECTURE=`uname -i` - -PACKAGE_URL="http://www.docker.com/" -PACKAGE_MAINTAINER="support@docker.com" -PACKAGE_DESCRIPTION="Linux container runtime -Docker complements LXC with a high-level API which operates at the process -level. It runs unix processes with strong guarantees of isolation and -repeatability across servers. -Docker is a great building block for automating distributed systems: -large-scale web deployments, database clusters, continuous deployment systems, -private PaaS, service-oriented architectures, etc." -PACKAGE_LICENSE="Apache-2.0" - -# bundle the RPM using FPM -- we may want to change this to rpmbuild at some point -bundle_rpm() { - DIR=$DEST/build - - # Include our udev rules - mkdir -p $DIR/etc/udev/rules.d - cp contrib/udev/80-docker.rules $DIR/etc/udev/rules.d/ - - mkdir -p $DIR/usr/lib/systemd/system - cp contrib/init/systemd/docker.{service,socket} $DIR/usr/lib/systemd/system - - cat > $DIR/usr/lib/systemd/system/docker.service <<'EOF' -[Unit] -Description=Docker Application Container Engine -Documentation=http://docs.docker.com -After=network.target docker.socket -Requires=docker.socket - -[Service] -Type=notify -EnvironmentFile=-/etc/sysconfig/docker -EnvironmentFile=-/etc/sysconfig/docker-storage -ExecStart=/usr/bin/docker -d $OPTIONS $DOCKER_STORAGE_OPTIONS -LimitNOFILE=1048576 -LimitNPROC=1048576 -MountFlags=private - -[Install] -WantedBy=multi-user.target -EOF - - mkdir -p $DIR/etc/sysconfig - cat > $DIR/etc/sysconfig/docker <<'EOF' -# /etc/sysconfig/docker - -# Modify these options if you want to change the way the docker daemon runs -OPTIONS=--selinux-enabled -H fd:// - -# Location used for temporary files, such as those created by -# docker load and build operations. Default is /var/lib/docker/tmp -# Can be overriden by setting the following environment variable. -# DOCKER_TMPDIR=/var/tmp -EOF - -cat > $DIR/etc/sysconfig/docker-storage <<'EOF' -# By default, Docker uses a loopback-mounted sparse file in -# /var/lib/docker. The loopback makes it slower, and there are some -# restrictive defaults, such as 100GB max storage. - -# If your installation did not set a custom storage for Docker, you -# may do it below. - -# Example: Use a custom pair of raw logical volumes (one for metadata, -# one for data). -# DOCKER_STORAGE_OPTIONS = --storage-opt dm.metadatadev=/dev/mylogvol/my-docker-metadata --storage-opt dm.datadev=/dev/mylogvol/my-docker-data - -DOCKER_STORAGE_OPTIONS= -EOF - - # Include contributed completions - mkdir -p $DIR/etc/bash_completion.d - cp contrib/completion/bash/docker $DIR/etc/bash_completion.d/ - mkdir -p $DIR/usr/share/zsh/vendor-completions - cp contrib/completion/zsh/_docker $DIR/usr/share/zsh/vendor-completions/ - mkdir -p $DIR/etc/fish/completions - cp contrib/completion/fish/docker.fish $DIR/etc/fish/completions/ - - # Include contributed man pages - docs/man/md2man-all.sh -q - manRoot="$DIR/usr/share/man" - mkdir -p "$manRoot" - for manDir in docs/man/man?; do - manBase="$(basename "$manDir")" # "man1" - for manFile in "$manDir"/*; do - manName="$(basename "$manFile")" # "docker-build.1" - mkdir -p "$manRoot/$manBase" - gzip -c "$manFile" > "$manRoot/$manBase/$manName.gz" - done - done - - # Copy the binary - # This will fail if the dynbinary bundle hasn't been built - mkdir -p $DIR/usr/bin - cp $DEST/../dynbinary/docker-$VERSION $DIR/usr/bin/docker - cp $DEST/../dynbinary/dockerinit-$VERSION $DIR/usr/bin/dockerinit - - # Generate postinst/prerm/postrm scripts - cat > $DEST/postinst <<'EOF' -EOF - - cat > $DEST/preinst <<'EOF' -if ! getent group docker > /dev/null; then - groupadd --system docker -fi -EOF - - cat > $DEST/prerm <<'EOF' -EOF - - cat > $DEST/postrm <<'EOF' -## In case this system is running systemd, we make systemd reload the unit files -## to pick up changes. -#if [ -d /run/systemd/system ] ; then -# systemctl --system daemon-reload > /dev/null || true -#fi -EOF - - chmod +x $DEST/postinst $DEST/prerm $DEST/postrm $DEST/preinst - - ( - # switch directories so we create *.deb in the right folder - cd $DEST - - # create PACKAGE_NAME-VERSION package - fpm -s dir -C $DIR \ - --name $PACKAGE_NAME-$VERSION --version "$PKGVERSION" \ - --epoch 7 \ - --before-install $DEST/preinst \ - --after-install $DEST/postinst \ - --before-remove $DEST/prerm \ - --after-remove $DEST/postrm \ - --architecture "$PACKAGE_ARCHITECTURE" \ - --prefix / \ - --depends iptables \ - --depends xz \ - --depends "systemd >= 208-20" \ - --depends "device-mapper-libs >= 7:1.02.90-1" \ - --depends "device-mapper-event-libs >= 7:1.02.90-1" \ - --depends libselinux \ - --depends libsepol \ - --depends sqlite \ - --description "$PACKAGE_DESCRIPTION" \ - --maintainer "$PACKAGE_MAINTAINER" \ - --conflicts docker \ - --conflicts docker-io \ - --conflicts lxc-docker-virtual-package \ - --conflicts lxc-docker \ - --url "$PACKAGE_URL" \ - --license "$PACKAGE_LICENSE" \ - --config-files etc/sysconfig \ - --config-files etc/udev/rules.d/80-docker.rules \ - --rpm-compression gzip \ - -t rpm . - ) - - # clean up after ourselves so we have a clean output directory - rm $DEST/postinst $DEST/prerm $DEST/postrm $DEST/preinst - rm -r $DIR -} - -bundle_rpm