Support for NTP/PTP coexistence
The NTP/PTP selection will now be done per host. NTP will the default selection. This commit; -Removes the enabled flag NTP and PTP API. Updates the CLI commands and the database. -Adds the parameter clock_synchronization to the host API. Valid values are ‘ntp’ and ‘ptp’. Updates the host CLI commands and the database. -Updates puppet to set NTP/PTP per host . -Updates the RestAPI documentation. Story: 2006499 Task: 36464 Change-Id: I37bbb30a014301f8786cb02e35f0a1bd39d2f4aa Signed-off-by: Kristine Bujold <kristine.bujold@windriver.com>
This commit is contained in:
parent
6f04c28cd4
commit
2d17e9849f
@ -4311,6 +4311,162 @@ badMediaType (415)
|
|||||||
"uuid":"81321749-5092-4faf-94ba-6a6853440725"
|
"uuid":"81321749-5092-4faf-94ba-6a6853440725"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
PTP
|
||||||
|
----
|
||||||
|
|
||||||
|
The PTP is the Precision Time Protocol entity for the system.
|
||||||
|
|
||||||
|
************************************
|
||||||
|
Shows attributes of the PTP object
|
||||||
|
************************************
|
||||||
|
|
||||||
|
.. rest_method:: GET /v1/ptp
|
||||||
|
|
||||||
|
**Normal response codes**
|
||||||
|
|
||||||
|
200
|
||||||
|
|
||||||
|
**Error response codes**
|
||||||
|
|
||||||
|
computeFault (400, 500, ...), serviceUnavailable (503), badRequest (400),
|
||||||
|
unauthorized (401), forbidden (403), badMethod (405), overLimit (413),
|
||||||
|
itemNotFound (404)
|
||||||
|
|
||||||
|
**Response parameters**
|
||||||
|
|
||||||
|
.. csv-table::
|
||||||
|
:header: "Parameter", "Style", "Type", "Description"
|
||||||
|
:widths: 20, 20, 20, 60
|
||||||
|
|
||||||
|
"mode (Optional)", "plain", "xsd:string", "PTP time stamping mode."
|
||||||
|
"transport (Optional)", "plain", "xsd:string", "PTP transport protocol."
|
||||||
|
"mechanism (Optional)", "plain", "xsd:string", "PTP delay mechanism."
|
||||||
|
"isystem_uuid (Optional)", "plain", "csapi:UUID", "The System UUID which the PTP belongs to."
|
||||||
|
"uuid (Optional)", "plain", "csapi:UUID", "The universally unique identifier for this object."
|
||||||
|
"links (Optional)", "plain", "xsd:list", "For convenience, resources contain links to themselves. This allows a client to easily obtain rather than construct resource URIs. The following types of link relations are associated with resources: a self link containing a versioned link to the resource, and a bookmark link containing a permanent link to a resource that is appropriate for long term storage."
|
||||||
|
"created_at (Optional)", "plain", "xsd:dateTime", "The time when the object was created."
|
||||||
|
"updated_at (Optional)", "plain", "xsd:dateTime", "The time when the object was last updated."
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"ptp":[
|
||||||
|
{
|
||||||
|
"links":[
|
||||||
|
{
|
||||||
|
"href":"http://192.168.204.2:6385/v1/ptps/70649b44-b462-445a-9fa5-9233a1b5842d",
|
||||||
|
"rel":"self"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href":"http://192.168.204.2:6385/ptps/70649b44-b462-445a-9fa5-9233a1b5842d",
|
||||||
|
"rel":"bookmark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"created_at":"2019-09-30T14:42:16.693209+00:00",
|
||||||
|
"updated_at":"2019-10-01T17:33:43.169595+00:00",
|
||||||
|
"mechanism":"e2e",
|
||||||
|
"mode":"hardware",
|
||||||
|
"transport":"l2",
|
||||||
|
"isystem_uuid":"ce178041-2b2c-405d-bf87-f19334a35582",
|
||||||
|
"uuid":"70649b44-b462-445a-9fa5-9233a1b5842d"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
This operation does not accept a request body.
|
||||||
|
|
||||||
|
***************************************
|
||||||
|
Modifies attributes of the PTP object
|
||||||
|
***************************************
|
||||||
|
|
||||||
|
.. rest_method:: PATCH /v1/ptp/{ptp_id}
|
||||||
|
|
||||||
|
The attributes of the PTP object that are configurable are:
|
||||||
|
|
||||||
|
- mode
|
||||||
|
- transport
|
||||||
|
- mechanism
|
||||||
|
|
||||||
|
**Normal response codes**
|
||||||
|
|
||||||
|
200
|
||||||
|
|
||||||
|
**Error response codes**
|
||||||
|
|
||||||
|
badMediaType (415)
|
||||||
|
|
||||||
|
**Request parameters**
|
||||||
|
|
||||||
|
.. csv-table::
|
||||||
|
:header: "Parameter", "Style", "Type", "Description"
|
||||||
|
:widths: 20, 20, 20, 60
|
||||||
|
|
||||||
|
"ptp_id", "URI", "csapi:UUID", "The unique identifier of the PTP for this system."
|
||||||
|
"mode (Optional)", "plain", "xsd:string", "PTP time stamping mode. Valid values are (is): ``hardware``, ``software`` or ``legacy``"
|
||||||
|
"transport (Optional)", "plain", "xsd:string", "PTP transport protocol. Valid values are (is): ``udp`` or ``l2``"
|
||||||
|
"mechanism (Optional)", "plain", "xsd:string", "PTP delay mechanism. Valid values are (is): ``e2e`` or ``p2p``"
|
||||||
|
|
||||||
|
**Response parameters**
|
||||||
|
|
||||||
|
.. csv-table::
|
||||||
|
:header: "Parameter", "Style", "Type", "Description"
|
||||||
|
:widths: 20, 20, 20, 60
|
||||||
|
|
||||||
|
"mode (Optional)", "plain", "xsd:string", "PTP time stamping mode."
|
||||||
|
"transport (Optional)", "plain", "xsd:string", "PTP transport protocol."
|
||||||
|
"mechanism (Optional)", "plain", "xsd:string", "PTP delay mechanism."
|
||||||
|
"isystem_uuid (Optional)", "plain", "csapi:UUID", "The System UUID which the NTP belongs to."
|
||||||
|
"uuid (Optional)", "plain", "csapi:UUID", "The universally unique identifier for this object."
|
||||||
|
"links (Optional)", "plain", "xsd:list", "For convenience, resources contain links to themselves. This allows a client to easily obtain rather than construct resource URIs. The following types of link relations are associated with resources: a self link containing a versioned link to the resource, and a bookmark link containing a permanent link to a resource that is appropriate for long term storage."
|
||||||
|
"created_at (Optional)", "plain", "xsd:dateTime", "The time when the object was created."
|
||||||
|
"updated_at (Optional)", "plain", "xsd:dateTime", "The time when the object was last updated."
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"path": "/mode",
|
||||||
|
"value": "legacy",
|
||||||
|
"op": "replace"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/transport",
|
||||||
|
"value": "udp",
|
||||||
|
"op": "replace"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/mechanism",
|
||||||
|
"value": "p2p",
|
||||||
|
"op": "replace"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"links":[
|
||||||
|
{
|
||||||
|
"href":"http://192.168.204.2:6385/v1/ptps/70649b44-b462-445a-9fa5-9233a1b5842d",
|
||||||
|
"rel":"self"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href":"http://192.168.204.2:6385/ptps/70649b44-b462-445a-9fa5-9233a1b5842d",
|
||||||
|
"rel":"bookmark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"created_at":"2014-09-30T14:42:16.693209+00:00",
|
||||||
|
"updated_at":"2014-10-01T17:35:43.162472+00:00",
|
||||||
|
"mechanism": "p2p"
|
||||||
|
"mode": "legacy"
|
||||||
|
"transport": "udp"
|
||||||
|
"isystem_uuid":"ce178041-2b2c-405d-bf87-f19334a35582",
|
||||||
|
"forisystemid":1,
|
||||||
|
"uuid":"70649b44-b462-445a-9fa5-9233a1b5842d"
|
||||||
|
}
|
||||||
|
|
||||||
-------------
|
-------------
|
||||||
External OAM
|
External OAM
|
||||||
-------------
|
-------------
|
||||||
@ -10896,7 +11052,7 @@ itemNotFound (404)
|
|||||||
"registry_images": [
|
"registry_images": [
|
||||||
{
|
{
|
||||||
"tag": null,
|
"tag": null,
|
||||||
"name": "docker.io/starlingx/ceph-config-helper"
|
"name": "docker.io/starlingx/ceph-config-helper"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tag": null,
|
"tag": null,
|
||||||
@ -10946,8 +11102,8 @@ itemNotFound (404)
|
|||||||
{
|
{
|
||||||
"registry_images": [
|
"registry_images": [
|
||||||
{
|
{
|
||||||
"tag": "v1.15.0",
|
"tag": "v1.15.0",
|
||||||
"name": "docker.io/starlingx/ceph-config-helper"
|
"name": "docker.io/starlingx/ceph-config-helper"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
SRC_DIR="cgts-client"
|
SRC_DIR="cgts-client"
|
||||||
TIS_PATCH_VER=70
|
TIS_PATCH_VER=71
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2019 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
@ -35,7 +35,7 @@ def _print_ihost_show(ihost):
|
|||||||
'location', 'uptime', 'reserved', 'created_at', 'updated_at',
|
'location', 'uptime', 'reserved', 'created_at', 'updated_at',
|
||||||
'boot_device', 'rootfs_device', 'install_output', 'console',
|
'boot_device', 'rootfs_device', 'install_output', 'console',
|
||||||
'tboot', 'vim_progress_status', 'software_load', 'install_state',
|
'tboot', 'vim_progress_status', 'software_load', 'install_state',
|
||||||
'install_state_info', 'inv_state']
|
'install_state_info', 'inv_state', 'clock_synchronization']
|
||||||
optional_fields = ['vsc_controllers', 'ttys_dcd']
|
optional_fields = ['vsc_controllers', 'ttys_dcd']
|
||||||
if ihost.subfunctions != ihost.personality:
|
if ihost.subfunctions != ihost.personality:
|
||||||
fields.append('subfunctions')
|
fields.append('subfunctions')
|
||||||
@ -141,13 +141,18 @@ def do_host_upgrade_list(cc, args):
|
|||||||
@utils.arg('-D', '--ttys_dcd',
|
@utils.arg('-D', '--ttys_dcd',
|
||||||
metavar='<true/false>',
|
metavar='<true/false>',
|
||||||
help='Enable/disable serial console data carrier detection')
|
help='Enable/disable serial console data carrier detection')
|
||||||
|
@utils.arg('-C', '--clock_synchronization',
|
||||||
|
metavar='<clock_synchronization>',
|
||||||
|
choices=['ntp', 'ptp'],
|
||||||
|
help='Clock synchronization, ntp or ptp. Default: ntp')
|
||||||
def do_host_add(cc, args):
|
def do_host_add(cc, args):
|
||||||
"""Add a new host."""
|
"""Add a new host."""
|
||||||
field_list = ['hostname', 'personality', 'subfunctions',
|
field_list = ['hostname', 'personality', 'subfunctions',
|
||||||
'mgmt_mac', 'mgmt_ip',
|
'mgmt_mac', 'mgmt_ip',
|
||||||
'bm_ip', 'bm_type', 'bm_username', 'bm_password',
|
'bm_ip', 'bm_type', 'bm_username', 'bm_password',
|
||||||
'boot_device', 'rootfs_device', 'install_output', 'console',
|
'boot_device', 'rootfs_device', 'install_output', 'console',
|
||||||
'vsc_controllers', 'location', 'ttys_dcd']
|
'vsc_controllers', 'location', 'ttys_dcd',
|
||||||
|
'clock_synchronization']
|
||||||
fields = dict((k, v) for (k, v) in vars(args).items()
|
fields = dict((k, v) for (k, v) in vars(args).items()
|
||||||
if k in field_list and not (v is None))
|
if k in field_list and not (v is None))
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2013-2015 Wind River Systems, Inc.
|
# Copyright (c) 2013-2019 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
@ -20,7 +20,7 @@ CREATION_ATTRIBUTES = ['hostname', 'personality', 'subfunctions',
|
|||||||
'boot_device', 'rootfs_device', 'install_output',
|
'boot_device', 'rootfs_device', 'install_output',
|
||||||
'console', 'tboot', 'vsc_controllers', 'ttys_dcd',
|
'console', 'tboot', 'vsc_controllers', 'ttys_dcd',
|
||||||
'administrative', 'operational', 'availability',
|
'administrative', 'operational', 'availability',
|
||||||
'invprovision']
|
'invprovision', 'clock_synchronization']
|
||||||
|
|
||||||
|
|
||||||
class ihost(base.Resource):
|
class ihost(base.Resource):
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2019 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
@ -14,8 +14,7 @@ from cgtsclient import exc
|
|||||||
|
|
||||||
|
|
||||||
def _print_intp_show(intp):
|
def _print_intp_show(intp):
|
||||||
fields = ['uuid', 'enabled', 'ntpservers',
|
fields = ['uuid', 'ntpservers', 'isystem_uuid', '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 +33,8 @@ def donot_config_ntp_list(cc, args):
|
|||||||
|
|
||||||
intps = cc.intp.list()
|
intps = cc.intp.list()
|
||||||
|
|
||||||
field_labels = ['uuid', 'enabled', 'ntpservers']
|
field_labels = ['uuid', 'ntpservers']
|
||||||
fields = ['uuid', 'enabled', 'ntpservers']
|
fields = ['uuid', 'ntpservers']
|
||||||
utils.print_list(intps, fields, field_labels, sortby=1)
|
utils.print_list(intps, fields, field_labels, sortby=1)
|
||||||
|
|
||||||
|
|
||||||
@ -70,9 +69,6 @@ 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='*',
|
||||||
@ -86,9 +82,6 @@ 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]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
########################################################################
|
########################################################################
|
||||||
#
|
#
|
||||||
# Copyright (c) 2018 Wind River Systems, Inc.
|
# Copyright (c) 2018-2019 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
@ -11,7 +11,7 @@ from cgtsclient import exc
|
|||||||
|
|
||||||
|
|
||||||
def _print_ptp_show(ptp):
|
def _print_ptp_show(ptp):
|
||||||
fields = ['uuid', 'enabled', 'mode', 'transport', 'mechanism',
|
fields = ['uuid', 'mode', 'transport', 'mechanism',
|
||||||
'isystem_uuid', 'created_at', 'updated_at']
|
'isystem_uuid', 'created_at', 'updated_at']
|
||||||
data = [(f, getattr(ptp, f, '')) for f in fields]
|
data = [(f, getattr(ptp, f, '')) for f in fields]
|
||||||
utils.print_tuple_list(data)
|
utils.print_tuple_list(data)
|
||||||
@ -30,14 +30,11 @@ def donot_config_ptp_list(cc, args):
|
|||||||
|
|
||||||
ptps = cc.ptp.list()
|
ptps = cc.ptp.list()
|
||||||
|
|
||||||
field_labels = ['uuid', 'enabled', 'mode', 'transport', 'mechanism']
|
field_labels = ['uuid', 'mode', 'transport', 'mechanism']
|
||||||
fields = ['uuid', 'enabled', 'mode', 'transport', 'mechanism']
|
fields = ['uuid', 'mode', 'transport', 'mechanism']
|
||||||
utils.print_list(ptps, fields, field_labels, sortby=1)
|
utils.print_list(ptps, fields, field_labels, sortby=1)
|
||||||
|
|
||||||
|
|
||||||
@utils.arg('--enabled',
|
|
||||||
metavar='<true/false>',
|
|
||||||
help="PTP service enabled.")
|
|
||||||
@utils.arg('--mode',
|
@utils.arg('--mode',
|
||||||
metavar='<mode>',
|
metavar='<mode>',
|
||||||
default=None,
|
default=None,
|
||||||
@ -58,8 +55,7 @@ def do_ptp_modify(cc, args):
|
|||||||
op = "replace"
|
op = "replace"
|
||||||
|
|
||||||
attributes = []
|
attributes = []
|
||||||
if args.enabled is not None:
|
|
||||||
attributes.append('enabled=%s' % args.enabled)
|
|
||||||
if args.mode is not None:
|
if args.mode is not None:
|
||||||
attributes.append('mode=%s' % args.mode)
|
attributes.append('mode=%s' % args.mode)
|
||||||
if args.transport is not None:
|
if args.transport is not None:
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
SRC_DIR="sysinv"
|
SRC_DIR="sysinv"
|
||||||
TIS_PATCH_VER=331
|
TIS_PATCH_VER=332
|
||||||
|
@ -422,6 +422,9 @@ class Host(base.APIBase):
|
|||||||
config_target = wtypes.text
|
config_target = wtypes.text
|
||||||
"Represent the configuration which needs to be applied to this ihost."
|
"Represent the configuration which needs to be applied to this ihost."
|
||||||
|
|
||||||
|
clock_synchronization = wtypes.text
|
||||||
|
"Represent the clock synchronization type of this ihost."
|
||||||
|
|
||||||
# Host uptime
|
# Host uptime
|
||||||
uptime = int
|
uptime = int
|
||||||
|
|
||||||
@ -563,7 +566,7 @@ class Host(base.APIBase):
|
|||||||
'software_load', 'target_load', 'peers', 'peer_id',
|
'software_load', 'target_load', 'peers', 'peer_id',
|
||||||
'install_state', 'install_state_info',
|
'install_state', 'install_state_info',
|
||||||
'iscsi_initiator_name',
|
'iscsi_initiator_name',
|
||||||
'inv_state']
|
'inv_state', 'clock_synchronization']
|
||||||
|
|
||||||
fields = minimum_fields if not expand else None
|
fields = minimum_fields if not expand else None
|
||||||
uhost = Host.from_rpc_object(rpc_ihost, fields)
|
uhost = Host.from_rpc_object(rpc_ihost, fields)
|
||||||
@ -1867,6 +1870,14 @@ class HostController(rest.RestController):
|
|||||||
LOG.exception(e)
|
LOG.exception(e)
|
||||||
raise wsme.exc.ClientSideError(_("Patching Error: %s") % e)
|
raise wsme.exc.ClientSideError(_("Patching Error: %s") % e)
|
||||||
|
|
||||||
|
if patched_ihost['clock_synchronization'] not in \
|
||||||
|
constants.CLOCK_SYNCHRONIZATION:
|
||||||
|
msg = _("Host update failed: clock_synchronization: "
|
||||||
|
"invalid choice: '%s', choose from %s" %
|
||||||
|
(patched_ihost['clock_synchronization'],
|
||||||
|
constants.CLOCK_SYNCHRONIZATION))
|
||||||
|
raise wsme.exc.ClientSideError(msg)
|
||||||
|
|
||||||
self._validate_capabilities(
|
self._validate_capabilities(
|
||||||
ihost_dict['capabilities'], patched_ihost['capabilities'])
|
ihost_dict['capabilities'], patched_ihost['capabilities'])
|
||||||
|
|
||||||
@ -2203,6 +2214,11 @@ class HostController(rest.RestController):
|
|||||||
self._handle_ttys_dcd_change(hostupdate.ihost_orig,
|
self._handle_ttys_dcd_change(hostupdate.ihost_orig,
|
||||||
hostupdate.ihost_patch['ttys_dcd'])
|
hostupdate.ihost_patch['ttys_dcd'])
|
||||||
|
|
||||||
|
if 'clock_synchronization' in hostupdate.delta:
|
||||||
|
# perform rpc to conductor to perform config apply
|
||||||
|
pecan.request.rpcapi.update_clock_synchronization_config(
|
||||||
|
pecan.request.context, patched_ihost)
|
||||||
|
|
||||||
log_end = cutils.timestamped("ihost_patch_end")
|
log_end = cutils.timestamped("ihost_patch_end")
|
||||||
if uptime_update:
|
if uptime_update:
|
||||||
LOG.debug("host %s %s patch" % (ihost_obj.hostname,
|
LOG.debug("host %s %s patch" % (ihost_obj.hostname,
|
||||||
@ -2212,8 +2228,8 @@ class HostController(rest.RestController):
|
|||||||
log_end))
|
log_end))
|
||||||
|
|
||||||
if ('administrative' in hostupdate.delta and
|
if ('administrative' in hostupdate.delta and
|
||||||
hostupdate.ihost_patch['administrative'] ==
|
hostupdate.ihost_patch['administrative'] ==
|
||||||
constants.ADMIN_LOCKED):
|
constants.ADMIN_LOCKED):
|
||||||
LOG.info("Update host memory for (%s)" % ihost_obj['hostname'])
|
LOG.info("Update host memory for (%s)" % ihost_obj['hostname'])
|
||||||
pecan.request.rpcapi.update_host_memory(pecan.request.context,
|
pecan.request.rpcapi.update_host_memory(pecan.request.context,
|
||||||
ihost_obj['uuid'])
|
ihost_obj['uuid'])
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2019 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
@ -66,9 +66,6 @@ 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."
|
||||||
|
|
||||||
@ -105,7 +102,6 @@ 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',
|
||||||
@ -152,23 +148,12 @@ 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 = ""
|
|
||||||
idns_nameservers_list = []
|
idns_nameservers_list = []
|
||||||
|
|
||||||
MAX_S = 3
|
MAX_S = 3
|
||||||
|
|
||||||
ptp_list = pecan.request.dbapi.ptp_get_by_isystem(ntp['forisystemid'])
|
|
||||||
|
|
||||||
if ptp_list:
|
|
||||||
if hasattr(ptp_list[0], 'enabled'):
|
|
||||||
if ptp_list[0].enabled is True and enabled is True:
|
|
||||||
raise wsme.exc.ClientSideError(_(
|
|
||||||
"NTP cannot be configured alongside with PTP."
|
|
||||||
" Please disable PTP before enabling NTP."))
|
|
||||||
|
|
||||||
dns_list = pecan.request.dbapi.idns_get_by_isystem(ntp['forisystemid'])
|
dns_list = pecan.request.dbapi.idns_get_by_isystem(ntp['forisystemid'])
|
||||||
|
|
||||||
if dns_list:
|
if dns_list:
|
||||||
@ -184,7 +169,8 @@ def _check_ntp_data(op, ntp):
|
|||||||
|
|
||||||
except (AddrFormatError, ValueError):
|
except (AddrFormatError, ValueError):
|
||||||
if utils.is_valid_hostname(ntpserver):
|
if utils.is_valid_hostname(ntpserver):
|
||||||
# If server address in FQDN, and no DNS servers, raise error
|
# If server address in FQDN, and no DNS servers,
|
||||||
|
# raise error
|
||||||
if len(idns_nameservers_list) == 0 and ntpserver != 'NC':
|
if len(idns_nameservers_list) == 0 and ntpserver != 'NC':
|
||||||
raise wsme.exc.ClientSideError(_(
|
raise wsme.exc.ClientSideError(_(
|
||||||
"A DNS server must be configured prior to "
|
"A DNS server must be configured prior to "
|
||||||
@ -200,9 +186,9 @@ def _check_ntp_data(op, ntp):
|
|||||||
raise wsme.exc.ClientSideError(_(
|
raise wsme.exc.ClientSideError(_(
|
||||||
"Invalid NTP server %s "
|
"Invalid NTP server %s "
|
||||||
"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 and enabled is None:
|
if len(intp_ntpservers_list) == 0:
|
||||||
raise wsme.exc.ClientSideError(_("No NTP parameters provided."))
|
raise wsme.exc.ClientSideError(_("No NTP parameters provided."))
|
||||||
|
|
||||||
if len(intp_ntpservers_list) > MAX_S:
|
if len(intp_ntpservers_list) > MAX_S:
|
||||||
@ -270,7 +256,7 @@ class NTPController(rest.RestController):
|
|||||||
"""Retrieve a list of ntps. Only one per system"""
|
"""Retrieve a list of ntps. Only one per system"""
|
||||||
|
|
||||||
return self._get_ntps_collection(isystem_uuid, marker, limit,
|
return self._get_ntps_collection(isystem_uuid, marker, limit,
|
||||||
sort_key, sort_dir)
|
sort_key, sort_dir)
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(intpCollection, types.uuid, types.uuid, int,
|
@wsme_pecan.wsexpose(intpCollection, types.uuid, types.uuid, int,
|
||||||
wtypes.text, wtypes.text)
|
wtypes.text, wtypes.text)
|
||||||
@ -359,18 +345,13 @@ 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(
|
||||||
service_change)
|
pecan.request.context)
|
||||||
else:
|
else:
|
||||||
LOG.info("No NTP config changes")
|
LOG.info("No NTP config changes")
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
########################################################################
|
########################################################################
|
||||||
#
|
#
|
||||||
# Copyright (c) 2018 Wind River Systems, Inc.
|
# Copyright (c) 2018-2019 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
@ -48,9 +48,6 @@ class PTP(base.APIBase):
|
|||||||
uuid = types.uuid
|
uuid = types.uuid
|
||||||
"Unique UUID for this ptp"
|
"Unique UUID for this ptp"
|
||||||
|
|
||||||
enabled = types.boolean
|
|
||||||
"Represent the status of the ptp."
|
|
||||||
|
|
||||||
mode = wtypes.Enum(str, 'hardware', 'software', 'legacy')
|
mode = wtypes.Enum(str, 'hardware', 'software', 'legacy')
|
||||||
"Time stamping mode used by ptp."
|
"Time stamping mode used by ptp."
|
||||||
|
|
||||||
@ -80,7 +77,6 @@ class PTP(base.APIBase):
|
|||||||
ptp = PTP(**rpc_ptp.as_dict())
|
ptp = PTP(**rpc_ptp.as_dict())
|
||||||
if not expand:
|
if not expand:
|
||||||
ptp.unset_fields_except(['uuid',
|
ptp.unset_fields_except(['uuid',
|
||||||
'enabled',
|
|
||||||
'mode',
|
'mode',
|
||||||
'transport',
|
'transport',
|
||||||
'mechanism',
|
'mechanism',
|
||||||
@ -118,21 +114,6 @@ class ptpCollection(collection.Collection):
|
|||||||
return collection
|
return collection
|
||||||
|
|
||||||
|
|
||||||
##############
|
|
||||||
# UTILS
|
|
||||||
##############
|
|
||||||
def _check_ptp_data(op, ptp):
|
|
||||||
enabled = ptp['enabled']
|
|
||||||
ntp_list = pecan.request.dbapi.intp_get_by_isystem(ptp['isystem_uuid'])
|
|
||||||
if ntp_list:
|
|
||||||
if hasattr(ntp_list[0], 'enabled'):
|
|
||||||
if ntp_list[0].enabled is True and enabled is True:
|
|
||||||
raise wsme.exc.ClientSideError(_(
|
|
||||||
"PTP cannot be configured alongside with NTP."
|
|
||||||
" Please disable NTP before enabling PTP."))
|
|
||||||
return ptp
|
|
||||||
|
|
||||||
|
|
||||||
LOCK_NAME = 'PTPController'
|
LOCK_NAME = 'PTPController'
|
||||||
|
|
||||||
|
|
||||||
@ -223,7 +204,7 @@ class PTPController(rest.RestController):
|
|||||||
except utils.JSONPATCH_EXCEPTIONS as e:
|
except utils.JSONPATCH_EXCEPTIONS as e:
|
||||||
raise exception.PatchError(patch=patch, reason=e)
|
raise exception.PatchError(patch=patch, reason=e)
|
||||||
|
|
||||||
ptp = _check_ptp_data("modify", ptp.as_dict())
|
ptp = ptp.as_dict()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Update only the fields that have changed
|
# Update only the fields that have changed
|
||||||
@ -242,9 +223,8 @@ class PTPController(rest.RestController):
|
|||||||
return PTP.convert_with_links(rpc_ptp)
|
return PTP.convert_with_links(rpc_ptp)
|
||||||
|
|
||||||
except exception.HTTPNotFound:
|
except exception.HTTPNotFound:
|
||||||
msg = _("PTP update failed: enabled %s : %s %s %s : patch %s"
|
msg = _("PTP update failed: %s %s %s : patch %s" %
|
||||||
% (ptp['enabled'], ptp['mode'], ptp['transport'],
|
(ptp['mode'], ptp['transport'], ptp['mechanism'], patch))
|
||||||
ptp['mechanism'], patch))
|
|
||||||
raise wsme.exc.ClientSideError(msg)
|
raise wsme.exc.ClientSideError(msg)
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(None, types.uuid, status_code=204)
|
@wsme_pecan.wsexpose(None, types.uuid, status_code=204)
|
||||||
|
@ -1457,3 +1457,12 @@ DEFAULT_DNS_SERVICE_DOMAIN = 'cluster.local'
|
|||||||
ANSIBLE_BOOTSTRAP_FLAG = os.path.join(tsc.VOLATILE_PATH, ".ansible_bootstrap")
|
ANSIBLE_BOOTSTRAP_FLAG = os.path.join(tsc.VOLATILE_PATH, ".ansible_bootstrap")
|
||||||
UNLOCK_READY_FLAG = os.path.join(tsc.PLATFORM_CONF_PATH, ".unlock_ready")
|
UNLOCK_READY_FLAG = os.path.join(tsc.PLATFORM_CONF_PATH, ".unlock_ready")
|
||||||
INVENTORY_WAIT_TIMEOUT_IN_SECS = 90
|
INVENTORY_WAIT_TIMEOUT_IN_SECS = 90
|
||||||
|
|
||||||
|
# Clock synchronization types
|
||||||
|
NTP = 'ntp'
|
||||||
|
PTP = 'ptp'
|
||||||
|
|
||||||
|
CLOCK_SYNCHRONIZATION = [
|
||||||
|
NTP,
|
||||||
|
PTP
|
||||||
|
]
|
||||||
|
@ -1621,7 +1621,7 @@ class ConductorManager(service.PeriodicService):
|
|||||||
:param do_worker_apply: configure the worker subfunctions of the host.
|
:param do_worker_apply: configure the worker subfunctions of the host.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
LOG.debug("configure_ihost %s" % host.hostname)
|
LOG.info("configure_ihost %s" % host.hostname)
|
||||||
|
|
||||||
# Generate system configuration files
|
# Generate system configuration files
|
||||||
# TODO(mpeters): remove this once all system reconfigurations properly
|
# TODO(mpeters): remove this once all system reconfigurations properly
|
||||||
@ -5385,14 +5385,17 @@ 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, service_change=False):
|
def update_clock_synchronization_config(self, context, host):
|
||||||
|
"""Update clock_synchronization configuration of a host"""
|
||||||
|
personalities = [host.get('personality')]
|
||||||
|
self._config_update_hosts(context, personalities, [host.get('uuid')],
|
||||||
|
reboot=True)
|
||||||
|
|
||||||
|
def update_ntp_config(self, context):
|
||||||
"""Update the NTP configuration"""
|
"""Update the NTP configuration"""
|
||||||
if service_change:
|
personalities = [constants.CONTROLLER,
|
||||||
personalities = [constants.CONTROLLER,
|
constants.WORKER,
|
||||||
constants.WORKER,
|
constants.STORAGE]
|
||||||
constants.STORAGE]
|
|
||||||
else:
|
|
||||||
personalities = [constants.CONTROLLER]
|
|
||||||
self._config_update_hosts(context, personalities, reboot=True)
|
self._config_update_hosts(context, personalities, reboot=True)
|
||||||
|
|
||||||
def update_ptp_config(self, context):
|
def update_ptp_config(self, context):
|
||||||
|
@ -726,13 +726,23 @@ 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, service_change=False):
|
def update_clock_synchronization_config(self, context, host):
|
||||||
|
"""Synchronously, have the conductor update the
|
||||||
|
clock_synchronization configuration of a host.
|
||||||
|
|
||||||
|
:param context: request context.
|
||||||
|
:param host: the host to be modified.
|
||||||
|
"""
|
||||||
|
return self.call(context,
|
||||||
|
self.make_msg('update_clock_synchronization_config',
|
||||||
|
host=host))
|
||||||
|
|
||||||
|
def update_ntp_config(self, context):
|
||||||
"""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_ptp_config(self, context):
|
def update_ptp_config(self, context):
|
||||||
"""Synchronously, have the conductor update the PTP configuration.
|
"""Synchronously, have the conductor update the PTP configuration.
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
#
|
||||||
|
# Copyright (c) 2019 Wind River Systems, Inc.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
from sqlalchemy import Column, MetaData, Table
|
||||||
|
from sqlalchemy import String
|
||||||
|
from sysinv.common import constants
|
||||||
|
|
||||||
|
ENGINE = 'InnoDB'
|
||||||
|
CHARSET = 'utf8'
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade(migrate_engine):
|
||||||
|
"""
|
||||||
|
This database upgrade creates a new host clock_synchronization attribute
|
||||||
|
for storing the clock_synchronization type (ntp/ptp) for a host.
|
||||||
|
"""
|
||||||
|
|
||||||
|
meta = MetaData()
|
||||||
|
meta.bind = migrate_engine
|
||||||
|
|
||||||
|
host = Table('i_host', meta, autoload=True)
|
||||||
|
host.create_column(Column('clock_synchronization', String(32)),
|
||||||
|
default=constants.NTP)
|
||||||
|
|
||||||
|
ntp = Table('i_ntp', meta, autoload=True)
|
||||||
|
ntp.drop_column(Column('enabled'))
|
||||||
|
|
||||||
|
ptp = Table('ptp', meta, autoload=True)
|
||||||
|
ptp.drop_column(Column('enabled'))
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade(migrate_engine):
|
||||||
|
meta = MetaData()
|
||||||
|
meta.bind = migrate_engine
|
||||||
|
|
||||||
|
# Downgrade is unsupported.
|
||||||
|
raise NotImplementedError('SysInv database downgrade is unsupported.')
|
@ -223,6 +223,8 @@ class ihost(Base):
|
|||||||
config_applied = Column(String(255))
|
config_applied = Column(String(255))
|
||||||
config_target = Column(String(255))
|
config_target = Column(String(255))
|
||||||
|
|
||||||
|
clock_synchronization = Column(String(32), default=constants.NTP)
|
||||||
|
|
||||||
boot_device = Column(String(255), default="/dev/sda")
|
boot_device = Column(String(255), default="/dev/sda")
|
||||||
rootfs_device = Column(String(255), default="/dev/sda")
|
rootfs_device = Column(String(255), default="/dev/sda")
|
||||||
install_output = Column(String(255), default="text")
|
install_output = Column(String(255), default="text")
|
||||||
@ -777,7 +779,6 @@ 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,
|
||||||
@ -792,13 +793,12 @@ class PTP(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=False)
|
|
||||||
mode = Column(String(16), default='hardware')
|
mode = Column(String(16), default='hardware')
|
||||||
transport = Column(String(4), default='l2')
|
transport = Column(String(4), default='l2')
|
||||||
mechanism = Column(String(4), default='e2e')
|
mechanism = Column(String(4), default='e2e')
|
||||||
|
|
||||||
system_id = Column(Integer,
|
system_id = Column(Integer,
|
||||||
ForeignKey('i_system.id', ondelete='CASCADE'))
|
ForeignKey('i_system.id', ondelete='CASCADE'))
|
||||||
|
|
||||||
system = relationship("isystem", lazy="joined", join_depth=1)
|
system = relationship("isystem", lazy="joined", join_depth=1)
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2013-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2019 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
@ -75,6 +75,7 @@ class Host(base.SysinvObject):
|
|||||||
'config_applied': utils.str_or_none,
|
'config_applied': utils.str_or_none,
|
||||||
'config_target': utils.str_or_none,
|
'config_target': utils.str_or_none,
|
||||||
'capabilities': utils.dict_or_none,
|
'capabilities': utils.dict_or_none,
|
||||||
|
'clock_synchronization': utils.str_or_none,
|
||||||
|
|
||||||
'boot_device': utils.str_or_none,
|
'boot_device': utils.str_or_none,
|
||||||
'rootfs_device': utils.str_or_none,
|
'rootfs_device': utils.str_or_none,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2013-2016 Wind River Systems, Inc.
|
# Copyright (c) 2013-2019 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
@ -21,7 +21,6 @@ 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,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
########################################################################
|
########################################################################
|
||||||
#
|
#
|
||||||
# Copyright (c) 2018 Wind River Systems, Inc.
|
# Copyright (c) 2018-2019 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
@ -19,7 +19,6 @@ class PTP(base.SysinvObject):
|
|||||||
'id': int,
|
'id': int,
|
||||||
'uuid': utils.str_or_none,
|
'uuid': utils.str_or_none,
|
||||||
|
|
||||||
'enabled': utils.bool_or_none,
|
|
||||||
'mode': utils.str_or_none,
|
'mode': utils.str_or_none,
|
||||||
'transport': utils.str_or_none,
|
'transport': utils.str_or_none,
|
||||||
'mechanism': utils.str_or_none,
|
'mechanism': utils.str_or_none,
|
||||||
|
@ -411,8 +411,13 @@ class PlatformPuppet(base.BasePuppet):
|
|||||||
else:
|
else:
|
||||||
ntpdate_timeout = "30"
|
ntpdate_timeout = "30"
|
||||||
|
|
||||||
|
if host.clock_synchronization == constants.NTP:
|
||||||
|
ntp_enabled = True
|
||||||
|
else:
|
||||||
|
ntp_enabled = False
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'platform::ntp::enabled': ntp.enabled,
|
'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,
|
||||||
}
|
}
|
||||||
@ -420,9 +425,14 @@ class PlatformPuppet(base.BasePuppet):
|
|||||||
def _get_host_ptp_config(self, host):
|
def _get_host_ptp_config(self, host):
|
||||||
ptp = self.dbapi.ptp_get_one()
|
ptp = self.dbapi.ptp_get_one()
|
||||||
|
|
||||||
|
if host.clock_synchronization == constants.PTP:
|
||||||
|
ptp_enabled = True
|
||||||
|
else:
|
||||||
|
ptp_enabled = False
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'platform::ptp::enabled':
|
'platform::ptp::enabled':
|
||||||
ptp.enabled,
|
ptp_enabled,
|
||||||
'platform::ptp::mode':
|
'platform::ptp::mode':
|
||||||
ptp.mode,
|
ptp.mode,
|
||||||
'platform::ptp::transport':
|
'platform::ptp::transport':
|
||||||
|
@ -33,6 +33,7 @@ class FakeConductorAPI(object):
|
|||||||
self.delete_barbican_secret = mock.MagicMock()
|
self.delete_barbican_secret = mock.MagicMock()
|
||||||
self.iplatform_update_by_ihost = mock.MagicMock()
|
self.iplatform_update_by_ihost = mock.MagicMock()
|
||||||
self.evaluate_app_reapply = mock.MagicMock()
|
self.evaluate_app_reapply = mock.MagicMock()
|
||||||
|
self.update_clock_synchronization_config = mock.MagicMock()
|
||||||
|
|
||||||
def create_ihost(self, context, values):
|
def create_ihost(self, context, values):
|
||||||
# Create the host in the DB as the code under test expects this
|
# Create the host in the DB as the code under test expects this
|
||||||
@ -691,6 +692,38 @@ class TestPatch(TestHost):
|
|||||||
result = self.get_json('/ihosts/%s' % ndict['hostname'])
|
result = self.get_json('/ihosts/%s' % ndict['hostname'])
|
||||||
self.assertEqual(new_location, result['location'])
|
self.assertEqual(new_location, result['location'])
|
||||||
|
|
||||||
|
def test_update_clock_synchronization(self):
|
||||||
|
# Create controller-0
|
||||||
|
ndict = dbutils.post_get_test_ihost(hostname='controller-0',
|
||||||
|
mgmt_ip=None,
|
||||||
|
serialid='serial1')
|
||||||
|
self.post_json('/ihosts', ndict,
|
||||||
|
headers={'User-Agent': 'sysinv-test'})
|
||||||
|
|
||||||
|
# Update clock_synchronization
|
||||||
|
|
||||||
|
response = self.patch_json('/ihosts/%s' % ndict['hostname'],
|
||||||
|
[{'path': '/clock_synchronization',
|
||||||
|
'value': constants.PTP,
|
||||||
|
'op': 'replace'}],
|
||||||
|
headers={'User-Agent': 'sysinv-test'})
|
||||||
|
self.assertEqual(response.content_type, 'application/json')
|
||||||
|
self.assertEqual(response.status_code, http_client.OK)
|
||||||
|
|
||||||
|
# Verify that the host was configured
|
||||||
|
self.fake_conductor_api.configure_ihost.assert_called_once()
|
||||||
|
|
||||||
|
# Verify that the app reapply was checked
|
||||||
|
self.fake_conductor_api.evaluate_app_reapply.assert_not_called()
|
||||||
|
|
||||||
|
# Verify that update_clock_synchronization_config was called
|
||||||
|
self.fake_conductor_api.update_clock_synchronization_config.\
|
||||||
|
assert_called_once()
|
||||||
|
|
||||||
|
# Verify that the host was updated with the new clock_synchronization
|
||||||
|
result = self.get_json('/ihosts/%s' % ndict['hostname'])
|
||||||
|
self.assertEqual(constants.PTP, result['clock_synchronization'])
|
||||||
|
|
||||||
def test_unlock_action_controller(self):
|
def test_unlock_action_controller(self):
|
||||||
self._configure_networks()
|
self._configure_networks()
|
||||||
# Create controller-0
|
# Create controller-0
|
||||||
@ -768,7 +801,7 @@ class TestPatch(TestHost):
|
|||||||
administrative=constants.ADMIN_LOCKED,
|
administrative=constants.ADMIN_LOCKED,
|
||||||
operational=constants.OPERATIONAL_ENABLED,
|
operational=constants.OPERATIONAL_ENABLED,
|
||||||
availability=constants.AVAILABILITY_ONLINE,
|
availability=constants.AVAILABILITY_ONLINE,
|
||||||
inv_state=None)
|
inv_state=None, clock_synchronization=constants.NTP)
|
||||||
|
|
||||||
# Unlock host
|
# Unlock host
|
||||||
response = self._patch_host_action(c0_host['hostname'],
|
response = self._patch_host_action(c0_host['hostname'],
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
# Copyright (c) 2013-2019 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
"""Sysinv test utilities."""
|
"""Sysinv test utilities."""
|
||||||
@ -162,6 +162,7 @@ def get_test_ihost(**kw):
|
|||||||
'install_state_info': kw.get('install_state_info', None),
|
'install_state_info': kw.get('install_state_info', None),
|
||||||
'iscsi_initiator_name': kw.get('iscsi_initiator_name', None),
|
'iscsi_initiator_name': kw.get('iscsi_initiator_name', None),
|
||||||
'inv_state': kw.get('inv_state', 'inventoried'),
|
'inv_state': kw.get('inv_state', 'inventoried'),
|
||||||
|
'clock_synchronization': kw.get('clock_synchronization', constants.NTP),
|
||||||
}
|
}
|
||||||
return inv
|
return inv
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user