Merge "Add label aliases"
This commit is contained in:
@@ -127,3 +127,12 @@ The attributes available to top-level label objects are:
|
||||
instance is retained for at least the minimum billing interval.
|
||||
|
||||
This setting takes precedence over `max-[ready-]age`.
|
||||
|
||||
.. attr:: aliases
|
||||
:type: str
|
||||
|
||||
A list of label aliases to associate with nodes created from
|
||||
this label. These labels may be used to request existing
|
||||
ready nodes that were previously created from this label, but
|
||||
none of their attributes will be used to define
|
||||
characteristics.
|
||||
|
||||
@@ -1178,6 +1178,15 @@
|
||||
Values set on individual labels may still override the
|
||||
values set here.
|
||||
|
||||
.. attr:: aliases
|
||||
:type: str
|
||||
|
||||
A list of label aliases to associate with nodes created from
|
||||
this label. These labels may be used to request existing
|
||||
ready nodes that were previously created from this label, but
|
||||
none of their attributes will be used to define
|
||||
characteristics.
|
||||
|
||||
.. attr:: az
|
||||
:type: str
|
||||
|
||||
@@ -1399,6 +1408,15 @@
|
||||
|
||||
A list of labels associated with this provider.
|
||||
|
||||
.. attr:: aliases
|
||||
:type: str
|
||||
|
||||
A list of label aliases to associate with nodes created from
|
||||
this label. These labels may be used to request existing
|
||||
ready nodes that were previously created from this label, but
|
||||
none of their attributes will be used to define
|
||||
characteristics.
|
||||
|
||||
.. attr:: az
|
||||
:type: str
|
||||
|
||||
|
||||
@@ -812,6 +812,15 @@
|
||||
Values set on individual labels may still override the
|
||||
values set here.
|
||||
|
||||
.. attr:: aliases
|
||||
:type: str
|
||||
|
||||
A list of label aliases to associate with nodes created from
|
||||
this label. These labels may be used to request existing
|
||||
ready nodes that were previously created from this label, but
|
||||
none of their attributes will be used to define
|
||||
characteristics.
|
||||
|
||||
.. attr:: boot-timeout
|
||||
:type: int
|
||||
:default: 300
|
||||
@@ -989,6 +998,15 @@
|
||||
|
||||
A list of labels associated with this provider.
|
||||
|
||||
.. attr:: aliases
|
||||
:type: str
|
||||
|
||||
A list of label aliases to associate with nodes created from
|
||||
this label. These labels may be used to request existing
|
||||
ready nodes that were previously created from this label, but
|
||||
none of their attributes will be used to define
|
||||
characteristics.
|
||||
|
||||
.. attr:: boot-timeout
|
||||
:type: int
|
||||
:default: 300
|
||||
|
||||
@@ -498,6 +498,15 @@
|
||||
Values set on individual labels may still override the
|
||||
values set here.
|
||||
|
||||
.. attr:: aliases
|
||||
:type: str
|
||||
|
||||
A list of label aliases to associate with nodes created from
|
||||
this label. These labels may be used to request existing
|
||||
ready nodes that were previously created from this label, but
|
||||
none of their attributes will be used to define
|
||||
characteristics.
|
||||
|
||||
.. attr:: annotations
|
||||
:type: dict
|
||||
|
||||
@@ -647,6 +656,15 @@
|
||||
|
||||
A list of labels associated with this provider.
|
||||
|
||||
.. attr:: aliases
|
||||
:type: str
|
||||
|
||||
A list of label aliases to associate with nodes created from
|
||||
this label. These labels may be used to request existing
|
||||
ready nodes that were previously created from this label, but
|
||||
none of their attributes will be used to define
|
||||
characteristics.
|
||||
|
||||
.. attr:: annotations
|
||||
:type: dict
|
||||
|
||||
|
||||
@@ -621,6 +621,15 @@
|
||||
Values set on individual labels may still override the
|
||||
values set here.
|
||||
|
||||
.. attr:: aliases
|
||||
:type: str
|
||||
|
||||
A list of label aliases to associate with nodes created from
|
||||
this label. These labels may be used to request existing
|
||||
ready nodes that were previously created from this label, but
|
||||
none of their attributes will be used to define
|
||||
characteristics.
|
||||
|
||||
.. attr:: auto-floating-ip
|
||||
:type: bool
|
||||
:default: True
|
||||
@@ -777,6 +786,15 @@
|
||||
|
||||
A list of labels associated with this provider.
|
||||
|
||||
.. attr:: aliases
|
||||
:type: str
|
||||
|
||||
A list of label aliases to associate with nodes created from
|
||||
this label. These labels may be used to request existing
|
||||
ready nodes that were previously created from this label, but
|
||||
none of their attributes will be used to define
|
||||
characteristics.
|
||||
|
||||
.. attr:: auto-floating-ip
|
||||
:type: bool
|
||||
:default: True
|
||||
|
||||
@@ -498,6 +498,15 @@
|
||||
Values set on individual labels may still override the
|
||||
values set here.
|
||||
|
||||
.. attr:: aliases
|
||||
:type: str
|
||||
|
||||
A list of label aliases to associate with nodes created from
|
||||
this label. These labels may be used to request existing
|
||||
ready nodes that were previously created from this label, but
|
||||
none of their attributes will be used to define
|
||||
characteristics.
|
||||
|
||||
.. attr:: boot-timeout
|
||||
:type: int
|
||||
:default: 300
|
||||
@@ -611,6 +620,15 @@
|
||||
|
||||
A list of labels associated with this provider.
|
||||
|
||||
.. attr:: aliases
|
||||
:type: str
|
||||
|
||||
A list of label aliases to associate with nodes created from
|
||||
this label. These labels may be used to request existing
|
||||
ready nodes that were previously created from this label, but
|
||||
none of their attributes will be used to define
|
||||
characteristics.
|
||||
|
||||
.. attr:: boot-timeout
|
||||
:type: int
|
||||
:default: 300
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
A new attribute, :attr:`label.aliases` is available for indicating
|
||||
to Zuul that if an existing node of other labels is ready
|
||||
for use, it may be used to satisfy a request for the label.
|
||||
@@ -0,0 +1,90 @@
|
||||
- pipeline:
|
||||
name: check
|
||||
manager: independent
|
||||
trigger:
|
||||
gerrit:
|
||||
- event: patchset-created
|
||||
success:
|
||||
gerrit:
|
||||
Verified: 1
|
||||
failure:
|
||||
gerrit:
|
||||
Verified: -1
|
||||
|
||||
- job:
|
||||
name: base
|
||||
parent: null
|
||||
run: playbooks/base.yaml
|
||||
nodeset:
|
||||
nodes:
|
||||
- label: debian-normal
|
||||
name: controller
|
||||
|
||||
- job:
|
||||
name: check-job
|
||||
run: playbooks/check.yaml
|
||||
|
||||
- project:
|
||||
name: org/project
|
||||
check:
|
||||
jobs:
|
||||
- check-job
|
||||
|
||||
- image:
|
||||
name: debian
|
||||
type: cloud
|
||||
|
||||
- flavor:
|
||||
name: normal
|
||||
|
||||
- flavor:
|
||||
name: spot
|
||||
|
||||
- label:
|
||||
name: debian-normal
|
||||
image: debian
|
||||
flavor: normal
|
||||
min-ready: 1
|
||||
|
||||
- label:
|
||||
name: debian-spot
|
||||
image: debian
|
||||
flavor: spot
|
||||
aliases: debian-normal
|
||||
min-ready: 1
|
||||
|
||||
- section:
|
||||
name: aws-base
|
||||
abstract: true
|
||||
connection: aws
|
||||
launch-timeout: 600
|
||||
launch-attempts: 2
|
||||
label-defaults:
|
||||
host-key-checking: false
|
||||
boot-timeout: 120
|
||||
key-name: zuul
|
||||
flavors:
|
||||
- name: normal
|
||||
instance-type: t3.medium
|
||||
- name: spot
|
||||
instance-type: t3.medium
|
||||
market-type: spot
|
||||
images:
|
||||
- name: debian
|
||||
image-id: ami-1e749f67
|
||||
|
||||
- section:
|
||||
name: aws-us-east-1
|
||||
parent: aws-base
|
||||
region: us-east-1
|
||||
|
||||
- provider:
|
||||
name: aws-us-east-1-main
|
||||
section: aws-us-east-1
|
||||
labels:
|
||||
- name: debian-normal
|
||||
reuse: true
|
||||
max-age: 600
|
||||
- name: debian-spot
|
||||
reuse: true
|
||||
max-age: 600
|
||||
@@ -0,0 +1,90 @@
|
||||
- pipeline:
|
||||
name: check
|
||||
manager: independent
|
||||
trigger:
|
||||
gerrit:
|
||||
- event: patchset-created
|
||||
success:
|
||||
gerrit:
|
||||
Verified: 1
|
||||
failure:
|
||||
gerrit:
|
||||
Verified: -1
|
||||
|
||||
- job:
|
||||
name: base
|
||||
parent: null
|
||||
run: playbooks/base.yaml
|
||||
nodeset:
|
||||
nodes:
|
||||
- label: debian-normal
|
||||
name: controller
|
||||
|
||||
- job:
|
||||
name: check-job
|
||||
run: playbooks/check.yaml
|
||||
|
||||
- project:
|
||||
name: org/project
|
||||
check:
|
||||
jobs:
|
||||
- check-job
|
||||
|
||||
- image:
|
||||
name: debian
|
||||
type: cloud
|
||||
|
||||
- flavor:
|
||||
name: normal
|
||||
|
||||
- flavor:
|
||||
name: spot
|
||||
|
||||
- label:
|
||||
name: debian-normal
|
||||
image: debian
|
||||
flavor: normal
|
||||
aliases: debian-spot
|
||||
min-ready: 1
|
||||
|
||||
- label:
|
||||
name: debian-spot
|
||||
image: debian
|
||||
flavor: spot
|
||||
min-ready: 1
|
||||
|
||||
- section:
|
||||
name: aws-base
|
||||
abstract: true
|
||||
connection: aws
|
||||
launch-timeout: 600
|
||||
launch-attempts: 2
|
||||
label-defaults:
|
||||
host-key-checking: false
|
||||
boot-timeout: 120
|
||||
key-name: zuul
|
||||
flavors:
|
||||
- name: normal
|
||||
instance-type: t3.medium
|
||||
- name: spot
|
||||
instance-type: t3.medium
|
||||
market-type: spot
|
||||
images:
|
||||
- name: debian
|
||||
image-id: ami-1e749f67
|
||||
|
||||
- section:
|
||||
name: aws-us-east-1
|
||||
parent: aws-base
|
||||
region: us-east-1
|
||||
|
||||
- provider:
|
||||
name: aws-us-east-1-main
|
||||
section: aws-us-east-1
|
||||
labels:
|
||||
- name: debian-normal
|
||||
reuse: true
|
||||
max-age: 600
|
||||
- name: debian-spot
|
||||
reuse: true
|
||||
max-age: 600
|
||||
@@ -0,0 +1,88 @@
|
||||
- pipeline:
|
||||
name: check
|
||||
manager: independent
|
||||
trigger:
|
||||
gerrit:
|
||||
- event: patchset-created
|
||||
success:
|
||||
gerrit:
|
||||
Verified: 1
|
||||
failure:
|
||||
gerrit:
|
||||
Verified: -1
|
||||
|
||||
- job:
|
||||
name: base
|
||||
parent: null
|
||||
run: playbooks/base.yaml
|
||||
nodeset:
|
||||
nodes:
|
||||
- label: debian-normal
|
||||
name: controller
|
||||
|
||||
- job:
|
||||
name: check-job
|
||||
run: playbooks/check.yaml
|
||||
|
||||
- project:
|
||||
name: org/project
|
||||
check:
|
||||
jobs:
|
||||
- check-job
|
||||
|
||||
- image:
|
||||
name: debian
|
||||
type: cloud
|
||||
|
||||
- flavor:
|
||||
name: normal
|
||||
|
||||
- flavor:
|
||||
name: spot
|
||||
|
||||
- label:
|
||||
name: debian-normal
|
||||
image: debian
|
||||
flavor: normal
|
||||
|
||||
- label:
|
||||
name: debian-spot
|
||||
image: debian
|
||||
flavor: spot
|
||||
|
||||
- section:
|
||||
name: aws-base
|
||||
abstract: true
|
||||
connection: aws
|
||||
launch-timeout: 600
|
||||
launch-attempts: 2
|
||||
label-defaults:
|
||||
host-key-checking: false
|
||||
boot-timeout: 120
|
||||
key-name: zuul
|
||||
flavors:
|
||||
- name: normal
|
||||
instance-type: t3.medium
|
||||
- name: spot
|
||||
instance-type: t3.medium
|
||||
market-type: spot
|
||||
images:
|
||||
- name: debian
|
||||
image-id: ami-1e749f67
|
||||
|
||||
- section:
|
||||
name: aws-us-east-1
|
||||
parent: aws-base
|
||||
region: us-east-1
|
||||
|
||||
- provider:
|
||||
name: aws-us-east-1-main
|
||||
section: aws-us-east-1
|
||||
labels:
|
||||
- name: debian-normal
|
||||
reuse: true
|
||||
max-age: 600
|
||||
aliases: debian-spot
|
||||
- name: debian-spot
|
||||
reuse: true
|
||||
max-age: 600
|
||||
@@ -3191,6 +3191,48 @@ class TestMinReadyLauncher(LauncherBaseTestCase):
|
||||
nodes_by_label = self._nodes_by_label()
|
||||
self.assertEqual(1, len(nodes_by_label['debian-emea']))
|
||||
|
||||
@simple_layout('layouts/nodepool-min-ready-aliases.yaml',
|
||||
enable_nodepool=True)
|
||||
def test_min_ready_aliases(self):
|
||||
for _ in iterate_timeout(60, "nodes to be ready"):
|
||||
nodes = self.launcher.api.nodes_cache.getItems()
|
||||
if len(nodes) != 1:
|
||||
continue
|
||||
if all(n.state == n.State.READY for n in nodes):
|
||||
break
|
||||
|
||||
# NOTE: This test relies on the min-ready algorithm processing
|
||||
# labels in the order they appear in the tenant config, but
|
||||
# that is not something we want to codify; it is a convenient
|
||||
# implementation detail that is okay to change.
|
||||
|
||||
# We create the aliased debian-normal instance first, so it
|
||||
# can be reused by debian-spot.
|
||||
self.waitUntilSettled()
|
||||
nodes = self.launcher.api.nodes_cache.getItems()
|
||||
self.assertEqual(1, len(nodes))
|
||||
|
||||
@simple_layout('layouts/nodepool-min-ready-aliases-reverse.yaml',
|
||||
enable_nodepool=True)
|
||||
def test_min_ready_aliases_reverse(self):
|
||||
for _ in iterate_timeout(60, "nodes to be ready"):
|
||||
nodes = self.launcher.api.nodes_cache.getItems()
|
||||
if len(nodes) != 2:
|
||||
continue
|
||||
if all(n.state == n.State.READY for n in nodes):
|
||||
break
|
||||
|
||||
# NOTE: This test relies on the min-ready algorithm processing
|
||||
# labels in the order they appear in the tenant config, but
|
||||
# that is not something we want to codify; it is a convenient
|
||||
# implementation detail that is okay to change.
|
||||
|
||||
# We create the unaliased debian-normal instance first, and it
|
||||
# is not reusable by debian-spot, so we end up with two nodes.
|
||||
self.waitUntilSettled()
|
||||
nodes = self.launcher.api.nodes_cache.getItems()
|
||||
self.assertEqual(2, len(nodes))
|
||||
|
||||
|
||||
class TestMinReadyTenantVariant(LauncherBaseTestCase):
|
||||
tenant_config_file = "config/launcher-min-ready/tenant-variant.yaml"
|
||||
@@ -4130,6 +4172,79 @@ class TestSubnodesAndReuse(LauncherBaseTestCase):
|
||||
except NoNodeError:
|
||||
break
|
||||
|
||||
@simple_layout('layouts/nodepool-reuse-aliases.yaml', enable_nodepool=True)
|
||||
def test_reuse_aliases(self):
|
||||
# Test requesting an alias of a reusable node
|
||||
ctx = self.createZKContext(None)
|
||||
request = self.requestNodes(['debian-normal'])
|
||||
self.assertEqual(request.State.FULFILLED, request.state)
|
||||
|
||||
nodes = self.launcher.api.nodes_cache.getItems()
|
||||
self.assertEqual(1, len(nodes))
|
||||
node = nodes[0]
|
||||
# Get a copy so we're not modifying the launcher's
|
||||
node = model.ProviderNode.fromZK(ctx, path=node.getPath())
|
||||
|
||||
with node.locked(ctx):
|
||||
with node.activeContext(ctx):
|
||||
node.unassign(ctx)
|
||||
node.assign(ctx, request_id="dne", tenant_name="test")
|
||||
# Modify the request so that the max zxid of the
|
||||
# request cache is later than the node assignment
|
||||
# (since the "dne" request does not exist).
|
||||
with request.locked(ctx), request.activeContext(ctx):
|
||||
request.priority += 1
|
||||
node.setState(node.State.USED)
|
||||
|
||||
for _ in iterate_timeout(10, "node to be recycled"):
|
||||
node.refresh(ctx)
|
||||
if node.state == node.State.READY:
|
||||
break
|
||||
|
||||
# The normal label can also be requested as a spot label
|
||||
request = self.requestNodes(['debian-spot'])
|
||||
self.assertEqual(request.State.FULFILLED, request.state)
|
||||
|
||||
nodes = self.launcher.api.nodes_cache.getItems()
|
||||
self.assertEqual(1, len(nodes))
|
||||
|
||||
@simple_layout('layouts/nodepool-reuse-aliases.yaml', enable_nodepool=True)
|
||||
def test_reuse_aliases_reverse(self):
|
||||
# Test the reverse of the above test: that label aliases are
|
||||
# one-way
|
||||
ctx = self.createZKContext(None)
|
||||
request = self.requestNodes(['debian-spot'])
|
||||
self.assertEqual(request.State.FULFILLED, request.state)
|
||||
|
||||
nodes = self.launcher.api.nodes_cache.getItems()
|
||||
self.assertEqual(1, len(nodes))
|
||||
node = nodes[0]
|
||||
# Get a copy so we're not modifying the launcher's
|
||||
node = model.ProviderNode.fromZK(ctx, path=node.getPath())
|
||||
|
||||
with node.locked(ctx):
|
||||
with node.activeContext(ctx):
|
||||
node.unassign(ctx)
|
||||
node.assign(ctx, request_id="dne", tenant_name="test")
|
||||
# Modify the request so that the max zxid of the
|
||||
# request cache is later than the node assignment
|
||||
# (since the "dne" request does not exist).
|
||||
with request.locked(ctx), request.activeContext(ctx):
|
||||
request.priority += 1
|
||||
node.setState(node.State.USED)
|
||||
|
||||
for _ in iterate_timeout(10, "node to be recycled"):
|
||||
node.refresh(ctx)
|
||||
if node.state == node.State.READY:
|
||||
break
|
||||
|
||||
# The spot label may not be requested as a normal label
|
||||
request = self.requestNodes(['debian-normal'])
|
||||
self.assertEqual(request.State.FULFILLED, request.state)
|
||||
|
||||
nodes = self.launcher.api.nodes_cache.getItems()
|
||||
self.assertEqual(2, len(nodes))
|
||||
|
||||
@simple_layout('layouts/nodepool-reuse.yaml', enable_nodepool=True)
|
||||
@okay_tracebacks('_checkNodescanRequest')
|
||||
def test_reuse_unreachable(self):
|
||||
|
||||
@@ -448,6 +448,7 @@ class LabelParser(object):
|
||||
'max-age': int,
|
||||
'min-retention-time': int,
|
||||
'max-nodes': int,
|
||||
'aliases': to_list(str),
|
||||
}
|
||||
schema = vs.Schema(label)
|
||||
|
||||
@@ -462,7 +463,8 @@ class LabelParser(object):
|
||||
conf.get('description'), conf.get('min-ready'),
|
||||
conf.get('max-ready-age'), conf.get('max-age'),
|
||||
conf.get('max-nodes'),
|
||||
conf.get('min-retention-time'))
|
||||
conf.get('min-retention-time'),
|
||||
as_list(conf.get('aliases')))
|
||||
label.source_context = conf.get('_source_context')
|
||||
label.start_mark = conf.get('_start_mark')
|
||||
return label
|
||||
|
||||
+20
-3
@@ -1720,12 +1720,14 @@ class Launcher:
|
||||
node_uuid = static_node.node_id
|
||||
connection_port = static_node.connection_port
|
||||
state = model.ProviderNode.State.BUILDING
|
||||
label_aliases = static_node.aliases
|
||||
label_aliases = set(static_node.aliases)
|
||||
else:
|
||||
node_uuid = uuid.uuid4().hex
|
||||
connection_port = image.connection_port
|
||||
state = model.ProviderNode.State.REQUESTED
|
||||
label_aliases = []
|
||||
label_aliases = set()
|
||||
label_aliases |= set(label.aliases)
|
||||
label_aliases = list(label_aliases)
|
||||
args = dict(
|
||||
uuid=node_uuid,
|
||||
state=state,
|
||||
@@ -2504,9 +2506,14 @@ class Launcher:
|
||||
label_scores,
|
||||
candidate_launchers):
|
||||
continue
|
||||
# We collect all label variants to determin if
|
||||
# We collect all label variants to determine if
|
||||
# min-ready is satisfied based on the config hashes
|
||||
tenant_labels[tenant_name][label.name].append(label)
|
||||
# Also collect all aliases
|
||||
for alias in label.aliases:
|
||||
if aliased_label := tenant_provider.labels.get(alias):
|
||||
tenant_labels[tenant_name][
|
||||
aliased_label.name].append(label)
|
||||
|
||||
unassigned_hashes = self._getUnassignedNodeLabelHashes()
|
||||
for tenant_name, min_ready_labels in tenant_labels.items():
|
||||
@@ -2524,7 +2531,13 @@ class Launcher:
|
||||
provider = random.choice(label_providers)
|
||||
label = provider.labels[label_name]
|
||||
yield label, provider
|
||||
# Add the node we just added to the node list for its label
|
||||
unassigned_hashes[label.name].append(label.config_hash)
|
||||
# And also all of its aliases
|
||||
for alias in label.aliases:
|
||||
if aliased_label := provider.labels.get(alias):
|
||||
unassigned_hashes[alias].append(
|
||||
label.config_hash)
|
||||
|
||||
def _hasHighestMinReadyScore(
|
||||
self, label_cname, label_scores, candidate_launchers):
|
||||
@@ -2547,6 +2560,10 @@ class Launcher:
|
||||
if node.request_id is not None:
|
||||
continue
|
||||
unassigned_nodes[node.label].append(node.label_config_hash)
|
||||
# Append our config hash for all other aliases that are
|
||||
# equivalent
|
||||
for alias in node.label_aliases:
|
||||
unassigned_nodes[alias].append(node.label_config_hash)
|
||||
return unassigned_nodes
|
||||
|
||||
def _getUnassignedNodes(self):
|
||||
|
||||
+12
-2
@@ -1753,7 +1753,8 @@ class Label(ConfigObject):
|
||||
"""
|
||||
|
||||
def __init__(self, name, image, flavor, description, min_ready,
|
||||
max_ready_age, max_age, max_nodes, min_retention_time):
|
||||
max_ready_age, max_age, max_nodes, min_retention_time,
|
||||
aliases):
|
||||
super().__init__()
|
||||
self.name = name
|
||||
self.image = image
|
||||
@@ -1764,6 +1765,7 @@ class Label(ConfigObject):
|
||||
self.max_age = max_age
|
||||
self.max_nodes = max_nodes
|
||||
self.min_retention_time = min_retention_time
|
||||
self.aliases = aliases
|
||||
|
||||
@property
|
||||
def project_canonical_name(self):
|
||||
@@ -1793,7 +1795,8 @@ class Label(ConfigObject):
|
||||
self.max_ready_age == other.max_ready_age and
|
||||
self.max_age == other.max_age and
|
||||
self.max_nodes == other.max_nodes and
|
||||
self.min_retention_time == other.min_retention_time)
|
||||
self.min_retention_time == other.min_retention_time and
|
||||
self.aliases == other.aliases)
|
||||
|
||||
def toDict(self):
|
||||
return {
|
||||
@@ -1807,6 +1810,7 @@ class Label(ConfigObject):
|
||||
'max_age': self.max_age,
|
||||
'max_nodes': self.max_nodes,
|
||||
'min_retention_time': self.min_retention_time,
|
||||
'aliases': self.aliases,
|
||||
}
|
||||
|
||||
def toConfig(self):
|
||||
@@ -1820,6 +1824,7 @@ class Label(ConfigObject):
|
||||
'max-age': self.max_age,
|
||||
# max-nodes is only permitted at the top level
|
||||
'min-retention-time': self.min_retention_time,
|
||||
'aliases': self.aliases,
|
||||
}
|
||||
|
||||
def validateReferences(self, layout):
|
||||
@@ -1831,6 +1836,11 @@ class Label(ConfigObject):
|
||||
raise Exception(
|
||||
f'The label "{self.name}" references an unknown flavor '
|
||||
f'"{self.flavor}"')
|
||||
for alias in self.aliases:
|
||||
if not layout.labels.get(alias):
|
||||
raise Exception(
|
||||
f'The label "{self.name}" references an unknown label '
|
||||
f'"{alias}"')
|
||||
|
||||
|
||||
class Section(ConfigObject):
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
import voluptuous as vs
|
||||
from zuul.lib.voluputil import (
|
||||
AsList,
|
||||
Constant,
|
||||
Nullable,
|
||||
Optional,
|
||||
@@ -79,6 +80,16 @@ common_label = vs.Schema({
|
||||
doc="""\
|
||||
Should the node be reused (True) or deleted (False) after use."""
|
||||
): bool,
|
||||
Optional(
|
||||
'aliases',
|
||||
doc="""\
|
||||
A list of label aliases to associate with nodes created from
|
||||
this label. These labels may be used to request existing
|
||||
ready nodes that were previously created from this label, but
|
||||
none of their attributes will be used to define
|
||||
characteristics.
|
||||
""",
|
||||
default=[]): AsList(str),
|
||||
Optional(
|
||||
'executor-zone',
|
||||
doc="""\
|
||||
|
||||
Reference in New Issue
Block a user