from shutil import which
__all__ = [
- "force_scheduler", "deploy_scheduler", "hook_scheduler",
+ "force_scheduler", "deploy_scheduler", "git_hook_scheduler",
"clean_branch", "package_and_upload", "SlackStatusPush",
- "XMPPStatusPush", "NixShellCommand"
+ "XMPPStatusPush", "LdapEdit", "NixShellCommand",
+ "all_builder_names", "compute_build_infos", "deploy_ssh_command",
+ "configure_slack_push", "configure_xmpp_push", "deploy_hook_scheduler",
]
# Small helpers"
def package_and_upload(package, package_dest, package_url):
return [
steps.ShellCommand(name="build package",
- logEnviron=False, haltOnFailure=True, workdir="source",
+ logEnviron=False, haltOnFailure=True,
command=["git", "archive", "HEAD", "-o", package]),
steps.FileUpload(name="upload package", workersrc=package,
- workdir="source", masterdest=package_dest,
+ masterdest=package_dest,
url=package_url, mode=0o644),
steps.ShellCommand(name="cleanup package", logEnviron=False,
- haltOnFailure=True, workdir="source", alwaysRun=True,
+ haltOnFailure=True, alwaysRun=True,
command=["rm", "-f", package]),
]
# Steps
class NixShellCommand(steps.ShellCommand):
def __init__(self, command=None, pure=True, nixfile=None, **kwargs):
- assert(isinstance(command, str))
oldpath = kwargs.get("env", {}).get("PATH", None)
if which("nix-shell", path=oldpath) is None:
kwargs["env"] = kwargs.get("env", {})
super().__init__(command=nixcommand, **kwargs)
# Schedulers
-def force_scheduler(name, builders):
+def force_scheduler(name, builders, nobranch=False):
+ if nobranch:
+ branch = util.FixedParameter(name="branch", default="")
+ else:
+ branch=util.StringParameter(name="branch", label="Git reference (tag, branch)", required=True)
+
return schedulers.ForceScheduler(name=name,
label="Force build", buttonName="Force build",
reason=util.StringParameter(name="reason", label="Reason", default="Force build"),
codebases=[
util.CodebaseParameter("",
- branch=util.StringParameter(
- name="branch", label="Git reference (tag, branch)", required=True),
+ branch=branch,
revision=util.FixedParameter(name="revision", default=""),
repository=util.FixedParameter(name="repository", default=""),
project=util.FixedParameter(name="project", default=""),
]
)
-def hook_scheduler(project, timer=10):
+def git_hook_scheduler(project, builders=[], timer=1):
+ if len(builders) == 0:
+ builders = ["{}_build".format(project)]
+ return schedulers.AnyBranchScheduler(
+ change_filter=util.ChangeFilter(category="gitolite-hooks", project=project),
+ name="{}_git_hook".format(project), treeStableTimer=timer, builderNames=builders)
+
+def deploy_hook_scheduler(project, builders, timer=1):
return schedulers.AnyBranchScheduler(
- change_filter=util.ChangeFilter(category="hooks", project=project),
- name=project, treeStableTimer=timer, builderNames=["{}_build".format(project)])
+ change_filter=util.ChangeFilter(category="deploy_webhook", project=project),
+ name="{}_deploy".format(project), treeStableTimer=timer, builderNames=builders)
+
+# Builders
+def all_builder_names(c):
+ return [builder.name for builder in c['builders']]
# Slack/XMPP status push
from buildbot.reporters.http import HttpStatusPushBase
"attachments": attachments,
}
+def configure_slack_push(c, secrets_file, builders):
+ c['services'].append(SlackStatusPush(
+ name="slack_status", builders=builders,
+ serverUrl=open(secrets_file + "/slack_webhook", "r").read().rstrip()))
+
class XMPPStatusPush(HttpStatusPushBase):
name = "XMPPStatusPush"
)
return text
+
+def configure_xmpp_push(c, secrets_file, builders, recipients):
+ c['services'].append(XMPPStatusPush(
+ name="xmpp_status", builders=builders, recipients=recipients,
+ password=open(secrets_file + "/notify_xmpp_password", "r").read().rstrip()))
+
+# LDAP edit
+from buildbot.process.buildstep import FAILURE
+from buildbot.process.buildstep import SUCCESS
+from buildbot.process.buildstep import BuildStep
+
+class LdapEdit(BuildStep):
+ name = "LdapEdit"
+ renderables = ["environment", "build_version", "build_hash", "ldap_password"]
+
+ def __init__(self, **kwargs):
+ self.environment = kwargs.pop("environment")
+ self.build_version = kwargs.pop("build_version")
+ self.build_hash = kwargs.pop("build_hash")
+ self.ldap_password = kwargs.pop("ldap_password")
+ self.ldap_host = kwargs.pop("ldap_host")
+ self.ldap_dn = kwargs.pop("ldap_dn")
+ self.ldap_roles_base = kwargs.pop("ldap_roles_base")
+ self.ldap_cn_template = kwargs.pop("ldap_cn_template")
+ self.config_key = kwargs.pop("config_key")
+ super().__init__(**kwargs)
+
+ def run(self):
+ import json
+ from ldap3 import Reader, Writer, Server, Connection, ObjectDef
+ server = Server(self.ldap_host)
+ conn = Connection(server,
+ user=self.ldap_dn,
+ password=self.ldap_password)
+ conn.bind()
+ obj = ObjectDef("immaePuppetClass", conn)
+ r = Reader(conn, obj,
+ "cn={},{}".format(self.ldap_cn_template.format(self.environment), self.ldap_roles_base))
+ r.search()
+ if len(r) > 0:
+ w = Writer.from_cursor(r)
+ for value in w[0].immaePuppetJson.values:
+ config = json.loads(value)
+ if "{}_version".format(self.config_key) in config:
+ config["{}_version".format(self.config_key)] = self.build_version
+ config["{}_sha256".format(self.config_key)] = self.build_hash
+ w[0].immaePuppetJson -= value
+ w[0].immaePuppetJson += json.dumps(config, indent=" ")
+ w.commit()
+ return defer.succeed(SUCCESS)
+ return defer.succeed(FAILURE)
+
+def compute_build_infos(prefix, release_path):
+ @util.renderer
+ def compute(props):
+ import re, hashlib
+ build_file = props.getProperty("build")
+ package_dest = "{}/{}".format(release_path, build_file)
+ version = re.match(r"{0}_(.*).tar.gz".format(prefix), build_file).group(1)
+ with open(package_dest, "rb") as f:
+ sha = hashlib.sha256(f.read()).hexdigest()
+ return {
+ "build_version": version,
+ "build_hash": sha,
+ }
+ return compute
+
+def deploy_ssh_command(ssh_key_path, deploy_hosts):
+ @util.renderer
+ def compute(props):
+ environment = props["environment"] if props.hasProperty("environment") else "integration"
+ ssh_command = [
+ "ssh", "-o", "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "-o", "CheckHostIP=no",
+ "-i", ssh_key_path ]
+ return ssh_command + deploy_hosts.get(environment, ["host.invalid"])
+ return compute