Provide API to enable/disable NTP service in SysInv
NTP API is modified to prevent both PTP and NTP from running at the same time. Additional parameter "--enabled=<true/false>" is intoduced for the "ntp-modify". User is able to disable NTP service before turning PTP service on. Depends-On: I0831487fb14de80edec0ee8df5cc6f23dfb6bae8 Change-Id: Icdf6b0a4bf5f5ffee6742a6cba03ed22c7d6d038 Story: 2002935 Task: 24646 Signed-off-by: Alex Kozyrev <alex.kozyrev@windriver.com>
This commit is contained in:
parent
a8f68a41b1
commit
5b0695fd9d
@ -1,2 +1,2 @@
|
|||||||
SRC_DIR="cgts-client"
|
SRC_DIR="cgts-client"
|
||||||
TIS_PATCH_VER=58
|
TIS_PATCH_VER=59
|
||||||
|
@ -60,7 +60,7 @@ def donot_dns_add(cc, args):
|
|||||||
suuid = getattr(idns, 'uuid', '')
|
suuid = getattr(idns, 'uuid', '')
|
||||||
|
|
||||||
except exc.HTTPNotFound:
|
except exc.HTTPNotFound:
|
||||||
raise exc.CommandError('DNS create failed: %s ' %
|
raise exc.CommandError('DNS create failed: name %s, fields %s ' %
|
||||||
(args.cname, fields))
|
(args.cname, fields))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -14,8 +14,8 @@ from cgtsclient import exc
|
|||||||
|
|
||||||
|
|
||||||
def _print_intp_show(intp):
|
def _print_intp_show(intp):
|
||||||
fields = ['uuid', 'ntpservers', 'isystem_uuid',
|
fields = ['uuid', 'enabled', 'ntpservers',
|
||||||
'created_at', 'updated_at']
|
'isystem_uuid', 'created_at', 'updated_at']
|
||||||
data = [(f, getattr(intp, f, '')) for f in fields]
|
data = [(f, getattr(intp, f, '')) for f in fields]
|
||||||
utils.print_tuple_list(data)
|
utils.print_tuple_list(data)
|
||||||
|
|
||||||
@ -34,8 +34,8 @@ def donot_config_ntp_list(cc, args):
|
|||||||
|
|
||||||
intps = cc.intp.list()
|
intps = cc.intp.list()
|
||||||
|
|
||||||
field_labels = ['uuid', 'ntpservers']
|
field_labels = ['uuid', 'enabled', 'ntpservers']
|
||||||
fields = ['uuid', 'ntpservers']
|
fields = ['uuid', 'enabled', 'ntpservers']
|
||||||
utils.print_list(intps, fields, field_labels, sortby=1)
|
utils.print_list(intps, fields, field_labels, sortby=1)
|
||||||
|
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ def donot_ntp_add(cc, args):
|
|||||||
suuid = getattr(intp, 'uuid', '')
|
suuid = getattr(intp, 'uuid', '')
|
||||||
|
|
||||||
except exc.HTTPNotFound:
|
except exc.HTTPNotFound:
|
||||||
raise exc.CommandError('NTP create failed: %s ' %
|
raise exc.CommandError('NTP create failed: name: %s, fields %s ' %
|
||||||
(args.cname, fields))
|
(args.cname, fields))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -69,10 +69,12 @@ def donot_ntp_add(cc, args):
|
|||||||
|
|
||||||
_print_intp_show(intp)
|
_print_intp_show(intp)
|
||||||
|
|
||||||
|
@utils.arg('--enabled',
|
||||||
|
metavar='<true/false>',
|
||||||
|
help="NTP service enabled.")
|
||||||
@utils.arg('attributes',
|
@utils.arg('attributes',
|
||||||
metavar='<path=value>',
|
metavar='<path=value>',
|
||||||
nargs='+',
|
nargs='*',
|
||||||
action='append',
|
action='append',
|
||||||
default=[],
|
default=[],
|
||||||
help="NTP attributes to modify ")
|
help="NTP attributes to modify ")
|
||||||
@ -83,6 +85,9 @@ def do_ntp_modify(cc, args):
|
|||||||
intp = intps[0]
|
intp = intps[0]
|
||||||
op = "replace"
|
op = "replace"
|
||||||
|
|
||||||
|
if args.enabled is not None:
|
||||||
|
args.attributes[0].append('enabled=%s' % args.enabled)
|
||||||
|
|
||||||
for attribute in args.attributes:
|
for attribute in args.attributes:
|
||||||
if 'ntpservers=' in attribute:
|
if 'ntpservers=' in attribute:
|
||||||
ntpservers = attribute[0].split('=')[1]
|
ntpservers = attribute[0].split('=')[1]
|
||||||
|
@ -30,8 +30,8 @@ def do_sdn_controller_show(cc, args):
|
|||||||
try:
|
try:
|
||||||
controller = cc.sdn_controller.get(args.uuid)
|
controller = cc.sdn_controller.get(args.uuid)
|
||||||
except exc.HTTPNotFound:
|
except exc.HTTPNotFound:
|
||||||
raise exc.CommandError('Create SDN Controller UUID not found: %s',
|
raise exc.CommandError('Create SDN Controller UUID not found: %s'
|
||||||
args.uuid)
|
% args.uuid)
|
||||||
_print_sdn_controller_show(controller)
|
_print_sdn_controller_show(controller)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
SRC_DIR="sysinv"
|
SRC_DIR="sysinv"
|
||||||
TIS_PATCH_VER=277
|
TIS_PATCH_VER=278
|
||||||
|
@ -154,9 +154,9 @@ def _check_dns_data(dns):
|
|||||||
MAX_S = 3
|
MAX_S = 3
|
||||||
|
|
||||||
if 'forisystemid' in dns.keys():
|
if 'forisystemid' in dns.keys():
|
||||||
ntp_list = pecan.request.dbapi.intp_get_list(dns['forisystemid'])
|
ntp_list = pecan.request.dbapi.intp_get_by_isystem(dns['forisystemid'])
|
||||||
else:
|
else:
|
||||||
ntp_list = []
|
ntp_list = pecan.request.dbapi.intp_get_by_isystem(dns['isystem_uuid'])
|
||||||
|
|
||||||
if nameservers:
|
if nameservers:
|
||||||
for nameservers in [n.strip() for n in nameservers.split(',')]:
|
for nameservers in [n.strip() for n in nameservers.split(',')]:
|
||||||
|
@ -1744,7 +1744,7 @@ class HostController(rest.RestController):
|
|||||||
delta_handle = list(delta)
|
delta_handle = list(delta)
|
||||||
|
|
||||||
uptime_update = False
|
uptime_update = False
|
||||||
if 'uptime' in delta:
|
if 'uptime' in delta_handle:
|
||||||
# There is a log of uptime updates, so just do a debug log
|
# There is a log of uptime updates, so just do a debug log
|
||||||
uptime_update = True
|
uptime_update = True
|
||||||
LOG.debug("%s %s patch" % (ihost_obj.hostname,
|
LOG.debug("%s %s patch" % (ihost_obj.hostname,
|
||||||
|
@ -65,6 +65,9 @@ class NTP(base.APIBase):
|
|||||||
uuid = types.uuid
|
uuid = types.uuid
|
||||||
"Unique UUID for this ntp"
|
"Unique UUID for this ntp"
|
||||||
|
|
||||||
|
enabled = types.boolean
|
||||||
|
"Represent the status of the intp."
|
||||||
|
|
||||||
ntpservers = wtypes.text
|
ntpservers = wtypes.text
|
||||||
"Represent the ntpservers of the intp. csv list."
|
"Represent the ntpservers of the intp. csv list."
|
||||||
|
|
||||||
@ -101,6 +104,7 @@ class NTP(base.APIBase):
|
|||||||
ntp = NTP(**rpc_ntp.as_dict())
|
ntp = NTP(**rpc_ntp.as_dict())
|
||||||
if not expand:
|
if not expand:
|
||||||
ntp.unset_fields_except(['uuid',
|
ntp.unset_fields_except(['uuid',
|
||||||
|
'enabled',
|
||||||
'ntpservers',
|
'ntpservers',
|
||||||
'isystem_uuid',
|
'isystem_uuid',
|
||||||
'created_at',
|
'created_at',
|
||||||
@ -147,6 +151,7 @@ class intpCollection(collection.Collection):
|
|||||||
##############
|
##############
|
||||||
def _check_ntp_data(op, ntp):
|
def _check_ntp_data(op, ntp):
|
||||||
# Get data
|
# Get data
|
||||||
|
enabled = ntp['enabled']
|
||||||
ntpservers = ntp['ntpservers']
|
ntpservers = ntp['ntpservers']
|
||||||
intp_ntpservers_list = []
|
intp_ntpservers_list = []
|
||||||
ntp_ntpservers = ""
|
ntp_ntpservers = ""
|
||||||
@ -154,7 +159,7 @@ def _check_ntp_data(op, ntp):
|
|||||||
|
|
||||||
MAX_S = 3
|
MAX_S = 3
|
||||||
|
|
||||||
dns_list = pecan.request.dbapi.idns_get_list(ntp['forisystemid'])
|
dns_list = pecan.request.dbapi.idns_get_by_isystem(ntp['forisystemid'])
|
||||||
|
|
||||||
if dns_list:
|
if dns_list:
|
||||||
if hasattr(dns_list[0], 'nameservers'):
|
if hasattr(dns_list[0], 'nameservers'):
|
||||||
@ -187,8 +192,8 @@ def _check_ntp_data(op, ntp):
|
|||||||
"Please configure a valid NTP "
|
"Please configure a valid NTP "
|
||||||
"IP address or hostname.") % (ntpserver))
|
"IP address or hostname.") % (ntpserver))
|
||||||
|
|
||||||
if len(intp_ntpservers_list) == 0:
|
if len(intp_ntpservers_list) == 0 and enabled is None:
|
||||||
raise wsme.exc.ClientSideError(_("No NTP servers provided."))
|
raise wsme.exc.ClientSideError(_("No NTP parameters provided."))
|
||||||
|
|
||||||
if len(intp_ntpservers_list) > MAX_S:
|
if len(intp_ntpservers_list) > MAX_S:
|
||||||
raise wsme.exc.ClientSideError(_(
|
raise wsme.exc.ClientSideError(_(
|
||||||
@ -344,12 +349,18 @@ class NTPController(rest.RestController):
|
|||||||
rpc_ntp[field] = ntp[field]
|
rpc_ntp[field] = ntp[field]
|
||||||
|
|
||||||
delta = rpc_ntp.obj_what_changed()
|
delta = rpc_ntp.obj_what_changed()
|
||||||
|
delta_handle = list(delta)
|
||||||
if delta:
|
if delta:
|
||||||
rpc_ntp.save()
|
rpc_ntp.save()
|
||||||
|
|
||||||
|
if 'enabled' in delta_handle:
|
||||||
|
service_change = True
|
||||||
|
else:
|
||||||
|
service_change = False
|
||||||
if action == constants.APPLY_ACTION:
|
if action == constants.APPLY_ACTION:
|
||||||
# perform rpc to conductor to perform config apply
|
# perform rpc to conductor to perform config apply
|
||||||
pecan.request.rpcapi.update_ntp_config(pecan.request.context)
|
pecan.request.rpcapi.update_ntp_config(pecan.request.context,
|
||||||
|
service_change)
|
||||||
else:
|
else:
|
||||||
LOG.info("No NTP config changes")
|
LOG.info("No NTP config changes")
|
||||||
|
|
||||||
|
@ -610,6 +610,10 @@ class MultipleResults(SysinvException):
|
|||||||
message = _("More than one result found.")
|
message = _("More than one result found.")
|
||||||
|
|
||||||
|
|
||||||
|
class NTPNotFound(NotFound):
|
||||||
|
message = _("No NTP with id %(uuid)s found.")
|
||||||
|
|
||||||
|
|
||||||
class DiskNotFound(NotFound):
|
class DiskNotFound(NotFound):
|
||||||
message = _("No disk with id %(disk_id)s")
|
message = _("No disk with id %(disk_id)s")
|
||||||
|
|
||||||
|
@ -5146,8 +5146,13 @@ class ConductorManager(service.PeriodicService):
|
|||||||
config_uuid = self._config_update_hosts(context, personalities)
|
config_uuid = self._config_update_hosts(context, personalities)
|
||||||
self._update_resolv_file(context, config_uuid, personalities)
|
self._update_resolv_file(context, config_uuid, personalities)
|
||||||
|
|
||||||
def update_ntp_config(self, context):
|
def update_ntp_config(self, context, service_change=False):
|
||||||
"""Update the NTP configuration"""
|
"""Update the NTP configuration"""
|
||||||
|
if service_change:
|
||||||
|
personalities = [constants.CONTROLLER,
|
||||||
|
constants.COMPUTE,
|
||||||
|
constants.STORAGE]
|
||||||
|
else:
|
||||||
personalities = [constants.CONTROLLER]
|
personalities = [constants.CONTROLLER]
|
||||||
self._config_update_hosts(context, personalities, reboot=True)
|
self._config_update_hosts(context, personalities, reboot=True)
|
||||||
|
|
||||||
|
@ -694,12 +694,13 @@ class ConductorAPI(sysinv.openstack.common.rpc.proxy.RpcProxy):
|
|||||||
"""
|
"""
|
||||||
return self.call(context, self.make_msg('update_dns_config'))
|
return self.call(context, self.make_msg('update_dns_config'))
|
||||||
|
|
||||||
def update_ntp_config(self, context):
|
def update_ntp_config(self, context, service_change=False):
|
||||||
"""Synchronously, have the conductor update the NTP configuration.
|
"""Synchronously, have the conductor update the NTP configuration.
|
||||||
|
|
||||||
:param context: request context.
|
:param context: request context.
|
||||||
"""
|
"""
|
||||||
return self.call(context, self.make_msg('update_ntp_config'))
|
return self.call(context, self.make_msg('update_ntp_config',
|
||||||
|
service_change=service_change))
|
||||||
|
|
||||||
def update_system_mode_config(self, context):
|
def update_system_mode_config(self, context):
|
||||||
"""Synchronously, have the conductor update the system mode
|
"""Synchronously, have the conductor update the system mode
|
||||||
|
@ -1945,14 +1945,15 @@ class Connection(object):
|
|||||||
|
|
||||||
:param forisystemid: intp belongs to this isystem
|
:param forisystemid: intp belongs to this isystem
|
||||||
:param values: A dict containing several items used to identify
|
:param values: A dict containing several items used to identify
|
||||||
and track the cpu.
|
and track the ntp settings.
|
||||||
{
|
{
|
||||||
|
'enabled': 'True'
|
||||||
'ntpservers': '0.pool.ntp.org,
|
'ntpservers': '0.pool.ntp.org,
|
||||||
1.pool.ntp.org,
|
1.pool.ntp.org,
|
||||||
2.pool.ntp.org',
|
2.pool.ntp.org',
|
||||||
'forisystemid': '1'
|
'forisystemid': '1'
|
||||||
}
|
}
|
||||||
:returns: An ntp.
|
:returns: An intp.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
|
@ -3577,7 +3577,7 @@ class Connection(api.Connection):
|
|||||||
try:
|
try:
|
||||||
return query.one()
|
return query.one()
|
||||||
except NoResultFound:
|
except NoResultFound:
|
||||||
raise exception.ServerNotFound(server=server)
|
raise exception.NTPNotFound(server=server)
|
||||||
|
|
||||||
@objects.objectify(objects.ntp)
|
@objects.objectify(objects.ntp)
|
||||||
def intp_create(self, values):
|
def intp_create(self, values):
|
||||||
@ -3633,7 +3633,7 @@ class Connection(api.Connection):
|
|||||||
|
|
||||||
count = query.update(values, synchronize_session='fetch')
|
count = query.update(values, synchronize_session='fetch')
|
||||||
if count != 1:
|
if count != 1:
|
||||||
raise exception.ServerNotFound(server=server)
|
raise exception.NTPNotFound(server=server)
|
||||||
return query.one()
|
return query.one()
|
||||||
|
|
||||||
def intp_destroy(self, server):
|
def intp_destroy(self, server):
|
||||||
@ -3644,7 +3644,7 @@ class Connection(api.Connection):
|
|||||||
try:
|
try:
|
||||||
query.one()
|
query.one()
|
||||||
except NoResultFound:
|
except NoResultFound:
|
||||||
raise exception.ServerNotFound(server=server)
|
raise exception.NTPNotFound(server=server)
|
||||||
# if node_ref['reservation'] is not None:
|
# if node_ref['reservation'] is not None:
|
||||||
# raise exception.NodeLocked(node=node)
|
# raise exception.NodeLocked(node=node)
|
||||||
|
|
||||||
@ -4418,7 +4418,7 @@ class Connection(api.Connection):
|
|||||||
# isystem_get() to raise an exception if the isystem is not found
|
# isystem_get() to raise an exception if the isystem is not found
|
||||||
isystem_obj = self.isystem_get(isystem_id)
|
isystem_obj = self.isystem_get(isystem_id)
|
||||||
query = model_query(models.remotelogging)
|
query = model_query(models.remotelogging)
|
||||||
query = query.filter_by(forisystemid=isystem_obj.id)
|
query = query.filter_by(system_id=isystem_obj.id)
|
||||||
return _paginate_query(models.remotelogging, limit, marker,
|
return _paginate_query(models.remotelogging, limit, marker,
|
||||||
sort_key, sort_dir, query)
|
sort_key, sort_dir, query)
|
||||||
|
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 Wind River Systems, Inc.
|
||||||
|
#
|
||||||
|
# The right to copy, distribute, modify, or otherwise make use
|
||||||
|
# of this software may be licensed only pursuant to the terms
|
||||||
|
# of an applicable Wind River license agreement.
|
||||||
|
#
|
||||||
|
|
||||||
|
from sqlalchemy import Column, MetaData, Table, Boolean
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(migrate_engine):
|
||||||
|
meta = MetaData()
|
||||||
|
meta.bind = migrate_engine
|
||||||
|
intp_table = Table('i_ntp', meta, autoload=True)
|
||||||
|
intp_table.create_column(Column('enabled', Boolean, default=True))
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade(migrate_engine):
|
||||||
|
meta = MetaData()
|
||||||
|
meta.bind = migrate_engine
|
||||||
|
|
||||||
|
intp_table = Table('i_ntp', meta, autoload=True)
|
||||||
|
intp_table.drop_column('enabled')
|
@ -823,6 +823,7 @@ class intp(Base):
|
|||||||
id = Column(Integer, primary_key=True)
|
id = Column(Integer, primary_key=True)
|
||||||
uuid = Column(String(36))
|
uuid = Column(String(36))
|
||||||
|
|
||||||
|
enabled = Column(Boolean, default=True)
|
||||||
ntpservers = Column(String(255)) # csv list of ntp servers
|
ntpservers = Column(String(255)) # csv list of ntp servers
|
||||||
|
|
||||||
forisystemid = Column(Integer,
|
forisystemid = Column(Integer,
|
||||||
|
@ -21,6 +21,7 @@ class NTP(base.SysinvObject):
|
|||||||
'id': int,
|
'id': int,
|
||||||
'uuid': utils.str_or_none,
|
'uuid': utils.str_or_none,
|
||||||
|
|
||||||
|
'enabled': utils.bool_or_none,
|
||||||
'ntpservers': utils.str_or_none,
|
'ntpservers': utils.str_or_none,
|
||||||
|
|
||||||
'forisystemid': utils.int_or_none,
|
'forisystemid': utils.int_or_none,
|
||||||
|
@ -378,8 +378,8 @@ class PlatformPuppet(base.BasePuppet):
|
|||||||
return config
|
return config
|
||||||
|
|
||||||
def _get_host_ntp_config(self, host):
|
def _get_host_ntp_config(self, host):
|
||||||
if host.personality == constants.CONTROLLER:
|
|
||||||
ntp = self.dbapi.intp_get_one()
|
ntp = self.dbapi.intp_get_one()
|
||||||
|
if host.personality == constants.CONTROLLER:
|
||||||
servers = ntp.ntpservers.split(',') if ntp.ntpservers else []
|
servers = ntp.ntpservers.split(',') if ntp.ntpservers else []
|
||||||
else:
|
else:
|
||||||
controller0_address = self._get_address_by_name(
|
controller0_address = self._get_address_by_name(
|
||||||
@ -425,6 +425,7 @@ class PlatformPuppet(base.BasePuppet):
|
|||||||
ntpdate_timeout = "30"
|
ntpdate_timeout = "30"
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
'platform::ntp::enabled': ntp.enabled,
|
||||||
'platform::ntp::servers': servers,
|
'platform::ntp::servers': servers,
|
||||||
'platform::ntp::ntpdate_timeout': ntpdate_timeout,
|
'platform::ntp::ntpdate_timeout': ntpdate_timeout,
|
||||||
}
|
}
|
||||||
|
@ -1886,3 +1886,12 @@ class TestMigrations(BaseMigrationTestCase, WalkVersionsMixin):
|
|||||||
getattr(sqlalchemy.types, coltype)))
|
getattr(sqlalchemy.types, coltype)))
|
||||||
# Assert deletion of the i_storconfig table
|
# Assert deletion of the i_storconfig table
|
||||||
self.assertTableNotExists(engine, 'storage_file')
|
self.assertTableNotExists(engine, 'storage_file')
|
||||||
|
|
||||||
|
def _check_074(self, engine, data):
|
||||||
|
ntps = db_utils.get_table(engine, 'i_ntp')
|
||||||
|
ntps_col = {
|
||||||
|
'enabled': 'Boolean',
|
||||||
|
}
|
||||||
|
for col, coltype in ntps_col.items():
|
||||||
|
self.assertTrue(isinstance(ntps.c[col].type,
|
||||||
|
getattr(sqlalchemy.types, coltype)))
|
||||||
|
Loading…
Reference in New Issue
Block a user