Add sync_jobs.py and a corresponding README file.

This commit is contained in:
parazyd 2018-09-26 18:11:53 +02:00
parent 19d55ecfd2
commit 0cf7f9e978
No known key found for this signature in database
GPG Key ID: F0CB28FCF78637DE
3 changed files with 172 additions and 0 deletions

69
jenkins_backend/README.md Normal file
View File

@ -0,0 +1,69 @@
toaster.do Jenkins backend
==========================
These python modules serve as the Jenkins backend to the Devuan SDK's
Web interface. They are to be executed by the web CGI when a new build
is requested.
Configuration
-------------
This backend is configured using two files. `config.py` and
`jenkins_creds.py`. The former contains variables that tell the backend
in what way to work and where to look for files. The latter -
`jenkins_creds.py` is not included in the git repository as it contains
important credentials which allow the backend to work with Jenkins' API.
The `jenkins_creds.py` file should look like the following:
```
jenkins_host = 'https://sdk.dyne.org:4443'
jenkins_user = 'toaster'
jenkins_pass = 'thetoasterpassword'
```
These files will be read and imported by `sync_jobs.py` when ran.
Usage
-----
```
usage: sync_jobs.py [-h] [-a] [-d] [-n] jobname
positional arguments:
jobname
optional arguments:
-h, --help show this help message and exit
-a, --add
-d, --delete
-n, --dryrun
```
The `jobname` argument should be in a specific format. It should contain
the requester's email, which sdk was chosen, the requested architecture,
and a timestamp.
In case of vm-sdk or live-sdk, these would look like:
```
parazyd@dyne.org-vm_amd64-1537977964
parazyd@dyne.org-live_amd64-1537977964
```
In case of arm-sdk, we also need to know the board we're building for:
```
parazyd@dyne.org-arm_armhf_sunxi-1537977964
```
All of this combined, the required command to add a new job to Jenkins
would look something like the following:
```
sync_jobs.py -a parazyd@dyne.org-vm_amd64-1537977964
```
In case of removing an existing job, all of the above applies the same
way. You just have to use `-d` instead of `-a`.

View File

@ -0,0 +1,4 @@
#!/usr/bin/env python3
# Physical path to where jobs are held
jobpath = '/srv/toaster'

99
jenkins_backend/sync_jobs.py Executable file
View File

@ -0,0 +1,99 @@
#!/usr/bin/env python3
"""
Module for backend talk with Jenkins executed by the web/CGI
"""
from argparse import ArgumentParser
from jenkins import Jenkins
from config import jobpath
from jenkins_creds import (jenkins_host, jenkins_user, jenkins_pass)
def html_escape(string):
"""
Function for escaping certain symbols to XML-compatible sequences.
"""
html_codes = [("'", '''), ('"', '"'), ('&', '&'),
('<', '&lt;'), ('>', '&gt;')]
for i in html_codes:
string = string.replace(i[0], i[1])
return string
def add_job(japi, jobname):
"""
Function for adding a job to Jenkins.
"""
info = jobname.split('-')
desc = 'WebSDK build for: %s\nStarted: %s' % (info[0], info[2])
sdk = info[1].split('_')[0]
arch = info[1].split('_')[1]
blendfile = '%s/%s/Dockerfile' % (jobpath, jobname)
if sdk == 'arm':
board = info[1].split('_')[2]
zshcmd = 'load devuan %s %s' % (board, blendfile)
elif sdk == 'live':
zshcmd = 'load devuan %s %s' % (arch, blendfile)
elif sdk == 'vm':
zshcmd = 'load devuan %s' % (blendfile)
command = "zsh -f -c 'source sdk && %s && build_image_dist'" % zshcmd
command = html_escape(command)
replacements = [('DESC', desc),
('SDK', sdk),
('ARCH', arch),
('COMMAND', command)]
sdk_job = open('toasterbuild.xml', encoding='utf-8').read()
for i in replacements:
sdk_job = sdk_job.replace('{{{%s}}}' % i[0], i[1])
return japi.create_job(jobname, sdk_job)
def del_job(japi, jobname):
"""
Function for deleting a Jenkins job.
"""
return japi.delete_job(jobname)
def main():
"""
Main routine.
"""
parser = ArgumentParser()
parser.add_argument('-a', '--add', action='store_true')
parser.add_argument('-d', '--delete', action='store_true')
parser.add_argument('-n', '--dryrun', action='store_true')
parser.add_argument('jobname')
# NOTE: jobname should be email-arch-date, and a predefined directory
# somewhere on the filesystem. e.g.:
# - parazyd@dyne.org-vm_amd64-198374198
# - parazyd@dyne.org-arm_armhf_raspi2-2198361991
args = parser.parse_args()
japi = Jenkins(jenkins_host, username=jenkins_user, password=jenkins_pass)
if args.add:
if args.dryrun:
print('Would add:', args.jobname)
return
print('Adding job:', args.jobname)
add_job(japi, args.jobname)
elif args.delete:
if args.dryrun:
print('Would remove:', args.jobname)
return
print('Removing job:', args.jobname)
del_job(japi, args.jobname)
if __name__ == '__main__':
main()