self.spec_created = {} # type: Dict[str, datetime.datetime]
self.spec_deleted = {} # type: Dict[str, datetime.datetime]
self.spec_preview = {} # type: Dict[str, ServiceSpec]
+ self._needs_configuration: Dict[str, bool] = {}
@property
def all_specs(self) -> Mapping[str, ServiceSpec]:
deleted = str_to_datetime(cast(str, j['deleted']))
self.spec_deleted[service_name] = deleted
+ if 'needs_configuration' in j:
+ self._needs_configuration[service_name] = cast(bool, j['needs_configuration'])
+
if 'rank_map' in j and isinstance(j['rank_map'], dict):
self._rank_maps[service_name] = {}
for rank_str, m in j['rank_map'].items():
self.spec_preview[name] = spec
return None
self._specs[name] = spec
+ self._needs_configuration[name] = True
if update_create:
self.spec_created[name] = datetime_now()
def _save(self, name: str) -> None:
data: Dict[str, Any] = {
'spec': self._specs[name].to_json(),
- 'created': datetime_to_str(self.spec_created[name]),
}
+ if name in self.spec_created:
+ data['created'] = datetime_to_str(self.spec_created[name])
if name in self._rank_maps:
data['rank_map'] = self._rank_maps[name]
if name in self.spec_deleted:
data['deleted'] = datetime_to_str(self.spec_deleted[name])
+ if name in self._needs_configuration:
+ data['needs_configuration'] = self._needs_configuration[name]
self.mgr.set_store(
SPEC_STORE_PREFIX + name,
del self.spec_created[service_name]
if service_name in self.spec_deleted:
del self.spec_deleted[service_name]
+ if service_name in self._needs_configuration:
+ del self._needs_configuration[service_name]
self.mgr.set_store(SPEC_STORE_PREFIX + service_name, None)
return found
self.save(self._specs[service_name])
return f'Set unmanaged to {str(value)} for service {service_name}'
+ def needs_configuration(self, name: str) -> bool:
+ return self._needs_configuration.get(name, False)
+
+ def mark_needs_configuration(self, name: str) -> None:
+ if name in self._specs:
+ self._needs_configuration[name] = True
+ self._save(name)
+ else:
+ self.mgr.log.warning(f'Attempted to mark unknown service "{name}" as needing configuration')
+
+ def mark_configured(self, name: str) -> None:
+ if name in self._specs:
+ self._needs_configuration[name] = False
+ self._save(name)
+ else:
+ self.mgr.log.warning(f'Attempted to mark unknown service "{name}" as having been configured')
+
class ClientKeyringSpec(object):
"""
if progress_total:
update_progress()
- # add any?
- did_config = False
-
self.log.debug('Hosts that will receive new daemons: %s' % slots_to_add)
self.log.debug('Daemons that will be removed: %s' % daemons_to_remove)
# deploy new daemon
daemon_id = slot.name
- if not did_config:
- svc.config(spec)
- did_config = True
daemon_spec = svc.make_daemon_spec(
slot.hostname, daemon_id, slot.network, spec,
progress_done += 1
update_progress()
hosts_altered.add(daemon_spec.host)
+ self.mgr.spec_store.mark_needs_configuration(spec.service_name())
except (RuntimeError, OrchestratorError) as e:
msg = (f"Failed while placing {slot.daemon_type}.{daemon_id} "
f"on {slot.hostname}: {e}")
progress_done += 1
update_progress()
hosts_altered.add(d.hostname)
+ self.mgr.spec_store.mark_needs_configuration(spec.service_name())
self.mgr.remote('progress', 'complete', progress_id)
except Exception as e:
self.mgr.remote('progress', 'fail', progress_id, str(e))
raise
finally:
+ if self.mgr.spec_store.needs_configuration(spec.service_name()):
+ svc.config(spec)
+ self.mgr.spec_store.mark_configured(spec.service_name())
if self.mgr.use_agent:
# can only send ack to agents if we know for sure port they bound to
hosts_altered = set([h for h in hosts_altered if (h in self.mgr.agent_cache.agent_ports and h in [