summaryrefslogtreecommitdiff
path: root/zuul/manager/independent.py
diff options
context:
space:
mode:
authorJames E. Blair <jeblair@linux.vnet.ibm.com>2015-12-11 14:46:03 -0800
committerJames E. Blair <jeblair@linux.vnet.ibm.com>2015-12-15 15:56:45 -0800
commit8300578a2a4fe0dd2cdae72ca07d369f68f17e6c (patch)
tree540540642a0a00d20c0bf54e2223543c467c9535 /zuul/manager/independent.py
parent07bf7c0bcb006c0b12745a23e467ee9eafb44211 (diff)
downloadzuul-8300578a2a4fe0dd2cdae72ca07d369f68f17e6c.tar.gz
Add job inheritance and start refactoring
This begins a lot of related changes refactoring config loading, the data model, etc., which will continue in subsequent changes. Change-Id: I2ca52a079a837555c1f668e29d5a2fe0a80c1af5
Diffstat (limited to 'zuul/manager/independent.py')
-rw-r--r--zuul/manager/independent.py95
1 files changed, 95 insertions, 0 deletions
diff --git a/zuul/manager/independent.py b/zuul/manager/independent.py
new file mode 100644
index 000000000..56901898d
--- /dev/null
+++ b/zuul/manager/independent.py
@@ -0,0 +1,95 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import logging
+
+from zuul import model
+from zuul.manager import BasePipelineManager, DynamicChangeQueueContextManager
+
+
+class IndependentPipelineManager(BasePipelineManager):
+ log = logging.getLogger("zuul.IndependentPipelineManager")
+ changes_merge = False
+
+ def _postConfig(self, layout):
+ super(IndependentPipelineManager, self)._postConfig(layout)
+
+ def getChangeQueue(self, change, existing=None):
+ # creates a new change queue for every change
+ if existing:
+ return DynamicChangeQueueContextManager(existing)
+ if change.project not in self.pipeline.getProjects():
+ self.pipeline.addProject(change.project)
+ change_queue = model.ChangeQueue(self.pipeline)
+ change_queue.addProject(change.project)
+ self.pipeline.addQueue(change_queue)
+ self.log.debug("Dynamically created queue %s", change_queue)
+ return DynamicChangeQueueContextManager(change_queue)
+
+ def enqueueChangesAhead(self, change, quiet, ignore_requirements,
+ change_queue):
+ ret = self.checkForChangesNeededBy(change, change_queue)
+ if ret in [True, False]:
+ return ret
+ self.log.debug(" Changes %s must be merged ahead of %s" %
+ (ret, change))
+ for needed_change in ret:
+ # This differs from the dependent pipeline by enqueuing
+ # changes ahead as "not live", that is, not intended to
+ # have jobs run. Also, pipeline requirements are always
+ # ignored (which is safe because the changes are not
+ # live).
+ r = self.addChange(needed_change, quiet=True,
+ ignore_requirements=True,
+ live=False, change_queue=change_queue)
+ if not r:
+ return False
+ return True
+
+ def checkForChangesNeededBy(self, change, change_queue):
+ if self.pipeline.ignore_dependencies:
+ return True
+ self.log.debug("Checking for changes needed by %s:" % change)
+ # Return true if okay to proceed enqueing this change,
+ # false if the change should not be enqueued.
+ if not hasattr(change, 'needs_changes'):
+ self.log.debug(" Changeish does not support dependencies")
+ return True
+ if not change.needs_changes:
+ self.log.debug(" No changes needed")
+ return True
+ changes_needed = []
+ for needed_change in change.needs_changes:
+ self.log.debug(" Change %s needs change %s:" % (
+ change, needed_change))
+ if needed_change.is_merged:
+ self.log.debug(" Needed change is merged")
+ continue
+ if self.isChangeAlreadyInQueue(needed_change, change_queue):
+ self.log.debug(" Needed change is already ahead in the queue")
+ continue
+ self.log.debug(" Change %s is needed" % needed_change)
+ if needed_change not in changes_needed:
+ changes_needed.append(needed_change)
+ continue
+ # This differs from the dependent pipeline check in not
+ # verifying that the dependent change is mergable.
+ if changes_needed:
+ return changes_needed
+ return True
+
+ def dequeueItem(self, item):
+ super(IndependentPipelineManager, self).dequeueItem(item)
+ # An independent pipeline manager dynamically removes empty
+ # queues
+ if not item.queue.queue:
+ self.pipeline.removeQueue(item.queue)