瀏覽代碼

docker-ci 0.5.6: Fully dockerize docker-ci. Add build test coverage. Add backup builder.

Docker-DCO-1.1-Signed-off-by: Daniel Mizyrycki <daniel@docker.com> (github: mzdaniel)
Daniel Mizyrycki 11 年之前
父節點
當前提交
b7db2d5f80
共有 33 個文件被更改,包括 460 次插入647 次删除
  1. 0 56
      hack/infrastructure/docker-ci.rst
  2. 24 42
      hack/infrastructure/docker-ci/Dockerfile
  3. 57 18
      hack/infrastructure/docker-ci/README.rst
  4. 1 1
      hack/infrastructure/docker-ci/VERSION
  5. 0 1
      hack/infrastructure/docker-ci/buildbot/README.rst
  6. 0 18
      hack/infrastructure/docker-ci/buildbot/buildbot.conf
  7. 5 4
      hack/infrastructure/docker-ci/buildbot/github.py
  8. 101 72
      hack/infrastructure/docker-ci/buildbot/master.cfg
  9. 0 9
      hack/infrastructure/docker-ci/buildbot/requirements.txt
  10. 0 59
      hack/infrastructure/docker-ci/buildbot/setup.sh
  11. 22 0
      hack/infrastructure/docker-ci/dcr/prod/docker-ci.yml
  12. 5 0
      hack/infrastructure/docker-ci/dcr/prod/settings.yml
  13. 22 0
      hack/infrastructure/docker-ci/dcr/stage/docker-ci.yml
  14. 5 0
      hack/infrastructure/docker-ci/dcr/stage/settings.yml
  15. 0 171
      hack/infrastructure/docker-ci/deployment.py
  16. 0 32
      hack/infrastructure/docker-ci/docker-coverage/coverage-docker.sh
  17. 0 25
      hack/infrastructure/docker-ci/docker-test/Dockerfile
  18. 0 33
      hack/infrastructure/docker-ci/docker-test/test_docker.sh
  19. 1 0
      hack/infrastructure/docker-ci/dockertest/docker
  20. 1 0
      hack/infrastructure/docker-ci/dockertest/docker-registry
  21. 13 0
      hack/infrastructure/docker-ci/dockertest/nightlyrelease
  22. 8 0
      hack/infrastructure/docker-ci/dockertest/project
  23. 12 0
      hack/infrastructure/docker-ci/nginx/nginx.conf
  24. 0 30
      hack/infrastructure/docker-ci/nightlyrelease/Dockerfile
  25. 0 40
      hack/infrastructure/docker-ci/nightlyrelease/dockerbuild.sh
  26. 0 18
      hack/infrastructure/docker-ci/registry-coverage/Dockerfile
  27. 0 18
      hack/infrastructure/docker-ci/registry-coverage/registry_coverage.sh
  28. 54 0
      hack/infrastructure/docker-ci/setup.sh
  29. 12 0
      hack/infrastructure/docker-ci/testbuilder/Dockerfile
  30. 12 0
      hack/infrastructure/docker-ci/testbuilder/docker-registry.sh
  31. 18 0
      hack/infrastructure/docker-ci/testbuilder/docker.sh
  32. 40 0
      hack/infrastructure/docker-ci/testbuilder/testbuilder.sh
  33. 47 0
      hack/infrastructure/docker-ci/tool/backup.py

+ 0 - 56
hack/infrastructure/docker-ci.rst

@@ -1,56 +0,0 @@
-docker-ci
-=========
-
-docker-ci is our buildbot continuous integration server,
-building and testing docker, hosted on EC2 and reachable at
-http://docker-ci.dotcloud.com
-
-
-Deployment
-==========
-
-# Load AWS credentials
-export AWS_ACCESS_KEY_ID=''
-export AWS_SECRET_ACCESS_KEY=''
-export AWS_KEYPAIR_NAME=''
-export AWS_SSH_PRIVKEY=''
-
-# Load buildbot credentials and config
-export BUILDBOT_PWD=''
-export IRC_PWD=''
-export IRC_CHANNEL='docker-dev'
-export SMTP_USER=''
-export SMTP_PWD=''
-export EMAIL_RCP=''
-
-# Load registry test credentials
-export REGISTRY_USER=''
-export REGISTRY_PWD=''
-
-cd docker/testing
-vagrant up --provider=aws
-
-
-github pull request
-===================
-
-The entire docker pull request test workflow is event driven by github. Its
-usage is fully automatic and the results are logged in docker-ci.dotcloud.com
-
-Each time there is a pull request on docker's github project, github connects
-to docker-ci using github's rest API documented in http://developer.github.com/v3/repos/hooks
-The issued command to program github's notification PR event was:
-curl -u GITHUB_USER:GITHUB_PASSWORD -d '{"name":"web","active":true,"events":["pull_request"],"config":{"url":"http://docker-ci.dotcloud.com:8011/change_hook/github?project=docker"}}' https://api.github.com/repos/dotcloud/docker/hooks
-
-buildbot (0.8.7p1) was patched using ./testing/buildbot/github.py, so it
-can understand the PR data github sends to it. Originally PR #1603 (ee64e099e0)
-implemented this capability. Also we added a new scheduler to exclusively filter
-PRs. and the 'pullrequest' builder to rebase the PR on top of master and test it.
-
-
-nighthly release
-================
-
-The nightly release process is done by buildbot, running a DinD container that downloads
-the docker repository and builds the release container. The resulting docker
-binary is then tested, and if everything is fine, the release is done.

+ 24 - 42
hack/infrastructure/docker-ci/Dockerfile

@@ -1,47 +1,29 @@
-# VERSION:        0.25
-# DOCKER-VERSION  0.6.6
-# AUTHOR:         Daniel Mizyrycki <daniel@docker.com>
-# DESCRIPTION:    Deploy docker-ci on Digital Ocean
-# COMMENTS:
-#     CONFIG_JSON is an environment variable json string loaded as:
-#
-# export CONFIG_JSON='
-#     { "DROPLET_NAME":        "docker-ci",
-#       "DO_CLIENT_ID":        "Digital_Ocean_client_id",
-#       "DO_API_KEY":          "Digital_Ocean_api_key",
-#       "DOCKER_KEY_ID":       "Digital_Ocean_ssh_key_id",
-#       "DOCKER_CI_KEY_PATH":  "docker-ci_private_key_path",
-#       "DOCKER_CI_PUB":       "$(cat docker-ci_ssh_public_key.pub)",
-#       "DOCKER_CI_KEY":       "$(cat docker-ci_ssh_private_key.key)",
-#       "BUILDBOT_PWD":        "Buildbot_server_password",
-#       "IRC_PWD":             "Buildbot_IRC_password",
-#       "SMTP_USER":           "SMTP_server_user",
-#       "SMTP_PWD":            "SMTP_server_password",
-#       "PKG_ACCESS_KEY":      "Docker_release_S3_bucket_access_key",
-#       "PKG_SECRET_KEY":      "Docker_release_S3_bucket_secret_key",
-#       "PKG_GPG_PASSPHRASE":  "Docker_release_gpg_passphrase",
-#       "INDEX_AUTH":          "Index_encripted_user_password",
-#       "REGISTRY_USER":       "Registry_test_user",
-#       "REGISTRY_PWD":        "Registry_test_password",
-#       "REGISTRY_BUCKET":     "Registry_S3_bucket_name",
-#       "REGISTRY_ACCESS_KEY": "Registry_S3_bucket_access_key",
-#       "REGISTRY_SECRET_KEY": "Registry_S3_bucket_secret_key",
-#       "IRC_CHANNEL":         "Buildbot_IRC_channel",
-#       "EMAIL_RCP":           "Buildbot_mailing_receipient" }'
-#
-#
-# TO_BUILD:   docker build -t docker-ci .
-# TO_DEPLOY:  docker run -e CONFIG_JSON="${CONFIG_JSON}" docker-ci
+# DOCKER-VERSION: 0.7.6
+# AUTHOR:         Daniel Mizyrycki <daniel@dotcloud.com>
+# DESCRIPTION:    docker-ci continuous integration service
+# TO_BUILD:       docker build -rm -t docker-ci/docker-ci .
+# TO_RUN:         docker run -rm -i -t -p 8000:80 -p 2222:22 -v /run:/var/socket \
+#                     -v /data/docker-ci:/data/docker-ci docker-ci/docker-ci
 
 from ubuntu:12.04
+maintainer Daniel Mizyrycki <daniel@dotcloud.com>
 
-run echo 'deb http://archive.ubuntu.com/ubuntu precise main universe' \
-    > /etc/apt/sources.list
-run apt-get update; apt-get install -y git python2.7 python-dev libevent-dev \
-    python-pip ssh rsync less vim
-run pip install requests fabric
+ENV DEBIAN_FRONTEND noninteractive
+RUN echo 'deb http://archive.ubuntu.com/ubuntu precise main universe' > \
+    /etc/apt/sources.list; apt-get update
+RUN apt-get install -y --no-install-recommends  python2.7 python-dev \
+    libevent-dev git supervisor ssh rsync less vim sudo gcc wget nginx
+RUN cd /tmp; wget http://python-distribute.org/distribute_setup.py
+RUN cd /tmp; python distribute_setup.py; easy_install pip; rm distribute_setup.py
 
-# Add deployment code and set default container command
-add . /docker-ci
-cmd "/docker-ci/deployment.py"
+RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
+RUN echo 'deb http://get.docker.io/ubuntu docker main' > \
+      /etc/apt/sources.list.d/docker.list; apt-get update
+RUN apt-get install -y lxc-docker-0.8.0
+RUN pip install SQLAlchemy==0.7.10 buildbot buildbot-slave pyopenssl boto
+RUN ln -s /var/socket/docker.sock /run/docker.sock
 
+ADD . /docker-ci
+RUN /docker-ci/setup.sh
+
+ENTRYPOINT ["supervisord", "-n"]

+ 57 - 18
hack/infrastructure/docker-ci/README.rst

@@ -1,26 +1,65 @@
-=======
-testing
-=======
+=========
+docker-ci
+=========
 
-This directory contains docker-ci testing related files.
+This directory contains docker-ci continuous integration system.
+As expected, it is a fully dockerized and deployed using
+docker-container-runner.
+docker-ci is based on Buildbot, a continuous integration system designed
+to automate the build/test cycle. By automatically rebuilding and testing
+the tree each time something has changed, build problems are pinpointed
+quickly, before other developers are inconvenienced by the failure.
+We are running buildbot at Rackspace to verify docker and docker-registry
+pass tests, and check for coverage code details.
 
+docker-ci instance is at https://docker-ci.docker.io/waterfall
 
-Buildbot
-========
+Inside docker-ci container we have the following directory structure:
 
-Buildbot is a continuous integration system designed to automate the
-build/test cycle. By automatically rebuilding and testing the tree each time
-something has changed, build problems are pinpointed quickly, before other
-developers are inconvenienced by the failure.
+/docker-ci                       source code of docker-ci
+/data/backup/docker-ci/          daily backup (replicated over S3)
+/data/docker-ci/coverage/{docker,docker-registry}/    mapped to host volumes
+/data/buildbot/{master,slave}/   main docker-ci buildbot config and database
+/var/socket/{docker.sock}        host volume access to docker socket
 
-We are running buildbot in Amazon's EC2 to verify docker passes all
-tests when commits get pushed to the master branch and building
-nightly releases using Docker in Docker awesome implementation made
-by Jerome Petazzoni.
 
-https://github.com/jpetazzo/dind
+Production deployment
+=====================
 
-Docker's buildbot instance is at http://docker-ci.dotcloud.com/waterfall
+::
 
-For deployment instructions, please take a look at
-hack/infrastructure/docker-ci/Dockerfile
+  # Clone docker-ci repository
+  git clone https://github.com/dotcloud/docker
+  cd docker/hack/infrastructure/docker-ci
+
+  export DOCKER_PROD=[PRODUCTION_SERVER_IP]
+
+  # Create data host volume. (only once)
+  docker -H $DOCKER_PROD run -v /home:/data ubuntu:12.04 \
+    mkdir -p /data/docker-ci/coverage/docker
+  docker -H $DOCKER_PROD run -v /home:/data ubuntu:12.04 \
+    mkdir -p /data/docker-ci/coverage/docker-registry
+  docker -H $DOCKER_PROD run -v /home:/data ubuntu:12.04 \
+    chown -R 1000.1000 /data/docker-ci
+
+  # dcr deployment. Define credentials and special environment dcr variables
+  # ( retrieved at /hack/infrastructure/docker-ci/dcr/prod/docker-ci.yml )
+  export WEB_USER=[DOCKER-CI-WEBSITE-USERNAME]
+  export WEB_IRC_PWD=[DOCKER-CI-WEBSITE-PASSWORD]
+  export BUILDBOT_PWD=[BUILDSLAVE_PASSWORD]
+  export AWS_ACCESS_KEY=[DOCKER_RELEASE_S3_ACCESS]
+  export AWS_SECRET_KEY=[DOCKER_RELEASE_S3_SECRET]
+  export GPG_PASSPHRASE=[DOCKER_RELEASE_PASSPHRASE]
+  export BACKUP_AWS_ID=[S3_BUCKET_CREDENTIAL_ACCESS]
+  export BACKUP_AWS_SECRET=[S3_BUCKET_CREDENTIAL_SECRET]
+  export SMTP_USER=[MAILGUN_SMTP_USERNAME]
+  export SMTP_PWD=[MAILGUN_SMTP_PASSWORD]
+  export EMAIL_RCP=[EMAIL_FOR_BUILD_ERRORS]
+
+  # Build docker-ci and testbuilder docker images
+  docker -H $DOCKER_PROD build -rm -t docker-ci/docker-ci .
+  (cd testbuilder; docker -H $DOCKER_PROD build -rm -t docker-ci/testbuilder .)
+
+  # Run docker-ci container ( assuming no previous container running )
+  (cd dcr/prod; dcr docker-ci.yml start)
+  (cd dcr/prod; dcr docker-ci.yml register docker-ci.docker.io)

+ 1 - 1
hack/infrastructure/docker-ci/VERSION

@@ -1 +1 @@
-0.4.5
+0.5.6

+ 0 - 1
hack/infrastructure/docker-ci/buildbot/README.rst

@@ -1 +0,0 @@
-Buildbot configuration and setup files

+ 0 - 18
hack/infrastructure/docker-ci/buildbot/buildbot.conf

@@ -1,18 +0,0 @@
-[program:buildmaster]
-command=twistd --nodaemon --no_save -y buildbot.tac
-directory=/data/buildbot/master
-chown= root:root
-redirect_stderr=true
-stdout_logfile=/var/log/supervisor/buildbot-master.log
-stderr_logfile=/var/log/supervisor/buildbot-master.log
-
-[program:buildworker]
-command=twistd --nodaemon --no_save -y buildbot.tac
-directory=/data/buildbot/slave
-chown= root:root
-redirect_stderr=true
-stdout_logfile=/var/log/supervisor/buildbot-slave.log
-stderr_logfile=/var/log/supervisor/buildbot-slave.log
-
-[group:buildbot]
-programs=buildmaster,buildworker

+ 5 - 4
hack/infrastructure/docker-ci/buildbot/github.py

@@ -17,7 +17,7 @@
 """
 github_buildbot.py is based on git_buildbot.py
 
-github_buildbot.py will determine the repository information from the JSON 
+github_buildbot.py will determine the repository information from the JSON
 HTTP POST it receives from github.com and build the appropriate repository.
 If your github repository is private, you must add a ssh key to the github
 repository for the user who initiated the build on the buildslave.
@@ -88,7 +88,8 @@ def getChanges(request, options = None):
         payload = json.loads(request.args['payload'][0])
         import urllib,datetime
         fname = str(datetime.datetime.now()).replace(' ','_').replace(':','-')[:19]
-        open('github_{0}.json'.format(fname),'w').write(json.dumps(json.loads(urllib.unquote(request.args['payload'][0])), sort_keys = True, indent = 2))
+        # Github event debug
+        # open('github_{0}.json'.format(fname),'w').write(json.dumps(json.loads(urllib.unquote(request.args['payload'][0])), sort_keys = True, indent = 2))
 
         if 'pull_request' in payload:
             user = payload['pull_request']['user']['login']
@@ -142,13 +143,13 @@ def process_change(payload, user, repo, repo_url, project):
                     'category'   : 'github_pullrequest',
                     'who'        : '{0} - PR#{1}'.format(user,payload['number']),
                     'files'      : [],
-                    'comments'   : payload['pull_request']['title'], 
+                    'comments'   : payload['pull_request']['title'],
                     'revision'   : newrev,
                     'when'       : convertTime(payload['pull_request']['updated_at']),
                     'branch'     : branch,
                     'revlink'    : '{0}/commit/{1}'.format(repo_url,newrev),
                     'repository' : repo_url,
-                    'project'  : project  }] 
+                    'project'  : project  }]
                 return changes
             for commit in payload['commits']:
                 files = []

+ 101 - 72
hack/infrastructure/docker-ci/buildbot/master.cfg

@@ -1,4 +1,4 @@
-import os
+import os, re
 from buildbot.buildslave import BuildSlave
 from buildbot.schedulers.forcesched import ForceScheduler
 from buildbot.schedulers.basic import SingleBranchScheduler
@@ -6,127 +6,156 @@ from buildbot.schedulers.timed import Nightly
 from buildbot.changes import filter
 from buildbot.config import BuilderConfig
 from buildbot.process.factory import BuildFactory
-from buildbot.process.properties import Interpolate
+from buildbot.process.properties import Property
 from buildbot.steps.shell import ShellCommand
 from buildbot.status import html, words
 from buildbot.status.web import authz, auth
 from buildbot.status.mail import MailNotifier
 
-PORT_WEB = 80           # Buildbot webserver port
-PORT_GITHUB = 8011      # Buildbot github hook port
-PORT_MASTER = 9989      # Port where buildbot master listen buildworkers
-TEST_USER = 'buildbot'  # Credential to authenticate build triggers
-TEST_PWD = 'docker'     # Credential to authenticate build triggers
-GITHUB_DOCKER = 'github.com/dotcloud/docker'
-BUILDBOT_PATH = '/data/buildbot'
-DOCKER_PATH = '/go/src/github.com/dotcloud/docker'
-DOCKER_CI_PATH = '/docker-ci'
+
+def ENV(x):
+    '''Promote an environment variable for global use returning its value'''
+    retval = os.environ.get(x, '')
+    globals()[x] = retval
+    return retval
+
+
+class TestCommand(ShellCommand):
+    '''Extend ShellCommand with optional summary logs'''
+    def __init__(self, *args, **kwargs):
+        super(TestCommand, self).__init__(*args, **kwargs)
+
+    def createSummary(self, log):
+        exit_status = re.sub(r'.+\n\+ exit (\d+).+',
+            r'\1', log.getText()[-100:], flags=re.DOTALL)
+        if exit_status != '0':
+            return
+        # Infer coverage path from log
+        if '+ COVERAGE_PATH' in log.getText():
+            path = re.sub(r'.+\+ COVERAGE_PATH=((.+?)-\d+).+',
+              r'\2/\1', log.getText(), flags=re.DOTALL)
+            url = '{}coverage/{}/index.html'.format(c['buildbotURL'], path)
+            self.addURL('coverage', url)
+        elif 'COVERAGE_FILE' in log.getText():
+            path = re.sub(r'.+\+ COVERAGE_FILE=((.+?)-\d+).+',
+              r'\2/\1', log.getText(), flags=re.DOTALL)
+            url = '{}coverage/{}/index.html'.format(c['buildbotURL'], path)
+            self.addURL('coverage', url)
+
+
+PORT_WEB = 8000      # Buildbot webserver port
+PORT_GITHUB = 8011   # Buildbot github hook port
+PORT_MASTER = 9989   # Port where buildbot master listen buildworkers
+
+BUILDBOT_URL = '//localhost:{}/'.format(PORT_WEB)
+DOCKER_REPO = 'https://github.com/docker-test/docker'
+DOCKER_TEST_ARGV = 'HEAD {}'.format(DOCKER_REPO)
+REGISTRY_REPO = 'https://github.com/docker-test/docker-registry'
+REGISTRY_TEST_ARGV = 'HEAD {}'.format(REGISTRY_REPO)
+if ENV('DEPLOYMENT') == 'staging':
+    BUILDBOT_URL = "//docker-ci-stage.docker.io/"
+if ENV('DEPLOYMENT') == 'production':
+    BUILDBOT_URL = '//docker-ci.docker.io/'
+    DOCKER_REPO = 'https://github.com/dotcloud/docker'
+    DOCKER_TEST_ARGV = ''
+    REGISTRY_REPO = 'https://github.com/dotcloud/docker-registry'
+    REGISTRY_TEST_ARGV = ''
 
 # Credentials set by setup.sh from deployment.py
-BUILDBOT_PWD = ''
-IRC_PWD = ''
-IRC_CHANNEL = ''
-SMTP_USER = ''
-SMTP_PWD = ''
-EMAIL_RCP = ''
+ENV('WEB_USER')
+ENV('WEB_IRC_PWD')
+ENV('BUILDBOT_PWD')
+ENV('SMTP_USER')
+ENV('SMTP_PWD')
+ENV('EMAIL_RCP')
+ENV('IRC_CHANNEL')
 
 
 c = BuildmasterConfig = {}
 
-c['title'] = "Docker"
+c['title'] = "docker-ci"
 c['titleURL'] = "waterfall"
-c['buildbotURL'] = "http://docker-ci.dotcloud.com/"
+c['buildbotURL'] = BUILDBOT_URL
 c['db'] = {'db_url':"sqlite:///state.sqlite"}
 c['slaves'] = [BuildSlave('buildworker', BUILDBOT_PWD)]
 c['slavePortnum'] = PORT_MASTER
 
 
 # Schedulers
-c['schedulers'] = [ForceScheduler(name='trigger', builderNames=['docker',
-    'index','registry','docker-coverage','registry-coverage','nightlyrelease'])]
-c['schedulers'] += [SingleBranchScheduler(name="all", treeStableTimer=None,
+c['schedulers'] = [ForceScheduler(name='trigger', builderNames=[
+    'docker', 'docker-registry', 'nightlyrelease', 'backup'])]
+c['schedulers'] += [SingleBranchScheduler(name="docker", treeStableTimer=None,
     change_filter=filter.ChangeFilter(branch='master',
-    repository='https://github.com/dotcloud/docker'), builderNames=['docker'])]
-c['schedulers'] += [SingleBranchScheduler(name='pullrequest',
-    change_filter=filter.ChangeFilter(category='github_pullrequest'), treeStableTimer=None,
-    builderNames=['pullrequest'])]
-c['schedulers'] += [Nightly(name='daily', branch=None, builderNames=['nightlyrelease',
-    'docker-coverage','registry-coverage'], hour=7, minute=00)]
-c['schedulers'] += [Nightly(name='every4hrs', branch=None, builderNames=['registry','index'],
-    hour=range(0,24,4), minute=15)]
+    repository=DOCKER_REPO), builderNames=['docker'])]
+c['schedulers'] += [SingleBranchScheduler(name="registry", treeStableTimer=None,
+    change_filter=filter.ChangeFilter(branch='master',
+    repository=REGISTRY_REPO), builderNames=['docker-registry'])]
+c['schedulers'] += [SingleBranchScheduler(name='docker-pr', treeStableTimer=None,
+    change_filter=filter.ChangeFilter(category='github_pullrequest',
+    project='docker'), builderNames=['docker-pr'])]
+c['schedulers'] += [SingleBranchScheduler(name='docker-registry-pr', treeStableTimer=None,
+    change_filter=filter.ChangeFilter(category='github_pullrequest',
+    project='docker-registry'), builderNames=['docker-registry-pr'])]
+c['schedulers'] += [Nightly(name='daily', branch=None, builderNames=[
+    'nightlyrelease', 'backup'], hour=7, minute=00)]
+
 
 # Builders
-# Docker commit test
-test_cmd = ('docker run -privileged mzdaniel/test_docker hack/dind'
-    ' test_docker.sh %(src::revision)s')
-factory = BuildFactory()
-factory.addStep(ShellCommand(description='Docker', logEnviron=False,
-    usePTY=True, command=["sh", "-c", Interpolate(test_cmd)]))
-c['builders'] = [BuilderConfig(name='docker',slavenames=['buildworker'],
-    factory=factory)]
 
-# Docker pull request test
-test_cmd = ('docker run -privileged mzdaniel/test_docker hack/dind'
-    ' test_docker.sh %(src::revision)s %(src::repository)s %(src::branch)s')
+# Backup
 factory = BuildFactory()
-factory.addStep(ShellCommand(description='pull_request', logEnviron=False,
-    usePTY=True, command=["sh", "-c", Interpolate(test_cmd)]))
-c['builders'] += [BuilderConfig(name='pullrequest',slavenames=['buildworker'],
+factory.addStep(TestCommand(description='backup', logEnviron=False,
+    usePTY=True, command='/docker-ci/tool/backup.py'))
+c['builders'] = [BuilderConfig(name='backup',slavenames=['buildworker'],
     factory=factory)]
 
-# Docker coverage test
+# Docker test
 factory = BuildFactory()
-factory.addStep(ShellCommand(description='docker-coverage', logEnviron=False,
-    usePTY=True, command='{0}/docker-coverage/coverage-docker.sh'.format(
-    DOCKER_CI_PATH)))
-c['builders'] += [BuilderConfig(name='docker-coverage',slavenames=['buildworker'],
+factory.addStep(TestCommand(description='docker', logEnviron=False,
+    usePTY=True, command='/docker-ci/dockertest/docker {}'.format(DOCKER_TEST_ARGV)))
+c['builders'] += [BuilderConfig(name='docker',slavenames=['buildworker'],
     factory=factory)]
 
-# Docker registry coverage test
+# Docker pull request test
 factory = BuildFactory()
-factory.addStep(ShellCommand(description='registry-coverage', logEnviron=False,
-    usePTY=True, command='docker run registry_coverage'.format(
-    DOCKER_CI_PATH)))
-c['builders'] += [BuilderConfig(name='registry-coverage',slavenames=['buildworker'],
+factory.addStep(TestCommand(description='docker-pr', logEnviron=False,
+    usePTY=True, command=['/docker-ci/dockertest/docker',
+    Property('revision'), Property('repository'), Property('branch')]))
+c['builders'] += [BuilderConfig(name='docker-pr',slavenames=['buildworker'],
     factory=factory)]
 
-# Registry functional test
+# docker-registry test
 factory = BuildFactory()
-factory.addStep(ShellCommand(description='registry', logEnviron=False,
-    command='. {0}/master/credentials.cfg; '
-    '{1}/functionaltests/test_registry.sh'.format(BUILDBOT_PATH, DOCKER_CI_PATH),
-    usePTY=True))
-c['builders'] += [BuilderConfig(name='registry',slavenames=['buildworker'],
+factory.addStep(TestCommand(description='docker-registry', logEnviron=False,
+    usePTY=True, command='/docker-ci/dockertest/docker-registry {}'.format(REGISTRY_TEST_ARGV)))
+c['builders'] += [BuilderConfig(name='docker-registry',slavenames=['buildworker'],
     factory=factory)]
 
-# Index functional test
+# Docker registry pull request test
 factory = BuildFactory()
-factory.addStep(ShellCommand(description='index', logEnviron=False,
-    command='. {0}/master/credentials.cfg; '
-    '{1}/functionaltests/test_index.py'.format(BUILDBOT_PATH, DOCKER_CI_PATH),
-    usePTY=True))
-c['builders'] += [BuilderConfig(name='index',slavenames=['buildworker'],
+factory.addStep(TestCommand(description='docker-registry-pr', logEnviron=False,
+    usePTY=True, command=['/docker-ci/dockertest/docker-registry',
+    Property('revision'), Property('repository'), Property('branch')]))
+c['builders'] += [BuilderConfig(name='docker-registry-pr',slavenames=['buildworker'],
     factory=factory)]
 
 # Docker nightly release
-nightlyrelease_cmd = ('docker version; docker run -i -t -privileged -e AWS_S3_BUCKET='
-    'test.docker.io dockerbuilder hack/dind dockerbuild.sh')
 factory = BuildFactory()
 factory.addStep(ShellCommand(description='NightlyRelease',logEnviron=False,
-    usePTY=True, command=nightlyrelease_cmd))
+    usePTY=True, command=['/docker-ci/dockertest/nightlyrelease']))
 c['builders'] += [BuilderConfig(name='nightlyrelease',slavenames=['buildworker'],
     factory=factory)]
 
 # Status
-authz_cfg = authz.Authz(auth=auth.BasicAuth([(TEST_USER, TEST_PWD)]),
+authz_cfg = authz.Authz(auth=auth.BasicAuth([(WEB_USER, WEB_IRC_PWD)]),
     forceBuild='auth')
 c['status'] = [html.WebStatus(http_port=PORT_WEB, authz=authz_cfg)]
 c['status'].append(html.WebStatus(http_port=PORT_GITHUB, allowForce=True,
     change_hook_dialects={ 'github': True }))
-c['status'].append(MailNotifier(fromaddr='buildbot@docker.io',
+c['status'].append(MailNotifier(fromaddr='docker-test@docker.io',
     sendToInterestedUsers=False, extraRecipients=[EMAIL_RCP],
     mode='failing', relayhost='smtp.mailgun.org', smtpPort=587, useTls=True,
     smtpUser=SMTP_USER, smtpPassword=SMTP_PWD))
 c['status'].append(words.IRC("irc.freenode.net", "dockerqabot",
-    channels=[IRC_CHANNEL], password=IRC_PWD, allowForce=True,
+    channels=[IRC_CHANNEL], password=WEB_IRC_PWD, allowForce=True,
     notify_events={'exception':1, 'successToFailure':1, 'failureToSuccess':1}))

+ 0 - 9
hack/infrastructure/docker-ci/buildbot/requirements.txt

@@ -1,9 +0,0 @@
-sqlalchemy<=0.7.9
-sqlalchemy-migrate>=0.7.2
-buildbot==0.8.7p1
-buildbot_slave==0.8.7p1
-nose==1.2.1
-requests==1.1.0
-flask==0.10.1
-simplejson==2.3.2
-selenium==2.35.0

+ 0 - 59
hack/infrastructure/docker-ci/buildbot/setup.sh

@@ -1,59 +0,0 @@
-#!/usr/bin/env bash
-
-# Setup of buildbot configuration. Package installation is being done by
-# Vagrantfile
-# Dependencies: buildbot, buildbot-slave, supervisor
-
-USER=$1
-CFG_PATH=$2
-DOCKER_PATH=$3
-BUILDBOT_PWD=$4
-IRC_PWD=$5
-IRC_CHANNEL=$6
-SMTP_USER=$7
-SMTP_PWD=$8
-EMAIL_RCP=$9
-REGISTRY_USER=${10}
-REGISTRY_PWD=${11}
-REGISTRY_BUCKET=${12}
-REGISTRY_ACCESS_KEY=${13}
-REGISTRY_SECRET_KEY=${14}
-BUILDBOT_PATH="/data/buildbot"
-SLAVE_NAME="buildworker"
-SLAVE_SOCKET="localhost:9989"
-
-export PATH="/bin:sbin:/usr/bin:/usr/sbin:/usr/local/bin"
-
-function run { su $USER -c "$1"; }
-
-# Exit if buildbot has already been installed
-[ -d "$BUILDBOT_PATH" ] && exit 0
-
-# Setup buildbot
-run "mkdir -p $BUILDBOT_PATH"
-cd $BUILDBOT_PATH
-run "buildbot create-master master"
-run "cp $CFG_PATH/master.cfg master"
-run "sed -i -E 's#(BUILDBOT_PWD = ).+#\1\"$BUILDBOT_PWD\"#' master/master.cfg"
-run "sed -i -E 's#(IRC_PWD = ).+#\1\"$IRC_PWD\"#' master/master.cfg"
-run "sed -i -E 's#(IRC_CHANNEL = ).+#\1\"$IRC_CHANNEL\"#' master/master.cfg"
-run "sed -i -E 's#(SMTP_USER = ).+#\1\"$SMTP_USER\"#' master/master.cfg"
-run "sed -i -E 's#(SMTP_PWD = ).+#\1\"$SMTP_PWD\"#' master/master.cfg"
-run "sed -i -E 's#(EMAIL_RCP = ).+#\1\"$EMAIL_RCP\"#' master/master.cfg"
-run "buildslave create-slave slave $SLAVE_SOCKET $SLAVE_NAME $BUILDBOT_PWD"
-run "echo 'export DOCKER_CREDS=\"$REGISTRY_USER:$REGISTRY_PWD\"' > $BUILDBOT_PATH/master/credentials.cfg"
-run "echo 'export S3_BUCKET=\"$REGISTRY_BUCKET\"' >> $BUILDBOT_PATH/master/credentials.cfg"
-run "echo 'export S3_ACCESS_KEY=\"$REGISTRY_ACCESS_KEY\"' >> $BUILDBOT_PATH/master/credentials.cfg"
-run "echo 'export S3_SECRET_KEY=\"$REGISTRY_SECRET_KEY\"' >> $BUILDBOT_PATH/master/credentials.cfg"
-
-# Patch github webstatus to capture pull requests
-cp $CFG_PATH/github.py /usr/local/lib/python2.7/dist-packages/buildbot/status/web/hooks
-
-# Allow buildbot subprocesses (docker tests) to properly run in containers,
-# in particular with docker -u
-run "sed -i 's/^umask = None/umask = 000/' slave/buildbot.tac"
-
-# Setup supervisor
-cp $CFG_PATH/buildbot.conf /etc/supervisor/conf.d/buildbot.conf
-sed -i -E "s/^chmod=0700.+/chmod=0770\nchown=root:$USER/" /etc/supervisor/supervisord.conf
-kill -HUP $(pgrep -f "/usr/bin/python /usr/bin/supervisord")

+ 22 - 0
hack/infrastructure/docker-ci/dcr/prod/docker-ci.yml

@@ -0,0 +1,22 @@
+docker-ci:
+  image: "docker-ci/docker-ci"
+  release_name: "docker-ci-0.5.6"
+  ports: ["80","2222:22","8011:8011"]
+  register: "80"
+  volumes: ["/run:/var/socket","/home/docker-ci:/data/docker-ci"]
+  command: []
+  env:
+    - "DEPLOYMENT=production"
+    - "IRC_CHANNEL=docker-testing"
+    - "BACKUP_BUCKET=backup-ci"
+    - "$WEB_USER"
+    - "$WEB_IRC_PWD"
+    - "$BUILDBOT_PWD"
+    - "$AWS_ACCESS_KEY"
+    - "$AWS_SECRET_KEY"
+    - "$GPG_PASSPHRASE"
+    - "$BACKUP_AWS_ID"
+    - "$BACKUP_AWS_SECRET"
+    - "$SMTP_USER"
+    - "$SMTP_PWD"
+    - "$EMAIL_RCP"

+ 5 - 0
hack/infrastructure/docker-ci/dcr/prod/settings.yml

@@ -0,0 +1,5 @@
+default:
+  hipaches: ['192.168.100.67:6379']
+  daemons: ['192.168.100.67:4243']
+  use_ssh: False
+

+ 22 - 0
hack/infrastructure/docker-ci/dcr/stage/docker-ci.yml

@@ -0,0 +1,22 @@
+docker-ci:
+  image: "docker-ci/docker-ci"
+  release_name: "docker-ci-stage"
+  ports: ["80","2222:22","8011:8011"]
+  register: "80"
+  volumes: ["/run:/var/socket","/home/docker-ci:/data/docker-ci"]
+  command: []
+  env:
+    - "DEPLOYMENT=staging"
+    - "IRC_CHANNEL=docker-testing-staging"
+    - "BACKUP_BUCKET=ci-backup-stage"
+    - "$BACKUP_AWS_ID"
+    - "$BACKUP_AWS_SECRET"
+    - "$WEB_USER"
+    - "$WEB_IRC_PWD"
+    - "$BUILDBOT_PWD"
+    - "$AWS_ACCESS_KEY"
+    - "$AWS_SECRET_KEY"
+    - "$GPG_PASSPHRASE"
+    - "$SMTP_USER"
+    - "$SMTP_PWD"
+    - "$EMAIL_RCP"

+ 5 - 0
hack/infrastructure/docker-ci/dcr/stage/settings.yml

@@ -0,0 +1,5 @@
+default:
+  hipaches: ['192.168.100.65:6379']
+  daemons: ['192.168.100.65:4243']
+  use_ssh: False
+

+ 0 - 171
hack/infrastructure/docker-ci/deployment.py

@@ -1,171 +0,0 @@
-#!/usr/bin/env python
-
-import os, sys, re, json, requests, base64
-from subprocess import call
-from fabric import api
-from fabric.api import cd, run, put, sudo
-from os import environ as env
-from datetime import datetime
-from time import sleep
-
-# Remove SSH private key as it needs more processing
-CONFIG = json.loads(re.sub(r'("DOCKER_CI_KEY".+?"(.+?)",)','',
-    env['CONFIG_JSON'], flags=re.DOTALL))
-
-# Populate environment variables
-for key in CONFIG:
-    env[key] = CONFIG[key]
-
-# Load SSH private key
-env['DOCKER_CI_KEY'] = re.sub('^.+"DOCKER_CI_KEY".+?"(.+?)".+','\\1',
-    env['CONFIG_JSON'],flags=re.DOTALL)
-
-DROPLET_NAME = env.get('DROPLET_NAME','docker-ci')
-TIMEOUT = 120            # Seconds before timeout droplet creation
-IMAGE_ID = 1004145       # Docker on Ubuntu 13.04
-REGION_ID = 4            # New York 2
-SIZE_ID = 62             # memory 2GB
-DO_IMAGE_USER = 'root'   # Image user on Digital Ocean
-API_URL = 'https://api.digitalocean.com/'
-DOCKER_PATH = '/go/src/github.com/dotcloud/docker'
-DOCKER_CI_PATH = '/docker-ci'
-CFG_PATH = '{}/buildbot'.format(DOCKER_CI_PATH)
-
-
-class DigitalOcean():
-
-    def __init__(self, key, client):
-        '''Set default API parameters'''
-        self.key = key
-        self.client = client
-        self.api_url = API_URL
-
-    def api(self, cmd_path, api_arg={}):
-        '''Make api call'''
-        api_arg.update({'api_key':self.key, 'client_id':self.client})
-        resp = requests.get(self.api_url + cmd_path, params=api_arg).text
-        resp = json.loads(resp)
-        if resp['status'] != 'OK':
-            raise Exception(resp['error_message'])
-        return resp
-
-    def droplet_data(self, name):
-        '''Get droplet data'''
-        data = self.api('droplets')
-        data = [droplet for droplet in data['droplets']
-            if droplet['name'] == name]
-        return data[0] if data else {}
-
-
-def json_fmt(data):
-    '''Format json output'''
-    return json.dumps(data, sort_keys = True, indent = 2)
-
-
-do = DigitalOcean(env['DO_API_KEY'], env['DO_CLIENT_ID'])
-
-# Get DROPLET_NAME data
-data = do.droplet_data(DROPLET_NAME)
-
-# Stop processing if DROPLET_NAME exists on Digital Ocean
-if data:
-    print ('Droplet: {} already deployed. Not further processing.'
-        .format(DROPLET_NAME))
-    exit(1)
-
-# Create droplet
-do.api('droplets/new', {'name':DROPLET_NAME, 'region_id':REGION_ID,
-    'image_id':IMAGE_ID, 'size_id':SIZE_ID,
-    'ssh_key_ids':[env['DOCKER_KEY_ID']]})
-
-# Wait for droplet to be created.
-start_time = datetime.now()
-while (data.get('status','') != 'active' and (
- datetime.now()-start_time).seconds < TIMEOUT):
-    data = do.droplet_data(DROPLET_NAME)
-    print data['status']
-    sleep(3)
-
-# Wait for the machine to boot
-sleep(15)
-
-# Get droplet IP
-ip = str(data['ip_address'])
-print 'droplet: {}    ip: {}'.format(DROPLET_NAME, ip)
-
-# Create docker-ci ssh private key so docker-ci docker container can communicate
-# with its EC2 instance
-os.makedirs('/root/.ssh')
-open('/root/.ssh/id_rsa','w').write(env['DOCKER_CI_KEY'])
-os.chmod('/root/.ssh/id_rsa',0600)
-open('/root/.ssh/config','w').write('StrictHostKeyChecking no\n')
-
-api.env.host_string = ip
-api.env.user = DO_IMAGE_USER
-api.env.key_filename = '/root/.ssh/id_rsa'
-
-# Correct timezone
-sudo('echo "America/Los_Angeles" >/etc/timezone')
-sudo('dpkg-reconfigure --frontend noninteractive tzdata')
-
-# Load public docker-ci key
-sudo("echo '{}' >> /root/.ssh/authorized_keys".format(env['DOCKER_CI_PUB']))
-
-# Create docker nightly release credentials file
-credentials = {
-    'AWS_ACCESS_KEY': env['PKG_ACCESS_KEY'],
-    'AWS_SECRET_KEY': env['PKG_SECRET_KEY'],
-    'GPG_PASSPHRASE': env['PKG_GPG_PASSPHRASE']}
-open(DOCKER_CI_PATH + '/nightlyrelease/release_credentials.json', 'w').write(
-    base64.b64encode(json.dumps(credentials)))
-
-# Transfer docker
-sudo('mkdir -p ' + DOCKER_CI_PATH)
-sudo('chown {}.{} {}'.format(DO_IMAGE_USER, DO_IMAGE_USER, DOCKER_CI_PATH))
-call('/usr/bin/rsync -aH {} {}@{}:{}'.format(DOCKER_CI_PATH, DO_IMAGE_USER, ip,
-    os.path.dirname(DOCKER_CI_PATH)), shell=True)
-
-# Install Docker and Buildbot dependencies
-sudo('mkdir /mnt/docker; ln -s /mnt/docker /var/lib/docker')
-sudo('apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9')
-sudo('echo deb https://get.docker.io/ubuntu docker main >'
-    ' /etc/apt/sources.list.d/docker.list')
-sudo('echo -e "deb http://archive.ubuntu.com/ubuntu raring main universe\n'
-    'deb http://us.archive.ubuntu.com/ubuntu/ raring-security main universe\n"'
-    ' > /etc/apt/sources.list; apt-get update')
-sudo('DEBIAN_FRONTEND=noninteractive apt-get install -q -y wget python-dev'
-    ' python-pip supervisor git mercurial linux-image-extra-$(uname -r)'
-    ' aufs-tools make libfontconfig libevent-dev libsqlite3-dev libssl-dev')
-sudo('wget -O - https://go.googlecode.com/files/go1.2.linux-amd64.tar.gz | '
-    'tar -v -C /usr/local -xz; ln -s /usr/local/go/bin/go /usr/bin/go')
-sudo('GOPATH=/go go get -d github.com/dotcloud/docker')
-sudo('pip install -r {}/requirements.txt'.format(CFG_PATH))
-
-# Install docker and testing dependencies
-sudo('apt-get install -y -q lxc-docker')
-sudo('curl -s https://phantomjs.googlecode.com/files/'
-    'phantomjs-1.9.1-linux-x86_64.tar.bz2 | tar jx -C /usr/bin'
-    ' --strip-components=2 phantomjs-1.9.1-linux-x86_64/bin/phantomjs')
-
-# Build docker-ci containers
-sudo('cd {}; docker build -t docker .'.format(DOCKER_PATH))
-sudo('cd {}; docker build -t docker-ci .'.format(DOCKER_CI_PATH))
-sudo('cd {}/nightlyrelease; docker build -t dockerbuilder .'.format(
-    DOCKER_CI_PATH))
-sudo('cd {}/registry-coverage; docker build -t registry_coverage .'.format(
-    DOCKER_CI_PATH))
-
-# Download docker-ci testing container
-sudo('docker pull mzdaniel/test_docker')
-
-# Setup buildbot
-sudo('mkdir /data')
-sudo('{0}/setup.sh root {0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10}'
-    ' {11} {12}'.format(CFG_PATH, DOCKER_PATH, env['BUILDBOT_PWD'],
-    env['IRC_PWD'], env['IRC_CHANNEL'], env['SMTP_USER'],
-    env['SMTP_PWD'], env['EMAIL_RCP'], env['REGISTRY_USER'],
-    env['REGISTRY_PWD'], env['REGISTRY_BUCKET'], env['REGISTRY_ACCESS_KEY'],
-    env['REGISTRY_SECRET_KEY']))
-
-# Preventively reboot docker-ci daily
-sudo('ln -s /sbin/reboot /etc/cron.daily')

+ 0 - 32
hack/infrastructure/docker-ci/docker-coverage/coverage-docker.sh

@@ -1,32 +0,0 @@
-#!/usr/bin/env bash
-
-set -x
-# Generate a random string of $1 characters
-function random {
-    cat /dev/urandom | tr -cd 'a-f0-9' | head -c $1
-}
-
-# Compute test paths
-BASE_PATH=`pwd`/test_docker_$(random 12)
-DOCKER_PATH=$BASE_PATH/go/src/github.com/dotcloud/docker
-export GOPATH=$BASE_PATH/go:$DOCKER_PATH/vendor
-
-# Fetch latest master
-mkdir -p $DOCKER_PATH
-cd $DOCKER_PATH
-git init .
-git fetch -q http://github.com/dotcloud/docker master
-git reset --hard FETCH_HEAD
-
-# Fetch go coverage
-cd $BASE_PATH/go
-GOPATH=$BASE_PATH/go go get github.com/axw/gocov/gocov
-sudo -E GOPATH=$GOPATH ./bin/gocov test -deps -exclude-goroot -v\
- -exclude github.com/gorilla/context,github.com/gorilla/mux,github.com/kr/pty,\
-code.google.com/p/go.net/websocket\
- github.com/dotcloud/docker | ./bin/gocov report; exit_status=$?
-
-# Cleanup testing directory
-rm -rf $BASE_PATH
-
-exit $exit_status

+ 0 - 25
hack/infrastructure/docker-ci/docker-test/Dockerfile

@@ -1,25 +0,0 @@
-# VERSION:        0.4
-# DOCKER-VERSION  0.6.6
-# AUTHOR:         Daniel Mizyrycki <daniel@docker.com>
-# DESCRIPTION:    Testing docker PRs and commits on top of master using
-# REFERENCES:     This code reuses the excellent implementation of
-#                 Docker in Docker made by Jerome Petazzoni.
-#                 https://github.com/jpetazzo/dind
-# COMMENTS:
-#   This Dockerfile adapts /Dockerfile to enable docker PRs and commits testing
-#   Optional arguments:
-#       [commit]  (default: 'HEAD')
-#       [repo]    (default: 'http://github.com/dotcloud/docker')
-#       [branch]  (default: 'master')
-# TO_BUILD:       docker build -t test_docker .
-# TO_RUN:         docker run -privileged test_docker hack/dind test_docker.sh [commit] [repo] [branch]
-
-from docker
-maintainer Daniel Mizyrycki <daniel@docker.com>
-
-# Setup go in PATH. Extracted from /Dockerfile
-env PATH /usr/local/go/bin:$PATH
-
-# Add test_docker.sh
-add test_docker.sh /usr/bin/test_docker.sh
-run chmod +x /usr/bin/test_docker.sh

+ 0 - 33
hack/infrastructure/docker-ci/docker-test/test_docker.sh

@@ -1,33 +0,0 @@
-#!/usr/bin/env bash
-
-set -x
-COMMIT=${1-HEAD}
-REPO=${2-http://github.com/dotcloud/docker}
-BRANCH=${3-master}
-
-# Compute test paths
-DOCKER_PATH=/go/src/github.com/dotcloud/docker
-
-# Timestamp
-echo
-date; echo
-
-# Fetch latest master
-cd /
-rm -rf /go
-git clone -q -b master http://github.com/dotcloud/docker $DOCKER_PATH
-cd $DOCKER_PATH
-
-# Merge commit
-git fetch -q "$REPO" "$BRANCH"
-git merge --no-edit $COMMIT || exit 255
-
-# Test commit
-./hack/make.sh test; exit_status=$?
-
-# Display load if test fails
-if [ $exit_status -ne 0 ] ; then
-    uptime; echo; free
-fi
-
-exit $exit_status

+ 1 - 0
hack/infrastructure/docker-ci/dockertest/docker

@@ -0,0 +1 @@
+project

+ 1 - 0
hack/infrastructure/docker-ci/dockertest/docker-registry

@@ -0,0 +1 @@
+project

+ 13 - 0
hack/infrastructure/docker-ci/dockertest/nightlyrelease

@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+if [ "$DEPLOYMENT" == "production" ]; then
+    AWS_S3_BUCKET='test.docker.io'
+else
+    AWS_S3_BUCKET='get-staging.docker.io'
+fi
+
+docker run -rm -privileged -v /run:/var/socket \
+    -e AWS_S3_BUCKET=$AWS_S3_BUCKET -e AWS_ACCESS_KEY=$AWS_ACCESS_KEY \
+    -e AWS_SECRET_KEY=$AWS_SECRET_KEY -e GPG_PASSPHRASE=$GPG_PASSPHRASE \
+    -e DOCKER_RELEASE=1 -e DEPLOYMENT=$DEPLOYMENT docker-ci/testbuilder docker
+

+ 8 - 0
hack/infrastructure/docker-ci/dockertest/project

@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+set -x
+
+PROJECT_NAME=$(basename $0)
+
+docker run -rm -u sysadmin -e DEPLOYMENT=$DEPLOYMENT -v /run:/var/socket \
+    -v /home/docker-ci/coverage/$PROJECT_NAME:/data docker-ci/testbuilder $PROJECT_NAME $1 $2 $3
+

+ 12 - 0
hack/infrastructure/docker-ci/nginx/nginx.conf

@@ -0,0 +1,12 @@
+server {
+    listen              80;
+    root /data/docker-ci;
+
+    location / {
+        proxy_pass http://localhost:8000/;
+    }
+
+    location /coverage {
+        root /data/docker-ci;
+    }
+}

+ 0 - 30
hack/infrastructure/docker-ci/nightlyrelease/Dockerfile

@@ -1,30 +0,0 @@
-# VERSION:        1.6
-# DOCKER-VERSION  0.6.6
-# AUTHOR:         Daniel Mizyrycki <daniel@docker.com>
-# DESCRIPTION:    Build docker nightly release using Docker in Docker.
-# REFERENCES:     This code reuses the excellent implementation of docker in docker
-#                 made by Jerome Petazzoni.  https://github.com/jpetazzo/dind
-# COMMENTS:
-#   release_credentials.json is a base64 json encoded file containing:
-#       { "AWS_ACCESS_KEY": "Test_docker_AWS_S3_bucket_id",
-#         "AWS_SECRET_KEY": "Test_docker_AWS_S3_bucket_key",
-#         "GPG_PASSPHRASE": "Test_docker_GPG_passphrase_signature" }
-# TO_BUILD:       docker build -t dockerbuilder .
-# TO_RELEASE:     docker run -i -t -privileged -e AWS_S3_BUCKET="test.docker.io" dockerbuilder hack/dind dockerbuild.sh
-
-from docker
-maintainer Daniel Mizyrycki <daniel@docker.com>
-
-# Add docker dependencies and downloading packages
-run echo 'deb http://archive.ubuntu.com/ubuntu precise main universe' > /etc/apt/sources.list
-run apt-get update; apt-get install -y -q wget python2.7
-
-# Add production docker binary
-run wget -q -O /usr/bin/docker http://get.docker.io/builds/Linux/x86_64/docker-latest; chmod +x /usr/bin/docker
-
-# Add proto docker builder
-add ./dockerbuild.sh /usr/bin/dockerbuild.sh
-run chmod +x /usr/bin/dockerbuild.sh
-
-# Add release credentials
-add ./release_credentials.json /root/release_credentials.json

+ 0 - 40
hack/infrastructure/docker-ci/nightlyrelease/dockerbuild.sh

@@ -1,40 +0,0 @@
-#!/usr/bin/env bash
-
-# Variables AWS_ACCESS_KEY, AWS_SECRET_KEY and PG_PASSPHRASE are decoded
-# from /root/release_credentials.json
-# Variable AWS_S3_BUCKET is passed to the environment from docker run -e
-
-# Turn debug off to load credentials from the environment
-set +x
-eval $(cat /root/release_credentials.json  | python -c '
-import sys,json,base64;
-d=json.loads(base64.b64decode(sys.stdin.read()));
-exec("""for k in d: print "export {0}=\\"{1}\\"".format(k,d[k])""")')
-
-# Fetch docker master branch
-set -x
-cd /
-rm -rf /go
-git clone -q -b master http://github.com/dotcloud/docker /go/src/github.com/dotcloud/docker
-cd /go/src/github.com/dotcloud/docker
-
-# Launch docker daemon using dind inside the container
-/usr/bin/docker version
-/usr/bin/docker -d &
-sleep 5
-
-# Build Docker release container
-docker build -t docker .
-
-# Test docker and if everything works well, release
-echo docker run -i -t -privileged -e AWS_S3_BUCKET=$AWS_S3_BUCKET -e AWS_ACCESS_KEY=XXXXX -e AWS_SECRET_KEY=XXXXX -e GPG_PASSPHRASE=XXXXX docker hack/release.sh
-set +x
-docker run -privileged -i -t -e AWS_S3_BUCKET=$AWS_S3_BUCKET -e AWS_ACCESS_KEY=$AWS_ACCESS_KEY -e AWS_SECRET_KEY=$AWS_SECRET_KEY -e GPG_PASSPHRASE=$GPG_PASSPHRASE docker hack/release.sh
-exit_status=$?
-
-# Display load if test fails
-set -x
-if [ $exit_status -ne 0 ] ; then
-    uptime; echo; free
-    exit 1
-fi

+ 0 - 18
hack/infrastructure/docker-ci/registry-coverage/Dockerfile

@@ -1,18 +0,0 @@
-# VERSION:        0.1
-# DOCKER-VERSION  0.6.4
-# AUTHOR:         Daniel Mizyrycki <daniel@dotcloud.com>
-# DESCRIPTION:    Docker registry coverage
-# COMMENTS:       Add registry coverage into the docker-ci image
-# TO_BUILD:       docker build -t registry_coverage .
-# TO_RUN:         docker run registry_coverage
-
-from docker-ci
-maintainer Daniel Mizyrycki <daniel@dotcloud.com>
-
-# Add registry_coverager.sh and dependencies
-run pip install coverage flask pyyaml requests simplejson python-glanceclient \
-    blinker redis boto gevent rsa mock
-add registry_coverage.sh /usr/bin/registry_coverage.sh
-run chmod +x /usr/bin/registry_coverage.sh
-
-cmd "/usr/bin/registry_coverage.sh"

+ 0 - 18
hack/infrastructure/docker-ci/registry-coverage/registry_coverage.sh

@@ -1,18 +0,0 @@
-#!/usr/bin/env bash
-
-set -x
-
-# Setup the environment
-REGISTRY_PATH=/data/docker-registry
-export SETTINGS_FLAVOR=test
-export DOCKER_REGISTRY_CONFIG=config_test.yml
-export PYTHONPATH=$REGISTRY_PATH/test
-
-# Fetch latest docker-registry master
-rm -rf $REGISTRY_PATH
-git clone https://github.com/dotcloud/docker-registry -b master $REGISTRY_PATH
-cd $REGISTRY_PATH
-
-# Generate coverage
-coverage run -m unittest discover test || exit 1
-coverage report --include='./*' --omit='./test/*'

+ 54 - 0
hack/infrastructure/docker-ci/setup.sh

@@ -0,0 +1,54 @@
+#!/usr/bin/env bash
+
+# Set timezone
+echo "GMT" >/etc/timezone
+dpkg-reconfigure --frontend noninteractive tzdata
+
+# Set ssh superuser
+mkdir -p /data/buildbot /var/run/sshd /run
+useradd -m -d /home/sysadmin -s /bin/bash -G sudo,docker -p '*' sysadmin
+sed -Ei 's/(\%sudo.*) ALL/\1 NOPASSWD:ALL/' /etc/sudoers
+cd /home/sysadmin
+mkdir .ssh
+chmod 700 .ssh
+cat > .ssh/authorized_keys << 'EOF'
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC7ALVhwQ68q1SjrKaAduOuOEAcWmb8kDZf5qA7T1fM8AP07EDC7nSKRJ8PXUBGTOQfxm89coJDuSJsTAZ+1PvglXhA0Mq6+knc6ZrZY+SuZlDIDAk4TOdVPoDZnmR1YW2McxHkhcGIOKeC8MMig5NeEjtgQwXzauUSPqeh8HMlLZRMooFYyyluIpn7NaCLzyWjwAQz2s3KyI7VE7hl+ncCrW86v+dciEdwqtzNoUMFb3iDpPxaiCl3rv+SB7co/5eUDTs1FZvUcYMXKQuf8R+2ZKzXOpwr0Zs8sKQXvXavCeWykwGgXLBjVkvrDcHuDD6UXCW63UKgmRECpLZaMBVIIRWLEEgTS5OSQTcxpMVe5zUW6sDvXHTcdPwWrcn1dE9F/0vLC0HJ4ADKelLX5zyTpmXGbuZuntIf1JO67D/K/P++uV1rmVIH+zgtOf23w5rX2zKb4BSTqP0sv61pmWV7MEVoEz6yXswcTjS92tb775v7XLU9vKAkt042ORFdE4/++hejhL/Lj52IRgjt1CJZHZsR9JywJZrz3kYuf8eU2J2FYh0Cpz5gmf0f+12Rt4HztnZxGPP4KuMa66e4+hpx1jynjMZ7D5QUnNYEmuvJByopn8HSluuY/kS5MMyZCZtJLEPGX4+yECX0Di/S0vCRl2NyqfCBqS+yXXT5SA1nFw== docker-test@docker.io
+EOF
+chmod 600 .ssh/authorized_keys
+chown -R sysadmin .ssh
+
+# Fix docker group id for use of host dockerd by sysadmin
+sed -Ei 's/(docker:x:)[^:]+/\1999/' /etc/group
+
+# Create buildbot configuration
+cd /data/buildbot; buildbot create-master master
+cp -a /data/buildbot/master/master.cfg.sample \
+    /data/buildbot/master/master.cfg
+cd /data/buildbot; \
+    buildslave create-slave slave localhost:9989 buildworker pass
+cp /docker-ci/buildbot/master.cfg /data/buildbot/master
+
+# Patch github webstatus to capture pull requests
+cp /docker-ci/buildbot/github.py /usr/local/lib/python2.7/dist-packages/buildbot/status/web/hooks
+chown -R sysadmin.sysadmin /data
+
+# Create nginx configuration
+rm /etc/nginx/sites-enabled/default
+cp /docker-ci/nginx/nginx.conf /etc/nginx/conf.d/buildbot.conf
+/bin/echo -e '\ndaemon off;\n' >> /etc/nginx/nginx.conf
+
+# Set supervisord buildbot, nginx and sshd processes
+/bin/echo -e "\
+[program:buildmaster]\n\
+command=twistd --nodaemon --no_save -y buildbot.tac\n\
+directory=/data/buildbot/master\n\
+user=sysadmin\n\n\
+[program:buildworker]\n\
+command=twistd --nodaemon --no_save -y buildbot.tac\n\
+directory=/data/buildbot/slave\n\
+user=sysadmin\n" > \
+    /etc/supervisor/conf.d/buildbot.conf
+/bin/echo -e "[program:nginx]\ncommand=/usr/sbin/nginx\n" > \
+    /etc/supervisor/conf.d/nginx.conf
+/bin/echo -e "[program:sshd]\ncommand=/usr/sbin/sshd -D\n" > \
+    /etc/supervisor/conf.d/sshd.conf

+ 12 - 0
hack/infrastructure/docker-ci/testbuilder/Dockerfile

@@ -0,0 +1,12 @@
+# TO_BUILD:      docker build -rm -no-cache -t docker-ci/testbuilder .
+# TO_RUN:        docker run -rm -u sysadmin \
+#                -v /run:/var/socket docker-ci/testbuilder docker-registry
+#
+
+FROM docker-ci/docker-ci
+ENV HOME /home/sysadmin
+
+RUN mkdir /testbuilder
+ADD . /testbuilder
+
+ENTRYPOINT ["/testbuilder/testbuilder.sh"]

+ 12 - 0
hack/infrastructure/docker-ci/testbuilder/docker-registry.sh

@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+set -x
+set -e
+PROJECT_PATH=$1
+
+# Build the docker project
+cd /data/$PROJECT_PATH
+sg docker -c "docker build -q -rm -t registry ."
+cd test; sg docker -c "docker build -q -rm -t docker-registry-test ."
+
+# Run the tests
+sg docker -c "docker run -rm -v /home/docker-ci/coverage/docker-registry:/data docker-registry-test"

+ 18 - 0
hack/infrastructure/docker-ci/testbuilder/docker.sh

@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+set -x
+set -e
+PROJECT_PATH=$1
+
+# Build the docker project
+cd /data/$PROJECT_PATH
+sg docker -c "docker build -q -rm -t docker ."
+
+if [ "$DOCKER_RELEASE" == "1" ]; then
+    # Do nightly release
+    echo sg docker -c "docker run -rm -privileged -v /run:/var/socket -e AWS_S3_BUCKET=$AWS_S3_BUCKET -e AWS_ACCESS_KEY= -e AWS_SECRET_KEY= -e GPG_PASSPHRASE= docker hack/release.sh"
+    set +x
+    sg docker -c "docker run -rm -privileged -v /run:/var/socket -e AWS_S3_BUCKET=$AWS_S3_BUCKET -e AWS_ACCESS_KEY=$AWS_ACCESS_KEY -e AWS_SECRET_KEY=$AWS_SECRET_KEY -e GPG_PASSPHRASE=$GPG_PASSPHRASE docker hack/release.sh"
+else
+    # Run the tests
+    sg docker -c "docker run -rm -privileged -v /home/docker-ci/coverage/docker:/data docker ./hack/infrastructure/docker-ci/docker-coverage/gocoverage.sh"
+fi

+ 40 - 0
hack/infrastructure/docker-ci/testbuilder/testbuilder.sh

@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+# Download,  build and run a docker project tests
+# Environment variables: DEPLOYMENT
+
+cat $0
+set -e
+set -x
+
+PROJECT=$1
+COMMIT=${2-HEAD}
+REPO=${3-https://github.com/dotcloud/$PROJECT}
+BRANCH=${4-master}
+REPO_PROJ="https://github.com/docker-test/$PROJECT"
+if [ "$DEPLOYMENT" == "production" ]; then
+    REPO_PROJ="https://github.com/dotcloud/$PROJECT"
+fi
+set +x
+
+# Generate a random string of $1 characters
+function random {
+    cat /dev/urandom | tr -cd 'a-f0-9' | head -c $1
+}
+
+PROJECT_PATH="$PROJECT-tmp-$(random 12)"
+
+# Set docker-test git user
+set -x
+git config --global user.email "docker-test@docker.io"
+git config --global user.name "docker-test"
+
+# Fetch project
+git clone -q $REPO_PROJ -b master /data/$PROJECT_PATH
+cd /data/$PROJECT_PATH
+echo "Git commit: $(git rev-parse HEAD)"
+git fetch -q $REPO $BRANCH
+git merge --no-edit $COMMIT
+
+# Build the project dockertest
+/testbuilder/$PROJECT.sh $PROJECT_PATH
+rm -rf /data/$PROJECT_PATH

+ 47 - 0
hack/infrastructure/docker-ci/tool/backup.py

@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+
+import os,sys,json
+from datetime import datetime
+from filecmp import cmp
+from subprocess import check_call
+from boto.s3.key import Key
+from boto.s3.connection import S3Connection
+
+def ENV(x):
+    '''Promote an environment variable for global use returning its value'''
+    retval = os.environ.get(x, '')
+    globals()[x] = retval
+    return retval
+
+ROOT_PATH = '/data/backup/docker-ci'
+TODAY = str(datetime.today())[:10]
+BACKUP_FILE = '{}/docker-ci_{}.tgz'.format(ROOT_PATH, TODAY)
+BACKUP_LINK = '{}/docker-ci.tgz'.format(ROOT_PATH)
+ENV('BACKUP_BUCKET')
+ENV('BACKUP_AWS_ID')
+ENV('BACKUP_AWS_SECRET')
+
+'''Create full master buildbot backup, avoiding duplicates'''
+# Ensure backup path exist
+if not os.path.exists(ROOT_PATH):
+    os.makedirs(ROOT_PATH)
+# Make actual backups
+check_call('/bin/tar czf {} -C /data --exclude=backup --exclude=buildbot/slave'
+    ' . 1>/dev/null 2>&1'.format(BACKUP_FILE),shell=True)
+# remove previous dump if it is the same as the latest
+if (os.path.exists(BACKUP_LINK) and cmp(BACKUP_FILE, BACKUP_LINK) and
+ os.path._resolve_link(BACKUP_LINK) != BACKUP_FILE):
+    os.unlink(os.path._resolve_link(BACKUP_LINK))
+# Recreate backup link pointing to latest backup
+try:
+    os.unlink(BACKUP_LINK)
+except:
+    pass
+os.symlink(BACKUP_FILE, BACKUP_LINK)
+
+# Make backup on S3
+bucket = S3Connection(BACKUP_AWS_ID,BACKUP_AWS_SECRET).get_bucket(BACKUP_BUCKET)
+k = Key(bucket)
+k.key = BACKUP_FILE
+k.set_contents_from_filename(BACKUP_FILE)
+bucket.copy_key(os.path.basename(BACKUP_LINK),BACKUP_BUCKET,BACKUP_FILE[1:])