E.g. when complaining about a missing netowork.
Signed-off-by: Sebastian Wagner <sebastian.wagner@suse.com>
keyring=keyring,
extra_config=extra_config)
+ @async_completion
def add_mon(self, spec):
# type: (orchestrator.ServiceSpec) -> orchestrator.Completion
# current support requires a network to be specified
- for host, network, _ in spec.placement.hosts:
- if not network:
- raise RuntimeError("Host '{}' is missing a network spec".format(host))
+ orchestrator.servicespec_validate_hosts_have_network_spec(spec)
def add_mons(daemons):
for _, _, name in spec.placement.hosts:
return self._get_daemons('mon').then(add_mons)
+ @async_completion
def apply_mon(self, spec):
# type: (orchestrator.ServiceSpec) -> orchestrator.Completion
"""
[self._require_hosts(host.hostname) for host in spec.placement.hosts]
# current support requires a network to be specified
- for host, network, _ in spec.placement.hosts:
- if not network:
- raise RuntimeError("Host '{}' is missing a network spec".format(host))
+ orchestrator.servicespec_validate_hosts_have_network_spec(spec)
def update_mons_with_daemons(daemons):
for _, _, name in spec.placement.hosts:
c = cephadm_module.apply_mon(ServiceSpec(placement=ps))
assert wait(cephadm_module, c) == ["Deployed mon.a on host 'test'"]
+ with pytest.raises(OrchestratorError, match="is missing a network spec"):
+ ps = PlacementSpec(hosts=['test'], count=1)
+ c = cephadm_module.apply_mon(ServiceSpec(placement=ps))
+ wait(cephadm_module, c)
+
@mock.patch("cephadm.module.CephadmOrchestrator._run_cephadm", _run_cephadm('[]'))
@mock.patch("cephadm.module.CephadmOrchestrator.send_command")
@mock.patch("cephadm.module.CephadmOrchestrator.mon_command", mon_command)
Orchestrator, OrchestratorClientMixin, \
OrchestratorValidationError, OrchestratorError, NoOrchestrator, \
ServiceSpec, NFSServiceSpec, RGWSpec, HostPlacementSpec, \
+ servicespec_validate_add, servicespec_validate_hosts_have_network_spec, \
ServiceDescription, InventoryFilter, PlacementSpec, HostSpec, \
DaemonDescription, \
InventoryNode, DeviceLightLoc, \
else:
self.count = 1
- def validate_add(self):
- if not self.name:
- raise OrchestratorValidationError('Cannot add Service: Name required')
+
+def servicespec_validate_add(self: ServiceSpec):
+ # This must not be a method of ServiceSpec, otherwise you'll hunt
+ # sub-interpreter affinity bugs.
+ if not self.name:
+ raise OrchestratorValidationError('Cannot add Service: Name required')
+
+
+def servicespec_validate_hosts_have_network_spec(self: ServiceSpec):
+ # This must not be a method of ServiceSpec, otherwise you'll hunt
+ # sub-interpreter affinity bugs.
+ if not self.placement.hosts:
+ raise OrchestratorValidationError('Service specification: no hosts provided')
+
+ for host, network, _ in self.placement.hosts:
+ if not network:
+ m = "Host '{host}' is missing a network spec\nE.g. {host}:1.2.3.0/24".format(
+ host=host)
+ logger.error(
+ f'validate_hosts_have_network_spec: id(OrchestratorValidationError)={id(OrchestratorValidationError)}')
+ raise OrchestratorValidationError(m)
+
class NFSServiceSpec(ServiceSpec):
self.namespace = namespace
def validate_add(self):
- super(NFSServiceSpec, self).validate_add()
-
+ servicespec_validate_add(self)
+
if not self.pool:
raise OrchestratorValidationError('Cannot add NFS: No Pool specified')
import pytest
from ceph.deployment import inventory
-from orchestrator import raise_if_exception, RGWSpec, Completion, ProgressReference
+from orchestrator import raise_if_exception, RGWSpec, Completion, ProgressReference, \
+ servicespec_validate_add
from orchestrator import InventoryNode, ServiceDescription
from orchestrator import OrchestratorValidationError
from orchestrator import HostPlacementSpec
"""
example = json.loads(test_rgwspec.__doc__.strip())
spec = RGWSpec.from_json(example)
- assert spec.validate_add() is None
+ assert servicespec_validate_add(spec) is None
def test_promise():