summaryrefslogtreecommitdiff
path: root/zuul
diff options
context:
space:
mode:
Diffstat (limited to 'zuul')
-rw-r--r--zuul/configloader.py2
-rw-r--r--zuul/model.py24
2 files changed, 25 insertions, 1 deletions
diff --git a/zuul/configloader.py b/zuul/configloader.py
index fb1695c18..669cd8bbd 100644
--- a/zuul/configloader.py
+++ b/zuul/configloader.py
@@ -428,6 +428,7 @@ class JobParser(object):
# Attributes of a job that can also be used in Project and ProjectTemplate
job_attributes = {'parent': vs.Any(str, None),
'final': bool,
+ 'protected': bool,
'failure-message': str,
'success-message': str,
'failure-url': str,
@@ -467,6 +468,7 @@ class JobParser(object):
simple_attributes = [
'final',
+ 'protected',
'timeout',
'workspace',
'voting',
diff --git a/zuul/model.py b/zuul/model.py
index 56d08a16f..04df7a80f 100644
--- a/zuul/model.py
+++ b/zuul/model.py
@@ -843,6 +843,7 @@ class Job(object):
semaphore=None,
attempts=3,
final=False,
+ protected=None,
roles=(),
required_projects={},
allowed_projects=None,
@@ -860,6 +861,7 @@ class Job(object):
inheritance_path=(),
parent_data=None,
description=None,
+ protected_origin=None,
)
self.inheritable_attributes = {}
@@ -1037,12 +1039,21 @@ class Job(object):
for k in self.execution_attributes:
if (other._get(k) is not None and
- k not in set(['final'])):
+ k not in set(['final', 'protected'])):
if self.final:
raise Exception("Unable to modify final job %s attribute "
"%s=%s with variant %s" % (
repr(self), k, other._get(k),
repr(other)))
+ if self.protected_origin:
+ # this is a protected job, check origin of job definition
+ this_origin = self.protected_origin
+ other_origin = other.source_context.project.canonical_name
+ if this_origin != other_origin:
+ raise Exception("Job %s which is defined in %s is "
+ "protected and cannot be inherited "
+ "from other projects."
+ % (repr(self), this_origin))
if k not in set(['pre_run', 'run', 'post_run', 'roles',
'variables', 'required_projects']):
# TODO(jeblair): determine if deepcopy is required
@@ -1053,6 +1064,17 @@ class Job(object):
if other.final != self.attributes['final']:
self.final = other.final
+ # Protected may only be set to true
+ if other.protected is not None:
+ # don't allow to reset protected flag
+ if not other.protected and self.protected_origin:
+ raise Exception("Unable to reset protected attribute of job"
+ " %s by job %s" % (
+ repr(self), repr(other)))
+ if not self.protected_origin:
+ self.protected_origin = \
+ other.source_context.project.canonical_name
+
# We must update roles before any playbook contexts
if other._get('roles') is not None:
self.addRoles(other.roles)