Skip to content
Snippets Groups Projects
Commit b167ad01 authored by ale's avatar ale
Browse files

Merge branch 'host-turndown' into 'master'

Add host turndown workflow

See merge request !303
parents a66d3074 e0af5620
No related branches found
No related tags found
1 merge request!303Add host turndown workflow
Pipeline #77483 canceled
......@@ -3318,6 +3318,19 @@ If you want more control over this process (Debian upgrades have been
event-less for a while now, but it's not always been the case) you
can of course run the upgrade manually.
### Decommissioning a host
When turning down a host, it is necessary, at some point, to
reschedule the services that were there onto some other hosts. To
achieve a smooth transition, this is best done while the host is still
available.
To do this, set the *turndown* attribute to *true* in the inventory
for the host you want to turn down, and then run *float* once more.
This should safely reschedule all services, and remove them from the
target host. It is then possible to simply shut down the target host
and wipe its data.
# Example scenarios
This section will look at some example scenarios and use cases for
......
No preview for this file type
......@@ -282,6 +282,16 @@ def _global_dns_map(inventory):
return dns
# Return the hosts that are not available for scheduling, as a
# Python set.
def _unavailable_hosts(inventory):
unavail = set()
for name, values in inventory['hosts'].items():
if values.get('turndown'):
unavail.add(name)
return unavail
# Build a group -> hosts map out of an inventory.
def _build_group_map(inventory, assignments=None):
group_map = {}
......@@ -499,7 +509,8 @@ class Assignments(object):
return str(self._fwd)
@classmethod
def _available_hosts(cls, service, group_map, service_hosts_map):
def _available_hosts(cls, service, group_map, service_hosts_map,
unavailable_hosts={}):
if 'schedule_with' in service:
return service_hosts_map[service['schedule_with']]
scheduling_groups = ['all']
......@@ -512,7 +523,7 @@ class Assignments(object):
if g not in group_map:
raise Exception(f'The scheduling_group "{g}" is not defined in inventoy')
available_hosts.update(group_map[g])
return list(available_hosts)
return list(available_hosts.difference(unavailable_hosts))
@classmethod
def schedule(cls, services, inventory):
......@@ -525,6 +536,7 @@ class Assignments(object):
"""
service_hosts_map = {}
service_master_map = {}
unavailable_hosts = _unavailable_hosts(inventory)
group_map = _build_group_map(inventory)
host_occupation = collections.defaultdict(int)
......@@ -540,13 +552,16 @@ class Assignments(object):
for service_name in sorted(services.keys(), key=_sort_key):
service = services[service_name]
available_hosts = cls._available_hosts(service, group_map,
service_hosts_map)
service_hosts_map,
unavailable_hosts)
num_instances = service.get('num_instances', 'all')
if num_instances == 'all':
service_hosts = sorted(available_hosts)
else:
service_hosts = sorted(_binpack(
available_hosts, host_occupation, num_instances))
if not service_hosts:
raise Exception(f'No hosts available to schedule service {service_name}')
service_hosts_map[service_name] = service_hosts
for h in service_hosts:
host_occupation[h] += 1
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment