else:
self.mgr.log.warning(f'Attempted to mark unknown service "{name}" as having been configured')
+ def get_specs_by_type(self, service_type: str) -> Mapping[str, ServiceSpec]:
+ return {
+ service_name: spec
+ for service_name, spec in self._specs.items()
+ if service_type == spec.service_type
+ }
+
class ClientKeyringSpec(object):
"""
result.append(dd)
return result
- @handle_orch_error
- def service_action(self, action: str, service_name: str) -> List[str]:
- if service_name not in self.spec_store.all_specs.keys() and service_name != 'osd':
- raise OrchestratorError(f'Invalid service name "{service_name}".'
- + ' View currently running services using "ceph orch ls"')
+ def perform_service_action(self, action: str, service_name: str) -> List[str]:
dds: List[DaemonDescription] = self.cache.get_daemons_by_service(service_name)
if not dds:
raise OrchestratorError(f'No daemons exist under service name "{service_name}".'
+ ' View currently running services using "ceph orch ls"')
- if action == 'stop' and service_name.split('.')[0].lower() in ['mgr', 'mon', 'osd']:
- return [f'Stopping entire {service_name} service is prohibited.']
self.log.info('%s service %s' % (action.capitalize(), service_name))
return [
self._schedule_daemon_action(dd.name(), action)
for dd in dds
]
+ @handle_orch_error
+ def service_action(self, action: str, service_name: str) -> List[str]:
+ if service_name not in self.spec_store.all_specs.keys():
+ raise OrchestratorError(f'Invalid service name "{service_name}".'
+ + ' View currently running services using "ceph orch ls"')
+ if action == 'stop' and service_name.split('.')[0].lower() in ['mgr', 'mon', 'osd']:
+ return [f'Stopping entire {service_name} service is prohibited.']
+
+ return self.perform_service_action(action, service_name)
+
def _rotate_daemon_key(self, daemon_spec: CephadmDaemonDeploySpec) -> str:
self.log.info(f'Rotating authentication key for {daemon_spec.name()}')
rc, out, err = self.mon_command({
def upgrade_stop(self) -> str:
return self.upgrade.upgrade_stop()
+ @handle_orch_error
+ def update_service(self, service_type: str, service_image: str, image: str) -> List[str]:
+ return self.upgrade.update_service(service_type, service_image, image)
+
@handle_orch_error
def replace_device(self,
hostname: str,
self.mgr.event.set()
return 'Stopped upgrade to %s' % target_image
+ def update_service(self, service_type: str, service_image: str, image: str) -> List[str]:
+ out = []
+ self.mgr.set_module_option(f"container_image_{service_image}", image)
+ # Redeploy all the service daemons of provided service type
+ for service_name, spec in self.mgr.spec_store.get_specs_by_type(service_type).items():
+ out.append(f'Processing "{service_name}" service\n')
+ try:
+ res = self.mgr.perform_service_action('redeploy', service_name)
+ except Exception as exp:
+ self.mgr.log.exception(f"Failed to redeploy service {service_name}")
+ out.append(f'{exp}\n')
+ else:
+ out.extend(res)
+ return out
+
def continue_upgrade(self) -> bool:
"""
Returns false, if nothing was done.
"""
raise NotImplementedError()
+ def update_service(self, service_type: str, service_image: str, image: str) -> OrchResult:
+ raise NotImplementedError()
+
@_hide_in_features
def upgrade_available(self) -> OrchResult:
"""
from ceph.deployment.hostspec import SpecValidationError
from ceph.deployment.utils import unwrap_ipv6
from ceph.utils import datetime_now
-
+from ceph.cephadm.images import NonCephImageServiceTypes
from mgr_util import to_pretty_timedelta, format_bytes
from mgr_module import MgrModule, HandleCommandResult, Option
from object_format import Format
completion = self.upgrade_stop()
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
+
+ @_cli_write_command('orch update service')
+ def _update_service(self, service_type: NonCephImageServiceTypes, image: str) -> HandleCommandResult:
+ """Update image for non-ceph image daemon"""
+ completion = self.update_service(service_type.value, service_type.name, image)
+ raise_if_exception(completion)
+ return HandleCommandResult(stdout=completion.result_str())
@property
def desc(self) -> str:
return self.value.desc
+
+
+class NonCephImageServiceTypes(Enum):
+ prometheus = 'prometheus'
+ loki = 'loki'
+ promtail = 'promtail'
+ node_exporter = 'node-exporter'
+ alertmanager = 'alertmanager'
+ grafana = 'grafana'
+ nvmeof = 'nvmeof'
+ snmp_gateway = 'snmp-gateway'
+ elasticsearch = 'elasticsearch'
+ jaeger_collector = 'jaeger-collector'
+ jaeger_query = 'jaeger-query'
+ jaeger_agent = 'jaeger-agent'
+ samba = 'smb'
+ oauth2_proxy = 'oauth2-proxy'