From 24f2b60fe48bf29c5f1263a116c01cdbd17de118 Mon Sep 17 00:00:00 2001 From: lemoer Date: Mon, 17 Jun 2019 21:52:10 +0200 Subject: [PATCH] Add jenkins-community-slave --- contrib/ci/jenkins-community-slave/Dockerfile | 27 +++++ contrib/ci/jenkins-community-slave/slave.py | 103 ++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 contrib/ci/jenkins-community-slave/Dockerfile create mode 100644 contrib/ci/jenkins-community-slave/slave.py diff --git a/contrib/ci/jenkins-community-slave/Dockerfile b/contrib/ci/jenkins-community-slave/Dockerfile new file mode 100644 index 00000000..9c53e01d --- /dev/null +++ b/contrib/ci/jenkins-community-slave/Dockerfile @@ -0,0 +1,27 @@ +FROM gluon + +USER root + +# this is needed to install default-jre-headless in debian slim images +RUN mkdir -p /usr/share/man/man1 + +RUN apt-get update && apt-get install -y default-jre-headless curl python python-pip git +RUN pip install jenkins-webapi + +# Get docker-compose in the agent container +RUN mkdir -p /home/jenkins +RUN mkdir -p /var/lib/jenkins + +# Start-up script to attach the slave to the master +ADD slave.py /var/lib/jenkins/slave.py + +WORKDIR /home/jenkins + +ENV JENKINS_URL "https://build.ffh.zone/" +ENV JENKINS_SLAVE_ADDRESS "" +ENV SLAVE_EXECUTORS "1" +ENV SLAVE_LABELS "docker" +ENV SLAVE_WORING_DIR "" +ENV CLEAN_WORKING_DIR "true" + +CMD [ "python", "-u", "/var/lib/jenkins/slave.py" ] diff --git a/contrib/ci/jenkins-community-slave/slave.py b/contrib/ci/jenkins-community-slave/slave.py new file mode 100644 index 00000000..87a59e24 --- /dev/null +++ b/contrib/ci/jenkins-community-slave/slave.py @@ -0,0 +1,103 @@ +from jenkins import Jenkins, JenkinsError, NodeLaunchMethod +import os +import signal +import sys +import urllib +import subprocess +import shutil +import requests +import time + +slave_jar = '/var/lib/jenkins/slave.jar' +slave_name = os.environ['SLAVE_NAME'] if os.environ['SLAVE_NAME'] != '' else 'docker-slave-' + os.environ['HOSTNAME'] +jnlp_url = os.environ['JENKINS_URL'] + '/computer/' + slave_name + '/slave-agent.jnlp' +slave_jar_url = os.environ['JENKINS_URL'] + '/jnlpJars/slave.jar' +print(slave_jar_url) +process = None + +def clean_dir(dir): + for root, dirs, files in os.walk(dir): + for f in files: + os.unlink(os.path.join(root, f)) + for d in dirs: + shutil.rmtree(os.path.join(root, d)) + +def slave_create(node_name, working_dir, executors, labels): + j = Jenkins(os.environ['JENKINS_URL'], os.environ['JENKINS_USER'], os.environ['JENKINS_PASS']) + j.node_create(node_name, working_dir, num_executors = int(executors), labels = labels, launcher = NodeLaunchMethod.JNLP) + +def slave_delete(node_name): + j = Jenkins(os.environ['JENKINS_URL'], os.environ['JENKINS_USER'], os.environ['JENKINS_PASS']) + j.node_delete(node_name) + +def slave_download(target): + if os.path.isfile(slave_jar): + os.remove(slave_jar) + + loader = urllib.URLopener() + loader.retrieve(os.environ['JENKINS_URL'] + '/jnlpJars/slave.jar', '/var/lib/jenkins/slave.jar') + +def slave_run(slave_jar, jnlp_url): + params = [ 'java', '-jar', slave_jar, '-jnlpUrl', jnlp_url ] + if os.environ['JENKINS_SLAVE_ADDRESS'] != '': + params.extend([ '-connectTo', os.environ['JENKINS_SLAVE_ADDRESS' ] ]) + + if os.environ['SLAVE_SECRET'] == '': + params.extend([ '-jnlpCredentials', os.environ['JENKINS_USER'] + ':' + os.environ['JENKINS_PASS'] ]) + else: + params.extend([ '-secret', os.environ['SLAVE_SECRET'] ]) + return subprocess.Popen(params, stdout=subprocess.PIPE) + +def signal_handler(sig, frame): + if process != None: + process.send_signal(signal.SIGINT) + +signal.signal(signal.SIGINT, signal_handler) +signal.signal(signal.SIGTERM, signal_handler) + +def h(): + print("ERROR!: please specify environment variables") + print("") + print('docker run -e "SLAVE_NAME=test" -e "SLAVE_SECRET=..." jenkins') + +if os.environ.get('SLAVE_NAME') is None: + h() + sys.exit(1) + +if os.environ.get('SLAVE_SECRET') is None: + h() + sys.exit(1) + +def master_ready(url): + try: + r = requests.head(url, verify=False, timeout=None) + return r.status_code == requests.codes.ok + except: + return False + +while not master_ready(slave_jar_url): + print("Master not ready yet, sleeping for 10sec!") + time.sleep(10) + +slave_download(slave_jar) +print 'Downloaded Jenkins slave jar.' + +if os.environ['SLAVE_WORING_DIR']: + os.setcwd(os.environ['SLAVE_WORING_DIR']) + +if os.environ['CLEAN_WORKING_DIR'] == 'true': + clean_dir(os.getcwd()) + print "Cleaned up working directory." + +if os.environ['SLAVE_NAME'] == '': + slave_create(slave_name, os.getcwd(), os.environ['SLAVE_EXECUTORS'], os.environ['SLAVE_LABELS']) + print 'Created temporary Jenkins slave.' + +process = slave_run(slave_jar, jnlp_url) +print 'Started Jenkins slave with name "' + slave_name + '" and labels [' + os.environ['SLAVE_LABELS'] + '].' +process.wait() + +print 'Jenkins slave stopped.' +if os.environ['SLAVE_NAME'] == '': + slave_delete(slave_name) + print 'Removed temporary Jenkins slave.'