bundles/apt: support spreading unattended-upgrades in a group
This commit is contained in:
parent
92cca7f396
commit
048fb83ee7
5 changed files with 81 additions and 24 deletions
|
@ -24,13 +24,18 @@ def patchday(metadata):
|
||||||
day = metadata.get('apt/unattended-upgrades/day')
|
day = metadata.get('apt/unattended-upgrades/day')
|
||||||
hour = metadata.get('apt/unattended-upgrades/hour')
|
hour = metadata.get('apt/unattended-upgrades/hour')
|
||||||
|
|
||||||
|
spread = metadata.get('apt/unattended-upgrades/spread_in_group', None)
|
||||||
|
if spread is not None:
|
||||||
|
spread_nodes = sorted(repo.nodes_in_group(spread))
|
||||||
|
day += spread_nodes.index(node)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'cron': {
|
'cron': {
|
||||||
'jobs': {
|
'jobs': {
|
||||||
'upgrade-and-reboot': '{minute} {hour} * * {day} root /usr/local/sbin/upgrade-and-reboot'.format(
|
'upgrade-and-reboot': '{minute} {hour} * * {day} root /usr/local/sbin/upgrade-and-reboot'.format(
|
||||||
minute=node.magic_number % 30,
|
minute=node.magic_number % 30,
|
||||||
hour=hour,
|
hour=hour,
|
||||||
day=day,
|
day=day%7,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,31 +1,18 @@
|
||||||
% for monitored_node in sorted(repo.nodes):
|
% for dt in downtimes:
|
||||||
<%
|
object ScheduledDowntime "${dt['name']}" {
|
||||||
auto_updates_enabled = (
|
host_name = "${dt['host']}"
|
||||||
monitored_node.has_any_bundle(['apt', 'c3voc-addons'])
|
|
||||||
or (
|
|
||||||
monitored_node.has_bundle('pacman')
|
|
||||||
and monitored_node.metadata.get('pacman/unattended-upgrades/is_enabled', False)
|
|
||||||
)
|
|
||||||
) and not monitored_node.metadata.get('icinga_options/exclude_from_monitoring', False)
|
|
||||||
%>\
|
|
||||||
% if auto_updates_enabled:
|
|
||||||
object ScheduledDowntime "unattended_upgrades" {
|
|
||||||
host_name = "${monitored_node.name}"
|
|
||||||
|
|
||||||
author = "unattended-upgrades"
|
author = "${dt['name']}"
|
||||||
comment = "Downtime for upgrade-and-reboot of node ${monitored_node.name}"
|
comment = "${dt['comment']}"
|
||||||
|
|
||||||
fixed = true
|
fixed = true
|
||||||
|
|
||||||
ranges = {
|
ranges = {
|
||||||
% if monitored_node.has_bundle('pacman'):
|
% for d,t in dt['times'].items():
|
||||||
"${days[monitored_node.metadata.get('pacman/unattended-upgrades/day')]}" = "${monitored_node.metadata.get('pacman/unattended-upgrades/hour')}:${monitored_node.magic_number%30}-${monitored_node.metadata.get('pacman/unattended-upgrades/hour')}:${(monitored_node.magic_number%30)+30}"
|
"${d}" = "${t}"
|
||||||
% else:
|
% endfor
|
||||||
"${days[monitored_node.metadata.get('apt/unattended-upgrades/day')]}" = "${monitored_node.metadata.get('apt/unattended-upgrades/hour')}:${monitored_node.magic_number%30}-${monitored_node.metadata.get('apt/unattended-upgrades/hour')}:${(monitored_node.magic_number%30)+30}"
|
|
||||||
% endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
child_options = "DowntimeTriggeredChildren"
|
child_options = "DowntimeTriggeredChildren"
|
||||||
}
|
}
|
||||||
% endif
|
|
||||||
% endfor
|
% endfor
|
||||||
|
|
|
@ -346,7 +346,8 @@ svc_systemd = {
|
||||||
|
|
||||||
# The actual hosts and services management starts here
|
# The actual hosts and services management starts here
|
||||||
bundles = set()
|
bundles = set()
|
||||||
for rnode in repo.nodes:
|
downtimes = []
|
||||||
|
for rnode in sorted(repo.nodes):
|
||||||
if rnode.metadata.get('icinga_options/exclude_from_monitoring', False):
|
if rnode.metadata.get('icinga_options/exclude_from_monitoring', False):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -388,6 +389,41 @@ for rnode in repo.nodes:
|
||||||
|
|
||||||
bundles |= set(rnode.metadata.get('icinga2_api', {}).keys())
|
bundles |= set(rnode.metadata.get('icinga2_api', {}).keys())
|
||||||
|
|
||||||
|
if rnode.has_any_bundle(['apt', 'c3voc-addons']):
|
||||||
|
day = rnode.metadata.get('apt/unattended-upgrades/day')
|
||||||
|
hour = rnode.metadata.get('apt/unattended-upgrades/hour')
|
||||||
|
minute = rnode.magic_number%30
|
||||||
|
|
||||||
|
spread = rnode.metadata.get('apt/unattended-upgrades/spread_in_group', None)
|
||||||
|
if spread is not None:
|
||||||
|
spread_nodes = sorted(repo.nodes_in_group(spread))
|
||||||
|
day += spread_nodes.index(rnode)
|
||||||
|
|
||||||
|
downtimes.append({
|
||||||
|
'name': 'unattended-upgrades',
|
||||||
|
'host': rnode.name,
|
||||||
|
'comment': f'Downtime for upgrade-and-reboot of node {rnode.name}',
|
||||||
|
'times': {
|
||||||
|
DAYS_TO_STRING[day%7]: f'{hour}:{minute}-{hour}:{minute+30}',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
elif (
|
||||||
|
rnode.has_bundle('pacman')
|
||||||
|
and rnode.metadata.get('pacman/unattended-upgrades/is_enabled', False)
|
||||||
|
):
|
||||||
|
day = rnode.metadata.get('pacman/unattended-upgrades/day')
|
||||||
|
hour = rnode.metadata.get('pacman/unattended-upgrades/hour')
|
||||||
|
minute = rnode.magic_number%30
|
||||||
|
|
||||||
|
downtimes.append({
|
||||||
|
'name': 'unattended-upgrades',
|
||||||
|
'host': rnode.name,
|
||||||
|
'comment': f'Downtime for upgrade-and-reboot of node {rnode.name}',
|
||||||
|
'times': {
|
||||||
|
DAYS_TO_STRING[day%7]: f'{hour}:{minute}-{hour}:{minute+30}',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
files['/etc/icinga2/conf.d/groups.conf'] = {
|
files['/etc/icinga2/conf.d/groups.conf'] = {
|
||||||
'source': 'icinga2/groups.conf',
|
'source': 'icinga2/groups.conf',
|
||||||
'content_type': 'mako',
|
'content_type': 'mako',
|
||||||
|
@ -408,7 +444,7 @@ files['/etc/icinga2/conf.d/downtimes.conf'] = {
|
||||||
'source': 'icinga2/downtimes.conf',
|
'source': 'icinga2/downtimes.conf',
|
||||||
'content_type': 'mako',
|
'content_type': 'mako',
|
||||||
'context': {
|
'context': {
|
||||||
'days': DAYS_TO_STRING,
|
'downtimes': downtimes,
|
||||||
},
|
},
|
||||||
'owner': 'nagios',
|
'owner': 'nagios',
|
||||||
'group': 'nagios',
|
'group': 'nagios',
|
||||||
|
|
|
@ -11,6 +11,11 @@ groups['dns'] = {
|
||||||
'powerdns',
|
'powerdns',
|
||||||
},
|
},
|
||||||
'metadata': {
|
'metadata': {
|
||||||
|
'apt': {
|
||||||
|
'unattended-upgrades': {
|
||||||
|
'spread_in_group': 'dns',
|
||||||
|
},
|
||||||
|
},
|
||||||
'powerdns': {
|
'powerdns': {
|
||||||
# Overridden in node metadata for primary server
|
# Overridden in node metadata for primary server
|
||||||
'is_secondary': True,
|
'is_secondary': True,
|
||||||
|
|
24
hooks/test_unattended_upgrades_spread.py
Normal file
24
hooks/test_unattended_upgrades_spread.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
from bundlewrap.exceptions import BundleError
|
||||||
|
from bundlewrap.utils.text import bold, green, yellow
|
||||||
|
from bundlewrap.utils.ui import io
|
||||||
|
|
||||||
|
|
||||||
|
def test(repo, **kwargs):
|
||||||
|
for node in repo.nodes:
|
||||||
|
if not node.has_bundle('apt'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
spread = node.metadata.get('apt/unattended-upgrades/spread_in_group', None)
|
||||||
|
if spread is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for rnode in repo.nodes_in_group(spread):
|
||||||
|
rspread = rnode.metadata.get('apt/unattended-upgrades/spread_in_group', None)
|
||||||
|
|
||||||
|
if spread != rspread:
|
||||||
|
raise BundleError(f'{node.name} sets apt/unattended-upgrades/spread_in_group to "{spread}", but node {rnode.name} in that group does set "{rspread}"!')
|
||||||
|
|
||||||
|
io.stdout('{x} {node} apt/unattended-upgrades/spread_in_group matches'.format(
|
||||||
|
x=green("✓"),
|
||||||
|
node=bold(node.name),
|
||||||
|
))
|
Loading…
Reference in a new issue