mirror of https://github.com/sipwise/repoapi.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
249 lines
7.6 KiB
249 lines
7.6 KiB
# Copyright (C) 2017 The Sipwise Team - http://sipwise.com
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify it
|
|
# under the terms of the GNU General Public License as published by the Free
|
|
# Software Foundation, either version 3 of the License, or (at your option)
|
|
# any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
# more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along
|
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
import logging
|
|
import os
|
|
import re
|
|
import urllib
|
|
from pathlib import Path
|
|
from uuid import uuid4
|
|
|
|
from yaml import load
|
|
from yaml import Loader
|
|
|
|
from . import exceptions as err
|
|
from .conf import settings
|
|
from repoapi.utils import openurl
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
base_url = (
|
|
"{base}/job/{job}/buildWithParameters?"
|
|
"token={token}&cause={cause}&uuid={uuid}&"
|
|
"release_uuid={release_uuid}"
|
|
)
|
|
project_url = (
|
|
base_url + "&branch={branch}&tag={tag}&release={release}&"
|
|
"distribution={distribution}"
|
|
)
|
|
copy_deps_url = base_url + "&release={release}&internal={internal}"
|
|
re_release = re.compile(r"^release-(mr[0-9]+\.[0-9]+(\.[0-9]+)?)$")
|
|
re_release_common = re.compile(r"^(release-)?(mr[0-9]+\.[0-9]+)(\.[0-9]+)?$")
|
|
|
|
|
|
def get_simple_release(version):
|
|
match = re_release.search(version)
|
|
if match:
|
|
return match.group(1)
|
|
if version.startswith("release-trunk-"):
|
|
return "trunk"
|
|
|
|
|
|
def get_common_release(version):
|
|
match = re_release_common.search(version)
|
|
if match:
|
|
return match.group(2)
|
|
if version.startswith("release-trunk-") or version == "trunk":
|
|
return "master"
|
|
|
|
|
|
def trigger_copy_deps(release, internal, release_uuid, uuid=None):
|
|
if release.startswith("release-trunk-"):
|
|
simple = release
|
|
else:
|
|
simple = get_simple_release(release)
|
|
if uuid is None:
|
|
uuid = uuid4()
|
|
params = {
|
|
"base": settings.JENKINS_URL,
|
|
"token": urllib.parse.quote(settings.JENKINS_TOKEN),
|
|
"job": "release-copy-debs-yml",
|
|
"cause": release,
|
|
"release": simple,
|
|
"internal": str(internal).lower(),
|
|
"uuid": uuid,
|
|
"release_uuid": release_uuid,
|
|
}
|
|
url = copy_deps_url.format(**params)
|
|
if settings.DEBUG:
|
|
logger.info("Debug mode, would trigger: %s", url)
|
|
else:
|
|
openurl(url)
|
|
return "{base}/job/{job}/".format(**params)
|
|
|
|
|
|
def trigger_build(
|
|
project,
|
|
release_uuid,
|
|
trigger_release,
|
|
trigger_branch_or_tag,
|
|
trigger_distribution,
|
|
uuid=None,
|
|
):
|
|
if uuid is None:
|
|
uuid = uuid4()
|
|
params = {
|
|
"base": settings.JENKINS_URL,
|
|
"job": project,
|
|
"token": urllib.parse.quote(settings.JENKINS_TOKEN),
|
|
"cause": urllib.parse.quote(trigger_release),
|
|
"branch": "none",
|
|
"tag": "none",
|
|
"release": urllib.parse.quote(trigger_release),
|
|
"distribution": urllib.parse.quote(trigger_distribution),
|
|
"uuid": uuid,
|
|
"release_uuid": release_uuid,
|
|
}
|
|
if trigger_branch_or_tag.startswith("tag/"):
|
|
tag = trigger_branch_or_tag.split("tag/")[1]
|
|
params["tag"] = urllib.parse.quote(tag)
|
|
|
|
# branch is like tag but removing the last element,
|
|
# e.g. tag=mr5.5.2.1 -> branch=mr5.5.2
|
|
branch = ".".join(tag.split(".")[0:-1])
|
|
params["branch"] = urllib.parse.quote(branch)
|
|
elif trigger_branch_or_tag.startswith("branch/"):
|
|
branch = trigger_branch_or_tag.split("branch/")[1]
|
|
params["branch"] = urllib.parse.quote(branch)
|
|
else:
|
|
params["branch"] = urllib.parse.quote(trigger_branch_or_tag)
|
|
|
|
url = project_url.format(**params)
|
|
if settings.DEBUG:
|
|
logger.info("Debug mode, would trigger: %s", url)
|
|
else:
|
|
openurl(url)
|
|
return "{base}/job/{job}/".format(**params)
|
|
|
|
|
|
class ReleaseConfig(object):
|
|
class WannaBuild:
|
|
def __init__(self, config, step=1):
|
|
self.config = config
|
|
self.no_deps = []
|
|
self.deps = []
|
|
self.step = step
|
|
build_deps = self.config.build_deps
|
|
for name in build_deps.keys():
|
|
flag = False
|
|
for prj, values in build_deps.items():
|
|
if name in values:
|
|
flag = True
|
|
self.deps.append(name)
|
|
break
|
|
if not flag:
|
|
self.no_deps.append(name)
|
|
|
|
def __iter__(self):
|
|
return self
|
|
|
|
def __next__(self):
|
|
if self.step == 0:
|
|
list_prj = self.no_deps
|
|
else:
|
|
list_prj = self.deps
|
|
|
|
if len(list_prj) > 0:
|
|
return list_prj.pop(0)
|
|
raise StopIteration
|
|
|
|
@classmethod
|
|
def supported_releases(cls):
|
|
skip_files = ["{}.yml".format(x) for x in settings.BUILD_RELEASES_SKIP]
|
|
res = []
|
|
for root, dirs, files in os.walk(
|
|
settings.BUILD_REPOS_SCRIPTS_CONFIG_DIR
|
|
):
|
|
for name in files:
|
|
path_name = Path(name)
|
|
if path_name.suffix != ".yml":
|
|
continue
|
|
if name not in skip_files:
|
|
res.append(Path(name).stem)
|
|
res.sort(reverse=True)
|
|
return res
|
|
|
|
@classmethod
|
|
def supported_releases_dict(cls):
|
|
sr = cls.supported_releases()
|
|
return [
|
|
{"release": version, "base": get_common_release(version)}
|
|
for version in sr
|
|
]
|
|
|
|
def __init__(self, name):
|
|
filename = get_simple_release(name)
|
|
if filename is None:
|
|
filename = name
|
|
self.config_file = "{}.yml".format(filename)
|
|
self.config_path = os.path.join(
|
|
settings.BUILD_REPOS_SCRIPTS_CONFIG_DIR, self.config_file
|
|
)
|
|
try:
|
|
with open(self.config_path) as f:
|
|
self.config = load(f, Loader=Loader)
|
|
except IOError:
|
|
msg = "could not read configuration file '{}'"
|
|
raise err.NoConfigReleaseFile(msg.format(self.config_path))
|
|
try:
|
|
self.jenkins_jobs = self.config["jenkins-jobs"]
|
|
except KeyError:
|
|
msg = "{} has no 'jenkins-jobs' info"
|
|
raise err.NoJenkinsJobsInfo(msg.format(self.config_file))
|
|
try:
|
|
if self.release is None:
|
|
raise err.NoReleaseInfo()
|
|
except KeyError:
|
|
msg = "{} has no 'distris' info"
|
|
raise err.NoDistrisInfo(msg.format(self.config_file))
|
|
|
|
@property
|
|
def build_deps(self):
|
|
return self.jenkins_jobs.get("build_deps", dict())
|
|
|
|
def wanna_build_deps(self, step=0):
|
|
return ReleaseConfig.WannaBuild(self, step)
|
|
|
|
@property
|
|
def branch(self):
|
|
release = self.release
|
|
if release == "trunk":
|
|
return "master"
|
|
release_count = release.count(".")
|
|
if release_count in [1, 2]:
|
|
return get_simple_release(release)
|
|
|
|
@property
|
|
def tag(self):
|
|
release = self.release
|
|
release_count = release.count(".")
|
|
if release_count == 2:
|
|
return "{}.1".format(get_simple_release(release))
|
|
|
|
@property
|
|
def release(self):
|
|
for dist in self.config["distris"]:
|
|
if dist.startswith("release-trunk-"):
|
|
return "trunk"
|
|
if dist.startswith("release-"):
|
|
return dist
|
|
|
|
@property
|
|
def debian_release(self):
|
|
return self.config["debian_release"]
|
|
|
|
@property
|
|
def projects(self):
|
|
return self.jenkins_jobs["projects"]
|