Launcher: add max-age

This is important for reused nodes; without it, they may never be
deleted.

Change-Id: I9be0c9bd8747c9d54e53e29562747f57261f3a95
This commit is contained in:
James E. Blair
2025-09-12 19:33:36 -07:00
parent df9790dd45
commit 7091d58a95
9 changed files with 140 additions and 8 deletions

View File

@@ -440,6 +440,7 @@ class LabelParser(object):
'description': str,
'min-ready': int,
'max-ready-age': int,
'max-age': int,
}
schema = vs.Schema(label)
@@ -452,7 +453,7 @@ class LabelParser(object):
label = model.Label(conf['name'], conf['image'], conf['flavor'],
conf.get('description'), conf.get('min-ready'),
conf.get('max-ready-age'))
conf.get('max-ready-age'), conf.get('max-age'))
label.source_context = conf.get('_source_context')
label.start_mark = conf.get('_start_mark')
return label

View File

@@ -1565,6 +1565,7 @@ class Launcher:
label=label.name,
label_config_hash=label.config_hash,
max_ready_age=label.max_ready_age,
max_age=label.max_age,
host_key_checking=label.host_key_checking,
boot_timeout=label.boot_timeout,
snapshot_timeout=label.snapshot_timeout,

View File

@@ -1716,7 +1716,7 @@ class Label(ConfigObject):
"""
def __init__(self, name, image, flavor, description, min_ready,
max_ready_age):
max_ready_age, max_age):
super().__init__()
self.name = name
self.image = image
@@ -1724,6 +1724,7 @@ class Label(ConfigObject):
self.description = description
self.min_ready = min_ready
self.max_ready_age = max_ready_age
self.max_age = max_age
@property
def canonical_name(self):
@@ -1747,7 +1748,8 @@ class Label(ConfigObject):
self.flavor == other.flavor and
self.description == other.description and
self.min_ready == other.min_ready and
self.max_ready_age == other.max_ready_age)
self.max_ready_age == other.max_ready_age and
self.max_age == other.max_age)
def toDict(self):
sc = self.source_context
@@ -1759,6 +1761,7 @@ class Label(ConfigObject):
'description': self.description,
'min_ready': self.min_ready,
'max_ready_age': self.max_ready_age,
'max_age': self.max_age,
}
def toConfig(self):
@@ -1771,6 +1774,7 @@ class Label(ConfigObject):
'description': self.description,
'min-ready': self.min_ready,
'max-ready-age': self.max_ready_age,
'max-age': self.max_age,
}
def validateReferences(self, layout):
@@ -2833,6 +2837,7 @@ class ProviderNode(zkobject.PolymorphicZKObjectMixin,
zuul_event_id=None,
span_info=None,
max_ready_age=None,
max_age=None,
state=self.State.REQUESTED,
request_time=time.time(),
state_time=time.time(),
@@ -2923,6 +2928,7 @@ class ProviderNode(zkobject.PolymorphicZKObjectMixin,
zuul_event_id=self.zuul_event_id,
span_info=self.span_info,
max_ready_age=self.max_ready_age,
max_age=self.max_age,
request_time=self.request_time,
state=self.state,
state_time=self.state_time,
@@ -2950,11 +2956,13 @@ class ProviderNode(zkobject.PolymorphicZKObjectMixin,
self.state_time = time.time()
def hasExpired(self):
if not self.max_ready_age:
return False
if self.state != self.State.READY:
return False
return (self.state_time + self.max_ready_age) < time.time()
if self.max_age:
if (self.request_time + self.max_age) < time.time():
return True
if self.max_ready_age and self.state == self.State.READY:
if (self.state_time + self.max_ready_age) < time.time():
return True
return False
def hasHoldExpired(self):
if not self.hold_expiration:

View File

@@ -36,6 +36,14 @@ common_label = vs.Schema({
The time (in seconds) an unassigned node should stay in ready state.
"""
): int,
Optional(
'max-age', default=0,
doc="""\
The time (in seconds) since creation that a node may be
available for use. Ready nodes older than this time will be
deleted.
"""
): int,
Optional(
'snapshot-timeout', default=3600,
doc="""The time (in seconds) to wait for a snapshot to complete."""

View File

@@ -646,6 +646,7 @@ class ProviderNodeConverter:
'state_time': state_time,
'comment': getattr(node, 'comment', None),
'max_ready_age': node.max_ready_age,
'max_age': node.max_age,
'interface_ip': node.interface_ip,
'public_ipv4': node.public_ipv4,
'private_ipv4': node.private_ipv4,
@@ -680,6 +681,7 @@ class ProviderNodeConverter:
'state_time': str,
'comment': str,
'max_ready_age': int,
'max_age': int,
'interface_ip': str,
'public_ipv4': str,
'private_ipv4': str,