From 45f81959e2b1f38e4e927cd451d18171e4f7cd0b Mon Sep 17 00:00:00 2001 From: Victor Seva Date: Tue, 20 Jun 2017 19:18:21 +0200 Subject: [PATCH] TT#17622 release_dashboard: add docker images forms Change-Id: I7da3b00a8a5f7f69d12876de33406919df223e31 --- release_dashboard/forms/__init__.py | 24 +++++ .../{forms.py => forms/build.py} | 10 +- release_dashboard/forms/docker.py | 28 ++++++ release_dashboard/models.py | 4 - .../release_dashboard/build_content.html | 2 + .../release_dashboard/build_docker.html | 13 +++ .../release_dashboard/build_result.html | 8 ++ .../templates/release_dashboard/index.html | 4 + release_dashboard/urls.py | 2 + release_dashboard/utils.py | 24 +++++ release_dashboard/views.py | 96 ++++++++++++++----- repoapi/settings/common.py | 18 ++++ 12 files changed, 198 insertions(+), 35 deletions(-) create mode 100644 release_dashboard/forms/__init__.py rename release_dashboard/{forms.py => forms/build.py} (85%) create mode 100644 release_dashboard/forms/docker.py create mode 100644 release_dashboard/templates/release_dashboard/build_docker.html diff --git a/release_dashboard/forms/__init__.py b/release_dashboard/forms/__init__.py new file mode 100644 index 0000000..fd544a3 --- /dev/null +++ b/release_dashboard/forms/__init__.py @@ -0,0 +1,24 @@ +# 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 . + +from django.conf import settings + +rd_settings = settings.RELEASE_DASHBOARD_SETTINGS +trunk_projects = sorted(set(rd_settings['projects']) - + set(rd_settings['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'] diff --git a/release_dashboard/forms.py b/release_dashboard/forms/build.py similarity index 85% rename from release_dashboard/forms.py rename to release_dashboard/forms/build.py index 5df8d6c..cdbfbd9 100644 --- a/release_dashboard/forms.py +++ b/release_dashboard/forms/build.py @@ -14,14 +14,8 @@ # with this program. If not, see . from django import forms -from django.conf import settings - -rd_settings = settings.RELEASE_DASHBOARD_SETTINGS -trunk_projects = sorted(set(rd_settings['projects']) - - set(rd_settings['abandoned']) - - set(rd_settings['build_deps'])) -trunk_build_deps = sorted(set(rd_settings['build_deps']) - - set(rd_settings['abandoned'])) +from . import rd_settings +from . import trunk_projects, trunk_build_deps class BuildForm(forms.Form): diff --git a/release_dashboard/forms/docker.py b/release_dashboard/forms/docker.py new file mode 100644 index 0000000..7d59257 --- /dev/null +++ b/release_dashboard/forms/docker.py @@ -0,0 +1,28 @@ +# Copyright (C) 2016 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 . + +from django import forms +from . import docker_projects + + +class BuildDockerForm(forms.Form): + common_select = forms.CharField(max_length=50) + + def __init__(self, *args, **kwargs): + super(BuildDockerForm, self).__init__(*args, **kwargs) + + for project in docker_projects: + self.fields['version_%s' % + project] = forms.CharField(max_length=15) diff --git a/release_dashboard/models.py b/release_dashboard/models.py index 2fdeda6..4451107 100644 --- a/release_dashboard/models.py +++ b/release_dashboard/models.py @@ -33,16 +33,13 @@ class Project(models.Model): res = set() for value in values: - logger.debug("ref[%s]", value["ref"]) match = re.search(val_ok_filter, value["ref"]) if match: val_ok = match.group(1) if regex is not None: if re.search(regex, val_ok): res.add(val_ok) - logger.debug("val_ok[%s] regex", val_ok) else: - logger.debug("val_ok[%s]", val_ok) res.add(val_ok) return sorted(res, reverse=True) @@ -51,7 +48,6 @@ class Project(models.Model): """gerrit responds with malformed json https://gerrit-review.googlesource.com/Documentation/rest-api.html#output """ - logging.debug("json[:5]: %s", text[:5]) return json.loads(text[5:]) def __str__(self): diff --git a/release_dashboard/templates/release_dashboard/build_content.html b/release_dashboard/templates/release_dashboard/build_content.html index 3d595ff..9181b03 100644 --- a/release_dashboard/templates/release_dashboard/build_content.html +++ b/release_dashboard/templates/release_dashboard/build_content.html @@ -20,6 +20,7 @@ {% endif %} +{% if not docker %}
+{% endif %} diff --git a/release_dashboard/templates/release_dashboard/build_docker.html b/release_dashboard/templates/release_dashboard/build_docker.html new file mode 100644 index 0000000..5314631 --- /dev/null +++ b/release_dashboard/templates/release_dashboard/build_docker.html @@ -0,0 +1,13 @@ +{% extends "release_dashboard/base.html" %} +{% load staticfiles %} +{% block title %}Build docker images per project{% endblock %} +{% block navlist %} +
  • Release Dashboard
  • +
  • Build Docker Images
  • +{% endblock %} +{% block content %} +{% include "release_dashboard/build_content.html" %} +{% endblock %} +{% block extrajs %} + +{% endblock %} diff --git a/release_dashboard/templates/release_dashboard/build_result.html b/release_dashboard/templates/release_dashboard/build_result.html index ea37279..ca68d1d 100644 --- a/release_dashboard/templates/release_dashboard/build_result.html +++ b/release_dashboard/templates/release_dashboard/build_result.html @@ -3,7 +3,11 @@ {% block title %}Build release{% endblock %} {% block navlist %}
  • Release Dashboard
  • +{% if release %}
  • Panel {{release}}
  • +{% else %} +
  • Build project docker images
  • +{% endif %} {% endblock %} {% block content %}
    @@ -18,7 +22,11 @@ {% for project in projects %} {% if project.url %}

    +{% if release %} {{ project.name }} +{% else %} + {{ project.name }} +{% endif %}

    {% else %}

    diff --git a/release_dashboard/templates/release_dashboard/index.html b/release_dashboard/templates/release_dashboard/index.html index 9ba2ba6..d1782b4 100644 --- a/release_dashboard/templates/release_dashboard/index.html +++ b/release_dashboard/templates/release_dashboard/index.html @@ -39,6 +39,10 @@ Refresh tag/branch Info +

  • + + Build project docker images +
  • diff --git a/release_dashboard/urls.py b/release_dashboard/urls.py index c65c816..9dc7251 100644 --- a/release_dashboard/urls.py +++ b/release_dashboard/urls.py @@ -31,4 +31,6 @@ urlpatterns = [ views.hotfix_build), url(r'^refresh/$', views.refresh_all, name='refresh_all'), url(r'^refresh/(?P[^/]+)/$', views.refresh, name='refresh'), + url(r'^build_docker/$', views.build_docker_images, + name='build_docker_images'), ] diff --git a/release_dashboard/utils.py b/release_dashboard/utils.py index 8968c2e..2bb7eb7 100644 --- a/release_dashboard/utils.py +++ b/release_dashboard/utils.py @@ -34,6 +34,9 @@ hotfix_url = ("{base}/job/release-tools-runner/buildWithParameters?" "PROJECTNAME={project}&repository={project}&" "push={push}&uuid={uuid}") +docker_url = ("{base}/job/build-project-docker/buildWithParameters?" + "token={token}&project={project}&branch={branch}") + def get_response(url): auth = HTTPDigestAuth( @@ -100,6 +103,27 @@ def trigger_build(project, trigger_release=None, return "{base}/job/{job}/".format(**params) +def trigger_docker_build(project, branch): + if branch == "ignore": + logger.debug("ignoring request to trigger project %s due" + " to request of version 'ignore'", project) + return + branch = branch.split("branch/")[1] + params = { + 'base': settings.JENKINS_URL, + 'token': urllib.quote(settings.JENKINS_TOKEN), + 'project': project, + 'branch': urllib.quote(branch), + } + + url = docker_url.format(**params) + if settings.DEBUG: + logger.debug("Debug mode, would trigger: %s", url) + else: + openurl(url) + return "{base}/job/build-project-docker/".format(**params) + + def get_gerrit_info(url): if settings.DEBUG: logger.debug("Debug mode, would trigger: %s", url) diff --git a/release_dashboard/views.py b/release_dashboard/views.py index 8d7aed1..e8d5d69 100644 --- a/release_dashboard/views.py +++ b/release_dashboard/views.py @@ -19,16 +19,17 @@ import json import uuid from django.shortcuts import render from django.http import HttpResponseNotFound, JsonResponse -from django.conf import settings from django.views.decorators.http import require_http_methods from release_dashboard.models import Project -from .utils import get_tags, get_branches, trigger_hotfix, trigger_build +from .utils import get_tags, get_branches +from .utils import trigger_hotfix, trigger_build, trigger_docker_build from .tasks import gerrit_fetch_info, gerrit_fetch_all -from .forms import BuildDepForm, BuildReleaseForm -from .forms import BuildTrunkDepForm, BuildTrunkReleaseForm -from .forms import trunk_projects, trunk_build_deps +from .forms.build import BuildDepForm, BuildReleaseForm +from .forms.build import BuildTrunkDepForm, BuildTrunkReleaseForm +from .forms.docker import BuildDockerForm +from .forms import trunk_projects, trunk_build_deps, docker_projects +from .forms import rd_settings -rd_settings = settings.RELEASE_DASHBOARD_SETTINGS logger = logging.getLogger(__name__) regex_hotfix = re.compile(r'^mr[0-9]+\.[0-9]+\.[0-9]+$') regex_mr = re.compile(r'^mr.+$') @@ -40,26 +41,29 @@ def index(request): return render(request, 'release_dashboard/index.html', context) -def _projects_versions(projects, regex=None, tag_only=False): +def _projects_versions(projects, regex=None, + tags=True, branches=True): res = [] for project in projects: info = { 'name': project, - 'tags': get_tags(project, regex), } - if not tag_only: + if tags: + info['tags'] = get_tags(project, regex) + if branches: info['branches'] = get_branches(project, regex) res.append(info) logger.debug(res) return res -def _common_versions(context, tag_only=False): +def _common_versions(context, tags=True, branches=True): common_versions = {'tags': set(), 'branches': set()} for project in context['projects']: - common_versions['tags'] |= set(project['tags']) - if not tag_only: + if tags: + common_versions['tags'] |= set(project['tags']) + if branches: common_versions['branches'] |= set(project['branches']) context['common_versions'] = { 'tags': sorted(common_versions['tags'], reverse=True), @@ -139,11 +143,12 @@ def build_deps(request, tag_only=False): 'projects': _projects_versions( rd_settings['build_deps'], regex_mr, - tag_only + True, + not tag_only, ), 'debian': rd_settings['debian_supported'], } - _common_versions(context, tag_only) + _common_versions(context, True, not tag_only) return render(request, 'release_dashboard/build_deps.html', context) @@ -151,7 +156,7 @@ def hotfix(request): context = { 'projects': _projects_versions( rd_settings['projects'], - regex_hotfix + regex_hotfix, ) } return render(request, 'release_dashboard/hotfix.html', context) @@ -170,11 +175,12 @@ def build_release(request, tag_only=False): 'projects': _projects_versions( rd_settings['projects'], regex_mr, - tag_only + True, + not tag_only, ), 'debian': rd_settings['debian_supported'], } - _common_versions(context, tag_only) + _common_versions(context, True, not tag_only) if tag_only: return render(request, 'release_dashboard/build_tag.html', context) return render(request, 'release_dashboard/build.html', context) @@ -204,12 +210,7 @@ def refresh(request, project): def build_trunk_deps(request): if request.method == "POST": - form = BuildTrunkDepForm(request.POST) - if form.is_valid(): - context = _build_logic(form, trunk_build_deps) - else: - context = {'error': 'form validation error'} - return render(request, 'release_dashboard/build_result.html', context) + pass else: context = { 'projects': _projects_versions( @@ -247,3 +248,52 @@ def build_trunk_release(request): 'debian': rd_settings['debian_supported'], } return render(request, 'release_dashboard/build_trunk.html', context) + + +def _build_docker_logic(form, projects): + result = _hash_versions(form.cleaned_data, projects) + context = {'projects': []} + for pro in projects: + try: + logger.debug( + "trying to trigger docker image at branch %s for project %s", + result[pro], pro) + url = trigger_docker_build(pro, result[pro]) + context['projects'].append( + {'name': pro, 'url': url}) + except KeyError: + logger.error("Houston, we have a problem with" + "trigger for %s", pro) + context['projects'].append( + {'name': pro, 'url': None}) + return context + + +def build_docker_images(request): + if request.method == "POST": + form = BuildDockerForm(request.POST) + if form.is_valid(): + context = _build_docker_logic(form, docker_projects) + else: + context = {'error': 'form validation error'} + return render(request, + 'release_dashboard/build_result.html', + context) + else: + context = { + 'projects': _projects_versions( + docker_projects, + regex_mr, + False, + True, + ), + 'common_versions': { + 'tags': [], + 'branches': [] + }, + 'docker': True, + } + _common_versions(context, False, True) + return render(request, + 'release_dashboard/build_docker.html', + context) diff --git a/repoapi/settings/common.py b/repoapi/settings/common.py index 3f3c7ed..a017f49 100644 --- a/repoapi/settings/common.py +++ b/repoapi/settings/common.py @@ -265,4 +265,22 @@ RELEASE_DASHBOARD_SETTINGS = { "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", + ), }