commit 38639fed9957f40c71ab1cd0ab767c33c79ca6b6
Date: Thu Nov 5 07:54:35 2015 +0100
jenkins: no longer use jenkins
diff --git a/ChangeLog b/ChangeLog
index 3efedea..712739e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,4 @@
-commit c9ed7e52758997a38724d549d764fa6d9b3b3193
+commit 36232fe550a9a07bbfcfdcdec6fd651186ba2635
Date: Tue Apr 28 12:04:04 2015 +0200
diff --git a/ceph_workbench/jenkins.py b/ceph_workbench/jenkins.py
deleted file mode 100644
index e01df85..0000000
--- a/ceph_workbench/jenkins.py
+++ /dev/null
@@ -1,575 +0,0 @@
-# -*- mode: python; coding: utf-8 -*-
-#
-#
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see `<http://www.gnu.org/licenses/>`.
-#
-import argparse
-import grp
-import json
-import logging
-import os
-import re
-import requests
-import shutil
-import subprocess
-import time
-
-from ceph_workbench import util
-
-
-class NoCredentials(Exception):
- pass
-
-cred_template = """
-{
- "domainCredentials": {
- "domain": {
- "name": "",
- "description": ""
- },
- "credentials": [
- {
- "scope": "GLOBAL",
- "id": "",
- "username": "{USERNAME}",
- "description": "{DESCRIPTION}",
- "privateKeySource": {
- "value": "1",
- "privateKeyFile": "{KEY_FILE}",
- "stapler-class": "com.cloudbees.jenkins.plugins\
-.sshcredentials.impl.BasicSSHUserPrivateKey$FileOnMasterPrivateKeySource"
- },
- "passphrase": "",
- "stapler-class": "com.cloudbees.jenkins.plugins\
-.sshcredentials.impl.BasicSSHUserPrivateKey",
- "kind": "com.cloudbees.jenkins.plugins\
-.sshcredentials.impl.BasicSSHUserPrivateKey"
- }
- ]
- }
-}
-"""
-
-
-class Jenkins:
-
- def __init__(self, args):
- self.args = args
- self.args.port_range = 3000
- self.args.jenkins_slave = 'ceph-jenkins-slave'
- self.args.jenkins_master = 'ceph-jenkins-master'
- self.args.libguestfs = 'libguestfs'
- self.args.jar_dir = '/tmp'
-
- def run(self):
- if self.args.publish_build_to_pull_request:
- return self.publish_build_to_pull_request()
- elif self.args.jenkins_make_check_bot:
- return subprocess.call([self.args.libdir +
- '/docker-make-check-bot'])
- elif self.args.jenkins_docker_run_slave:
- return self.run_slave('docker', self.args.jenkins_docker_run_slave)
- elif self.args.jenkins_qemu_prepare:
- return self.prepare_qemu_img(self.args.jenkins_qemu_image)
- elif self.args.jenkins_qemu_run_slave:
- return self.run_slave('qemu', self.args.jenkins_qemu_run_slave)
- elif self.args.jenkins_docker_destroy_slave:
- return self.docker_destroy_slave(
- self.args.jenkins_docker_destroy_slave)
- elif self.args.jenkins_run_master:
- return self.run_master()
-
- @staticmethod
- def get_parser():
- parser = argparse.ArgumentParser(
- description="Jenkins",
- conflict_handler='resolve',
- )
- parser.add_argument('--jenkins-run-master',
- action='store_true',
- help='run the jenkins master')
- parser.add_argument('--jenkins-docker-run-slave',
- help=('run the jenkins slave in docker and '
- 'register it to the jenkins master'))
- parser.add_argument('--jenkins-docker-destroy-slave',
- help='destroy the jenkins docker slave')
- parser.add_argument('--jenkins-qemu-run-slave',
- help=('run the jenkins slave in qemu and '
- 'register it to the jenkins master'))
- parser.add_argument('--jenkins-qemu-prepare',
- action='store_true',
- help=('create a directory with '
- 'a ready to use image'))
- parser.add_argument('--jenkins-qemu-image',
- help='for instance ubuntu-14.04-i386')
- parser.add_argument('--jenkins-qemu-ram',
- default='512',
- help='RAM for qemu, in GB')
- parser.add_argument('--jenkins-qemu-ssh-port',
- help='ssh port to connect to the qemu instance')
- parser.add_argument('--jenkins-make-check-bot',
- help='run the jenkins-make-check-bot helper')
- parser.add_argument('--publish-build-to-pull-request',
- help='add a comment to pull request XXX')
- parser.add_argument('--jenkins-git-branch',
- help=('only for --publish-build-to-pull-request, '
- 'force the GIT_BRANCH value'))
- parser.add_argument('--jenkins-host',
- help='hostname of the jenkins master')
- parser.add_argument('--jenkins-port',
- default='80',
- help='port of the jenkins master')
- parser.add_argument('--jenkins-ssh-host',
- help='jenkins host name for ssh protocol')
- parser.add_argument('--jenkins-ssh-port',
- default='22',
- help='jenkins port for ssh protocol')
- parser.add_argument('--jenkins-ssh-key',
- help='jenkins ssh private key')
- parser.add_argument('--jenkins-user',
- help='jenkins user name for API authentication')
- parser.add_argument('--jenkins-password',
- help='jenkins password for API authentication')
- parser.add_argument('--github-repo',
- help='GitHub repo (for instance ceph/ceph)')
- parser.add_argument('--github-token',
- help='GitHub authentication token')
- parser.add_argument('--libdir',
- help='directory containing helpers programs')
- parser.add_argument('--datadir',
- help='directory for persistent data')
- parser.add_argument('--jenkins-home',
- help='jenkins home directory, on the docker host',
- default=os.environ['HOME'])
- return parser
-
- @staticmethod
- def factory(argv):
- return Jenkins(Jenkins.get_parser().parse_args(argv))
-
- def get_url(self):
- return ('http://' + self.args.jenkins_host +
- ':' + self.args.jenkins_port)
-
- def publish_build_to_pull_request(self):
- r = requests.get(self.get_url() + '/' +
- self.args.publish_build_to_pull_request + '/api/json')
- r.raise_for_status()
- report = r.json()
- logging.debug("publish_build_to_pull_request: downstream " +
- str(report))
- for action in report['actions']:
- if "causes" in action:
- cause = action['causes'][0]
- upstream = (cause['upstreamUrl'] + '/' +
- str(cause['upstreamBuild']))
- r = requests.get(self.get_url() + '/' + upstream + '/api/json')
- r.raise_for_status()
- report = r.json()
- logging.debug("publish_build_to_pull_request: upstream " + str(report))
- if self.args.jenkins_git_branch:
- branch_name = self.args.jenkins_git_branch
- else:
- for action in report['actions']:
- if "lastBuiltRevision" in action:
- branch = action["lastBuiltRevision"]["branch"][0]
- branch_name = branch['name']
- runs = {}
- for run in report['runs']:
- if run['number'] == report['number']:
- r = requests.get(run['url'] + 'api/json')
- r.raise_for_status()
- runs[run['url']] = r.json()['result']
- body = report['result'] + ": " + report['url'] + "\n"
- for url in sorted(runs):
- body += "* " + runs[url] + " " + url + "/console\n"
- logging.debug("publish_build_to_pull_request: " + body)
- if 'pull/' in branch_name:
- (pr,) = re.findall('\d+$', branch_name)
- payload = {'body': body}
- r = requests.post('https://api.github.com/repos/' +
- self.args.github_repo + '/issues/' +
- pr + '/comments?access_token=' +
- self.args.github_token,
- data=json.dumps(payload))
- r.raise_for_status()
- return r.json()['body']
- else:
- return body
-
- def get_cli_jar(self):
- return self.args.jar_dir + '/jenkins-cli.jar'
-
- def run_cli(self, *args, **kwargs):
- jar = self.get_cli_jar()
- if not os.path.exists(jar):
- r = requests.get(self.get_url() +
- '/jnlpJars/jenkins-cli.jar')
- with open(jar, 'wb') as fd:
- for chunk in r.iter_content(4096):
- fd.write(chunk)
- cmd = ['java', '-jar', jar, '-s', self.get_url()] + list(args)
- s = subprocess.Popen(cmd,
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- if 'payload' in kwargs:
- payload = kwargs['payload'].encode('utf-8')
- else:
- payload = None
- (stdoutdata, stderrdata) = s.communicate(input=payload)
- stdoutdata = stdoutdata.decode('utf-8')
- stderrdata = stderrdata.decode('utf-8')
- logging.debug(" ".join(cmd) + ":" +
- " stdout " + stdoutdata +
- " stderr " + stderrdata)
- return stdoutdata + stderrdata
-
- def master_port(self, name):
- (number,) = re.findall('(\d+)$', name)
- return str(self.args.port_range + int(number))
-
- def slave_port(self, name):
- (number,) = re.findall('(\d+)$', name)
- return str(4000 + int(number))
-
- def find_node(self, name):
- r = requests.get(self.get_url() + '/computer/api/json')
- r.raise_for_status()
- return name in map(lambda x: x['displayName'], r.json()['computer'])
-
- def destroy_node(self, name):
- if self.find_node(name):
- self.run_cli("delete-node", name)
-
- def next_node_name(self):
- r = requests.get(self.get_url() + '/computer/api/json')
- r.raise_for_status()
- nodes = r.json()['computer']
- highest = 0
- for node in nodes:
- name_with_number = re.findall('(\d+)$', node['displayName'])
- if name_with_number:
- highest = max(highest, int(name_with_number[0]))
- highest += 1
- return "slave%03d" % highest
-
- def create_node(self, name):
- # assume the master is running in docker and slaves are accessed
- # via a ssh tunel open on the docker host
- credentials = self.slave_credential_id()
- port = self.master_port(name)
- payload = """
-<?xml version="1.0" encoding="UTF-8"?>
-<slave>
- <name>{name}</name>
- <description></description>
- <remoteFS>/home/jenkins</remoteFS>
- <numExecutors>1</numExecutors>
- <mode>NORMAL</mode>
- <retentionStrategy class="hudson.slaves.RetentionStrategy$Always"/>
- <launcher class="hudson.plugins.sshslaves.SSHLauncher"
- <host>localhost</host>
- <port>{port}</port>
- <credentialsId>{credentials}</credentialsId>
- <maxNumRetries>0</maxNumRetries>
- <retryWaitTime>0</retryWaitTime>
- </launcher>
- <label>docker ceph-workbench</label>
- <nodeProperties/>
- <userId>admin</userId>
-</slave>
-""".format(port=port,
- name=name,
- credentials=credentials)
- logging.debug('create_node: ' + name + ' ' + payload)
- self.run_cli('create-node', name, payload=payload)
- r = requests.get(self.get_url() +
- '/computer/' + name + '/api/json')
- r.raise_for_status()
- return r.json()
-
- def run_slave(self, kind, name):
- if name == 'new':
- name = self.next_node_name()
- self.create_node(name)
- if kind == 'docker':
- return self.docker_run_slave(name)
- elif kind == 'qemu':
- return self.qemu_run_slave(name)
- else:
- raise Exception(kind + ' is not docker nor qemu')
-
- def slave_credential_id(self):
- auth = (self.args.jenkins_user, self.args.jenkins_password)
- r = requests.get(self.get_url() +
- '/credential-store/domain/_/api/json',
- auth=auth)
- r.raise_for_status()
- slave_description = 'for jenkins slaves'
- credentials = {}
- for credential in list(r.json()['credentials']):
- c = requests.get(self.get_url() +
- ('/credential-store/domain/_/credential/' +
- credential + '/api/json'),
- auth=auth)
- c.raise_for_status()
- credentials[c.json()['description']] = credential
-
- if slave_description in credentials:
- return credentials[slave_description]
- else:
- raise NoCredentials('no "' + slave_description +
- '" credential in ' +
- str(credentials))
-
- def fetch_ssh_key(self, directory):
- if not os.path.exists(directory):
- os.makedirs(directory, 0o755)
- dotssh = directory + '/.ssh'
- if not os.path.exists(dotssh):
- os.mkdir(dotssh, 0o700)
- if self.args.jenkins_ssh_key:
- key = '-i ' + self.args.jenkins_ssh_key + ' '
- else:
- key = ''
- if self.args.jenkins_ssh_port:
- port = '-P ' + self.args.jenkins_ssh_port + ' '
- else:
- port = ''
- known_hosts = self.ignore_known_hosts()
- util.sh('scp ' + known_hosts + key + port +
- self.args.jenkins_ssh_host +
- ':/var/jenkins_home/.ssh/id_rsa* ' +
- dotssh)
- shutil.copyfile(dotssh + '/id_rsa.pub',
- dotssh + '/authorized_keys')
- os.chmod(dotssh + '/authorized_keys', 0o600)
-
- @staticmethod
- def ignore_known_hosts():
- return ('-o UserKnownHostsFile=/dev/null '
- '-o StrictHostKeyChecking=no ')
-
- def tunnel(self, port):
- script = ("ssh {known_hosts} " +
- " -p {jenkins_port} -f -N -R {port}:localhost:22 " +
- " {jenkins_host}")
- return script.format(known_hosts=self.ignore_known_hosts(),
- port=port,
- jenkins_port=self.args.jenkins_ssh_port,
- jenkins_host=self.args.jenkins_ssh_host)
-
- def qemu_get_img(self):
- image = self.args.jenkins_qemu_image
- image_dir = self.args.datadir + "/" + image
- if (os.path.exists(image_dir) and
- os.path.exists(image_dir + '/.ssh')):
- return image_dir
- elif self.docker_p():
- return self.prepare_qemu_img(image)
- else:
- host = self.args.jenkins_ssh_host
- util.sh("rsync -avz " + host + ":" + image + "/ " +
- image_dir + "/")
- return image_dir
-
- def qemu_ssh(self, name, command):
- slave_port = self.slave_port(name)
- known_hosts = self.ignore_known_hosts()
- image = self.args.jenkins_qemu_image
- key = self.args.datadir + '/' + image + '/.ssh/id_rsa'
- return util.sh("ssh -p " + slave_port + " " + known_hosts + " " +
- " -i " + key + " jenkins@localhost " + command)
-
- def qemu_destroy_slave(self, name):
- self.qemu_ssh(name, 'sudo halt -p')
- return self.destroy_node(name)
-
- def qemu_run_slave(self, name):
- image = self.args.jenkins_qemu_image
- image_dir = self.qemu_get_img()
- ram = self.args.jenkins_qemu_ram
- if not os.path.exists(image_dir + '/' + image + '.img'):
- shutil.copyfile(image_dir + '/' + image + '.orig',
- image_dir + '/' + image + '.img')
- master_port = self.master_port(name)
- slave_port = self.slave_port(name)
- util.sh(('cd {image_dir} ; ' +
- 'kvm -name {name} ' +
- '-m {ram} -smp {cpus},sockets=1 ' +
- '-drive file={image}.img,if=virtio ' +
- '-net nic -net user,hostfwd=tcp::{slave_port}-:22 ' +
- '-kernel vmlinuz-* -initrd initrd.* ' +
- '-append "root=/dev/vda1 ro ds=nocloud-net ' +
- ' brd.rd_size={rd_size} ' +
- ' master_port={master_port}" ' +
- '-display none').format(ram=ram,
- slave_port=slave_port,
- master_port=master_port,
- name=name,
- cpus=str(8),
- rd_size=str(16 * 1024 * 1024),
- image=image,
- image_dir=image_dir))
-
- def prepare_qemu_img(self, image):
- self.docker_build_libguestfs()
- libdir = os.path.abspath(self.args.libdir)
- datadir = os.path.abspath(self.args.datadir)
- image_dir = datadir + '/' + image
- self.fetch_ssh_key(image_dir)
- script = """\
-#!/bin/sh -e
-mkfs -t ext4 /dev/ram1
-mkdir -p /home/jenkins/workspace
-mount /dev/ram1 /home/jenkins/workspace
-chown jenkins /home/jenkins/workspace
-port=$(perl -ne 'print if(s/.*master_port=([0-9]*).*/$1/)' < /proc/cmdline)
-if test "$port" ; then
- su - -c "{tunnel}" jenkins &
-fi
- """.format(tunnel=self.tunnel('$port'))
- open(image_dir + '/rc.local', 'w').write(script)
- util.sh('docker run --rm ' +
- ' -v ' + datadir + ':' + datadir +
- ' -v ' + libdir + ':' + libdir +
- ' -w ' + datadir +
- ' ' + self.args.libguestfs + ' ' + libdir + '/' +
- 'create-qemu-img ' + image + ' ' + str(os.getuid()))
- return True
-
- def docker_p(self):
- try:
- self.docker_version()
- return True
- except subprocess.CalledProcessError:
- return False
-
- def docker_version(self):
- return util.sh("docker --version | "
- " perl -pe 's/.*version (.*),.*/\\1/'")
-
- def docker_build_slave(self):
- if self.args.jenkins_slave not in util.sh('docker images'):
- util.sh('docker build -t ' + self.args.jenkins_slave + " " +
- self.args.libdir + '/jenkins-slave-docker')
- return True
- return False
-
- def docker_build_libguestfs(self):
- if self.args.libguestfs not in util.sh('docker images'):
- util.sh('docker build -t ' + self.args.libguestfs + " " +
- self.args.libdir + '/libguestfs-docker')
- return True
- return False
-
- def docker_destroy_slave(self, name):
- util.sh('docker stop ' + name + ' || true')
- util.sh('docker rm ' + name + ' || true')
- return self.destroy_node(name)
-
- def docker_run_slave(self, name):
- self.docker_build_slave()
- slave_port = self.slave_port(name)
- docker_host_version = util.sh("docker --version | "
- " perl -pe 's/.*version (.*),.*/\\1/'")
- master_port = self.master_port(name)
- script = """
-#!/bin/bash
-usermod --uid {uid} jenkins
-groupmod --gid {docker_group_id} docker
-apt-get install -y lxc-docker-{docker_host_version}
-su - -c '{tunnel}' jenkins
-/usr/sbin/sshd -D -E /var/log/auth.log
- """.format(tunnel=self.tunnel(master_port),
- docker_group_id=grp.getgrnam('docker').gr_gid,
- uid=os.getuid(),
- docker_host_version=docker_host_version)
- open(self.args.jenkins_home + '/setup.sh', 'w').write(script)
- self.fetch_ssh_key(self.args.jenkins_home)
- util.sh('docker stop ' + name + ' || true')
- util.sh('docker rm ' + name + ' || true')
- home = os.path.abspath(self.args.jenkins_home)
- util.sh('docker run -d --name ' + name + ' ' +
- ' -p ' + slave_port + ':22 ' +
- ' -v ' + home + ':/home/jenkins ' +
- ' -v /var/run/docker.sock:/run/docker.sock ' +
- self.args.jenkins_slave + ' ' +
- ' bash /home/jenkins/setup.sh')
- return name
-
- def docker_build_master(self):
- if self.args.jenkins_master not in util.sh('docker images'):
- util.sh('docker build -t ' + self.args.jenkins_master + " " +
- self.args.libdir + '/jenkins-docker')
- return True
- return False
-
- def run_master(self):
- self.docker_build_master()
- home = os.path.abspath(self.args.jenkins_home)
- dotssh = home + '/.ssh'
- if not os.path.exists(dotssh):
- os.makedirs(dotssh, 0o700)
- util.sh('ssh-keygen -N "" -f ' + dotssh + '/id_rsa')
- shutil.copyfile(dotssh + '/id_rsa.pub',
- dotssh + '/authorized_keys')
- os.chmod(dotssh + '/authorized_keys', 0o600)
- util.sh('docker run -d --name ' + self.args.jenkins_master +
- ' -p 50000:50000' +
- ' -p ' + self.args.jenkins_port + ':8080' +
- ' -p ' + self.args.jenkins_ssh_port + ':22' +
- ' -v ' + home + ':/var/jenkins_home' +
- ' ' + self.args.jenkins_master)
-
- def wait_for_credentials():
- timeout = 120
- for t in range(timeout):
- try:
- self.add_credential()
- logging.debug('run_master:wait_for_credentials ' +
- str(self.slave_credential_id()))
- logging.debug('run_master:wait_for_credentials done')
- return
- except requests.exceptions.ConnectionError as e:
- logging.debug('run_master:wait_for_credentials ' + str(e))
- except requests.exceptions.HTTPError as e:
- logging.debug('run_master:wait_for_credentials ' + str(e))
- except NoCredentials as e:
- logging.debug('run_master:wait_for_credentials ' + str(e))
- time.sleep(1)
- raise Exception('failed to add credential')
- wait_for_credentials()
-
- def destroy_master(self):
- util.sh('docker stop ' + self.args.jenkins_master)
- util.sh('docker rm ' + self.args.jenkins_master)
- return True
-
- def add_credential(self):
- cred = (cred_template.
- replace('{KEY_FILE}', '/var/jenkins_home/.ssh/id_rsa').
- replace('{USERNAME}', 'jenkins').
- replace('{DESCRIPTION}', 'for jenkins slaves'))
- r = requests.post(self.get_url() + '/credentials/configSubmit',
- data={'description': 'GLOBAL DESCRIPTION',
- 'name': 'GLOBAL NAME',
- 'json': cred})
- r.raise_for_status()
- return r.text
diff --git a/ceph_workbench/main.py b/ceph_workbench/main.py
index a3c2084..5fa00a0 100644
--- a/ceph_workbench/main.py
+++ b/ceph_workbench/main.py
@@ -18,7 +18,6 @@
# along with this program. If not, see `<http://www.gnu.org/licenses/>`.
#
import argparse
-from ceph_workbench import jenkins
from ceph_workbench import wbbackport
from github2gitlab import main
import logging
@@ -71,15 +70,6 @@ class CephWorkbench:
func=wbbackport.WBBackport,
)
- subparsers.add_parser(
- 'jenkins',
- help='Drive and inspect the Jenkins building Ceph',
- parents=[jenkins.Jenkins.get_parser()],
- add_help=False,
- ).set_defaults(
- func=jenkins.Jenkins,
- )
-
def run(self, argv):
args = self.parser.parse_args(argv)
diff --git a/data_files/jenkins-docker/Dockerfile b/data_files/jenkins-docker/Dockerfile
deleted file mode 100644
index 799b046..0000000
--- a/data_files/jenkins-docker/Dockerfile
+++ /dev/null
@@ -1,13 +0,0 @@
-FROM jenkins
-USER root
-RUN apt-get update && apt-get install -y openssh-server
-# Standard SSH port
-EXPOSE 22
-EXPOSE 50000
-
-RUN sed -i 's|session required pam_loginuid.so|session optional pam_loginuid.so|g' /etc/pam.d/sshd
-RUN mkdir -p /var/run/sshd
-
-RUN ( echo '#!/bin/bash' ; echo /usr/sbin/sshd ; echo chown -R jenkins /var/jenkins_home/.ssh ; echo /usr/local/bin/jenkins.sh ) > /usr/local/bin/jenkins-and-ssh.sh ; chmod +x /usr/local/bin/jenkins-and-ssh.sh
-
-ENTRYPOINT ["/usr/local/bin/jenkins-and-ssh.sh"]
diff --git a/data_files/jenkins-slave-docker/Dockerfile b/data_files/jenkins-slave-docker/Dockerfile
deleted file mode 100644
index 6179bd3..0000000
--- a/data_files/jenkins-slave-docker/Dockerfile
+++ /dev/null
@@ -1,32 +0,0 @@
-# This Dockerfile is used to build an image containing basic stuff to be used as a Jenkins slave build node.
-FROM ubuntu:trusty
-
-RUN echo deb http://get.docker.com/ubuntu docker main | tee /etc/apt/sources.list.d/docker.list ; apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
-# Make sure the package repository is up to date.
-RUN apt-get update
-RUN apt-get -y upgrade
-
-RUN apt-get install -y openssh-server git lxc-docker ntp python-pip jq ccache
-# http://stackoverflow.com/questions/27341064/how-do-i-fix-importerror-cannot-import-name-incompleteread
-RUN easy_install -U pip
-RUN pip install ceph-workbench
-RUN sed -i 's|session required pam_loginuid.so|session optional pam_loginuid.so|g' /etc/pam.d/sshd
-RUN mkdir -p /var/run/sshd
-
-# Install JDK 7 (latest edition)
-RUN apt-get install -y openjdk-7-jdk
-
-# Add user jenkins to the image
-RUN adduser --quiet jenkins
-# Set password for the jenkins user (you may want to alter this).
-RUN echo "jenkins:jenkins" | chpasswd
-
-RUN usermod -aG docker jenkins
-
-RUN echo 'jenkins ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/jenkins
-
-# Standard SSH port
-EXPOSE 22
-
-CMD ["/usr/sbin/sshd", "-D"]
diff --git a/docs/index.rst b/docs/index.rst
index 853fc6b..f6ee366 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -25,11 +25,10 @@ development workflow for `Ceph <http://ceph.com>`_.
subcommands:
valid subcommands
- {github2gitlab,backport,jenkins}
+ {github2gitlab,backport}
sub-command -h
github2gitlab Mirror a GitHub project to GitLab
backport Backport reports
- jenkins Drive and inspect the Jenkins building Ceph
User Guide
----------
@@ -43,7 +42,6 @@ instructions for getting the most out of ceph-workbench.
user/intro
user/install
- user/jenkins
Contributor Guide
diff --git a/docs/user/jenkins.rst b/docs/user/jenkins.rst
deleted file mode 100644
index cc323e7..0000000
--- a/docs/user/jenkins.rst
+++ /dev/null
@@ -1,152 +0,0 @@
-.. _jenkins:
-
-Jenkins
-=======
-
-::
-
- +----------------+
- | commit pushed |
- | in ceph |
- +----------------+
- | (0)
- v
- +----------------+
- ssh tunnel | jenkins master | ssh tunnel
- +-------------| ceph job |----------------+
- | (1) +----------------+ |
- | |
- | |
- v v
- +----------+ +----------+
- | jenkins | | jenkins |
- | slave | | slave |
- | (docker) | | (qemu) |
- +----------+ +----------+
- | | (3) |
- (2) | +-------------------------+ (3) |
- | | |
- v v v
- +-----------+ +--------------+ +--------------+
- | container | | container | | qemu i386 |
- | centos 7 | | ubuntu 14.04 | | ubuntu 14.04 |
- +-----------+ +--------------+ +--------------+
- | | |
- v v |
- +-------------------+ +-------------------+ |
- | run-make-check.sh | | run-make-check.sh | |
- +-------------------+ +-------------------+ |
- | | v
- | | +-------------------+
- | +-----------------+ | | run-make-check.sh |
- +---->| jenkins master |<---+ +-------------------+
- | ceph-report | |
- | job |<----------------------+
- +-----------------+
- |
- | (4)
- v
-
-
-.. _`jenkins master`: http://jenkins.ceph.dachary.org/
-.. _`jenkins job`: http://jenkins.ceph.dachary.org/job/ceph/
-.. _`run-make-check.sh`: http://workbench.dachary.org/ceph/ceph/blob/master/run-make-check.sh
-.. _`ceph repository`: http://workbench.dachary.org/ceph/ceph/
-
-A `jenkins job`_ is triggered every time a commit is pushed to the
-`ceph repository`_ and executes the `run-make-check.sh`_ script to
-verify it compiles and passes unit and functional tests.
-
-The `jenkins master`_ delegates the execution of `run-make-check.sh`_
-to `jenkins slaves <http://jenkins.ceph.dachary.org/computer/>`_. If
-the git branch matches a pull request found in the `Ceph official
-repository <http://github.com/ceph/ceph/>`_, a comment is added when
-the run is complete. When there is a failure the full output of the
-script can be browsed to figure out what went wrong.
-
-Jenkins slave CPU & RAM requirements
-------------------------------------
-
-The minimum configuration of a slave is:
-
-- bare metal with 32GB RAM, SSD with 16GB free space, 8 cores OR
-- virtual machine with 32GB RAM, 20GB root disk, 8 cores
-
-It can be hosted on a private IP: it will initiate a tunnel to the
-jenkins master.
-
-Hosting a jenkins slave
------------------------
-
-In the simplest way to contribute a jenkins slave is when a jenkins
-admin can ssh to it as root. If the slave is behind a firewall
-hosting_private it :ref:`requires two more steps <hosting_private>`.
-
-#. Add the following public key to the ``/root/.ssh/authorized_keys`` file
- of the machine hosting the jenkins slave.
-
- ::
-
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDA9mo/xFNhLSCADCjmPQ0MnlTdpIaC8O6vHT5/z7i0boZhLsTe84Gq6sg6qIQY/847/FX52wN6YxMYYjr4478eGa1n84L88WHA4updDT4/LbKzu3aYOVPD6NlkMGKmoJOQazY5z2Mpa/gYHDboZgyyLQ3ApSlM9SCc0xJIJwhGv4uAPjWDzkjCyMCjAOu0NPzJ97uuKgS7e5u1vxL3+6hn7HlIU9wSnA3PEmMUHC8p3f0sHnX5OeZcLwxOAD8v3Q74Lg7yNTc8K0wBuA/G32Tad2QZxFsuSkOyuvhQnWe7dqPL6Jvr20A9wu2A7WVbQ7YaxwngMjB26Pezxg4mFUYV ubuntu@jenkins
-#. Send a mail to `Ceph Development
-
-The jenkins admin will then do the following:
-
-#. Create a jenkins user with a home at ``/home/jenkins``
-#. Allow the jenkins user to use docker
-
- ::
-
- $ sudo usermod -aG docker jenkins
-
-#. :ref:`Install <install>` ceph-workbench
-#. Logout
-#. Create a new node on the jenkins master, create a jenkins slave container and connect it with the new node.
-
- ::
-
- $ ceph-workbench jenkins \
- --jenkins-url http://jenkins.ceph.dachary.org/ \
- --jenkins-user admin \
- --jenkins-password XXXXXXXX \
- --jenkins-docker-run-slave new
- slave940
-#. Verify that the newly created node is connected and ready to run
- jobs at http://jenkins.ceph.dachary.org/computer/slave094/
-
-.. _hosting_private:
-
-Hosting a jenkins slave on a private IP
----------------------------------------
-
-The process for hosting a jenkins slave requires more steps if the
-hosted slave cannot be access from the net:
-
-#. Send a mail to `Ceph Development
- disk, CPU) of the machine that could host a jenkins slave.
-#. Wait for the following to be sent:
- - a ssh key
- - the name of the slave (for instance **slave904**)
-#. Create a jenkins user with a home at ``/home/jenkins``
-#. Allow the jenkins user to use docker
-
- ::
-
- sudo usermod -aG docker jenkins
-
-#. :ref:`Install <install>` ceph-workbench
-#. Login as jenkins
-#. Add the ssh key to ``~/.ssh``
-#. Connect to the jenkins master
-
- ::
-
- ceph-workbench jenkins \
- --jenkins-url http://jenkins.ceph.dachary.org/ \
- --jenkins-docker-run-slave slave904
diff --git a/requirements.txt b/requirements.txt
index 3af59f9..2f75c77 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -7,3 +7,4 @@ github2gitlab
six>=1.9.0
sphinx>=1.1.3
docutils>=0.11
+twisted>=15.2
diff --git a/tests/jenkins-define-credentials.py b/tests/jenkins-define-credentials.py
deleted file mode 100644
index 66a79f2..0000000
--- a/tests/jenkins-define-credentials.py
+++ /dev/null
@@ -1,46 +0,0 @@
-import requests
-import sys
-
-cred_template = """
-{
- "domainCredentials": {
- "domain": {
- "name": "",
- "description": ""
- },
- "credentials": [
- {
- "scope": "GLOBAL",
- "id": "",
- "username": "{USERNAME}",
- "description": "{DESCRIPTION}",
- "privateKeySource": {
- "value": "1",
- "privateKeyFile": "{KEY_FILE}",
- "stapler-class": "com.cloudbees.jenkins.plugins\
-.sshcredentials.impl.BasicSSHUserPrivateKey$FileOnMasterPrivateKeySource"
- },
- "passphrase": "",
- "stapler-class": "com.cloudbees.jenkins.plugins\
-.sshcredentials.impl.BasicSSHUserPrivateKey",
- "kind": "com.cloudbees.jenkins.plugins\
-.sshcredentials.impl.BasicSSHUserPrivateKey"
- }
- ]
- }
-}
-"""
-
-
-def init(url):
- cred = (cred_template.
- replace('{KEY_FILE}', '/var/jenkins_home/.ssh/id_rsa').
- replace('{USERNAME}', 'ubuntu').
- replace('{DESCRIPTION}', 'for jenkins slaves'))
- r = requests.post(url + '/credentials/configSubmit',
- data={'description': 'GLOBAL DESCRIPTION',
- 'name': 'GLOBAL NAME',
- 'json': cred})
- r.raise_for_status()
-
-init(*sys.argv[1:])
diff --git a/tests/test_jenkins.py b/tests/test_jenkins.py
deleted file mode 100644
index 2782ef9..0000000
--- a/tests/test_jenkins.py
+++ /dev/null
@@ -1,510 +0,0 @@
-# -*- mode: python; coding: utf-8 -*-
-#
-#
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-import logging
-import os
-import responses
-import shutil
-import subprocess
-import testtools
-import threading
-import time
-
-from ceph_workbench import jenkins
-from ceph_workbench import util
-
-JENKINS = {
- 'ssh-port': '5555',
- 'key': 'data/jenkins/.ssh/id_rsa',
- 'host': 'localhost',
- 'port': '11080',
- 'user': 'admin',
- 'password': 'admin',
- 'qemu-image': 'ubuntu-14.04-i386',
-}
-
-logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s',
- level=logging.DEBUG)
-
-
-def try_a_few_times(command):
- timeout = 120
- for t in range(timeout):
- time.sleep(1)
- try:
- return util.sh(command)
- except subprocess.CalledProcessError:
- pass
- raise Exception(command + ' failed ' + str(timeout) + ' times')
-
-
-class TestJenkinsAll(testtools.TestCase):
-
- @classmethod
- def setUpClass(cls):
- image_dir = 'data/' + JENKINS['qemu-image']
- dotssh = image_dir + '/.ssh'
- if os.path.exists(dotssh):
- shutil.rmtree(dotssh)
- img = image_dir + '/' + JENKINS['qemu-image'] + '.img'
- if os.path.exists(img):
- os.unlink(img)
- home = 'data/jenkins'
- cls.j = jenkins.Jenkins.factory([
- '--jenkins-ssh-host', JENKINS['ssh-host'],
- '--jenkins-ssh-port', JENKINS['ssh-port'],
- '--jenkins-home', home,
- '--jenkins-host', JENKINS['host'],
- '--jenkins-port', JENKINS['port'],
- '--libdir', 'data_files',
- '--datadir', 'data',
- '--jenkins-run-master',
- ])
- cls.tearDownClass()
- cls.j.run()
- try_a_few_times(
- "ssh -p " + JENKINS['ssh-port'] +
- " -i " + JENKINS['key'] +
- " " + JENKINS['ssh-host'] +
- " ps fauwwwx")
- # when the cli port 50000 is not yet open, the cli returns a
- # rather confusing error message:
- # SEVERE: I/O error in channel Chunked connection ...
- # https://issues.jenkins-ci.org/browse/JENKINS-23232
-
- def wait_for_cli():
- timeout = 120
- for t in range(timeout):
- out = cls.j.run_cli('help')
- if "create-node" in out:
- return
- logging.debug('wait_for_cli ' + out)
- time.sleep(1)
- raise Exception('failed to communicate with cli')
- wait_for_cli()
-
- @classmethod
- def tearDownClass(cls):
- if os.path.exists(cls.j.get_cli_jar()):
- os.unlink(cls.j.get_cli_jar())
- util.sh('docker stop ' + cls.j.args.jenkins_master + ' || true')
- util.sh('docker rm ' + cls.j.args.jenkins_master + ' || true')
- util.sh('docker rmi ' + cls.j.args.jenkins_master + ' || true')
- util.sh('sudo rm -fr data/jenkins')
-
- @responses.activate
- def test_publish_build_to_pull_request(self):
- pr = '123'
- build = 'ceph/3'
- jenkins_url = 'http://jenkins'
- upstream_build = '12'
- upstream_url = 'job/ceph'
- build_report = """
-{
- "actions": [
- {
- "causes": [
- {
- "shortDescription": "Started by upstream project build number 12",
- "upstreamBuild": {upstream_build},
- "upstreamProject": "ceph",
- "upstreamUrl": "{upstream_url}"
- }
- ]
- },
- {}
- ],
- "artifacts": [],
- "building": false,
- "description": null,
- "duration": 3996,
- "estimatedDuration": 2042,
- "executor": null,
- "fullDisplayName": "ceph-report #1",
- "id": "2015-04-06_08-26-47",
- "keepLog": false,
- "number": 1,
- "result": "SUCCESS",
- "timestamp": 1428308807127,
- "url": "http://jenkins/job/ceph-report/1/",
- "builtOn": "rex003",
- "changeSet": {
- "items": [],
- "kind": null
- },
- "culprits": []
-}
-""".replace('{upstream_url}',
- upstream_url).replace('{upstream_build}',
- upstream_build)
- responses.add(responses.GET, jenkins_url + '/' + build + '/api/json',
- body=build_report, status=200,
- content_type='application/json')
- os_url = 'http://jenkins/job/ceph/TARGET_OPERATING_SYSTEM'
- upstream_build_report = """
-{
- "actions": [
- {
- "causes": [
- {
- "shortDescription": "Started by user Ceph Admin",
- "userId": "admin",
- "userName": "Ceph Admin"
- }
- ]
- },
- {},
- {
- "buildsByBranchName": {
- "refs/remotes/origin/pull/123": {
- "buildNumber": 12,
- "buildResult": null,
- "marked": {
- "SHA1": "23549bfbbdc88c874d9660889450612d2d372b26",
- "branch": [
- {
- "SHA1": "23549bfbbdc88c874d9660889450612d2d372b26",
- "name": "refs/remotes/origin/pull/123"
- }
- ]
- },
- "revision": {
- "SHA1": "23549bfbbdc88c874d9660889450612d2d372b26",
- "branch": [
- {
- "SHA1": "23549bfbbdc88c874d9660889450612d2d372b26",
- "name": "refs/remotes/origin/pull/123"
- }
- ]
- }
- }
- },
- "lastBuiltRevision": {
- "SHA1": "23549bfbbdc88c874d9660889450612d2d372b26",
- "branch": [
- {
- "SHA1": "23549bfbbdc88c874d9660889450612d2d372b26",
- "name": "refs/remotes/origin/pull/123"
- }
- ]
- },
- "remoteUrls": [
- "http://workbench.dachary.org/ceph/ceph.git"
- ],
- "scmName": ""
- },
- {},
- {}
- ],
- "artifacts": [],
- "building": false,
- "description": null,
- "duration": 31117,
- "estimatedDuration": 1971442,
- "executor": null,
- "fullDisplayName": "ceph #12",
- "id": "2015-04-06_08-26-06",
- "keepLog": false,
- "number": 12,
- "result": "FAILURE",
- "timestamp": 1428308766532,
- "url": "http://jenkins/{upstream_url}/{upstream_build}/",
- "builtOn": "rex003",
- "changeSet": {
- "items": [],
- "kind": "git"
- },
- "culprits": [],
- "runs": [
- {
- "number": {upstream_build},
- "url": "{os_url}=centos-7/{upstream_build}/"
- },
- {
- "number": {upstream_build},
- "url": "{os_url}=ubuntu-14.04/{upstream_build}/"
- },
- {
- "number": 1,
- "url": "http://jenkins/job/ceph/system=centos-7/1/"
- }
- ]
-}
-""".replace('{upstream_url}',
- upstream_url).replace('{upstream_build}',
- upstream_build).replace('{os_url}', os_url)
- responses.add(responses.GET, jenkins_url + '/' +
- upstream_url + '/' + upstream_build + '/api/json',
- body=upstream_build_report, status=200,
- content_type='application/json')
- build_url = ("http://jenkins/" + upstream_url +
- "/TARGET_OPERATING_SYSTEM=centos-7/" + upstream_build)
- os_build_report = """
-{
- "actions": [
- {
- "lastBuiltRevision": {
- "SHA1": "23549bfbbdc88c874d9660889450612d2d372b26",
- "branch": [
- {
- "SHA1": "23549bfbbdc88c874d9660889450612d2d372b26",
- "name": "refs/remotes/origin/pull/123"
- }
- ]
- }
- }
- ],
- "number": {upstream_build},
- "result": "{result}",
- "url": "{build_url}"
-}
-"""
- centos_build_report = (os_build_report.
- replace('{build_url}', build_url).
- replace('{result}', 'SUCCESS').
- replace('{upstream_build}', upstream_build))
- responses.add(responses.GET, build_url + '/api/json',
- body=centos_build_report, status=200,
- content_type='application/json')
- build_url = ("http://jenkins/" + upstream_url +
- "/TARGET_OPERATING_SYSTEM=ubuntu-14.04/" +
- upstream_build)
- ubuntu_build_report = (os_build_report.
- replace('{build_url}', build_url).
- replace('{result}', 'FAILURE').
- replace('{upstream_build}', upstream_build))
- responses.add(responses.GET, build_url + '/api/json',
- body=ubuntu_build_report, status=200,
- content_type='application/json')
- github_repo = 'my/repo'
- github_token = 'TOKEN'
- expected = """\
-FAILURE: http://jenkins/job/ceph/12/
-* SUCCESS http://jenkins/job/ceph/TARGET_OPERATING_SYSTEM=centos-7/12/
-* FAILURE http://jenkins/job/ceph/TARGET_OPERATING_SYSTEM=ubuntu-14.04/12/
-"""
- github_url = ('https://api.github.com/repos/' + github_repo +
- '/issues/' + pr + '/comments?access_token=' +
- github_token)
-
- def request_callback(request):
- return (200, {}, request.body)
- responses.add_callback(responses.POST, github_url,
- callback=request_callback,
- content_type='application/json',
- match_querystring=True)
- j = jenkins.Jenkins.factory([
- '--publish-build-to-pull-request', build,
- '--jenkins-host', JENKINS['host'],
- '--jenkins-port', JENKINS['port'],
- '--github-repo', github_repo,
- '--github-token', github_token,
- ])
- self.assertEquals(expected, j.run())
-
- def test_next_node_name(self):
- j = jenkins.Jenkins.factory([
- '--jenkins-host', JENKINS['host'],
- '--jenkins-port', JENKINS['port'],
- ])
- self.assertEquals("slave001", j.next_node_name())
-
- def test_slave_credential_id(self):
- j = jenkins.Jenkins.factory([
- '--jenkins-host', JENKINS['host'],
- '--jenkins-port', JENKINS['port'],
- '--jenkins-user', JENKINS['user'],
- '--jenkins-password', JENKINS['password'],
- ])
- self.assertTrue("-" in j.slave_credential_id())
-
- def test_run_cli(self):
- j = jenkins.Jenkins.factory([
- '--jenkins-host', JENKINS['host'],
- '--jenkins-port', JENKINS['port'],
- ])
- self.assertIn("create-node", j.run_cli('help'))
-
- def test_create_node(self):
- j = jenkins.Jenkins.factory([
- '--jenkins-host', JENKINS['host'],
- '--jenkins-port', JENKINS['port'],
- '--jenkins-user', JENKINS['user'],
- '--jenkins-password', JENKINS['password'],
- ])
- name = 'NAME005'
- n = j.create_node(name)
- self.assertEquals(name, n['displayName'])
- j.destroy_node(name)
-
- def test_build_slave(self):
- j = jenkins.Jenkins.factory([
- '--libdir', 'data_files',
- ])
- j.docker_build_slave()
- self.assertIn(j.args.jenkins_slave,
- util.sh("docker images " + j.args.jenkins_slave))
-
- def test_build_libguestfs(self):
- j = jenkins.Jenkins.factory([
- '--libdir', 'data_files',
- ])
- j.docker_build_libguestfs()
- self.assertIn(j.args.libguestfs,
- util.sh("docker images " + j.args.libguestfs))
-
- def test_prepare_qemu_img(self):
- j = jenkins.Jenkins.factory([
- '--jenkins-ssh-host', JENKINS['ssh-host'],
- '--jenkins-ssh-key', JENKINS['key'],
- '--jenkins-ssh-port', JENKINS['ssh-port'],
- '--jenkins-qemu-image', JENKINS['qemu-image'],
- '--libdir', 'data_files',
- '--datadir', 'data',
- '--jenkins-qemu-prepare',
- ])
- j.run()
- self.assertTrue(os.path.exists('data/' + JENKINS['qemu-image']))
- self.assertTrue(os.path.exists('data/' + JENKINS['qemu-image'] +
- '/.ssh/id_rsa'))
-
- def test_qemu_run_jenkins_slave(self):
- options = [
- '--jenkins-ssh-host', JENKINS['ssh-host'],
- '--jenkins-ssh-key', JENKINS['key'],
- '--jenkins-ssh-port', JENKINS['ssh-port'],
- '--jenkins-host', JENKINS['host'],
- '--jenkins-port', JENKINS['port'],
- '--jenkins-user', JENKINS['user'],
- '--jenkins-password', JENKINS['password'],
- '--jenkins-qemu-image', JENKINS['qemu-image'],
- '--libdir', 'data_files',
- '--datadir', 'data',
- ]
- j = jenkins.Jenkins.factory(options)
- name = j.next_node_name()
- master_port = str(j.master_port(name))
- slave_port = str(j.slave_port(name))
- # this is implicit when calling qemu_run_slave
- # but we call it outside of the thread so that it
- # blocks the test because it may take a long time
- # and be confused with something going wrong in
- # the thread
- j.qemu_get_img()
-
- def kvm_start():
- other = jenkins.Jenkins.factory(options + [
- '--jenkins-qemu-run-slave', 'new',
- ])
- other.qemu_run_slave(name)
- kvm = threading.Thread(target=kvm_start)
- kvm.start()
-
- known_hosts = j.ignore_known_hosts()
- # ssh to the slave and give time to kvm launch
- via_slave_cmdline = try_a_few_times(
- "ssh -p " + slave_port +
- " " + known_hosts +
- " -i " + JENKINS['key'] +
- " jenkins@localhost cat /proc/cmdline")
- self.assertIn(master_port, via_slave_cmdline)
- util.sh("ssh -p " + slave_port +
- " " + known_hosts +
- " -i " + JENKINS['key'] +
- " jenkins@localhost ps fauwwx")
- # ssh to the slave via the master
- via_master_cmdline = try_a_few_times(
- "ssh -p " + JENKINS['ssh-port'] +
- " " + known_hosts +
- " -i " + JENKINS['key'] +
- " " + JENKINS['ssh-host'] +
- " ssh -p " + master_port +
- " " + known_hosts +
- " localhost cat /proc/cmdline")
- self.assertIn('ds=nocloud-net', via_master_cmdline)
- # halt the kvm process and expect the kvm thread to return
- j.qemu_destroy_slave(name)
- kvm.join()
- self.assertFalse(j.find_node(name))
-
- def test_docker_run_jenkins_slave(self):
- options = [
- '--jenkins-ssh-host', JENKINS['ssh-host'],
- '--jenkins-ssh-key', JENKINS['key'],
- '--jenkins-ssh-port', JENKINS['ssh-port'],
- '--jenkins-host', JENKINS['host'],
- '--jenkins-port', JENKINS['port'],
- '--jenkins-user', JENKINS['user'],
- '--jenkins-password', JENKINS['password'],
- '--libdir', 'data_files',
- '--jenkins-home', 'data_files',
- ]
- j = jenkins.Jenkins.factory(options + [
- '--jenkins-docker-run-slave', 'new',
- ])
- name = j.run()
- self.assertTrue(j.find_node(name))
- j.docker_destroy_slave(name)
- self.assertFalse(j.find_node(name))
-
- name = 'slave010'
- j = jenkins.Jenkins.factory(options + [
- '--jenkins-docker-run-slave', name,
- ])
- self.assertEquals(name, j.run())
- j.docker_destroy_slave(name)
- self.assertFalse(j.find_node(name))
-
-
-class TestJenkinsMaster(testtools.TestCase):
-
- def test_build_master(self):
- j = jenkins.Jenkins.factory([
- '--libdir', 'data_files',
- ])
- util.sh('docker rmi ' + j.args.jenkins_master + ' || true')
- j.docker_build_master()
- self.assertIn(j.args.jenkins_master,
- util.sh("docker images " + j.args.jenkins_master))
-
- def test_run_master(self):
- home = 'data/jenkins'
- j = jenkins.Jenkins.factory([
- '--jenkins-ssh-host', JENKINS['ssh-host'],
- '--jenkins-ssh-port', JENKINS['ssh-port'],
- '--jenkins-home', home,
- '--jenkins-host', JENKINS['host'],
- '--jenkins-port', JENKINS['port'],
- '--libdir', 'data_files',
- '--datadir', 'data',
- '--jenkins-run-master',
- ])
- util.sh('docker stop ' + j.args.jenkins_master + ' || true')
- util.sh('docker rm ' + j.args.jenkins_master + ' || true')
- util.sh('docker rmi ' + j.args.jenkins_master + ' || true')
- util.sh('sudo rm -fr data/jenkins')
- j.run()
- out = try_a_few_times(
- "ssh -p " + JENKINS['ssh-port'] +
- " -i " + JENKINS['key'] +
- " " + JENKINS['ssh-host'] +
- " ps fauwwwx")
- self.assertIn("jenkins.war", out)
- self.assertTrue(j.destroy_master())