From e5544416c2b0ee818285b9a13761f1c351d7676f Mon Sep 17 00:00:00 2001 From: dave Date: Sat, 2 Feb 2019 16:59:34 -0800 Subject: [PATCH] add docker building funcs --- examples/dockerbuild.py | 30 +++++++++++++++++ examples/logic.py | 18 +++++++++++ setup.py | 2 +- shipper/__init__.py | 1 - shipper/lib.py | 71 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 examples/dockerbuild.py create mode 100644 examples/logic.py diff --git a/examples/dockerbuild.py b/examples/dockerbuild.py new file mode 100644 index 0000000..d7f0e1a --- /dev/null +++ b/examples/dockerbuild.py @@ -0,0 +1,30 @@ +from shipper.lib import ShipperJob, SshConnection, GiteaCheckoutTask, LambdaTask, \ + DockerBuildTask, DockerTagTask, DockerPushTask + + +# This job accepts gitea webooks and builds docker images. If the "imagename" parameter is passed, it will be used to +# name the image. Otherwise, a repo named "docker-image-name" would builds/pushes a docker image called "image-name". + + +job = ShipperJob() +job.default_connection(SshConnection(None, None, key="testkey.pem")) +job.add_task(GiteaCheckoutTask("code", allow_branches=["master"])) + + +def getimgname(job): + if "imagename" in job.props: # prefer "imagename" url param + imagename = job.props["imagename"] + else: # fall back to repo name, stripping 'docker-' prefix if needed. + imagename = job.props["payload"]["repository"]["name"] # Expecting a repo name like "docker-nginx" + if imagename.startswith("docker-"): # strip the "docker-" repo name prefix + imagename = imagename[len("docker-"):] + + job.props["docker_imagename"] = "dpedu/" + imagename # we'll build the image locally as this + job.props["docker_tag"] = "apps2reg:5000/dpedu/" + imagename # then tag and push it as this + + +job.add_task(LambdaTask(getimgname)) + +job.add_task(DockerBuildTask()) +job.add_task(DockerTagTask()) +job.add_task(DockerPushTask()) diff --git a/examples/logic.py b/examples/logic.py new file mode 100644 index 0000000..9583c5c --- /dev/null +++ b/examples/logic.py @@ -0,0 +1,18 @@ +from shipper.lib import ShipperJob, SshConnection, SshTask, GiteaCheckoutTask, CmdTask, LambdaTask + + +job = ShipperJob() +job.default_connection(SshConnection(None, None, key="testkey.pem")) +job.add_task(GiteaCheckoutTask("code", allow_branches=["master"])) + + +# LambdaTask lets you call a method while the job is running and insert new tasks into the queue. Tasks yielded from +# this function will be the next steps executed. +def dobuild(job): + reponame = job.props["payload"]["repository"]["name"] + print("Repo name is:", reponame) + yield CmdTask("echo {}".format(reponame)) + + +job.add_task(LambdaTask(dobuild)) + diff --git a/setup.py b/setup.py index dc3005b..b2f7350 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup import os -__version__ = "0.0.1" +__version__ = "0.0.2" reqs = open(os.path.join(os.path.dirname(__file__), "requirements.txt")).read().split() diff --git a/shipper/__init__.py b/shipper/__init__.py index 445488c..a1d7e42 100644 --- a/shipper/__init__.py +++ b/shipper/__init__.py @@ -61,7 +61,6 @@ class TaskExecutor(object): # Extract post body if present - we decode json and pass through other types as-is payload = None - print("Login: ", cherrypy.request.login) if cherrypy.request.method == "POST": cl = cherrypy.request.headers.get('Content-Length', None) if cl: diff --git a/shipper/lib.py b/shipper/lib.py index df64263..149a2ee 100644 --- a/shipper/lib.py +++ b/shipper/lib.py @@ -237,3 +237,74 @@ class GiteaCheckoutTask(GitCheckoutTask): def __repr__(self): return "" + + +class LambdaTask(ShipperTask): + """ + Run tasks generated by this task at execution time. Func should return a list of tasks. + """ + def __init__(self, func): + super().__init__() + self.func = func + + def run(self, job): + inserted = 0 + steps = self.func(job) + if steps: + for newstep in steps: + job.tasks.insert(inserted, newstep) + inserted += 1 + print("Prepended", inserted, "steps") + + def __repr__(self): + return "".format(self.func) + + +class DockerBuildTask(ShipperTask): + def __init__(self, imagename=None, codedir=None): + super().__init__() + self.imagename = imagename + self.codedir = codedir + + def run(self, job): + imagename = self.imagename or job.props.get("docker_imagename") + codedir = self.codedir or job.props.get("docker_codedir") or "code" + cmd = ["docker", "build", "-t", imagename, codedir] + print("Calling", cmd) + # subprocess.check_call(cmd) + + def __repr__(self): + return "" + + +class DockerPushTask(ShipperTask): + def __init__(self, imagename=None): + super().__init__() + self.imagename = imagename + + def run(self, job): + imagename = self.imagename or job.props.get("docker_imagename") + cmd = ["docker", "push", imagename] + print("Calling", cmd) + # subprocess.check_call(cmd) + + def __repr__(self): + return "" + + +class DockerTagTask(ShipperTask): + def __init__(self, imagename=None, tag=None): + super().__init__() + self.imagename = imagename + self.tag = tag + + def run(self, job): + imagename = self.imagename or job.props.get("docker_imagename") + tag = self.tag or job.props.get("docker_tag") + cmd = ["docker", "tag", imagename, tag] + print("Calling", cmd) + # subprocess.check_call(cmd) + job.props["docker_imagename"] = tag + + def __repr__(self): + return "" \ No newline at end of file