# Copyright (c) 2015 Mirantis Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from oslo_config import cfg from oslo_log import log as logging from sahara import conductor as cond from sahara import context from sahara.i18n import _LI from sahara.i18n import _LW from sahara.plugins import provisioning as common_configs from sahara.utils import cluster as c_u CONF = cfg.CONF LOG = logging.getLogger(__name__) conductor = cond.API ntp_opts = [ cfg.StrOpt('default_ntp_server', default="pool.ntp.org", help="Default ntp server for time sync") ] CONF.register_opts(ntp_opts) def _get_os_distrib(remote): return remote.execute_command('lsb_release -is')[1].strip().lower() def _sudo(remote, cmd): remote.execute_command(cmd, run_as_root=True) def _restart_ntp(remote): distrib = _get_os_distrib(remote) cmd = "service %s restart" if distrib == 'ubuntu': cmd = cmd % "ntp" else: cmd = cmd % "ntpd" _sudo(remote, cmd) def _verify_installation(remote): distrib = _get_os_distrib(remote) if distrib == 'ubuntu': return remote.execute_command("dpkg -s ntp") else: return remote.execute_command("rpm -q ntp") def _check_ntp_installed(remote): try: exit_code, stdout = _verify_installation(remote) if exit_code != 0: return False return True except Exception: return False def _configure_ntp_on_instance(instance, url): with context.set_current_instance_id(instance.instance_id): LOG.debug("Configuring ntp server") with instance.remote() as r: if not _check_ntp_installed(r): # missing ntp service LOG.warning(_LW("Unable to configure NTP service")) return r.append_to_file( "/etc/ntp.conf", "server {url}".format(url=url), run_as_root=True) _restart_ntp(r) try: _sudo(r, "ntpdate -u {url}".format(url=url)) except Exception as e: LOG.debug("Update time on VM failed with error: %s", e) LOG.info(_LI("NTP successfully configured")) def is_ntp_enabled(cluster): target = common_configs.NTP_ENABLED.applicable_target name = common_configs.NTP_ENABLED.name cl_configs = cluster.cluster_configs if target not in cl_configs or name not in cl_configs[target]: return common_configs.NTP_ENABLED.default_value return cl_configs[target][name] def retrieve_ntp_server_url(cluster): target = common_configs.NTP_URL.applicable_target name = common_configs.NTP_URL.name cl_configs = cluster.cluster_configs if target not in cl_configs or name not in cl_configs[target]: return CONF.default_ntp_server return cl_configs[target][name] def configure_ntp(cluster_id): cluster = conductor.cluster_get(context.ctx(), cluster_id) if not is_ntp_enabled(cluster): LOG.debug("Don't configure NTP on cluster") return instances = c_u.get_instances(cluster) url = retrieve_ntp_server_url(cluster) with context.ThreadGroup() as tg: for instance in instances: tg.spawn("configure-ntp-%s" % instance.instance_name, _configure_ntp_on_instance, instance, url)