| |
@@ -40,6 +40,7 @@
|
| |
from koji.util import md5_constructor
|
| |
from koji.util import sha1_constructor
|
| |
from koji.util import dslice
|
| |
+ from koji.util import multi_fnmatch
|
| |
import os
|
| |
import re
|
| |
import rpm
|
| |
@@ -4804,7 +4805,7 @@
|
| |
raise koji.GenericError("Build already exists: %r" % buildinfo)
|
| |
else:
|
| |
# gather needed data
|
| |
- buildinfo = dslice(metadata['build'], ['name', 'version', 'release', 'extra'])
|
| |
+ buildinfo = dslice(metadata['build'], ['name', 'version', 'release', 'extra', 'source'])
|
| |
# epoch is not in the metadata spec, but we allow it to be specified
|
| |
buildinfo['epoch'] = metadata['build'].get('epoch', None)
|
| |
buildinfo['start_time'] = \
|
| |
@@ -7383,6 +7384,30 @@
|
| |
#else
|
| |
raise koji.GenericError, "policy requires package data"
|
| |
|
| |
+
|
| |
+ def policy_get_cgs(data):
|
| |
+ """Determine content generators from policy data"""
|
| |
+
|
| |
+ if not data.has_key('build'):
|
| |
+ raise koji.GenericError, "policy requires build data"
|
| |
+ binfo = get_build(data['build'], strict=True)
|
| |
+
|
| |
+ # first get buildroots used
|
| |
+ rpm_brs = [r['buildroot_id'] for r in list_rpms(buildID=binfo['id'])]
|
| |
+ archive_brs = [a['buildroot_id'] for a in list_archives(buildID=binfo['id'])]
|
| |
+
|
| |
+ # pull cg info out
|
| |
+ # note that br_id will be None if a component had no buildroot
|
| |
+ cgs = set()
|
| |
+ for br_id in set(rpm_brs + archive_brs):
|
| |
+ if br_id is None:
|
| |
+ cgs.add(None)
|
| |
+ else:
|
| |
+ cgs.add(get_buildroot(br_id, strict=True)['cg_name'])
|
| |
+
|
| |
+ return cgs
|
| |
+
|
| |
+
|
| |
class NewPackageTest(koji.policy.BaseSimpleTest):
|
| |
"""Checks to see if a package exists yet"""
|
| |
name = 'is_new_package'
|
| |
@@ -7415,6 +7440,54 @@
|
| |
data[self.field] = volinfo['name']
|
| |
return super(VolumeTest, self).run(data)
|
| |
|
| |
+
|
| |
+ class CGMatchAnyTest(koji.policy.BaseSimpleTest):
|
| |
+ """Checks content generator against glob patterns
|
| |
+
|
| |
+ The 'any' means that if any of the cgs for the build (there can be more
|
| |
+ than one) match the pattern list, then the result is True
|
| |
+ """
|
| |
+
|
| |
+ name = 'cg_match_any'
|
| |
+
|
| |
+ def run(self, data):
|
| |
+ #we need to find the volume name from the base data
|
| |
+ cgs = policy_get_cgs(data)
|
| |
+ patterns = self.str.split()[1:]
|
| |
+ for cg_name in cgs:
|
| |
+ if cg_name is None:
|
| |
+ # component with no br, or br with no cg
|
| |
+ continue
|
| |
+ if multi_fnmatch(cg_name, patterns):
|
| |
+ return True
|
| |
+ # else
|
| |
+ return False
|
| |
+
|
| |
+
|
| |
+ class CGMatchAllTest(koji.policy.BaseSimpleTest):
|
| |
+ """Checks content generator against glob patterns
|
| |
+
|
| |
+ The 'all' means that all of the cgs for the build (there can be more
|
| |
+ than one) must match the pattern list for the result to be true.
|
| |
+ """
|
| |
+
|
| |
+ name = 'cg_match_all'
|
| |
+
|
| |
+ def run(self, data):
|
| |
+ #we need to find the volume name from the base data
|
| |
+ cgs = policy_get_cgs(data)
|
| |
+ if not cgs:
|
| |
+ return False
|
| |
+ patterns = self.str.split()[1:]
|
| |
+ for cg_name in cgs:
|
| |
+ if cg_name is None:
|
| |
+ return False
|
| |
+ if not multi_fnmatch(cg_name, patterns):
|
| |
+ return False
|
| |
+ # else
|
| |
+ return True
|
| |
+
|
| |
+
|
| |
class TagTest(koji.policy.MatchTest):
|
| |
name = 'tag'
|
| |
field = '_tagname'
|
| |
@@ -7498,6 +7571,9 @@
|
| |
if br_id is None:
|
| |
continue
|
| |
tagname = get_buildroot(br_id)['tag_name']
|
| |
+ if tagname is None:
|
| |
+ # content generator buildroots might not have tag info
|
| |
+ continue
|
| |
for pattern in args:
|
| |
if fnmatch.fnmatch(tagname, pattern):
|
| |
return True
|
| |
@@ -7618,24 +7694,27 @@
|
| |
if data.has_key('source'):
|
| |
data[self.field] = data['source']
|
| |
elif data.has_key('build'):
|
| |
- #crack open the build task
|
| |
build = get_build(data['build'])
|
| |
- if build['task_id'] is None:
|
| |
- #imported, no source to match against
|
| |
- return False
|
| |
- task = Task(build['task_id'])
|
| |
- info = task.getInfo()
|
| |
- params = task.getRequest()
|
| |
- #signatures:
|
| |
- # build - (src, target, opts=None)
|
| |
- # maven - (url, target, opts=None)
|
| |
- # winbuild - (name, source_url, target, opts=None)
|
| |
- if info['method'] == 'winbuild':
|
| |
- data[self.field] = params[1]
|
| |
- elif info['method'] == 'indirectionimage':
|
| |
+ if build['source'] is not None:
|
| |
+ data[self.field] = build['source']
|
| |
+ elif build['task_id'] is None:
|
| |
+ # no source to match against
|
| |
return False
|
| |
else:
|
| |
- data[self.field] = params[0]
|
| |
+ #crack open the build task
|
| |
+ task = Task(build['task_id'])
|
| |
+ info = task.getInfo()
|
| |
+ params = task.getRequest()
|
| |
+ #signatures:
|
| |
+ # build - (src, target, opts=None)
|
| |
+ # maven - (url, target, opts=None)
|
| |
+ # winbuild - (name, source_url, target, opts=None)
|
| |
+ if info['method'] == 'winbuild':
|
| |
+ data[self.field] = params[1]
|
| |
+ elif info['method'] == 'indirectionimage':
|
| |
+ return False
|
| |
+ else:
|
| |
+ data[self.field] = params[0]
|
| |
else:
|
| |
return False
|
| |
return super(SourceTest, self).run(data)
|
| |