mirror of
https://pagure.io/fm-orchestrator.git
synced 2026-02-03 05:03:43 +08:00
Remove references to COPR
This commit is contained in:
@@ -46,15 +46,6 @@ MBS is able to perform local module builds by directing local Mock.
|
||||
MBS supports threaded Mock builds which utilizes performance and
|
||||
significantly speeds up local module builds.
|
||||
|
||||
Copr
|
||||
----
|
||||
|
||||
Copr is yet another an easy-to-use automatic build system providing a
|
||||
package repository as its output.
|
||||
|
||||
As with Koji, MBS comes with its own ``copr.conf`` config file which allows
|
||||
altering your default Copr configuration.
|
||||
|
||||
_`Client tooling`
|
||||
=================
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ class BaseConfiguration(object):
|
||||
KOJI_REPOSITORY_URL = 'https://kojipkgs.fedoraproject.org/repos'
|
||||
KOJI_TAG_PREFIXES = ['module']
|
||||
KOJI_ENABLE_CONTENT_GENERATOR = True
|
||||
COPR_CONFIG = '/etc/module-build-service/copr.conf'
|
||||
PDC_URL = 'https://pdc.fedoraproject.org/rest_api/v1'
|
||||
PDC_INSECURE = False
|
||||
PDC_DEVELOP = True
|
||||
@@ -138,4 +137,3 @@ class LocalBuildConfiguration(BaseConfiguration):
|
||||
class DevConfiguration(LocalBuildConfiguration):
|
||||
DEBUG = True
|
||||
LOG_BACKEND = 'console'
|
||||
COPR_CONFIG = path.join(confdir, 'copr.conf')
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
[copr-cli]
|
||||
login =
|
||||
username =
|
||||
token =
|
||||
copr_url = http://copr-fe-dev.cloud.fedoraproject.org
|
||||
@@ -1,398 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2016 Red Hat, Inc.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# Written by Jakub Kadlčík <jkadlcik@redhat.com>
|
||||
|
||||
|
||||
import logging
|
||||
import os
|
||||
import koji
|
||||
import tempfile
|
||||
import threading
|
||||
import subprocess
|
||||
import shutil
|
||||
|
||||
from copr.client import CoprClient
|
||||
from copr.exceptions import CoprRequestException
|
||||
|
||||
from module_build_service import log
|
||||
import module_build_service.scm
|
||||
import module_build_service.utils
|
||||
|
||||
from module_build_service.builder.base import GenericBuilder
|
||||
from module_build_service.builder.utils import execute_cmd
|
||||
from module_build_service.builder.KojiModuleBuilder import KojiModuleBuilder
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
|
||||
class CoprModuleBuilder(GenericBuilder):
|
||||
|
||||
"""
|
||||
See http://blog.samalik.com/copr-in-the-modularity-world/
|
||||
especially section "Building a stack"
|
||||
"""
|
||||
|
||||
backend = "copr"
|
||||
_build_lock = threading.Lock()
|
||||
|
||||
@module_build_service.utils.validate_koji_tag('tag_name')
|
||||
def __init__(self, owner, module, config, tag_name, components):
|
||||
self.owner = owner
|
||||
self.config = config
|
||||
self.tag_name = tag_name
|
||||
self.module = module
|
||||
self.module_str = module.name
|
||||
|
||||
self.copr = None
|
||||
self.client = CoprModuleBuilder._get_client(config)
|
||||
self.client.username = self.owner
|
||||
self.chroot = "custom-1-x86_64"
|
||||
self.__prep = False
|
||||
|
||||
@classmethod
|
||||
def _get_client(cls, config):
|
||||
return CoprClient.create_from_file_config(config.copr_config)
|
||||
|
||||
def buildroot_connect(self, groups):
|
||||
"""
|
||||
This is an idempotent call to create or resume and validate the build
|
||||
environment. .build() should immediately fail if .buildroot_connect()
|
||||
wasn't called.
|
||||
|
||||
Koji Example: create tag, targets, set build tag inheritance...
|
||||
"""
|
||||
self.copr = self._get_copr_safe()
|
||||
self._create_module_safe()
|
||||
mmd = self.module.mmd()
|
||||
|
||||
# Even though get_buildrequires returns a dictionary with the values as lists, there will
|
||||
# always be a single item in the list after MBS processes it
|
||||
buildrequires_d = {name: dep.get()[0]
|
||||
for name, dep in mmd.get_dependencies()[0].get_buildrequires().items()}
|
||||
buildrequires = ["@{}:{}/{}".format(n, s, "buildroot")
|
||||
for n, s in buildrequires_d.items()]
|
||||
|
||||
buildroot_profile = mmd.get_profiles().get("buildroot")
|
||||
if buildroot_profile:
|
||||
buildrequires.extend(buildroot_profile.get_rpms())
|
||||
|
||||
self._update_chroot(packages=buildrequires)
|
||||
|
||||
if self.copr and self.copr.projectname and self.copr.username:
|
||||
self.__prep = True
|
||||
log.info("%r buildroot sucessfully connected." % self)
|
||||
|
||||
def _get_copr_safe(self):
|
||||
kwargs = {
|
||||
"ownername": self.module.copr_owner or self.owner,
|
||||
"projectname": self.module.copr_project or
|
||||
CoprModuleBuilder._tag_to_copr_name(self.tag_name)
|
||||
}
|
||||
|
||||
try:
|
||||
copr = self._get_copr(**kwargs)
|
||||
except CoprRequestException:
|
||||
self._create_copr(**kwargs)
|
||||
copr = self._get_copr(**kwargs)
|
||||
|
||||
self._create_chroot_safe(copr, self.chroot)
|
||||
self.client.modify_project(copr.projectname, copr.username,
|
||||
use_bootstrap_container=True)
|
||||
return copr
|
||||
|
||||
def _get_copr(self, ownername, projectname):
|
||||
return self.client.get_project_details(projectname, username=ownername).handle
|
||||
|
||||
def _create_copr(self, ownername, projectname):
|
||||
return self.client.create_project(ownername, projectname, [self.chroot])
|
||||
|
||||
def _create_chroot_safe(self, copr, chroot):
|
||||
detail = copr.get_project_details().data["detail"]
|
||||
current_chroots = detail["yum_repos"].keys()
|
||||
if chroot not in current_chroots:
|
||||
self.client.modify_project(copr.projectname, copr.username,
|
||||
chroots=current_chroots + [chroot])
|
||||
|
||||
def _create_module_safe(self):
|
||||
modulemd = self._dump_mmd()
|
||||
kwargs = {
|
||||
"username": self.module.copr_owner or self.owner,
|
||||
"projectname": self.module.copr_project or
|
||||
CoprModuleBuilder._tag_to_copr_name(self.tag_name),
|
||||
"modulemd": modulemd,
|
||||
"create": True,
|
||||
"build": False,
|
||||
}
|
||||
try:
|
||||
self.client.make_module(**kwargs)
|
||||
except CoprRequestException as ex:
|
||||
if "already exists" not in ex.message.get("nsv", [""])[0]:
|
||||
raise RuntimeError("Buildroot is not prep-ed")
|
||||
finally:
|
||||
os.remove(modulemd)
|
||||
|
||||
def _dump_mmd(self):
|
||||
# Write module's name, stream and version into the modulemd file
|
||||
# so Copr can parse it from there
|
||||
mmd = self.module.mmd()
|
||||
mmd.set_name(str(self.module.name))
|
||||
mmd.set_stream(str(self.module.stream))
|
||||
mmd.set_version(int(self.module.version))
|
||||
|
||||
modulemd = tempfile.mktemp()
|
||||
mmd.dump(modulemd)
|
||||
return modulemd
|
||||
|
||||
def buildroot_ready(self, artifacts=None):
|
||||
"""
|
||||
:param artifacts=None : a list of artifacts supposed to be in the buildroot
|
||||
(['bash-123-0.el6'])
|
||||
|
||||
returns when the buildroot is ready (or contains the specified artifact)
|
||||
|
||||
This function is here to ensure that the buildroot (repo) is ready and
|
||||
contains the listed artifacts if specified.
|
||||
"""
|
||||
# @TODO check whether artifacts are in the buildroot (called from repos.py)
|
||||
return True
|
||||
|
||||
def buildroot_add_artifacts(self, artifacts, install=False):
|
||||
"""
|
||||
:param artifacts: list of artifacts to be available or installed
|
||||
(install=False) in the buildroot (e.g list of $NEVRAS)
|
||||
:param install=False: pre-install artifact in the buildroot (otherwise
|
||||
"just make it available for install")
|
||||
|
||||
Example:
|
||||
|
||||
koji tag-build $module-build-tag bash-1.234-1.el6
|
||||
if install:
|
||||
koji add-group-pkg $module-build-tag build bash
|
||||
# This forces install of bash into buildroot and srpm-buildroot
|
||||
koji add-group-pkg $module-build-tag srpm-build bash
|
||||
"""
|
||||
|
||||
# Install the module-build-macros into the buildroot
|
||||
# We are using same hack as mock builder does
|
||||
for artifact in artifacts:
|
||||
if artifact and artifact.startswith("module-build-macros"):
|
||||
self._update_chroot(packages=["module-build-macros"])
|
||||
break
|
||||
|
||||
# Start of a new batch of builds is triggered by buildsys.repo.done message.
|
||||
# However in Copr there is no such thing. Therefore we are going to fake
|
||||
# the message when builds are finished
|
||||
from module_build_service.scheduler.consumer import fake_repo_done_message
|
||||
fake_repo_done_message(self.tag_name)
|
||||
|
||||
def buildroot_add_repos(self, dependencies):
|
||||
log.info("%r adding deps on %r" % (self, dependencies))
|
||||
# @TODO get architecture from some builder variable
|
||||
repos = [self._dependency_repo(d, "x86_64") for d in dependencies]
|
||||
|
||||
# @FIXME
|
||||
# Kojipkgs repos have been prematurely disabled without providing any
|
||||
# suitable alternative for Copr. This is a temporary workaround until
|
||||
# we figure out how to solve this permanently.
|
||||
compose = ("https://kojipkgs.fedoraproject.org/compose/"
|
||||
"latest-Fedora-Modular-{}/compose/Server/x86_64/os/")
|
||||
|
||||
# We need to enable copr repositories with modularity DNF
|
||||
# so we can install modules into the buildroot
|
||||
copr = ("https://copr-be.cloud.fedoraproject.org/results/"
|
||||
"@copr/{}/fedora-26-x86_64/")
|
||||
|
||||
repos.extend([
|
||||
compose.format("27"),
|
||||
compose.format("Rawhide"),
|
||||
copr.format("dnf-modularity-nightly"),
|
||||
copr.format("dnf-modularity-buildroot-deps"),
|
||||
])
|
||||
|
||||
self._update_chroot(repos=repos)
|
||||
|
||||
def _update_chroot(self, packages=None, repos=None):
|
||||
request = self.client.get_chroot(self.copr.projectname, self.copr.username, self.chroot)
|
||||
chroot = request.data["chroot"]
|
||||
current_packages = (chroot["buildroot_pkgs"] or "").split()
|
||||
current_repos = (chroot["repos"] or "").split()
|
||||
|
||||
def merge(current, new):
|
||||
current, new = current or [], new or []
|
||||
return " ".join(set(current + new))
|
||||
|
||||
self.client.edit_chroot(self.copr.projectname, self.chroot,
|
||||
ownername=self.copr.username,
|
||||
packages=merge(current_packages, packages),
|
||||
repos=merge(current_repos, repos))
|
||||
|
||||
def _dependency_repo(self, module, arch, backend="copr"):
|
||||
try:
|
||||
repo = GenericBuilder.tag_to_repo(backend, self.config, module, arch)
|
||||
return repo
|
||||
except ValueError:
|
||||
if backend == "copr":
|
||||
return self._dependency_repo(module, arch, "koji")
|
||||
|
||||
def tag_artifacts(self, artifacts):
|
||||
pass
|
||||
|
||||
def list_tasks_for_components(self, component_builds=None, state='active'):
|
||||
pass
|
||||
|
||||
def build(self, artifact_name, source):
|
||||
"""
|
||||
:param artifact_name : A package name. We can't guess it since macros
|
||||
in the buildroot could affect it, (e.g. software
|
||||
collections).
|
||||
:param source : an SCM URL, clearly identifying the build artifact in a
|
||||
repository
|
||||
:return 4-tuple of the form (build task id, state, reason, nvr)
|
||||
|
||||
The artifact_name parameter is used in koji add-pkg (and it's actually
|
||||
the only reason why we need to pass it). We don't really limit source
|
||||
types. The actual source is usually delivered as an SCM URL from
|
||||
fedmsg.
|
||||
|
||||
Example
|
||||
.build("bash", "git://someurl/bash#damn") #build from SCM URL
|
||||
.build("bash", "/path/to/srpm.src.rpm") #build from source RPM
|
||||
"""
|
||||
log.info("Copr build")
|
||||
|
||||
if not self.__prep:
|
||||
raise RuntimeError("Buildroot is not prep-ed")
|
||||
|
||||
# TODO: If we are sure that this method is thread-safe, we can just
|
||||
# remove _build_lock locking.
|
||||
with CoprModuleBuilder._build_lock:
|
||||
# Git sources are treated specially.
|
||||
if source.startswith(("git://", "http://", "https://")):
|
||||
response = self.build_scm(source)
|
||||
else:
|
||||
response = self.build_srpm(artifact_name, source)
|
||||
|
||||
if response.output != "ok":
|
||||
log.error(response.error)
|
||||
return response.data["ids"][0], koji.BUILD_STATES["BUILDING"], response.message, None
|
||||
|
||||
def build_srpm(self, artifact_name, source, build_id=None):
|
||||
# Build package from `source`
|
||||
return self.client.create_new_build(self.copr.projectname, [source],
|
||||
username=self.copr.username,
|
||||
chroots=[self.chroot])
|
||||
|
||||
def build_scm(self, source):
|
||||
url, commit = source.split("?#")
|
||||
url = (url.replace("git://", "https://")
|
||||
.replace("pkgs.fedoraproject.org", "src.fedoraproject.org/git"))
|
||||
td = tempfile.mkdtemp()
|
||||
cod = clone(url, td)
|
||||
branch = git_branch_contains(cod, commit)
|
||||
rmdir(cod)
|
||||
return self.client.create_new_build_distgit(self.copr.projectname, url, branch=branch,
|
||||
username=self.copr.username,
|
||||
chroots=[self.chroot])
|
||||
|
||||
def finalize(self):
|
||||
modulemd = self._dump_mmd()
|
||||
|
||||
# Create a module from previous project
|
||||
result = self.client.make_module(username=self.copr.username,
|
||||
projectname=self.copr.projectname,
|
||||
modulemd=modulemd, create=False, build=True)
|
||||
os.remove(modulemd)
|
||||
if result.output != "ok":
|
||||
log.error(result.error)
|
||||
return
|
||||
|
||||
log.info(result.message)
|
||||
log.info(result.data["modulemd"])
|
||||
|
||||
@staticmethod
|
||||
def get_disttag_srpm(disttag, module_build):
|
||||
# @FIXME
|
||||
return KojiModuleBuilder.get_disttag_srpm(disttag, module_build)
|
||||
|
||||
@property
|
||||
def module_build_tag(self):
|
||||
# Workaround koji specific code in modules.py
|
||||
return {"name": self.tag_name}
|
||||
|
||||
@classmethod
|
||||
def repo_from_tag(cls, config, tag_name, arch):
|
||||
"""
|
||||
:param backend: a string representing the backend e.g. 'koji'.
|
||||
:param config: instance of module_build_service.config.Config
|
||||
:param tag_name: Tag for which the repository is returned
|
||||
:param arch: Architecture for which the repository is returned
|
||||
|
||||
Returns URL of repository containing the built artifacts for
|
||||
the tag with particular name and architecture.
|
||||
"""
|
||||
# @TODO get the correct user
|
||||
# @TODO get the correct project
|
||||
owner, project = "@copr", cls._tag_to_copr_name(tag_name)
|
||||
|
||||
# Premise is that tag_name is in name-stream-version format
|
||||
name, stream, version = tag_name.rsplit("-", 2)
|
||||
|
||||
try:
|
||||
client = cls._get_client(config)
|
||||
response = client.get_module_repo(owner, project, name, stream, version, arch).data
|
||||
return response["repo"]
|
||||
|
||||
except CoprRequestException as e:
|
||||
raise ValueError(e)
|
||||
|
||||
def cancel_build(self, task_id):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
@module_build_service.utils.validate_koji_tag('koji_tag')
|
||||
def _tag_to_copr_name(cls, koji_tag):
|
||||
return koji_tag.replace("+", "-")
|
||||
|
||||
|
||||
def clone(url, path):
|
||||
log.debug('Cloning source URL: %s' % url)
|
||||
scm = module_build_service.scm.SCM(url)
|
||||
return scm.checkout(path)
|
||||
|
||||
|
||||
def rmdir(path):
|
||||
try:
|
||||
if path is not None:
|
||||
shutil.rmtree(path)
|
||||
except Exception as e:
|
||||
log.warning(
|
||||
"Failed to remove temporary directory {!r}: {}".format(
|
||||
path, str(e)))
|
||||
|
||||
|
||||
def git_branch_contains(cod, commit):
|
||||
cmd = ["git", "branch", "-r", "--contains", commit, "--sort", "-committerdate"]
|
||||
out, err = execute_cmd(cmd, cwd=cod, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
branch = out.split()[0].split("/")[1]
|
||||
if " -> " in branch:
|
||||
branch = branch.split(" -> ")[0]
|
||||
return branch
|
||||
@@ -52,11 +52,6 @@ logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
|
||||
class MockModuleBuilder(GenericBuilder):
|
||||
"""
|
||||
See http://blog.samalik.com/copr-in-the-modularity-world/
|
||||
especially section "Building a stack"
|
||||
"""
|
||||
|
||||
backend = "mock"
|
||||
# Global build_id/task_id we increment when new build is executed.
|
||||
_build_id_lock = threading.Lock()
|
||||
@@ -314,8 +309,6 @@ class MockModuleBuilder(GenericBuilder):
|
||||
pass
|
||||
|
||||
def buildroot_add_repos(self, dependencies):
|
||||
# TODO: We support only dependencies from Koji here. This should be
|
||||
# extended to Copr in the future.
|
||||
self._load_mock_config()
|
||||
for tag in dependencies:
|
||||
# If tag starts with mock_resultdir, it means it is path to local
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import pkg_resources
|
||||
|
||||
from module_build_service import conf
|
||||
from module_build_service.builder.base import GenericBuilder
|
||||
|
||||
__all__ = [
|
||||
@@ -8,7 +7,4 @@ __all__ = [
|
||||
]
|
||||
|
||||
for entrypoint in pkg_resources.iter_entry_points('mbs.builder_backends'):
|
||||
# Only import the copr builder if it is configured since we don't want to include the copr
|
||||
# module as a dependency for all installations
|
||||
if entrypoint.name != "copr" or conf.system == 'copr':
|
||||
GenericBuilder.register_backend_class(entrypoint.load())
|
||||
GenericBuilder.register_backend_class(entrypoint.load())
|
||||
|
||||
@@ -43,14 +43,6 @@ from module_build_service.utils import create_dogpile_key_generator_func
|
||||
|
||||
"""
|
||||
Example workflows - helps to see the difference in implementations
|
||||
Copr workflow:
|
||||
|
||||
1) create project (input: name, chroot deps: e.g. epel7)
|
||||
2) optional: selects project dependencies e.g. epel-7
|
||||
3) build package a.src.rpm # package is automatically added into buildroot
|
||||
after it's finished
|
||||
4) createrepo (package.a.src.rpm is available)
|
||||
|
||||
Koji workflow
|
||||
|
||||
1) create tag, and build-tag
|
||||
@@ -279,7 +271,7 @@ class GenericBuilder(six.with_metaclass(ABCMeta)):
|
||||
|
||||
It could be utilized for various purposes such as cleaning or
|
||||
running additional build-system based operations on top of
|
||||
finished builds (e.g. for copr - composing them into module)
|
||||
finished builds
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
@@ -38,9 +38,8 @@ from module_build_service import logger
|
||||
SUPPORTED_STRATEGIES = ['changed-and-after', 'only-changed', 'all']
|
||||
|
||||
SUPPORTED_RESOLVERS = {
|
||||
'pdc': {'builders': ['koji', 'mock', 'copr']},
|
||||
'copr': {'builders': ['copr', 'mock']},
|
||||
'db': {'builders': ['koji', 'mock', 'copr']}
|
||||
'pdc': {'builders': ['koji', 'mock']},
|
||||
'db': {'builders': ['koji', 'mock']}
|
||||
}
|
||||
|
||||
|
||||
@@ -511,7 +510,7 @@ class Config(object):
|
||||
|
||||
def _setifok_system(self, s):
|
||||
s = str(s)
|
||||
if s not in ("koji", "copr", "mock"):
|
||||
if s not in ("koji", "mock"):
|
||||
raise ValueError("Unsupported buildsystem: %s." % s)
|
||||
self._system = s
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ try:
|
||||
except ImportError:
|
||||
from funcsigs import signature
|
||||
|
||||
from module_build_service import log, conf
|
||||
from module_build_service import log
|
||||
|
||||
|
||||
class IgnoreMessage(Exception):
|
||||
@@ -164,15 +164,6 @@ class FedmsgMessageParser(MessageParser):
|
||||
msg_obj = MBSModule(
|
||||
msg_id, msg_inner_msg.get('id'), msg_inner_msg.get('state'))
|
||||
|
||||
elif conf.system == category == 'copr' and object == 'build':
|
||||
copr = msg_inner_msg.get('copr')
|
||||
build = msg_inner_msg.get('build')
|
||||
status = msg_inner_msg.get('status')
|
||||
pkg = msg_inner_msg.get('pkg')
|
||||
version = msg_inner_msg.get('version')
|
||||
what = msg_inner_msg.get('what')
|
||||
msg_obj = CoprBuildEnd(msg_id, build, status, copr, pkg, version, what)
|
||||
|
||||
# If the message matched the regex and is important to the app,
|
||||
# it will be returned
|
||||
if msg_obj:
|
||||
@@ -235,39 +226,6 @@ class KojiRepoChange(BaseMessage):
|
||||
self.repo_tag = repo_tag
|
||||
|
||||
|
||||
class CoprBuildEnd(KojiBuildChange):
|
||||
""" A class that inherits from KojiBuildChange to provide a message
|
||||
object for a build info from Copr
|
||||
|
||||
@TODO There should be a base class for CoprBuildEnd and KojiBuildChange
|
||||
and conditions in the code should check for it's descendants instead of KojiBuildChange
|
||||
directly.
|
||||
In such case this class would not have to inherit from koji class
|
||||
|
||||
:param msg_id: the id of the msg (e.g. 2016-SomeGUID)
|
||||
:param build_id: the id of the build (e.g. 264382)
|
||||
:param status: the new build state
|
||||
(see http://copr-backend.readthedocs.io/package/constants.html#backend.constants.BuildStatus )
|
||||
:param copr: the project name
|
||||
:param pkg: the full name of what is being built
|
||||
(e.g. mutt-kz-1.5.23.1-1.20150203.git.c8504a8a.fc21)
|
||||
:param state_reason: the optional reason as to why the state changed
|
||||
"""
|
||||
def __init__(self, msg_id, build_id, status, copr, pkg, version, what=None):
|
||||
ver, rel = version.split("-", 1)
|
||||
super(CoprBuildEnd, self).__init__(
|
||||
msg_id=msg_id,
|
||||
build_id=build_id,
|
||||
task_id=build_id,
|
||||
build_new_state=status,
|
||||
build_name=pkg,
|
||||
build_version=ver,
|
||||
build_release=rel,
|
||||
state_reason=what,
|
||||
)
|
||||
self.copr = copr
|
||||
|
||||
|
||||
class MBSModule(BaseMessage):
|
||||
""" A class that inherits from BaseMessage to provide a message
|
||||
object for a module event generated by module_build_service
|
||||
@@ -340,7 +298,7 @@ def _in_memory_publish(topic, msg, conf, service):
|
||||
|
||||
_fedmsg_backend = {
|
||||
'publish': _fedmsg_publish,
|
||||
'services': ['buildsys', 'mbs', 'copr'],
|
||||
'services': ['buildsys', 'mbs'],
|
||||
'parser': FedmsgMessageParser(),
|
||||
'topic_suffix': '.',
|
||||
}
|
||||
|
||||
23
module_build_service/migrations/versions/9d5e6938588f_.py
Normal file
23
module_build_service/migrations/versions/9d5e6938588f_.py
Normal file
@@ -0,0 +1,23 @@
|
||||
"""Remove the COPR columns
|
||||
|
||||
Revision ID: 9d5e6938588f
|
||||
Revises: 708ac8950f55
|
||||
Create Date: 2018-06-28 13:57:08.977877
|
||||
|
||||
"""
|
||||
|
||||
revision = '9d5e6938588f'
|
||||
down_revision = '708ac8950f55'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.drop_column('module_builds', 'copr_project')
|
||||
op.drop_column('module_builds', 'copr_owner')
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.add_column('module_builds', sa.Column('copr_owner', sa.VARCHAR(), nullable=True))
|
||||
op.add_column('module_builds', sa.Column('copr_project', sa.VARCHAR(), nullable=True))
|
||||
@@ -180,8 +180,6 @@ class ModuleBuild(MBSBase):
|
||||
koji_tag = db.Column(db.String) # This gets set after 'wait'
|
||||
# Koji tag to which tag the Content Generator Koji build.
|
||||
cg_build_koji_tag = db.Column(db.String) # This gets set after wait
|
||||
copr_owner = db.Column(db.String)
|
||||
copr_project = db.Column(db.String)
|
||||
scmurl = db.Column(db.String)
|
||||
owner = db.Column(db.String, nullable=False)
|
||||
time_submitted = db.Column(db.DateTime, nullable=False)
|
||||
@@ -410,8 +408,7 @@ class ModuleBuild(MBSBase):
|
||||
|
||||
@classmethod
|
||||
def create(cls, session, conf, name, stream, version, modulemd, scmurl, username,
|
||||
context=None,
|
||||
copr_owner=None, copr_project=None, rebuild_strategy=None, publish_msg=True):
|
||||
context=None, rebuild_strategy=None, publish_msg=True):
|
||||
now = datetime.utcnow()
|
||||
module = cls(
|
||||
name=name,
|
||||
@@ -424,8 +421,6 @@ class ModuleBuild(MBSBase):
|
||||
owner=username,
|
||||
time_submitted=now,
|
||||
time_modified=now,
|
||||
copr_owner=copr_owner,
|
||||
copr_project=copr_project,
|
||||
# If the rebuild_strategy isn't specified, use the default
|
||||
rebuild_strategy=rebuild_strategy or conf.rebuild_strategy
|
||||
)
|
||||
@@ -482,7 +477,7 @@ class ModuleBuild(MBSBase):
|
||||
list everytime, because local modules make sense only when
|
||||
building using Mock backend or during tests.
|
||||
"""
|
||||
if conf.system in ["koji", "copr"]:
|
||||
if conf.system in ["koji"]:
|
||||
return []
|
||||
|
||||
filters = {}
|
||||
|
||||
@@ -88,7 +88,7 @@ def failed(config, session, msg):
|
||||
component.state_reason = build.state_reason
|
||||
session.add(component)
|
||||
|
||||
# Tell the external buildsystem to wrap up (copr API)
|
||||
# Tell the external buildsystem to wrap up
|
||||
builder.finalize()
|
||||
else:
|
||||
# Do not overwrite state_reason set by Frontend if any.
|
||||
@@ -128,7 +128,7 @@ def done(config, session, msg):
|
||||
builder = module_build_service.builder.GenericBuilder.create_from_module(
|
||||
session, build, config)
|
||||
|
||||
# Tell the external buildsystem to wrap up (CG import, copr API, createrepo, etc.)
|
||||
# Tell the external buildsystem to wrap up (CG import, createrepo, etc.)
|
||||
builder.finalize()
|
||||
|
||||
build.transition(config, state="ready")
|
||||
|
||||
@@ -132,10 +132,6 @@ class MBSProducer(PollingProducer):
|
||||
)
|
||||
module_build_service.scheduler.consumer.work_queue_put(msg)
|
||||
|
||||
elif conf.system == 'copr':
|
||||
# @TODO
|
||||
pass
|
||||
|
||||
elif conf.system == 'mock':
|
||||
pass
|
||||
|
||||
|
||||
@@ -285,12 +285,6 @@ class BaseHandler(object):
|
||||
raise ValidationError('The request contains unspecified parameters: {}'
|
||||
.format(", ".join(forbidden_params)))
|
||||
|
||||
forbidden_params = [k for k in self.data if k.startswith("copr_")]
|
||||
if conf.system != "copr" and forbidden_params:
|
||||
raise ValidationError(('The request contains parameters specific to Copr builder:'
|
||||
' {} even though {} is used')
|
||||
.format(", ".join(forbidden_params), conf.system))
|
||||
|
||||
if not conf.no_auth and "owner" in self.data:
|
||||
raise ValidationError(("The request contains 'owner' parameter,"
|
||||
" however NO_AUTH is not allowed"))
|
||||
|
||||
4
setup.py
4
setup.py
@@ -53,9 +53,6 @@ setup(name='module-build-service',
|
||||
'mbs.builder_backends': [
|
||||
'koji = module_build_service.builder.KojiModuleBuilder:KojiModuleBuilder',
|
||||
'mock = module_build_service.builder.MockModuleBuilder:MockModuleBuilder',
|
||||
# TODO - let's move this out into its own repo so @frostyx can
|
||||
# iterate without us blocking him.
|
||||
'copr = module_build_service.builder.CoprModuleBuilder:CoprModuleBuilder',
|
||||
],
|
||||
'mbs.resolver_backends': [
|
||||
'pdc = module_build_service.resolver.PDCResolver:PDCResolver',
|
||||
@@ -64,7 +61,6 @@ setup(name='module-build-service',
|
||||
},
|
||||
data_files=[('/etc/module-build-service/', ['conf/cacert.pem',
|
||||
'conf/config.py',
|
||||
'conf/copr.conf',
|
||||
'conf/koji.conf',
|
||||
'conf/mock.cfg',
|
||||
'conf/yum.conf']),
|
||||
|
||||
@@ -452,25 +452,6 @@ class TestBuild:
|
||||
module_build_service.scheduler.main(msgs, stop)
|
||||
assert models.ModuleBuild.query.first().state == models.BUILD_STATES['ready']
|
||||
|
||||
@patch('module_build_service.auth.get_user', return_value=user)
|
||||
def test_submit_build_with_optional_params(self, mocked_get_user, conf_system, dbg):
|
||||
params = {'branch': 'master', 'scmurl': 'git://pkgs.stg.fedoraproject.org/modules/'
|
||||
'testmodule.git?#620ec77321b2ea7b0d67d82992dda3e1d67055b4'}
|
||||
not_existing_param = {"not_existing_param": "foo"}
|
||||
copr_owner_param = {"copr_owner": "foo"}
|
||||
|
||||
def submit(data):
|
||||
rv = self.client.post('/module-build-service/1/module-builds/', data=json.dumps(data))
|
||||
return json.loads(rv.data)
|
||||
|
||||
data = submit(dict(params, **not_existing_param))
|
||||
assert "The request contains unspecified parameters:" in data["message"]
|
||||
assert "not_existing_param" in data["message"]
|
||||
assert data["status"] == 400
|
||||
|
||||
data = submit(dict(params, **copr_owner_param))
|
||||
assert "The request contains parameters specific to Copr builder" in data["message"]
|
||||
|
||||
@patch('module_build_service.auth.get_user', return_value=user)
|
||||
@patch('module_build_service.scm.SCM')
|
||||
def test_submit_build_cancel(self, mocked_scm, mocked_get_user, conf_system, dbg):
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
from module_build_service import messaging
|
||||
from module_build_service.messaging import KojiRepoChange # noqa
|
||||
from mock import patch, PropertyMock
|
||||
|
||||
|
||||
class TestFedmsgMessaging:
|
||||
@@ -53,43 +52,6 @@ class TestFedmsgMessaging:
|
||||
assert msg.build_id == 614503
|
||||
assert msg.build_new_state == 1
|
||||
|
||||
@patch("module_build_service.config.Config.system",
|
||||
new_callable=PropertyMock, return_value="copr")
|
||||
def test_copr_build_end(self, conf_system):
|
||||
# http://fedora-fedmsg.readthedocs.io/en/latest/topics.html#copr-build-end
|
||||
copr_build_end_msg = {
|
||||
'msg': {
|
||||
'build': 100,
|
||||
'chroot': 'fedora-20-x86_64',
|
||||
'copr': 'mutt-kz',
|
||||
'ip': '172.16.3.3',
|
||||
'pid': 12010,
|
||||
'pkg': 'mutt-kz', # Reality doesnt match the linked docs
|
||||
'status': 1,
|
||||
'user': 'fatka',
|
||||
'version': '1.5.23.1-1.20150203.git.c8504a8a.fc21',
|
||||
'what': ('build end: user:fatka copr:mutt-kz build:100 ip:172.16.3.3 '
|
||||
'pid:12010 status:1'),
|
||||
'who': 'worker-2'
|
||||
},
|
||||
'msg_id': '2013-b05a323d-37ee-4396-9635-7b5dfaf5441b',
|
||||
'timestamp': 1383956707.634,
|
||||
'topic': 'org.fedoraproject.prod.copr.build.end',
|
||||
'username': 'copr'
|
||||
}
|
||||
|
||||
msg = messaging.FedmsgMessageParser().parse(copr_build_end_msg)
|
||||
assert isinstance(msg, messaging.KojiBuildChange)
|
||||
assert msg.msg_id == '2013-b05a323d-37ee-4396-9635-7b5dfaf5441b'
|
||||
assert msg.build_id == 100
|
||||
assert msg.task_id == 100
|
||||
assert msg.build_new_state == 1
|
||||
assert msg.build_name == 'mutt-kz'
|
||||
assert msg.build_version == '1.5.23.1'
|
||||
assert msg.build_release == '1.20150203.git.c8504a8a.fc21'
|
||||
assert msg.state_reason == ('build end: user:fatka copr:mutt-kz build:100 ip:172.16.3.3 '
|
||||
'pid:12010 status:1')
|
||||
|
||||
def test_buildsys_tag(self):
|
||||
# https://fedora-fedmsg.readthedocs.io/en/latest/topics.html#id134
|
||||
buildsys_tag_msg = {
|
||||
|
||||
@@ -25,7 +25,6 @@ from module_build_service.messaging import KojiTagChange, KojiRepoChange
|
||||
|
||||
class TestConsumer:
|
||||
|
||||
@patch('module_build_service.messaging.conf.messaging', new='fedmsg')
|
||||
def test_get_abstracted_msg_fedmsg(self):
|
||||
"""
|
||||
Test the output of get_abstracted_msg() when using the
|
||||
@@ -63,7 +62,6 @@ class TestConsumer:
|
||||
|
||||
@patch('module_build_service.scheduler.consumer.models')
|
||||
@patch.object(MBSConsumer, 'process_message')
|
||||
@patch('module_build_service.messaging.conf.messaging', new='fedmsg')
|
||||
def test_consume_fedmsg(self, process_message, models):
|
||||
"""
|
||||
Test the MBSConsumer.consume() method when using the
|
||||
|
||||
Reference in New Issue
Block a user