support reference bundle in build-on-commit action #11

Merged
merged 8 commits into from Dec 13, 2016
View
@@ -4,6 +4,12 @@ build-on-commit:
charm-name:
description: Name of the charm.
type: string
+ reference-bundle:
+ description: |
+ Optional charm store URL for a bundle to use to test the given
+ charm. For example, "cs:~charmers/mediawiki-single".
+ type: string
+ default: ""
repo:
description: Git repository.
type: string
View
@@ -1,7 +1,15 @@
#!/usr/bin/env python3
-from charmhelpers.core import hookenv
-from charms.reactive import RelationBase
-from jenkins import Jenkins
+
+import sys
+
+sys.path.append('lib')
+from charms.layer.basic import activate_venv # noqa: E402
+activate_venv()
+
+from charmhelpers.core import hookenv # noqa: E402
+from charms.reactive import RelationBase # noqa: E402
+from cwrhelpers import app_from_bundle, fail_action # noqa: E402
+from jenkins import Jenkins # noqa: E402
def add_job():
@@ -15,11 +23,24 @@ def add_job():
jenkins_connection_info["admin_username"],
jenkins_connection_info["admin_password"])
+ # If we have a reference bundle, determine the app name used for our charm
+ charm_name = hookenv.action_get("charm-name")
+ if hookenv.action_get("reference-bundle"):
+ bundle_name = hookenv.action_get("reference-bundle")
+ if not bundle_name.startswith("cs:"):
+ bundle_name = "cs:{}".format(bundle_name)
+ bundle_app_name = app_from_bundle(bundle_name, charm_name)
+
+ if not bundle_app_name:
+ fail_action("{} not found in {}".format(charm_name, bundle_name))
+
rep = {"{{gitrepo}}": hookenv.action_get("repo"),
- "{{pushtochannel}}": hookenv.action_get("push-to-channel"),
- "{{lpid}}": hookenv.action_get("lp-id"),
+ "{{pushtochannel}}": hookenv.action_get("push-to-channel") or "",
+ "{{lpid}}": hookenv.action_get("lp-id") or "",
"{{branch}}": hookenv.action_get("branch"),
- "{{charmname}}": hookenv.action_get("charm-name"),
+ "{{charmname}}": charm_name,
+ "{{referencebundle}}": bundle_name or "",
+ "{{bundleappname}}": bundle_app_name or "",
"{{refspec}}": "",
"{{controller}}": hookenv.action_get("controller")}
@@ -1,7 +1,15 @@
#!/usr/bin/env python3
-from charmhelpers.core import hookenv
-from charms.reactive import RelationBase
-from jenkins import Jenkins
+
+import sys
+
+sys.path.append('lib')
+from charms.layer.basic import activate_venv # noqa: E402
+activate_venv()
+
+from charmhelpers.core import hookenv # noqa: E402
+from charms.reactive import RelationBase # noqa: E402
+from cwrhelpers import app_from_bundle, fail_action # noqa: E402
+from jenkins import Jenkins # noqa: E402
def add_job():
@@ -15,14 +23,25 @@ def add_job():
jenkins_connection_info["admin_username"],
jenkins_connection_info["admin_password"])
+ # If we have a reference bundle, determine the app name used for our charm
charm_name = hookenv.action_get("charm-name")
- refspec = "<refspec>+refs/tags/*:refs/remotes/origin/tags/*</refspec>"
+ if hookenv.action_get("reference-bundle"):
+ bundle_name = hookenv.action_get("reference-bundle")
+ if not bundle_name.startswith("cs:"):
+ bundle_name = "cs:{}".format(bundle_name)
+ bundle_app_name = app_from_bundle(bundle_name, charm_name)
+
+ if not bundle_app_name:
+ fail_action("{} not found in {}".format(charm_name, bundle_name))
+ refspec = "<refspec>+refs/tags/*:refs/remotes/origin/tags/*</refspec>"
rep = {"{{gitrepo}}": hookenv.action_get("repo"),
- "{{pushtochannel}}": hookenv.action_get("push-to-channel"),
- "{{lpid}}": hookenv.action_get("lp-id"),
+ "{{pushtochannel}}": hookenv.action_get("push-to-channel") or "",
+ "{{lpid}}": hookenv.action_get("lp-id") or "",
"{{branch}}": "*/tags/*",
"{{charmname}}": charm_name,
+ "{{referencebundle}}": bundle_name or "",
+ "{{bundleappname}}": bundle_app_name or "",
"{{refspec}}": refspec,
"{{controller}}": hookenv.action_get("controller")}
View
@@ -0,0 +1,53 @@
+#!/usr/bin/env python3
+
+import sys
+import time
+import yaml
+
+sys.path.append('lib')
+from charms.layer.basic import activate_venv # noqa: E402
+activate_venv()
+
+from charmhelpers.core import hookenv # noqa: E402
+from jenkins import NotFoundException # noqa: E402
+from theblues import charmstore # noqa: E402
+
+
+def app_from_bundle(bundle, charm):
+ '''Return the app name used in the given bundle for a given charm.'''
+ cs = charmstore.CharmStore()
+ bundle_yaml = cs.files(bundle, filename='bundle.yaml', read_file=True)
+ yaml_contents = yaml.safe_load(bundle_yaml)
+ for app, app_config in yaml_contents['services'].items():
+ if charm in app_config['charm']:
+ return app
+ return None
+
+
+def fail_action(msg, output=None):
+ '''Fail an action with a message and (optionally) additional output.'''
+ if output:
+ hookenv.action_set({'output': output})
+ hookenv.action_fail(msg)
+ sys.exit()
+
+
+def wait_result(jclient, job_name, build_number, secs_to_wait=60):
+ timeout = time.time() + secs_to_wait
+ while True:
+ time.sleep(5)
+ if time.time() > timeout:
+ raise Exception("Job timeout")
+ try:
+ build_info = jclient.get_build_info(job_name, build_number)
+ if build_info["result"] == 'FAILURE':
+ outcome = 'fail'
+ else:
+ outcome = 'success'
+
+ output = jclient.get_build_console_output(job_name, build_number)
+ return outcome, output
+ except NotFoundException:
+ print("Jenkins job {} not running yet".format(build_number))
+ except:
+ raise
@@ -1,24 +0,0 @@
-#!/usr/bin/env python3
-import time
-from jenkins import Jenkins, NotFoundException
-
-
-def wait_result(jclient, job_name, build_number, secs_to_wait=60):
- timeout = time.time() + secs_to_wait
- while True:
- time.sleep(5)
- if time.time() > timeout:
- raise Exception("Job timeout")
- try:
- build_info = jclient.get_build_info(job_name, build_number)
- if build_info["result"] == 'FAILURE':
- outcome = 'fail'
- else:
- outcome = 'success'
-
- output = jclient.get_build_console_output(job_name, build_number)
- return outcome, output
- except NotFoundException as e:
- print("Jenkins job {} not running yet".format(build_number))
- except:
- raise
@@ -1,14 +1,15 @@
#!/usr/bin/env python3
-import sys
-sys.path.append('lib')
-import os
import json
-from charmhelpers.core import hookenv
-from controller.helpers import get_controllers
+import sys
+
+sys.path.append('lib')
+from charms.layer.basic import activate_venv # noqa: E402
+activate_venv()
+from charmhelpers.core import hookenv # noqa: E402
+from controller.helpers import get_controllers # noqa: E402
-HOME = "/var/lib/jenkins"
def list_controllers():
'''
@@ -1,9 +1,16 @@
#!/usr/bin/env python3
-from jenkinshelpers import wait_result
-from charmhelpers.core import hookenv
-from charms.reactive import RelationBase
-from jenkins import Jenkins, NotFoundException
-from subprocess import call
+
+import subprocess
+import sys
+
+sys.path.append('lib')
+from charms.layer.basic import activate_venv # noqa: E402
+activate_venv()
+
+from cwrhelpers import wait_result # noqa: E402
+from charmhelpers.core import hookenv # noqa: E402
+from charms.reactive import RelationBase # noqa: E402
+from jenkins import Jenkins # noqa: E402
def register_controller():
@@ -29,7 +36,7 @@ def register_controller():
build_outcome, build_output = wait_result(jclient, "RegisterController", next_build_number)
hookenv.action_set({'outcome': build_outcome})
hookenv.action_set({"output": build_output})
- call(["hooks/update-status"])
+ subprocess.call(["hooks/update-status"])
if __name__ == "__main__":
View
@@ -1,11 +1,17 @@
#!/usr/bin/env python3
-import os
-import errno
+
import base64
+import errno
+import os
import subprocess
-from charmhelpers.core.host import chownr
-from charmhelpers.core import hookenv
+import sys
+
+sys.path.append('lib')
+from charms.layer.basic import activate_venv # noqa: E402
+activate_venv()
+from charmhelpers.core.host import chownr # noqa: E402
+from charmhelpers.core import hookenv # noqa: E402
USER = "jenkins"
GROUP = "jenkins"
View
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-import subprocess
+import subprocess
USER = "jenkins"
@@ -1,9 +1,16 @@
#!/usr/bin/env python3
-from jenkinshelpers import wait_result
-from charmhelpers.core import hookenv
-from charms.reactive import RelationBase
-from jenkins import Jenkins
-from subprocess import call
+
+import subprocess
+import sys
+
+sys.path.append('lib')
+from charms.layer.basic import activate_venv # noqa: E402
+activate_venv()
+
+from cwrhelpers import wait_result # noqa: E402
+from charmhelpers.core import hookenv # noqa: E402
+from charms.reactive import RelationBase # noqa: E402
+from jenkins import Jenkins # noqa: E402
def unregister_controller():
@@ -24,10 +31,10 @@ def unregister_controller():
params = {'CONTROLLER_NAME': name}
jclient.build_job("UnregisterController", params)
- build_outcome, build_output = wait_result(jclient, "UnregisterController", next_build_number)
+ build_outcome, build_output = wait_result(jclient, "UnregisterController", next_build_number)
hookenv.action_set({'outcome': build_outcome})
hookenv.action_set({"output": build_output})
- call(["hooks/update-status"])
+ subprocess.call(["hooks/update-status"])
if __name__ == "__main__":
@@ -23,7 +23,7 @@
<builders>
<hudson.tasks.Shell>
<command>
-sed -i.bak '/lxd/c\' /var/lib/jenkins/controller.names
+sed -i.bak "/$CONTROLLER_NAME/d" /var/lib/jenkins/controller.names
juju unregister $CONTROLLER_NAME -y
</command>
</hudson.tasks.Shell>
@@ -50,8 +50,18 @@ export JUJU_REPOSITORY=&quot;/tmp/&quot;
charm build
juju switch {{controller}}
-juju add-model test-$BUILD_NUMBER
-bundletester -e {{controller}}:test-$BUILD_NUMBER -vFt /tmp/builds/{{charmname}}
+juju add-model test-{{charmname}}-$BUILD_NUMBER
+
+if [ -z "{{referencebundle}}"]
+then
+ bundletester -e {{controller}}:test-{{charmname}}-$BUILD_NUMBER \
+ -vFt /tmp/builds/{{charmname}}
+else
+ juju deploy -m {{controller}}:test-{{charmname}}-$BUILD_NUMBER \
+ /tmp/builds/{{charmname}} {{bundleappname}}
+ bundletester -e {{controller}}:test-{{charmname}}-$BUILD_NUMBER \
+ -vFt {{referencebundle}} --bundle bundle.yaml
+fi
if [ ! -z "{{pushtochannel}}" ]
then
@@ -66,7 +76,7 @@ fi
<org.jenkinsci.plugins.postbuildscript.PostBuildScript plugin="postbuildscript@0.17">
<buildSteps>
<hudson.tasks.Shell>
- <command>juju destroy-model test-$BUILD_NUMBER -y</command>
+ <command>juju destroy-model test-{{charmname}}-$BUILD_NUMBER -y</command>
</hudson.tasks.Shell>
</buildSteps>
<scriptOnlyIfSuccess>false</scriptOnlyIfSuccess>
View
@@ -1,2 +1,3 @@
jujubigdata>=7.0.0,<8.0.0
-python-jenkins>=0.4.13,<1.0.0
+python-jenkins>=0.4.13,<1.0.0
+theblues