TT#43813 release_dashboard: split settings per application

Using https://django-appconf.readthedocs.io/en/latest/ helps us to
keep configs per application

Change-Id: I6dbac01d56ce1ea71d611e0e98a74a0875fe747c
changes/17/38717/3
Victor Seva 6 years ago
parent e9e2833f35
commit 3237f930fd

@ -0,0 +1,185 @@
# Copyright (C) 2020 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/>.
from django.conf import settings # noqa
from appconf import AppConf
class ReleaseDashboardConf(AppConf):
FILTER_TAGS = r"^refs/tags/(.+)$"
FILTER_BRANCHES = r"^refs/heads/(.+)$"
FILTER_MRXX = r"^mr[0-9]+\.[0-9]+$"
FILTER_MRXXX = r"^mr[0-9]+\.[0-9]+\.[0-9]+$"
DEBIAN_RELEASES = (
"auto",
"buster",
"stretch",
"jessie",
"wheezy",
"squeeze",
)
BUILD_DEPS = (
"check-tools",
"data-hal",
"libswrate",
"sipwise-base",
"mediaproxy-ng",
"ngcp-schema",
"rtpengine",
"libtcap",
"libinewrate",
)
PROJECTS = (
"acc-cdi",
"asterisk",
"asterisk-sounds",
"asterisk-voicemail",
"backup-tools",
"bulk-processor",
"bulk-processor-projects",
"bootenv",
"captagent",
"cdr-exporter",
"cfg-schema",
"check-tools",
"cleanup-tools",
"cloudpbx-devices",
"cloudpbx-sources",
"collectd-mod-redis",
"comx",
"comx-application",
"comx-fileshare-service",
"comx-sip",
"comx-xmpp",
"csta-testsuite",
"data-hal",
"db-schema",
"dhtest",
"diva-drivers",
"deployment-iso",
"documentation",
"faxserver",
"glusterfs-config",
"heartbeat",
"hylafaxplus",
"iaxmodem",
"installer",
"janus-admin",
"janus-client",
"kamailio",
"kamailio-config-tests",
"keyring",
"kibana",
"klish",
"libhsclient-c-wrapper",
"libinewrate",
"libswrate",
"libtcap",
"license-client",
"lnpd",
"lua-ngcp-kamailio",
"mediaproxy-ng",
"mediaproxy-redis",
"mediator",
"megacli",
"metapackages",
"monitoring-tools",
"netscript",
"ngcp-api-tools",
"ngcp-csc",
"ngcp-csc-ui",
"ngcp-exporter",
"ngcp-fauditd",
"ngcp-inventory",
"ngcp-klish-config",
"ngcp-logfs",
"ngcp-panel",
"ngcp-prompts",
"ngcp-rtcengine",
"ngcp-schema",
"ngcp-status",
"ngcp-sudo-plugin",
"ngcp-support",
"ngcp-user-framework",
"ngcpcfg",
"ngcpcfg-api",
"ngcpcfg-ha",
"ngrep-sip",
"ossbss",
"prosody",
"pushd",
"rate-o-mat",
"reminder",
"rtpengine",
"rtpengine-redis",
"sems",
"sems-app",
"sems-ha",
"sems-modules",
"sems-pbx",
"sems-prompts",
"sipsak",
"sipwise-base",
"snmp-agent",
"system-tests",
"system-tools",
"templates",
"upgrade",
"vmnotify",
"voisniff-ng",
"websocket",
"www_admin",
"www_csc",
)
ABANDONED = (
"asterisk",
"asterisk-sounds",
"cloudpbx-devices",
"collectd-mod-redis",
"comx",
"comx-sip",
"comx-xmpp",
"diva-drivers",
"hylafaxplus",
"iaxmodem",
"mediaproxy-ng",
"mediaproxy-redis",
"rtpengine-redis",
"ossbss",
"sems-prompts",
"sipsak",
"www_admin",
"www_csc",
)
DOCKER_PROJECTS = (
"comx-fileshare-service",
"data-hal",
"documentation",
"janus-admin",
"janus-client",
"kamailio-config-tests",
"libswrate",
"libtcap",
"lua-ngcp-kamailio",
"ngcp-csc",
"ngcp-panel",
"ngcp-rtcengine",
"ngcpcfg",
"rate-o-mat",
"snmp-agent",
"system-tools",
)
class Meta:
prefix = "release_dashboard"

@ -1,24 +1,21 @@
# Copyright (C) 2017 The Sipwise Team - http://sipwise.com # Copyright (C) 2017 The Sipwise Team - http://sipwise.com
#
# This program is free software: you can redistribute it and/or modify it # 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 # 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) # Software Foundation, either version 3 of the License, or (at your option)
# any later version. # any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT # This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details. # more details.
#
# You should have received a copy of the GNU General Public License along # You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>. # with this program. If not, see <http://www.gnu.org/licenses/>.
from ..conf import settings
from django.conf import settings projects = set(settings.RELEASE_DASHBOARD_PROJECTS)
abandoned = set(settings.RELEASE_DASHBOARD_ABANDONED)
rd_settings = settings.RELEASE_DASHBOARD_SETTINGS build_deps = set(settings.RELEASE_DASHBOARD_BUILD_DEPS)
trunk_projects = sorted(set(rd_settings['projects']) - trunk_projects = sorted(projects - abandoned - build_deps)
set(rd_settings['abandoned']) - trunk_build_deps = sorted(build_deps - abandoned)
set(rd_settings['build_deps']))
trunk_build_deps = sorted(set(rd_settings['build_deps']) -
set(rd_settings['abandoned']))
docker_projects = rd_settings['docker_projects']

@ -1,21 +1,22 @@
# Copyright (C) 2016 The Sipwise Team - http://sipwise.com # Copyright (C) 2016 The Sipwise Team - http://sipwise.com
#
# This program is free software: you can redistribute it and/or modify it # 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 # 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) # Software Foundation, either version 3 of the License, or (at your option)
# any later version. # any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT # This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details. # more details.
#
# You should have received a copy of the GNU General Public License along # You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>. # with this program. If not, see <http://www.gnu.org/licenses/>.
from django import forms from django import forms
from . import rd_settings
from . import trunk_projects, trunk_build_deps from . import trunk_build_deps
from . import trunk_projects
from ..conf import settings
class BuildForm(forms.Form): class BuildForm(forms.Form):
@ -25,40 +26,40 @@ class BuildForm(forms.Form):
class BuildDepForm(BuildForm): class BuildDepForm(BuildForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(BuildDepForm, self).__init__(*args, **kwargs) super(BuildDepForm, self).__init__(*args, **kwargs)
for project in rd_settings['build_deps']: for project in settings.RELEASE_DASHBOARD_BUILD_DEPS:
self.fields['version_%s' % self.fields["version_%s" % project] = forms.CharField(
project] = forms.CharField(max_length=15) max_length=15
)
class BuildReleaseForm(BuildForm): class BuildReleaseForm(BuildForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(BuildReleaseForm, self).__init__(*args, **kwargs) super(BuildReleaseForm, self).__init__(*args, **kwargs)
for project in rd_settings['projects']: for project in settings.RELEASE_DASHBOARD_PROJECTS:
self.fields['version_%s' % self.fields["version_%s" % project] = forms.CharField(
project] = forms.CharField(max_length=15) max_length=15
)
class BuildTrunkDepForm(BuildForm): class BuildTrunkDepForm(BuildForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(BuildTrunkDepForm, self).__init__(*args, **kwargs) super(BuildTrunkDepForm, self).__init__(*args, **kwargs)
for project in trunk_build_deps: for project in trunk_build_deps:
self.fields['version_%s' % self.fields["version_%s" % project] = forms.CharField(
project] = forms.CharField(max_length=30) max_length=30
)
class BuildTrunkReleaseForm(BuildForm): class BuildTrunkReleaseForm(BuildForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(BuildTrunkReleaseForm, self).__init__(*args, **kwargs) super(BuildTrunkReleaseForm, self).__init__(*args, **kwargs)
for project in trunk_projects: for project in trunk_projects:
self.fields['version_%s' % self.fields["version_%s" % project] = forms.CharField(
project] = forms.CharField(max_length=30) max_length=30
)

@ -1,20 +1,20 @@
# Copyright (C) 2016 The Sipwise Team - http://sipwise.com # Copyright (C) 2016 The Sipwise Team - http://sipwise.com
#
# This program is free software: you can redistribute it and/or modify it # 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 # 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) # Software Foundation, either version 3 of the License, or (at your option)
# any later version. # any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT # This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details. # more details.
#
# You should have received a copy of the GNU General Public License along # You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>. # with this program. If not, see <http://www.gnu.org/licenses/>.
from django import forms from django import forms
from . import docker_projects
from ..conf import settings
class BuildDockerForm(forms.Form): class BuildDockerForm(forms.Form):
@ -23,6 +23,7 @@ class BuildDockerForm(forms.Form):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(BuildDockerForm, self).__init__(*args, **kwargs) super(BuildDockerForm, self).__init__(*args, **kwargs)
for project in docker_projects: for project in settings.RELEASE_DASHBOARD_DOCKER_PROJECTS:
self.fields['version_%s' % self.fields["version_%s" % project] = forms.CharField(
project] = forms.CharField(max_length=15) max_length=15
)

@ -1,24 +1,27 @@
# Copyright (C) 2016 The Sipwise Team - http://sipwise.com # Copyright (C) 2016 The Sipwise Team - http://sipwise.com
#
# This program is free software: you can redistribute it and/or modify it # 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 # 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) # Software Foundation, either version 3 of the License, or (at your option)
# any later version. # any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT # This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details. # more details.
#
# You should have received a copy of the GNU General Public License along # You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>. # with this program. If not, see <http://www.gnu.org/licenses/>.
import json
import logging import logging
import re import re
import json
from datetime import datetime from datetime import datetime
from django.db import models from django.db import models
from django_extensions.db.fields.json import JSONField
from django_extensions.db.fields import ModificationDateTimeField from django_extensions.db.fields import ModificationDateTimeField
from django_extensions.db.fields.json import JSONField
from .conf import settings
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -56,7 +59,9 @@ class Project(models.Model):
@property @property
def tags(self): def tags(self):
return Project._filter_values(self.json_tags, '^refs/tags/(.+)$') return Project._filter_values(
self.json_tags, settings.RELEASE_DASHBOARD_FILTER_TAGS
)
@tags.setter @tags.setter
def tags(self, value): def tags(self, value):
@ -64,33 +69,38 @@ class Project(models.Model):
@property @property
def branches(self): def branches(self):
return Project._filter_values(self.json_branches, '^refs/heads/(.+)$') return Project._filter_values(
self.json_branches, settings.RELEASE_DASHBOARD_FILTER_BRANCHES
)
@branches.setter @branches.setter
def branches(self, value): def branches(self, value):
self.json_branches = Project._get_filtered_json(value) self.json_branches = Project._get_filtered_json(value)
def filter_tags(self, regex): def filter_tags(self, regex):
return Project._filter_values(self.json_tags, return Project._filter_values(
'^refs/tags/(.+)$', regex) self.json_tags, settings.RELEASE_DASHBOARD_FILTER_TAGS, regex
)
def filter_branches(self, regex): def filter_branches(self, regex):
return Project._filter_values(self.json_branches, return Project._filter_values(
'^refs/heads/(.+)$', regex) self.json_branches,
settings.RELEASE_DASHBOARD_FILTER_BRANCHES,
regex,
)
def filter_docker_images(self, images): def filter_docker_images(self, images):
r = re.compile(self.name) r = re.compile(self.name)
return filter(r.search, images) return filter(r.search, images)
def branches_mrXX(self): def branches_mrXX(self):
return self.filter_branches(r'^mr[0-9]+\.[0-9]+$') return self.filter_branches(settings.RELEASE_DASHBOARD_FILTER_MRXX)
def branches_mrXXX(self): def branches_mrXXX(self):
return self.filter_branches(r'^mr[0-9]+\.[0-9]+\.[0-9]+$') return self.filter_branches(settings.RELEASE_DASHBOARD_FILTER_MRXXX)
class DockerImageManager(models.Manager): class DockerImageManager(models.Manager):
def images_with_tags(self, project=None): def images_with_tags(self, project=None):
qs = self.get_queryset().filter(dockertag__isnull=False) qs = self.get_queryset().filter(dockertag__isnull=False)
if project: if project:
@ -109,7 +119,7 @@ class DockerImage(models.Model):
@property @property
def tags(self): def tags(self):
res = self.dockertag_set.all().values_list('name', flat=True) res = self.dockertag_set.all().values_list("name", flat=True)
return res return res
@ -130,11 +140,9 @@ class DockerTag(models.Model):
if self.manifests is None: if self.manifests is None:
return None return None
try: try:
value = self.manifests['history'][0]['v1Compatibility'] value = self.manifests["history"][0]["v1Compatibility"]
time = json.loads(value) time = json.loads(value)
created = time['created'].split('.') created = time["created"].split(".")
return datetime.strptime( return datetime.strptime(created[0], "%Y-%m-%dT%H:%M:%S")
created[0], except Exception:
'%Y-%m-%dT%H:%M:%S')
except Exception as e:
return None return None

@ -1,28 +1,29 @@
# Copyright (C) 2016 The Sipwise Team - http://sipwise.com # Copyright (C) 2016 The Sipwise Team - http://sipwise.com
#
# This program is free software: you can redistribute it and/or modify it # 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 # 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) # Software Foundation, either version 3 of the License, or (at your option)
# any later version. # any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT # This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details. # more details.
#
# You should have received a copy of the GNU General Public License along # You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>. # with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import absolute_import
import logging import logging
from celery import shared_task from celery import shared_task
from release_dashboard.models import Project, DockerImage, DockerTag
from django.conf import settings from .conf import settings
from .models import DockerImage
from .models import DockerTag
from .models import Project
from .utils import build from .utils import build
from .utils import docker from .utils import docker
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
rd_settings = settings.RELEASE_DASHBOARD_SETTINGS
@shared_task(ignore_result=True) @shared_task(ignore_result=True)
@ -35,7 +36,7 @@ def gerrit_fetch_info(projectname):
@shared_task(ignore_result=True) @shared_task(ignore_result=True)
def gerrit_fetch_all(): def gerrit_fetch_all():
for project in rd_settings['projects']: for project in settings.RELEASE_DASHBOARD_PROJECTS:
gerrit_fetch_info.delay(project) gerrit_fetch_info.delay(project)
@ -47,10 +48,8 @@ def docker_fetch_info(imagename):
manifest, digest = docker.get_docker_manifests(image.name, tagname) manifest, digest = docker.get_docker_manifests(image.name, tagname)
if digest: if digest:
DockerTag.objects.create( DockerTag.objects.create(
name=tagname, name=tagname, image=image, manifests=manifest, reference=digest
image=image, )
manifests=manifest,
reference=digest)
@shared_task(ignore_result=True) @shared_task(ignore_result=True)
@ -59,8 +58,7 @@ def docker_fetch_project(projectname):
images = docker.get_docker_repositories() images = docker.get_docker_repositories()
project = Project.objects.get(name=projectname) project = Project.objects.get(name=projectname)
for imagename in project.filter_docker_images(images): for imagename in project.filter_docker_images(images):
image = DockerImage.objects.create(name=imagename, image = DockerImage.objects.create(name=imagename, project=project)
project=project)
logger.debug("%s created" % image) logger.debug("%s created" % image)
docker_fetch_info.delay(image.name) docker_fetch_info.delay(image.name)
@ -70,11 +68,10 @@ def docker_fetch_all():
DockerImage.objects.all().delete() DockerImage.objects.all().delete()
images = docker.get_docker_repositories() images = docker.get_docker_repositories()
logger.debug("images: %s" % images) logger.debug("images: %s" % images)
for projectname in rd_settings['docker_projects']: for projectname in settings.RELEASE_DASHBOARD_DOCKER_PROJECTS:
project, _ = Project.objects.get_or_create(name=projectname) project, _ = Project.objects.get_or_create(name=projectname)
for imagename in project.filter_docker_images(images): for imagename in project.filter_docker_images(images):
image = DockerImage.objects.create(name=imagename, image = DockerImage.objects.create(name=imagename, project=project)
project=project)
logger.debug("%s created" % image) logger.debug("%s created" % image)
docker_fetch_info.delay(image.name) docker_fetch_info.delay(image.name)

@ -0,0 +1,27 @@
# Copyright (C) 2015 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/>.
from django.test import TestCase
class TestReleaseDashboardConf(TestCase):
def test_django_settings(self):
from django.conf import settings
self.assertIsNotNone(settings.RELEASE_DASHBOARD_DEBIAN_RELEASES)
def test_release_dashboard_settings(self):
from release_dashboard.conf import settings
self.assertIsNotNone(settings.RELEASE_DASHBOARD_DEBIAN_RELEASES)

@ -1,43 +1,45 @@
# Copyright (C) 2015 The Sipwise Team - http://sipwise.com # Copyright (C) 2015 The Sipwise Team - http://sipwise.com
# This program is free software: you can redistribute it and/or modify it # 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 # 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) # Software Foundation, either version 3 of the License, or (at your option)
# any later version. # any later version.
# This program is distributed in the hope that it will be useful, but WITHOUT # This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details. # more details.
# You should have received a copy of the GNU General Public License along # You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>. # with this program. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
import uuid
import urllib import urllib
import uuid
import requests import requests
from requests.auth import HTTPBasicAuth from requests.auth import HTTPBasicAuth
from django.conf import settings
from ..conf import settings
from repoapi.utils import openurl from repoapi.utils import openurl
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
project_url = ("{base}/job/{job}/buildWithParameters?" project_url = (
"{base}/job/{job}/buildWithParameters?"
"token={token}&cause={cause}&branch={branch}&" "token={token}&cause={cause}&branch={branch}&"
"tag={tag}&release={release}&" "tag={tag}&release={release}&"
"distribution={distribution}&uuid={uuid}") "distribution={distribution}&uuid={uuid}"
)
hotfix_url = ("{base}/job/release-tools-runner/buildWithParameters?" hotfix_url = (
"{base}/job/release-tools-runner/buildWithParameters?"
"token={token}&action={action}&branch={branch}&" "token={token}&action={action}&branch={branch}&"
"PROJECTNAME={project}&repository={project}&" "PROJECTNAME={project}&repository={project}&"
"push={push}&uuid={uuid}") "push={push}&uuid={uuid}"
)
def get_response(url): def get_response(url):
auth = HTTPBasicAuth( auth = HTTPBasicAuth(
settings.GERRIT_REST_HTTP_USER, settings.GERRIT_REST_HTTP_USER, settings.GERRIT_REST_HTTP_PASSWD
settings.GERRIT_REST_HTTP_PASSWD) )
response = requests.get(url, auth=auth) response = requests.get(url, auth=auth)
return response return response
@ -46,12 +48,12 @@ def trigger_hotfix(project, branch, push="yes"):
flow_uuid = uuid.uuid4() flow_uuid = uuid.uuid4()
params = { params = {
"base": settings.JENKINS_URL, "base": settings.JENKINS_URL,
'token': urllib.parse.quote(settings.JENKINS_TOKEN), "token": urllib.parse.quote(settings.JENKINS_TOKEN),
'action': urllib.parse.quote("--hotfix"), "action": urllib.parse.quote("--hotfix"),
'branch': urllib.parse.quote(branch), "branch": urllib.parse.quote(branch),
'project': urllib.parse.quote(project), "project": urllib.parse.quote(project),
'push': urllib.parse.quote(push), "push": urllib.parse.quote(push),
'uuid': flow_uuid, "uuid": flow_uuid,
} }
url = hotfix_url.format(**params) url = hotfix_url.format(**params)
@ -63,38 +65,44 @@ def trigger_hotfix(project, branch, push="yes"):
return "%s/job/release-tools-runner/" % settings.JENKINS_URL return "%s/job/release-tools-runner/" % settings.JENKINS_URL
def trigger_build(project, trigger_release=None, def trigger_build(
project,
trigger_release=None,
trigger_branch_or_tag=None, trigger_branch_or_tag=None,
trigger_distribution=None, trigger_distribution=None,
flow_uuid=uuid.uuid4()): flow_uuid=uuid.uuid4(),
):
if trigger_branch_or_tag == "ignore": if trigger_branch_or_tag == "ignore":
logger.debug("ignoring request to trigger project %s due" logger.debug(
" to request of version 'ignore'", project) "ignoring request to trigger project %s due"
" to request of version 'ignore'",
project,
)
return return
params = { params = {
'base': settings.JENKINS_URL, "base": settings.JENKINS_URL,
'job': project, "job": project,
'token': urllib.parse.quote(settings.JENKINS_TOKEN), "token": urllib.parse.quote(settings.JENKINS_TOKEN),
'cause': urllib.parse.quote(trigger_release), "cause": urllib.parse.quote(trigger_release),
'branch': 'none', "branch": "none",
'tag': 'none', "tag": "none",
'release': urllib.parse.quote(trigger_release), "release": urllib.parse.quote(trigger_release),
'distribution': urllib.parse.quote(trigger_distribution), "distribution": urllib.parse.quote(trigger_distribution),
'uuid': flow_uuid, "uuid": flow_uuid,
} }
if trigger_branch_or_tag.startswith("tag/"): if trigger_branch_or_tag.startswith("tag/"):
tag = trigger_branch_or_tag.split("tag/")[1] tag = trigger_branch_or_tag.split("tag/")[1]
params['tag'] = urllib.parse.quote(tag) params["tag"] = urllib.parse.quote(tag)
# branch is like tag but removing the last element, # branch is like tag but removing the last element,
# e.g. tag=mr5.5.2.1 -> branch=mr5.5.2 # e.g. tag=mr5.5.2.1 -> branch=mr5.5.2
branch = ".".join(tag.split(".")[0:-1]) branch = ".".join(tag.split(".")[0:-1])
params['branch'] = urllib.parse.quote(branch) params["branch"] = urllib.parse.quote(branch)
elif trigger_branch_or_tag.startswith("branch/"): elif trigger_branch_or_tag.startswith("branch/"):
branch = trigger_branch_or_tag.split("branch/")[1] branch = trigger_branch_or_tag.split("branch/")[1]
params['branch'] = urllib.parse.quote(branch) params["branch"] = urllib.parse.quote(branch)
else: else:
params['branch'] = urllib.parse.quote(trigger_branch_or_tag) params["branch"] = urllib.parse.quote(trigger_branch_or_tag)
url = project_url.format(**params) url = project_url.format(**params)
if settings.DEBUG: if settings.DEBUG:
@ -125,7 +133,6 @@ def get_gerrit_branches(project, regex=None):
def is_ngcp_project(projectname): def is_ngcp_project(projectname):
ngcp_projects = settings.RELEASE_DASHBOARD_SETTINGS['projects'] if projectname in settings.RELEASE_DASHBOARD_PROJECTS:
if projectname in ngcp_projects:
return True return True
return False return False

@ -1,43 +1,49 @@
# Copyright (C) 2017 The Sipwise Team - http://sipwise.com # Copyright (C) 2017 The Sipwise Team - http://sipwise.com
#
# This program is free software: you can redistribute it and/or modify it # 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 # 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) # Software Foundation, either version 3 of the License, or (at your option)
# any later version. # any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT # This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details. # more details.
#
# You should have received a copy of the GNU General Public License along # You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>. # with this program. If not, see <http://www.gnu.org/licenses/>.
import json
import logging import logging
import urllib import urllib
import requests
import json
import uuid import uuid
from django.conf import settings
import requests
from ..conf import settings
from repoapi.utils import openurl from repoapi.utils import openurl
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
docker_url = ("{base}/job/build-project-docker/buildWithParameters?" docker_url = (
"token={token}&project={project}&branch={branch}") "{base}/job/build-project-docker/buildWithParameters?"
"token={token}&project={project}&branch={branch}"
)
def trigger_docker_build(project, branch): def trigger_docker_build(project, branch):
if branch == "ignore": if branch == "ignore":
logger.debug("ignoring request to trigger project %s due" logger.debug(
" to request of version 'ignore'", project) "ignoring request to trigger project %s due"
" to request of version 'ignore'",
project,
)
return return
branch = branch.split("branch/")[1] branch = branch.split("branch/")[1]
params = { params = {
'base': settings.JENKINS_URL, "base": settings.JENKINS_URL,
'token': urllib.parse.quote(settings.JENKINS_TOKEN), "token": urllib.parse.quote(settings.JENKINS_TOKEN),
'project': project, "project": project,
'branch': urllib.parse.quote(branch), "branch": urllib.parse.quote(branch),
} }
url = docker_url.format(**params) url = docker_url.format(**params)
@ -69,10 +75,11 @@ def get_docker_info(url):
def get_docker_manifests_info(url): def get_docker_manifests_info(url):
headers = {'accept': headers = {
'application/vnd.docker.distribution.manifest.v2+json'} "accept": "application/vnd.docker.distribution.manifest.v2+json"
}
response = _get_info(url, headers) response = _get_info(url, headers)
return (response.text, response.headers['Docker-Content-Digest']) return (response.text, response.headers["Docker-Content-Digest"])
def delete_docker_info(url): def delete_docker_info(url):
@ -89,14 +96,14 @@ def delete_docker_info(url):
def get_docker_repositories(): def get_docker_repositories():
if settings.DEBUG: if settings.DEBUG:
result = json.loads(settings.DOCKER_REGISTRY) result = json.loads(settings.DOCKER_REGISTRY)
return result['repositories'] return result["repositories"]
else: else:
url = settings.DOCKER_REGISTRY_URL.format("_catalog") url = settings.DOCKER_REGISTRY_URL.format("_catalog")
try: try:
info = get_docker_info(url) info = get_docker_info(url)
logger.debug("response: %s" % info) logger.debug("response: %s" % info)
result = json.loads(info) result = json.loads(info)
return result['repositories'] return result["repositories"]
except Exception as e: except Exception as e:
logger.error(e) logger.error(e)
return [] return []
@ -105,8 +112,8 @@ def get_docker_repositories():
def get_docker_tags(image): def get_docker_tags(image):
if settings.DEBUG: if settings.DEBUG:
try: try:
return settings.DOCKER_IMAGES[image] return settings.RELEASE_DASHBOARD_DOCKER_IMAGES[image]
except Exception as e: except KeyError:
return [] return []
else: else:
url = settings.DOCKER_REGISTRY_URL.format("%s/tags/list" % image) url = settings.DOCKER_REGISTRY_URL.format("%s/tags/list" % image)
@ -114,15 +121,15 @@ def get_docker_tags(image):
info = get_docker_info(url) info = get_docker_info(url)
logger.debug("response: %s" % info) logger.debug("response: %s" % info)
result = json.loads(info) result = json.loads(info)
return result['tags'] return result["tags"]
except Exception as e: except Exception as e:
logger.error('image: %s %s' % (image, e)) logger.error("image: %s %s" % (image, e))
return [] return []
def get_docker_manifests(image, tag): def get_docker_manifests(image, tag):
if settings.DEBUG: if settings.DEBUG:
return ('{}', uuid.uuid4()) return ("{}", uuid.uuid4())
else: else:
dru = settings.DOCKER_REGISTRY_URL dru = settings.DOCKER_REGISTRY_URL
url = dru.format("%s/manifests/%s" % (image, tag)) url = dru.format("%s/manifests/%s" % (image, tag))
@ -132,7 +139,7 @@ def get_docker_manifests(image, tag):
result = json.loads(info) result = json.loads(info)
return (result, digest) return (result, digest)
except Exception as e: except Exception as e:
logger.error('image: %s tag:%s %s' % (image, tag, e)) logger.error("image: %s tag:%s %s" % (image, tag, e))
return (None, None) return (None, None)
@ -140,19 +147,19 @@ def delete_tag(image, reference, tag_name):
try: try:
dru = settings.DOCKER_REGISTRY_URL dru = settings.DOCKER_REGISTRY_URL
url = dru.format("%s/manifests/%s" % (image, reference)) url = dru.format("%s/manifests/%s" % (image, reference))
logger.debug('docker delete_tag(%s)' % (url)) logger.debug("docker delete_tag(%s)" % (url))
delete_docker_info(url) delete_docker_info(url)
except: except Exception:
# it does not work for some, retrieve Docker-Content-Digest from # it does not work for some, retrieve Docker-Content-Digest from
# manifests and delete using that as reference # manifests and delete using that as reference
dru = settings.DOCKER_REGISTRY_URL dru = settings.DOCKER_REGISTRY_URL
url = dru.format("%s/manifests/%s" % (image, tag_name)) url = dru.format("%s/manifests/%s" % (image, tag_name))
logger.debug('docker delete_tag() get_docker_manif_info(): %s' % (url)) logger.debug("docker delete_tag() get_docker_manif_info(): %s" % (url))
response = get_docker_manifests_info(url) response = get_docker_manifests_info(url)
logger.debug(' - response text: %s' % (response[0])) logger.debug(" - response text: %s" % (response[0]))
logger.debug(' - response Docker-Content-Digest: %s' % (response[1])) logger.debug(" - response Docker-Content-Digest: %s" % (response[1]))
dru = settings.DOCKER_REGISTRY_URL dru = settings.DOCKER_REGISTRY_URL
url = dru.format("%s/manifests/%s" % (image, response[1])) url = dru.format("%s/manifests/%s" % (image, response[1]))
logger.info('docker delete_tag() will delete: %s' % (url)) logger.info("docker delete_tag() will delete: %s" % (url))
delete_docker_info(url) delete_docker_info(url)

@ -16,7 +16,7 @@ import re
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from release_dashboard.forms import rd_settings from ..conf import settings
from release_dashboard.utils import get_branches from release_dashboard.utils import get_branches
from release_dashboard.utils import get_tags from release_dashboard.utils import get_tags
@ -26,7 +26,7 @@ regex_mr = re.compile(r"^mr.+$")
# support "master" + "$supported_debian_releases/master" for branch selection, # support "master" + "$supported_debian_releases/master" for branch selection,
# e.g. for trunk builds when not everything might build against master # e.g. for trunk builds when not everything might build against master
debian_releases = [] debian_releases = []
for debian_release in rd_settings["debian_supported"]: for debian_release in settings.RELEASE_DASHBOARD_DEBIAN_RELEASES:
if debian_release != "auto": if debian_release != "auto":
debian_releases.append(debian_release) debian_releases.append(debian_release)
regex_master = re.compile( regex_master = re.compile(

@ -30,19 +30,19 @@ from . import _projects_versions
from . import regex_hotfix from . import regex_hotfix
from . import regex_master from . import regex_master
from . import regex_mr from . import regex_mr
from ..conf import settings
from ..forms import trunk_build_deps
from ..forms import trunk_projects
from ..forms.build import BuildDepForm
from ..forms.build import BuildReleaseForm
from ..forms.build import BuildTrunkDepForm
from ..forms.build import BuildTrunkReleaseForm
from ..models import Project
from ..tasks import gerrit_fetch_all
from ..tasks import gerrit_fetch_info
from ..utils import build
from build.models import BuildRelease from build.models import BuildRelease
from build.utils import ReleaseConfig from build.utils import ReleaseConfig
from release_dashboard.forms import rd_settings
from release_dashboard.forms import trunk_build_deps
from release_dashboard.forms import trunk_projects
from release_dashboard.forms.build import BuildDepForm
from release_dashboard.forms.build import BuildReleaseForm
from release_dashboard.forms.build import BuildTrunkDepForm
from release_dashboard.forms.build import BuildTrunkReleaseForm
from release_dashboard.models import Project
from release_dashboard.tasks import gerrit_fetch_all
from release_dashboard.tasks import gerrit_fetch_info
from release_dashboard.utils import build
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -81,7 +81,7 @@ def build_release(request, release):
@login_required @login_required
@require_http_methods(["POST"]) @require_http_methods(["POST"])
def hotfix_build(request, branch, project): def hotfix_build(request, branch, project):
if project not in rd_settings["projects"]: if project not in settings.RELEASE_DASHBOARD_PROJECTS:
error = "repo:%s not valid" % project error = "repo:%s not valid" % project
logger.error(error) logger.error(error)
return HttpResponseNotFound(error) return HttpResponseNotFound(error)
@ -134,16 +134,19 @@ def build_deps_old(request, tag_only=False):
if request.method == "POST": if request.method == "POST":
form = BuildDepForm(request.POST) form = BuildDepForm(request.POST)
if form.is_valid(): if form.is_valid():
context = _build_logic(form, rd_settings["build_deps"]) context = _build_logic(form, settings.RELEASE_DASHBOARD_BUILD_DEPS)
else: else:
context = {"error": "form validation error"} context = {"error": "form validation error"}
return render(request, "release_dashboard/build_result.html", context) return render(request, "release_dashboard/build_result.html", context)
else: else:
context = { context = {
"projects": _projects_versions( "projects": _projects_versions(
rd_settings["build_deps"], regex_mr, True, not tag_only, settings.RELEASE_DASHBOARD_BUILD_DEPS,
regex_mr,
True,
not tag_only,
), ),
"debian": rd_settings["debian_supported"], "debian": settings.RELEASE_DASHBOARD_DEBIAN_SUPPORTED,
} }
_common_versions(context, True, not tag_only) _common_versions(context, True, not tag_only)
return render(request, "release_dashboard/build_deps.html", context) return render(request, "release_dashboard/build_deps.html", context)
@ -151,7 +154,9 @@ def build_deps_old(request, tag_only=False):
@login_required @login_required
def hotfix(request): def hotfix(request):
prj_list = _projects_versions(rd_settings["projects"], regex_hotfix) prj_list = _projects_versions(
settings.RELEASE_DASHBOARD_PROJECTS, regex_hotfix
)
context = {"projects": prj_list} context = {"projects": prj_list}
return render(request, "release_dashboard/hotfix.html", context) return render(request, "release_dashboard/hotfix.html", context)
@ -162,16 +167,19 @@ def build_release_old(request, tag_only=False):
if request.method == "POST": if request.method == "POST":
form = BuildReleaseForm(request.POST) form = BuildReleaseForm(request.POST)
if form.is_valid(): if form.is_valid():
context = _build_logic(form, rd_settings["projects"]) context = _build_logic(form, settings.RELEASE_DASHBOARD_PROJECTS)
else: else:
context = {"error": "form validation error"} context = {"error": "form validation error"}
return render(request, "release_dashboard/build_result.html", context) return render(request, "release_dashboard/build_result.html", context)
else: else:
context = { context = {
"projects": _projects_versions( "projects": _projects_versions(
rd_settings["projects"], regex_mr, True, not tag_only, settings.RELEASE_DASHBOARD_PROJECTS,
regex_mr,
True,
not tag_only,
), ),
"debian": rd_settings["debian_supported"], "debian": settings.RELEASE_DASHBOARD_DEBIAN_SUPPORTED,
} }
_common_versions(context, True, not tag_only) _common_versions(context, True, not tag_only)
if tag_only: if tag_only:
@ -187,7 +195,7 @@ def refresh_all(request):
else: else:
template = "release_dashboard/refresh.html" template = "release_dashboard/refresh.html"
projects = [] projects = []
for project in rd_settings["projects"]: for project in settings.RELEASE_DASHBOARD_PROJECTS:
info = {"name": project, "tags": None} info = {"name": project, "tags": None}
projects.append(info) projects.append(info)
return render(request, template, {"projects": projects}) return render(request, template, {"projects": projects})
@ -204,7 +212,7 @@ def build_trunk_deps_old(request):
if request.method == "POST": if request.method == "POST":
form = BuildTrunkDepForm(request.POST) form = BuildTrunkDepForm(request.POST)
if form.is_valid(): if form.is_valid():
context = _build_logic(form, rd_settings["build_deps"]) context = _build_logic(form, settings.RELEASE_DASHBOARD_BUILD_DEPS)
else: else:
context = {"error": "form validation error"} context = {"error": "form validation error"}
return render(request, "release_dashboard/build_result.html", context) return render(request, "release_dashboard/build_result.html", context)
@ -213,7 +221,7 @@ def build_trunk_deps_old(request):
context = { context = {
"projects": _projects_versions(trunk_build_deps, regex_master,), "projects": _projects_versions(trunk_build_deps, regex_master,),
"common_versions": {"tags": [], "branches": ["master"]}, "common_versions": {"tags": [], "branches": ["master"]},
"debian": rd_settings["debian_supported"], "debian": settings.RELEASE_DASHBOARD_DEBIAN_SUPPORTED,
} }
return render(request, template, context) return render(request, template, context)
@ -231,6 +239,6 @@ def build_trunk_release_old(request):
context = { context = {
"projects": _projects_versions(trunk_projects, regex_master,), "projects": _projects_versions(trunk_projects, regex_master,),
"common_versions": {"tags": [], "branches": ["master"]}, "common_versions": {"tags": [], "branches": ["master"]},
"debian": rd_settings["debian_supported"], "debian": settings.RELEASE_DASHBOARD_DEBIAN_SUPPORTED,
} }
return render(request, "release_dashboard/build_trunk.html", context) return render(request, "release_dashboard/build_trunk.html", context)

@ -1,18 +1,20 @@
# Copyright (C) 2015 The Sipwise Team - http://sipwise.com # Copyright (C) 2015 The Sipwise Team - http://sipwise.com
#
# This program is free software: you can redistribute it and/or modify it # 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 # 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) # Software Foundation, either version 3 of the License, or (at your option)
# any later version. # any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT # This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details. # more details.
#
# You should have received a copy of the GNU General Public License along # You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>. # with this program. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
import re import re
from django.conf import settings
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.http import Http404 from django.http import Http404
from django.http import JsonResponse from django.http import JsonResponse
@ -26,9 +28,9 @@ from . import _common_versions
from . import _hash_versions from . import _hash_versions
from . import _projects_versions from . import _projects_versions
from . import regex_mr from . import regex_mr
from ..conf import settings
from release_dashboard import serializers from release_dashboard import serializers
from release_dashboard import tasks from release_dashboard import tasks
from release_dashboard.forms import docker_projects
from release_dashboard.forms.docker import BuildDockerForm from release_dashboard.forms.docker import BuildDockerForm
from release_dashboard.models import DockerImage from release_dashboard.models import DockerImage
from release_dashboard.models import DockerTag from release_dashboard.models import DockerTag
@ -80,14 +82,20 @@ def build_docker_images(request):
if request.method == "POST": if request.method == "POST":
form = BuildDockerForm(request.POST) form = BuildDockerForm(request.POST)
if form.is_valid(): if form.is_valid():
context = _build_docker_logic(form, docker_projects) context = _build_docker_logic(
form, settings.RELEASE_DASHBOARD_DOCKER_PROJECTS
)
else: else:
context = {"error": "form validation error"} context = {"error": "form validation error"}
return render(request, "release_dashboard/build_result.html", context) return render(request, "release_dashboard/build_result.html", context)
else: else:
context = { context = {
"projects": _projects_versions( "projects": _projects_versions(
docker_projects, regex_mr, False, True, True, settings.RELEASE_DASHBOARD_DOCKER_PROJECTS,
regex_mr,
False,
True,
True,
), ),
"common_versions": {"tags": [], "branches": ["master"]}, "common_versions": {"tags": [], "branches": ["master"]},
"docker": True, "docker": True,
@ -104,7 +112,7 @@ def refresh_all(request):
else: else:
template = "release_dashboard/refresh_docker.html" template = "release_dashboard/refresh_docker.html"
projects = [] projects = []
for project in docker_projects: for project in settings.RELEASE_DASHBOARD_DOCKER_PROJECTS:
info = {"name": project, "tags": None} info = {"name": project, "tags": None}
projects.append(info) projects.append(info)
return render(request, template, {"projects": projects}) return render(request, template, {"projects": projects})

@ -137,165 +137,3 @@ CELERY_ACCEPT_CONTENT = ["json"]
CELERY_RESULT_BACKEND = "django-db" CELERY_RESULT_BACKEND = "django-db"
HOTFIX_ARTIFACT = "debian_changelog.txt" HOTFIX_ARTIFACT = "debian_changelog.txt"
DEBIAN_RELEASES = (
"auto",
"buster",
"stretch",
"jessie",
"wheezy",
"squeeze",
)
RELEASE_DASHBOARD_SETTINGS = {
"debian_supported": DEBIAN_RELEASES,
"build_deps": (
"check-tools",
"data-hal",
"libswrate",
"sipwise-base",
"mediaproxy-ng",
"ngcp-schema",
"rtpengine",
"libtcap",
"libinewrate",
),
"projects": (
"acc-cdi",
"asterisk",
"asterisk-sounds",
"asterisk-voicemail",
"backup-tools",
"bulk-processor",
"bulk-processor-projects",
"bootenv",
"captagent",
"cdr-exporter",
"cfg-schema",
"check-tools",
"cleanup-tools",
"cloudpbx-devices",
"cloudpbx-sources",
"collectd-mod-redis",
"comx",
"comx-application",
"comx-fileshare-service",
"comx-sip",
"comx-xmpp",
"csta-testsuite",
"data-hal",
"db-schema",
"dhtest",
"diva-drivers",
"deployment-iso",
"documentation",
"faxserver",
"glusterfs-config",
"heartbeat",
"hylafaxplus",
"iaxmodem",
"installer",
"janus-admin",
"janus-client",
"kamailio",
"kamailio-config-tests",
"keyring",
"kibana",
"klish",
"libhsclient-c-wrapper",
"libinewrate",
"libswrate",
"libtcap",
"license-client",
"lnpd",
"lua-ngcp-kamailio",
"mediaproxy-ng",
"mediaproxy-redis",
"mediator",
"megacli",
"metapackages",
"monitoring-tools",
"netscript",
"ngcp-api-tools",
"ngcp-csc",
"ngcp-csc-ui",
"ngcp-exporter",
"ngcp-fauditd",
"ngcp-inventory",
"ngcp-klish-config",
"ngcp-logfs",
"ngcp-panel",
"ngcp-prompts",
"ngcp-rtcengine",
"ngcp-schema",
"ngcp-status",
"ngcp-sudo-plugin",
"ngcp-support",
"ngcp-user-framework",
"ngcpcfg",
"ngcpcfg-api",
"ngcpcfg-ha",
"ngrep-sip",
"ossbss",
"prosody",
"pushd",
"rate-o-mat",
"reminder",
"rtpengine",
"rtpengine-redis",
"sems",
"sems-app",
"sems-ha",
"sems-modules",
"sems-pbx",
"sems-prompts",
"sipsak",
"sipwise-base",
"snmp-agent",
"system-tests",
"system-tools",
"templates",
"upgrade",
"vmnotify",
"voisniff-ng",
"websocket",
"www_admin",
"www_csc",
),
"abandoned": (
"asterisk",
"asterisk-sounds",
"cloudpbx-devices",
"collectd-mod-redis",
"comx",
"comx-sip",
"comx-xmpp",
"diva-drivers",
"hylafaxplus",
"iaxmodem",
"mediaproxy-ng",
"mediaproxy-redis",
"rtpengine-redis",
"ossbss",
"sems-prompts",
"sipsak",
"www_admin",
"www_csc",
),
"docker_projects": (
"comx-fileshare-service",
"data-hal",
"documentation",
"janus-admin",
"janus-client",
"kamailio-config-tests",
"libswrate",
"libtcap",
"lua-ngcp-kamailio",
"ngcp-csc",
"ngcp-panel",
"ngcp-rtcengine",
"ngcpcfg",
"rate-o-mat",
"snmp-agent",
"system-tools",
),
}

@ -63,7 +63,7 @@ DOCKER_REGISTRY = """
""" """
BUILD_POOL = 1 BUILD_POOL = 1
DOCKER_IMAGES = { RELEASE_DASHBOARD_DOCKER_IMAGES = {
"data-hal-jessie": [ "data-hal-jessie": [
"Ia9b03983d174a1546631f5b42e605235809711ef", "Ia9b03983d174a1546631f5b42e605235809711ef",
"If508e72c01d9bc78836a40204e508585d1dc3555", "If508e72c01d9bc78836a40204e508585d1dc3555",

Loading…
Cancel
Save