Use NodeSet objects in jobs and NodeRequests

Change-Id: Iff50e28973b3f5d47963cb03a073866ffbfc8961
This commit is contained in:
James E. Blair 2016-09-02 12:09:54 -07:00
parent a98340fafd
commit 0eaad558b5
5 changed files with 36 additions and 32 deletions

View File

@ -100,7 +100,7 @@ class JobParser(object):
'files': to_list(str),
'auth': to_list(auth),
'irrelevant-files': to_list(str),
'nodes': [node],
'nodes': vs.Any([node], str),
'timeout': int,
'_source_project': model.Project,
}
@ -124,13 +124,16 @@ class JobParser(object):
job.hold_following_changes = conf.get('hold-following-changes', False)
job.mutex = conf.get('mutex', None)
if 'nodes' in conf:
nodes = {}
for node in as_list(conf['nodes']):
name = node['name']
if name in nodes:
raise Exception("Duplicate node name")
nodes[node['name']] = node['image']
job.nodes = nodes
conf_nodes = conf['nodes']
if isinstance(conf_nodes, six.string_types):
# This references an existing named nodeset in the layout.
ns = layout.nodesets[conf_nodes]
else:
ns = model.NodeSet()
for conf_node in conf_nodes:
node = model.Node(conf_node['name'], conf_node['image'])
ns.addNode(node)
job.nodeset = ns
tags = conf.get('tags')
if tags:

View File

@ -300,7 +300,7 @@ class LaunchClient(object):
"Launch job %s (uuid: %s) on nodes %s for change %s "
"with dependent changes %s" % (
job, uuid,
item.current_build_set.getJobNodes(job.name),
item.current_build_set.getJobNodeSet(job.name),
item.change,
[x.change for x in dependent_items]))
dependent_items = dependent_items[:]
@ -374,7 +374,7 @@ class LaunchClient(object):
params['items'] = merger_items
params['projects'] = []
nodes = []
for node in item.current_build_set.getJobNodes(job.name):
for node in item.current_build_set.getJobNodeSet(job.name).getNodes():
nodes.append(dict(name=node.name, image=node.image))
params['nodes'] = nodes
projects = set()

View File

@ -616,11 +616,11 @@ class PipelineManager(object):
request = event.request
build_set = request.build_set
build_set.jobNodeRequestComplete(request.job.name, request,
request.nodes)
request.nodeset)
self.log.info("Completed node request %s for job %s of item %s "
"with nodes %s" %
(request, request.job, build_set.item,
request.nodes))
request.nodeset))
def reportItem(self, item):
if not item.reported:

View File

@ -378,6 +378,9 @@ class NodeSet(object):
raise Exception("Duplicate node in %s" % (self,))
self.nodes[node.name] = node
def getNodes(self):
return self.nodes.values()
def __repr__(self):
if self.name:
name = self.name + ' '
@ -389,15 +392,14 @@ class NodeSet(object):
class NodeRequest(object):
"""A request for a set of nodes."""
def __init__(self, build_set, job, nodes):
def __init__(self, build_set, job, nodeset):
self.build_set = build_set
self.job = job
self.nodes = nodes
# TODOv3(jeblair): use a NodeSet here
self.nodeset = nodeset
self.id = uuid4().hex
def __repr__(self):
return '<NodeRequest %s>' % (self.nodes,)
return '<NodeRequest %s>' % (self.nodeset,)
class Job(object):
@ -406,7 +408,7 @@ class Job(object):
attributes = dict(
timeout=None,
# variables={},
nodes={},
nodeset=NodeSet(),
auth={},
workspace=None,
pre_run=None,
@ -634,7 +636,7 @@ class BuildSet(object):
self.unable_to_merge = False
self.failing_reasons = []
self.merge_state = self.NEW
self.nodes = {} # job -> nodes
self.nodesets = {} # job -> nodeset
self.node_requests = {} # job -> reqs
self.files = RepoFiles()
self.layout = None
@ -676,9 +678,10 @@ class BuildSet(object):
keys.sort()
return [self.builds.get(x) for x in keys]
def getJobNodes(self, job_name):
# Return None if not provisioned; [] if no nodes required
return self.nodes.get(job_name)
def getJobNodeSet(self, job_name):
# Return None if not provisioned; empty NodeSet if no nodes
# required
return self.nodesets.get(job_name)
def setJobNodeRequest(self, job_name, req):
if job_name in self.node_requests:
@ -688,10 +691,10 @@ class BuildSet(object):
def getJobNodeRequest(self, job_name):
return self.node_requests.get(job_name)
def jobNodeRequestComplete(self, job_name, req, nodes):
if job_name in self.nodes:
def jobNodeRequestComplete(self, job_name, req, nodeset):
if job_name in self.nodesets:
raise Exception("Prior node request for %s" % (job_name))
self.nodes[job_name] = nodes
self.nodesets[job_name] = nodeset
del self.node_requests[job_name]
@ -846,8 +849,8 @@ class QueueItem(object):
else:
# There is no build for the root of this job tree,
# so it has not run yet.
nodes = self.current_build_set.getJobNodes(job.name)
if nodes is None:
nodeset = self.current_build_set.getJobNodeSet(job.name)
if nodeset is None:
# The nodes for this job are not ready, skip
# it for now.
continue
@ -876,8 +879,8 @@ class QueueItem(object):
if job:
if not job.changeMatches(self.change):
continue
nodes = self.current_build_set.getJobNodes(job.name)
if nodes is None:
nodeset = self.current_build_set.getJobNodeSet(job.name)
if nodeset is None:
req = self.current_build_set.getJobNodeRequest(job.name)
if req is None:
toreq.append(job)

View File

@ -10,7 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from zuul.model import Node, NodeRequest
from zuul.model import NodeRequest
class Nodepool(object):
@ -19,9 +19,7 @@ class Nodepool(object):
self.sched = scheduler
def requestNodes(self, build_set, job):
nodes = job.nodes.items()
nodes = [Node(name, image) for (name, image) in nodes]
req = NodeRequest(build_set, job, nodes)
req = NodeRequest(build_set, job, job.nodeset)
self.requests[req.id] = req
self._requestComplete(req.id)
return req