Merge remote-tracking branch 'origin/master' into f/centos8
Signed-off-by: Charles Short <charles.short@windriver.com> Change-Id: Ia0115b20fb4325983b0a039fb7a7fd145e81f650
This commit is contained in:
commit
63d6de4701
|
@ -3,6 +3,7 @@
|
|||
templates:
|
||||
- publish-stx-docs
|
||||
- stx-release-notes-jobs
|
||||
- stx-bandit-jobs
|
||||
check:
|
||||
jobs:
|
||||
- openstack-tox-pep8
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
sphinx>=1.6.2
|
||||
openstackdocstheme>=1.26.0 # Apache-2.0
|
||||
sphinx>=2.0.0,!=2.1.0 # BSD
|
||||
openstackdocstheme>=2.2.1 # Apache-2.0
|
||||
|
||||
# Release Notes documentation
|
||||
reno>=0.1.1 # Apache2
|
||||
reno>=3.1.0 # Apache-2.0
|
||||
|
|
|
@ -27,12 +27,6 @@ project = u'StarlingX GUI'
|
|||
copyright = '2018, StarlingX'
|
||||
author = 'StarlingX'
|
||||
|
||||
# The short X.Y version
|
||||
version = ''
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = '0.1'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
|
@ -58,8 +52,11 @@ source_suffix = '.rst'
|
|||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
bug_project = '1027'
|
||||
bug_tag = 'stx.bug'
|
||||
# openstackdocstheme options
|
||||
openstackdocs_repo_name = 'starlingx/gui'
|
||||
openstackdocs_use_storyboard = True
|
||||
openstackdocs_auto_name = False
|
||||
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
@ -74,7 +71,7 @@ language = None
|
|||
exclude_patterns = []
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
pygments_style = 'native'
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
|
10
pylint.rc
10
pylint.rc
|
@ -26,6 +26,7 @@ load-plugins=
|
|||
# can either give multiple identifier separated by comma (,) or put this option
|
||||
# multiple time (only on the command line, not in the configuration file where
|
||||
# it should appear only once).
|
||||
# W0107 unnecessary-pass
|
||||
# W0201 attribute-defined-outside-init
|
||||
# W0212 protected-access var starting with _ used outside class or descendant
|
||||
# W0221 arguments-differ
|
||||
|
@ -37,8 +38,13 @@ load-plugins=
|
|||
# E0202 method-hidden
|
||||
# E0203 access-member-before-definition
|
||||
# E1101 no-member
|
||||
disable=C, R, W0201, W0212, W0221, W0235, W0403, W0511, W0613, W0703,
|
||||
E0202, E0203, E1101
|
||||
# The next two error codes are because Django 1.11.20 cannot be specified
|
||||
# without a custom upper constraints file
|
||||
# E0401: Unable to import 'django.core.urlresolvers' (import-error)
|
||||
# E0611: No name 'urlresolvers' in module 'django.core' (no-name-in-module)
|
||||
disable=C, R, W0107, W0201, W0212, W0221, W0235, W0403, W0511, W0613, W0703,
|
||||
E0202, E0203, E1101,
|
||||
E0401, E0611
|
||||
|
||||
|
||||
[REPORTS]
|
||||
|
|
|
@ -31,8 +31,10 @@ extensions = [
|
|||
'reno.sphinxext',
|
||||
]
|
||||
|
||||
bug_project = '1027'
|
||||
bug_tag = 'stx.bug'
|
||||
# openstackdocstheme options
|
||||
openstackdocs_repo_name = 'starlingx/gui'
|
||||
openstackdocs_use_storyboard = True
|
||||
openstackdocs_auto_name = False
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
# templates_path = ['_templates']
|
||||
|
@ -82,7 +84,7 @@ exclude_patterns = []
|
|||
# show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
pygments_style = 'native'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
# modindex_common_prefix = []
|
||||
|
@ -131,10 +133,6 @@ html_theme = 'starlingxdocs'
|
|||
# directly to the root of the documentation.
|
||||
# html_extra_path = []
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
html_last_updated_fmt = '%Y-%m-%d %H:%M'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
# html_use_smartypants = True
|
||||
|
|
|
@ -68,7 +68,7 @@ def subcloud_create(request, data):
|
|||
|
||||
def subcloud_update(request, subcloud_id, changes):
|
||||
response = dcmanagerclient(request).subcloud_manager.update_subcloud(
|
||||
subcloud_id, **changes.get('updated'))
|
||||
subcloud_id, data=changes.get('updated'))
|
||||
# Updating returns a list of subclouds for some reason
|
||||
return [Subcloud(subcloud) for subcloud in response]
|
||||
|
||||
|
@ -90,8 +90,8 @@ class Strategy(base.APIResourceWrapper):
|
|||
|
||||
def get_strategy(request):
|
||||
try:
|
||||
response = dcmanagerclient(request).sw_update_manager.\
|
||||
patch_strategy_detail()
|
||||
response = dcmanagerclient(request).sw_patch_manager.\
|
||||
update_sw_strategy_detail()
|
||||
except APIException as e:
|
||||
if e.error_code == 404:
|
||||
return None
|
||||
|
@ -103,21 +103,22 @@ def get_strategy(request):
|
|||
|
||||
|
||||
def strategy_create(request, data):
|
||||
response = dcmanagerclient(request).sw_update_manager.\
|
||||
create_patch_strategy(**data)
|
||||
response = dcmanagerclient(request).sw_patch_manager.\
|
||||
create_sw_update_strategy(**data)
|
||||
return Strategy(response)
|
||||
|
||||
|
||||
def strategy_apply(request):
|
||||
return dcmanagerclient(request).sw_update_manager.apply_patch_strategy()
|
||||
return dcmanagerclient(request).sw_patch_manager.apply_sw_update_strategy()
|
||||
|
||||
|
||||
def strategy_abort(request):
|
||||
return dcmanagerclient(request).sw_update_manager.abort_patch_strategy()
|
||||
return dcmanagerclient(request).sw_patch_manager.abort_sw_update_strategy()
|
||||
|
||||
|
||||
def strategy_delete(request):
|
||||
return dcmanagerclient(request).sw_update_manager.delete_patch_strategy()
|
||||
return dcmanagerclient(request).sw_patch_manager.\
|
||||
delete_sw_update_strategy()
|
||||
|
||||
|
||||
class Step(base.APIResourceWrapper):
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# Copyright (c) 2013-2020 Wind River Systems, Inc.
|
||||
# Copyright (c) 2013-2021 Wind River Systems, Inc.
|
||||
#
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
@ -966,8 +966,8 @@ class Host(base.APIResourceWrapper):
|
|||
self._subfunction_avail)
|
||||
|
||||
@property
|
||||
def worker_config_required(self):
|
||||
return self.config_status == 'Worker config required'
|
||||
def config_required(self):
|
||||
return self.config_status == 'config required'
|
||||
|
||||
@property
|
||||
def location(self):
|
||||
|
@ -2004,7 +2004,7 @@ class Interface(base.APIResourceWrapper):
|
|||
"""Wrapper for Inventory Interfaces"""
|
||||
|
||||
_attrs = ['id', 'uuid', 'ifname', 'ifclass', 'iftype', 'imtu', 'imac',
|
||||
'aemode', 'txhashpolicy', 'vlan_id',
|
||||
'aemode', 'txhashpolicy', 'primary_reselect', 'vlan_id',
|
||||
'uses', 'used_by', 'ihost_uuid',
|
||||
'ipv4_mode', 'ipv6_mode', 'ipv4_pool', 'ipv6_pool',
|
||||
'sriov_numvfs', 'sriov_vf_driver']
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2013-2020 Wind River Systems, Inc.
|
||||
# Copyright (c) 2013-2021 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -76,7 +76,6 @@ class CheckboxSelectMultiple(forms.widgets.CheckboxSelectMultiple):
|
|||
attrs, renderer)
|
||||
else:
|
||||
hi = forms.HiddenInput(self.attrs)
|
||||
hi.is_hidden = False # ensure text is rendered
|
||||
return mark_safe(self.empty_value + hi.render(name, None, attrs))
|
||||
|
||||
|
||||
|
@ -153,6 +152,7 @@ class AddInterface(forms.SelfHandlingForm):
|
|||
('ae', _("aggregated ethernet")),
|
||||
('vlan', _("vlan")),
|
||||
('vf', _("vf")),
|
||||
('ethernet', _("ethernet")),
|
||||
)
|
||||
|
||||
SRIOV_VF_DRIVER_CHOICES = (
|
||||
|
@ -173,6 +173,12 @@ class AddInterface(forms.SelfHandlingForm):
|
|||
('layer2', _("layer2")),
|
||||
)
|
||||
|
||||
AE_PRIMARY_RESELECT_CHOICES = (
|
||||
('always', _("always")),
|
||||
('better', _("better")),
|
||||
('failure', _("failure")),
|
||||
)
|
||||
|
||||
IPV4_MODE_CHOICES = (
|
||||
('disabled', _("Disabled")),
|
||||
('static', _("Static")),
|
||||
|
@ -252,6 +258,16 @@ class AddInterface(forms.SelfHandlingForm):
|
|||
'data-ae_mode-balanced': 'Aggregated Ethernet - Tx Policy',
|
||||
'data-ae_mode-802.3ad': 'Aggregated Ethernet - Tx Policy'}))
|
||||
|
||||
primary_reselect = forms.ChoiceField(
|
||||
label=_("Aggregated Ethernet - Primary Reselect"),
|
||||
required=False,
|
||||
choices=AE_PRIMARY_RESELECT_CHOICES,
|
||||
widget=forms.Select(
|
||||
attrs={
|
||||
'class': 'switched',
|
||||
'data-switch-on': 'ae_mode',
|
||||
'data-ae_mode-active_standby': 'Primary Reselect'}))
|
||||
|
||||
vlan_id = forms.IntegerField(
|
||||
label=_("Vlan ID"),
|
||||
initial=1,
|
||||
|
@ -452,15 +468,15 @@ class AddInterface(forms.SelfHandlingForm):
|
|||
nt_choices = self.fields['ifclass'].choices
|
||||
self.fields['ifclass'].choices = [i for i in nt_choices if
|
||||
i[0] != 'data']
|
||||
else:
|
||||
datanets = sysinv.data_network_list(self.request)
|
||||
for dn in datanets:
|
||||
label = "{} (mtu={})".format(dn.name, dn.mtu)
|
||||
datanet = (str(dn.name), label)
|
||||
datanet_choices.append(datanet)
|
||||
if dn.name not in used_datanets:
|
||||
datanet_filtered.append(datanet)
|
||||
initial_datanet_name.append(str(dn.name))
|
||||
|
||||
datanets = sysinv.data_network_list(self.request)
|
||||
for dn in datanets:
|
||||
label = "{} (mtu={})".format(dn.name, dn.mtu)
|
||||
datanet = (str(dn.name), label)
|
||||
datanet_choices.append(datanet)
|
||||
if dn.name not in used_datanets:
|
||||
datanet_filtered.append(datanet)
|
||||
initial_datanet_name.append(str(dn.name))
|
||||
|
||||
self.fields['datanetworks_data'].choices = datanet_filtered
|
||||
self.fields['datanetworks_sriov'].choices = datanet_filtered
|
||||
|
@ -608,8 +624,11 @@ class AddInterface(forms.SelfHandlingForm):
|
|||
if data['iftype'] != 'ae':
|
||||
del data['txhashpolicy']
|
||||
del data['aemode']
|
||||
del data['primary_reselect']
|
||||
elif data['aemode'] == 'active_standby':
|
||||
del data['txhashpolicy']
|
||||
elif data['aemode'] != 'active_standby':
|
||||
del data['primary_reselect']
|
||||
|
||||
if 'sriov_numvfs' in data:
|
||||
data['sriov_numvfs'] = str(data['sriov_numvfs'])
|
||||
|
@ -912,8 +931,11 @@ class UpdateInterface(AddInterface):
|
|||
if data['iftype'] != 'ae':
|
||||
del data['txhashpolicy']
|
||||
del data['aemode']
|
||||
del data['primary_reselect']
|
||||
elif data['aemode'] == 'active_standby':
|
||||
del data['txhashpolicy']
|
||||
elif data['aemode'] != 'active_standby':
|
||||
del data['primary_reselect']
|
||||
|
||||
if not data['ifclass'] or data['ifclass'] == 'none':
|
||||
avail_port_list = sysinv.host_port_list(
|
||||
|
@ -969,14 +991,8 @@ class UpdateInterface(AddInterface):
|
|||
current_interface = sysinv.host_interface_get(
|
||||
self.request, interface_id)
|
||||
ifnet_data['interface_uuid'] = current_interface.uuid
|
||||
if data['networks_to_add']:
|
||||
for n in data['networks_to_add']:
|
||||
ifnet_data['network_uuid'] = n
|
||||
sysinv.interface_network_assign(request, **ifnet_data)
|
||||
elif data['datanetworks_to_add']:
|
||||
for n in data['datanetworks_to_add']:
|
||||
ifnet_data['datanetwork_uuid'] = n
|
||||
sysinv.interface_datanetwork_assign(request, **ifnet_data)
|
||||
networks_to_add = data['networks_to_add']
|
||||
datanetworks_to_add = data['datanetworks_to_add']
|
||||
|
||||
del data['networks']
|
||||
del data['networks_to_add']
|
||||
|
@ -984,9 +1000,18 @@ class UpdateInterface(AddInterface):
|
|||
del data['datanetworks']
|
||||
del data['datanetworks_to_add']
|
||||
del data['interface_datanetworks_to_remove']
|
||||
|
||||
interface = sysinv.host_interface_update(request,
|
||||
interface_id,
|
||||
**data)
|
||||
if networks_to_add:
|
||||
for n in networks_to_add:
|
||||
ifnet_data['network_uuid'] = n
|
||||
sysinv.interface_network_assign(request, **ifnet_data)
|
||||
elif datanetworks_to_add:
|
||||
for n in datanetworks_to_add:
|
||||
ifnet_data['datanetwork_uuid'] = n
|
||||
sysinv.interface_datanetwork_assign(request, **ifnet_data)
|
||||
|
||||
msg = _('Interface "%s" was'
|
||||
' successfully updated.') % data['ifname']
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2013-2019 Wind River Systems, Inc.
|
||||
# Copyright (c) 2013-2021 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -15,6 +15,7 @@ from horizon import exceptions
|
|||
from horizon import tables
|
||||
|
||||
from starlingx_dashboard import api as stx_api
|
||||
import sysinv.common.constants as sysinv_const
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -40,8 +41,12 @@ class DeleteInterface(tables.DeleteAction):
|
|||
|
||||
def allowed(self, request, interface=None):
|
||||
host = self.table.kwargs['host']
|
||||
return (host._administrative == 'locked' and
|
||||
interface.iftype != 'ethernet')
|
||||
if interface.uses:
|
||||
if (stx_api.sysinv.is_system_mode_simplex(request)
|
||||
and interface.iftype == sysinv_const.INTERFACE_TYPE_VF):
|
||||
return True
|
||||
else:
|
||||
return host._administrative == 'locked'
|
||||
|
||||
def delete(self, request, interface_id):
|
||||
host_id = self.table.kwargs['host_id']
|
||||
|
@ -83,13 +88,20 @@ class CreateInterface(tables.LinkAction):
|
|||
def allowed(self, request, datum):
|
||||
host = self.table.kwargs['host']
|
||||
|
||||
if host._administrative != 'locked':
|
||||
is_aio_sx = stx_api.sysinv.is_system_mode_simplex(request)
|
||||
if (host._administrative != 'locked' and not is_aio_sx):
|
||||
return False
|
||||
|
||||
count = 0
|
||||
sriov_count = 0
|
||||
for i in host.interfaces:
|
||||
if i.ifclass:
|
||||
count = count + 1
|
||||
if i.ifclass == sysinv_const.INTERFACE_CLASS_PCI_SRIOV:
|
||||
sriov_count += 1
|
||||
|
||||
if is_aio_sx and host._administrative != 'locked' and sriov_count == 0:
|
||||
return False
|
||||
|
||||
if host.subfunctions and 'worker' not in host.subfunctions and \
|
||||
count >= len(INTERFACE_CLASS_TYPES):
|
||||
|
@ -110,7 +122,13 @@ class EditInterface(tables.LinkAction):
|
|||
|
||||
def allowed(self, request, datum):
|
||||
host = self.table.kwargs['host']
|
||||
return host._administrative == 'locked'
|
||||
intf = datum
|
||||
if (stx_api.sysinv.is_system_mode_simplex(request)
|
||||
and intf.iftype == sysinv_const.INTERFACE_TYPE_ETHERNET
|
||||
and intf.ifclass != sysinv_const.INTERFACE_CLASS_PCI_SRIOV):
|
||||
return True
|
||||
else:
|
||||
return host._administrative == 'locked'
|
||||
|
||||
|
||||
def get_attributes(interface):
|
||||
|
@ -120,6 +138,10 @@ def get_attributes(interface):
|
|||
if interface.aemode in ['balanced', '802.3ad']:
|
||||
attr_str = "%s, AE_XMIT_HASH_POLICY=%s" % (
|
||||
attr_str, interface.txhashpolicy)
|
||||
elif (interface.aemode == 'active_standby' and
|
||||
interface.primary_reselect):
|
||||
attr_str = "%s, primary_reselect=%s" % (
|
||||
attr_str, interface.primary_reselect)
|
||||
if interface.ifclass and interface.ifclass == 'data':
|
||||
attrs = [attr.strip() for attr in attr_str.split(",")]
|
||||
for a in attrs:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2013-2019 Wind River Systems, Inc.
|
||||
# Copyright (c) 2013-2021 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -281,6 +281,7 @@ class UpdateView(forms.ModalFormView):
|
|||
'iftype': interface.iftype,
|
||||
'aemode': interface.aemode,
|
||||
'txhashpolicy': interface.txhashpolicy,
|
||||
'primary_reselect': interface.primary_reselect,
|
||||
# 'ports': interface.ports,
|
||||
# 'uses': interface.uses,
|
||||
'ifclass': interface.ifclass,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||
# Copyright (c) 2013-2021 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -125,6 +125,7 @@ class EditStorageVolume(forms.SelfHandlingForm):
|
|||
|
||||
if journal:
|
||||
data['journal_location'] = journal
|
||||
data['journal_size_mib'] = int(data['journal_size_gib']) * 1024
|
||||
else:
|
||||
data['journal_location'] = None
|
||||
data['journal_size_mib'] = \
|
||||
|
@ -404,12 +405,10 @@ class AddLocalVolumeGroup(forms.SelfHandlingForm):
|
|||
if lvg.vg_state in current_lvg_states]
|
||||
|
||||
compatible_lvgs = []
|
||||
if host.personality.lower().startswith(
|
||||
stx_api.sysinv.PERSONALITY_CONTROLLER):
|
||||
compatible_lvgs += [stx_api.sysinv.LVG_CINDER_VOLUMES]
|
||||
|
||||
if stx_api.sysinv.SUBFUNCTIONS_WORKER in subfunctions:
|
||||
compatible_lvgs += [stx_api.sysinv.LVG_NOVA_LOCAL]
|
||||
compatible_lvgs += [stx_api.sysinv.LVG_NOVA_LOCAL,
|
||||
stx_api.sysinv.LVG_CGTS_VG]
|
||||
|
||||
allowed_lvgs = set(compatible_lvgs) - set(current_lvgs)
|
||||
|
||||
|
@ -539,11 +538,11 @@ class AddPhysicalVolume(forms.SelfHandlingForm):
|
|||
compatible_lvgs = []
|
||||
if host.personality.lower().startswith(
|
||||
stx_api.sysinv.PERSONALITY_CONTROLLER):
|
||||
compatible_lvgs += [stx_api.sysinv.LVG_CGTS_VG,
|
||||
stx_api.sysinv.LVG_CINDER_VOLUMES]
|
||||
compatible_lvgs += [stx_api.sysinv.LVG_CGTS_VG]
|
||||
|
||||
if stx_api.sysinv.SUBFUNCTIONS_WORKER in subfunctions:
|
||||
compatible_lvgs += [stx_api.sysinv.LVG_NOVA_LOCAL]
|
||||
compatible_lvgs += [stx_api.sysinv.LVG_NOVA_LOCAL,
|
||||
stx_api.sysinv.LVG_CGTS_VG]
|
||||
|
||||
avail_disk_list = stx_api.sysinv.host_disk_list(self.request,
|
||||
host_uuid)
|
||||
|
@ -551,21 +550,15 @@ class AddPhysicalVolume(forms.SelfHandlingForm):
|
|||
partitions = stx_api.sysinv.host_disk_partition_list(self.request,
|
||||
host_uuid)
|
||||
ipv_list = stx_api.sysinv.host_pv_list(self.request, host_uuid)
|
||||
|
||||
disk_tuple_list = []
|
||||
partitions_tuple_list = []
|
||||
ilvg_tuple_list = []
|
||||
|
||||
pv_cinder_volumes = next(
|
||||
(pv for pv in ipv_list
|
||||
if pv.lvm_vg_name == stx_api.sysinv.LVG_CINDER_VOLUMES), None)
|
||||
|
||||
for lvg in ilvg_list:
|
||||
if (lvg.lvm_vg_name in compatible_lvgs and
|
||||
lvg.vg_state in [stx_api.sysinv.LVG_ADD,
|
||||
stx_api.sysinv.LVG_PROV]):
|
||||
if (lvg.lvm_vg_name == stx_api.sysinv.LVG_CINDER_VOLUMES and
|
||||
pv_cinder_volumes):
|
||||
continue
|
||||
ilvg_tuple_list.append((lvg.uuid, lvg.lvm_vg_name))
|
||||
|
||||
for disk in avail_disk_list:
|
||||
|
@ -663,16 +656,16 @@ class AddPhysicalVolume(forms.SelfHandlingForm):
|
|||
messages.success(request, msg)
|
||||
return stor
|
||||
except exc.ClientException as ce:
|
||||
msg = _('Failed to create physical volume.')
|
||||
msg = _('Failed to create physical volume. ')
|
||||
|
||||
# Allow REST API error message to appear on UI
|
||||
w_msg = str(ce)
|
||||
if ('Warning:' in w_msg):
|
||||
if 'Warning:' in w_msg:
|
||||
LOG.info(ce)
|
||||
messages.warning(request, w_msg.split(':', 1)[-1])
|
||||
messages.warning(request, msg + (w_msg.split(':', 1)[-1]))
|
||||
else:
|
||||
LOG.error(ce)
|
||||
messages.error(request, w_msg)
|
||||
messages.error(request, msg + w_msg)
|
||||
|
||||
# Redirect to host details pg
|
||||
redirect = reverse(self.failure_url, args=[host_id])
|
||||
|
|
|
@ -386,8 +386,7 @@ class AddLocalVolumeGroup(tables.LinkAction):
|
|||
self.classes = classes
|
||||
|
||||
if not host._administrative == 'locked':
|
||||
if 'worker' in host._subfunctions and \
|
||||
host.worker_config_required is False:
|
||||
if host.config_required is False:
|
||||
if "disabled" not in self.classes:
|
||||
self.classes = [c for c in self.classes] + ['disabled']
|
||||
self.verbose_name = string_concat(self.verbose_name, ' ',
|
||||
|
@ -401,11 +400,8 @@ class AddLocalVolumeGroup(tables.LinkAction):
|
|||
if lvg.vg_state in current_lvg_states]
|
||||
compatible_lvgs = []
|
||||
|
||||
if host._personality == 'controller':
|
||||
compatible_lvgs += [sysinv.LVG_CINDER_VOLUMES]
|
||||
|
||||
if 'worker' in host._subfunctions:
|
||||
compatible_lvgs += [sysinv.LVG_NOVA_LOCAL]
|
||||
compatible_lvgs += [sysinv.LVG_NOVA_LOCAL, sysinv.LVG_CGTS_VG]
|
||||
|
||||
allowed_lvgs = set(compatible_lvgs) - set(current_lvgs)
|
||||
if not any(allowed_lvgs):
|
||||
|
@ -440,8 +436,7 @@ class RemoveLocalVolumeGroup(tables.DeleteAction):
|
|||
|
||||
if lvg.lvm_vg_name == sysinv.LVG_NOVA_LOCAL:
|
||||
return ((host._administrative == 'locked') or
|
||||
(('worker' in host._subfunctions) and
|
||||
(host.worker_config_required is True)))
|
||||
(host.config_required is True))
|
||||
elif lvg.lvm_vg_name == sysinv.LVG_CINDER_VOLUMES:
|
||||
return (sysinv.STORAGE_BACKEND_LVM not in storage_backend and
|
||||
sysinv.LVG_ADD in lvg.vg_state)
|
||||
|
@ -518,26 +513,18 @@ class AddPhysicalVolume(tables.LinkAction):
|
|||
classes = [c for c in self.classes if c != "disabled"]
|
||||
self.classes = classes
|
||||
|
||||
# cgts-vg, cinder-volumes: Allow adding to any controller
|
||||
# Allow adding to any controller
|
||||
if host._personality == sysinv.PERSONALITY_CONTROLLER:
|
||||
return True
|
||||
|
||||
# nova-local: Allow adding to any locked host with a worker
|
||||
# subfunction. On an AIO, the previous check superceeds this.
|
||||
# Allow adding to any locked host
|
||||
if host._administrative != 'locked':
|
||||
if 'worker' in host._subfunctions and \
|
||||
host.worker_config_required is False:
|
||||
host.config_required is False:
|
||||
if "disabled" not in self.classes:
|
||||
self.classes = [c for c in self.classes] + ['disabled']
|
||||
self.verbose_name = string_concat(self.verbose_name, ' ',
|
||||
_("(Node Unlocked)"))
|
||||
elif "nova-local" not in [
|
||||
lvg.lvm_vg_name for lvg in
|
||||
sysinv.host_lvg_list(request, host.uuid)]:
|
||||
if "disabled" not in self.classes:
|
||||
self.classes = [c for c in self.classes] + ['disabled']
|
||||
self.verbose_name = string_concat(self.verbose_name, ' ',
|
||||
_("(No nova-local LVG)"))
|
||||
|
||||
return True # The action should always be displayed
|
||||
|
||||
|
@ -565,8 +552,7 @@ class RemovePhysicalVolume(tables.DeleteAction):
|
|||
|
||||
if pv.lvm_vg_name == sysinv.LVG_NOVA_LOCAL:
|
||||
return ((host._administrative == 'locked') or
|
||||
(('worker' in host._subfunctions) and
|
||||
(host.worker_config_required is True)))
|
||||
(host.config_required is True))
|
||||
elif pv.lvm_vg_name == sysinv.LVG_CINDER_VOLUMES:
|
||||
return (sysinv.STORAGE_BACKEND_LVM not in storage_backend and
|
||||
sysinv.PV_ADD in pv.pv_state)
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
{% if interfaces.aemode == 'balanced' %}
|
||||
{{" | "}} {{ interfaces.txhashpolicy }}
|
||||
{% endif %}
|
||||
{% if interfaces.aemode == 'active_standby' %}
|
||||
{{" | "}} {{ interfaces.primary_reselect }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{{ " | MTU =" }} {{ interfaces.imtu }}
|
||||
</li>
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
{% if interfaces.aemode == 'balanced' %}
|
||||
{{" | "}} {{ interfaces.txhashpolicy }}
|
||||
{% endif %}
|
||||
{% if interfaces.aemode == 'active_standby' %}
|
||||
{{" | "}} {{ interfaces.primary_reselect }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{{" | MTU="}} {{ interfaces.imtu }}
|
||||
</li>
|
||||
|
|
|
@ -41,14 +41,9 @@
|
|||
function confirm_pv_device() {
|
||||
lvg = lvg_dropdown.options[lvg_dropdown.selectedIndex].text;
|
||||
if (lvg.indexOf("cgts-vg") !== -1) {
|
||||
var str = "This operation is irreversible. Are you sure you want to add the selected device to cgts-vg?";
|
||||
var confirm = window.confirm(str);
|
||||
if (confirm != true) {
|
||||
return false;
|
||||
}
|
||||
return confirm('This operation is irreversible. Are you sure you want to add the selected device to cgts-vg?');
|
||||
}
|
||||
|
||||
document.getElementById('add_physicalvolume_form').submit();
|
||||
return "";
|
||||
}
|
||||
|
||||
/* Obtain the stor function dropdown. */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
% extends 'base.html' %}
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Create Storage Profile" %}{% endblock %}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
% extends 'base.html' %}
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Create Local Volume Group" %}{% endblock %}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
% extends 'base.html' %}
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Create Local Volume Group" %}{% endblock %}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2013-2019 Wind River Systems, Inc.
|
||||
# Copyright (c) 2013-2020 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -47,7 +47,7 @@ class AddView(workflows.WorkflowView):
|
|||
'personality': "",
|
||||
'subfunctions': "",
|
||||
'mgmt_mac': "",
|
||||
'bm_type': stx_api.sysinv.BM_TYPE_NULL,
|
||||
'bm_type': "",
|
||||
'bm_ip': "",
|
||||
'bm_username': ""}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2013-2020 Wind River Systems, Inc.
|
||||
# Copyright (c) 2013-2021 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -14,7 +14,6 @@ import sysinv.common.constants as sysinv_const
|
|||
from cgtsclient.common import constants
|
||||
from cgtsclient import exc
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _ # noqa
|
||||
from django.views.decorators.debug import sensitive_variables # noqa
|
||||
|
||||
|
@ -196,13 +195,6 @@ class AddHostInfoAction(workflows.Action):
|
|||
self.fields['personality'].choices = \
|
||||
PERSONALITY_CHOICES_WITHOUT_STORAGE
|
||||
|
||||
# Remove worker personality if in DC mode and region
|
||||
if getattr(self.request.user, 'services_region', None) == 'RegionOne' \
|
||||
and getattr(settings, 'DC_MODE', False):
|
||||
self.fields['personality'].choices = \
|
||||
[choice for choice in self.fields['personality'].choices
|
||||
if choice[0] != stx_api.sysinv.PERSONALITY_WORKER]
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(AddHostInfoAction, self).clean()
|
||||
return cleaned_data
|
||||
|
@ -297,13 +289,6 @@ class UpdateHostInfoAction(workflows.Action):
|
|||
self.fields['personality'].choices = \
|
||||
PERSONALITY_CHOICES_WITHOUT_STORAGE
|
||||
|
||||
# Remove worker personality if in DC mode and region
|
||||
if getattr(self.request.user, 'services_region', None) == 'RegionOne' \
|
||||
and getattr(settings, 'DC_MODE', False):
|
||||
self.fields['personality'].choices = \
|
||||
[choice for choice in self.fields['personality'].choices
|
||||
if choice[0] != stx_api.sysinv.PERSONALITY_WORKER]
|
||||
|
||||
# hostname cannot be modified once it is set
|
||||
if self.initial['hostname']:
|
||||
self.fields['hostname'].widget.attrs['readonly'] = 'readonly'
|
||||
|
|
|
@ -378,6 +378,11 @@
|
|||
gettext('The subcloud must be in the managed state before you can access detailed views.'));
|
||||
return;
|
||||
}
|
||||
if (cloud.availability_status != 'online') {
|
||||
toast.add('error',
|
||||
gettext('The subcloud must be online before you can access detailed views.'));
|
||||
return;
|
||||
}
|
||||
|
||||
keystone.getCurrentUserSession().success(function(session){
|
||||
session.available_services_regions.indexOf(cloud.name)
|
||||
|
@ -400,6 +405,11 @@
|
|||
gettext('The subcloud must be in the managed management state before you can access detailed views.'));
|
||||
return;
|
||||
}
|
||||
if (cloud.availability_status != 'online') {
|
||||
toast.add('error',
|
||||
gettext('The subcloud must be online before you can access detailed views.'));
|
||||
return;
|
||||
}
|
||||
|
||||
keystone.getCurrentUserSession().success(function(session){
|
||||
if (session.available_services_regions.indexOf(cloud.name) > -1) {
|
||||
|
|
|
@ -53,11 +53,20 @@
|
|||
<span ng-show="cloud.availability_status==='offline'" class="fa fa-circle status-danger"></span>
|
||||
{$ cloud.availability_status $}</td>
|
||||
<td class="rsp-p1">
|
||||
<span ng-show="cloud.deploy_status==='pre-install-failed' || cloud.deploy_status==='install-failed' || cloud.deploy_status==='bootstrap-failed' || cloud.deploy_status==='deploy-failed'"
|
||||
<span ng-show="cloud.deploy_status==='pre-install-failed' || cloud.deploy_status==='install-failed'
|
||||
|| cloud.deploy_status==='bootstrap-failed' || cloud.deploy_status==='deploy-failed'
|
||||
|| cloud.deploy_status==='deploy-prep-failed' || cloud.deploy_status==='data-migration-failed'
|
||||
|| cloud.deploy_status==='restore-prep-failed' || cloud.deploy_status==='restore-failed'"
|
||||
class="fa fa-circle status-danger"></span>
|
||||
<span ng-show="cloud.deploy_status==='not-deployed' || cloud.deploy_status==='pre-install' || cloud.deploy_status==='installing' || cloud.deploy_status==='bootstrapping' || cloud.deploy_status==='deploying'"
|
||||
<span ng-show="cloud.deploy_status==='not-deployed' || cloud.deploy_status==='pre-install'
|
||||
|| cloud.deploy_status==='installing' || cloud.deploy_status==='bootstrapping'
|
||||
|| cloud.deploy_status==='deploying' || cloud.deploy_status==='pre-deploy'
|
||||
|| cloud.deploy_status==='migrating-data' || cloud.deploy_status==='pre-restore'
|
||||
|| cloud.deploy_status==='restoring'"
|
||||
class="fa fa-circle status-warning"></span>
|
||||
<span ng-show="cloud.deploy_status=='complete'" class="fa fa-circle status-success"></span>
|
||||
<span ng-show="cloud.deploy_status=='complete' || cloud.deploy_status==='installed'
|
||||
|| cloud.deploy_status==='migrated'"
|
||||
class="fa fa-circle status-success"></span>
|
||||
{$ cloud.deploy_status $}
|
||||
</td>
|
||||
<td class="rsp-p1">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2017 Wind River Systems, Inc.
|
||||
* Copyright (c) 2017-2020 Wind River Systems, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
|
@ -43,9 +43,17 @@
|
|||
|
||||
function getSummaries() {
|
||||
return apiService.get('/api/dc_manager/alarm_summaries/')
|
||||
.error(function () {
|
||||
.error(function (error) {
|
||||
|
||||
toastService.clearErrors();
|
||||
toastService.add('error', gettext('Unable to retrieve the subcloud alarm summaries.'));
|
||||
|
||||
// We do this check to prevent the user from seeing a popup with this
|
||||
// error when they are about to switch from the SystemController's
|
||||
// region to a subcloud. The error can be raised when there are still
|
||||
// SystemController's pending requests in the queue.
|
||||
if (error != "Invalid service catalog: dcmanager") {
|
||||
toastService.add('error', gettext('Unable to retrieve the subcloud alarm summaries.'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -119,9 +127,16 @@
|
|||
|
||||
function getSubClouds() {
|
||||
return apiService.get('/api/dc_manager/subclouds/')
|
||||
.error(function () {
|
||||
.error(function (error) {
|
||||
toastService.clearErrors();
|
||||
toastService.add('error', gettext('Unable to retrieve the subclouds.'));
|
||||
|
||||
// We do this check to prevent the user from seeing a popup with this
|
||||
// error when they are about to switch from the SystemController's
|
||||
// region to a subcloud. The error can be raised when there are still
|
||||
// SystemController's pending requests in the queue.
|
||||
if (error != "Invalid service catalog: dcmanager") {
|
||||
toastService.add('error', gettext('Unable to retrieve the subclouds.'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2019-2020 Wind River Systems, Inc.
|
||||
# Copyright (c) 2019-2021 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -69,11 +69,16 @@ DC_MODE = False
|
|||
if distributed_cloud_role and distributed_cloud_role in ['systemcontroller',
|
||||
'subcloud']:
|
||||
DC_MODE = True
|
||||
DEFAULT_SERVICE_REGIONS = {
|
||||
'*': 'SystemController',
|
||||
}
|
||||
|
||||
|
||||
HORIZON_CONFIG["user_home"] = \
|
||||
"starlingx_dashboard.utils.settings.get_user_home"
|
||||
|
||||
OPENSTACK_ENDPOINT_TYPE = "adminURL"
|
||||
SECONDARY_ENDPOINT_TYPE = "adminURL"
|
||||
|
||||
# Override Django tempory file upload directory
|
||||
# Directory in which upload streamed files will be temporarily saved. A value
|
||||
|
@ -137,12 +142,15 @@ for root, _dirs, files in os.walk('/opt/branding/applied'):
|
|||
ADD_TEMPLATE_DIRS = [os.path.join(ROOT_PATH, 'starlingx_templates')]
|
||||
TEMPLATES[0]['DIRS'] = ADD_TEMPLATE_DIRS + TEMPLATES[0]['DIRS']
|
||||
|
||||
OPENRC_CUSTOM_TEMPLATE = 'starlingx-openrc.sh.template'
|
||||
|
||||
STATIC_ROOT = "/www/pages/static"
|
||||
COMPRESS_OFFLINE = True
|
||||
|
||||
# Secure site configuration
|
||||
SESSION_COOKIE_HTTPONLY = True
|
||||
ENFORCE_PASSWORD_CHECK = True
|
||||
HORIZON_CONFIG["disable_password_reveal"] = True
|
||||
|
||||
# Size of thread batch
|
||||
THREAD_BATCH_SIZE = 100
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
{% load shellfilter %}#!/usr/bin/env bash
|
||||
{% load align_auth_url %}
|
||||
|
||||
#
|
||||
# Copyright (c) 2020 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# To use an OpenStack cloud you need to authenticate against the Identity
|
||||
# service named keystone, which returns a **Token** and **Service Catalog**.
|
||||
# The catalog contains the endpoints for all services the user/tenant has
|
||||
# access to - such as Compute, Image Service, Identity, Object Storage, Block
|
||||
# Storage, and Networking (code-named nova, glance, keystone, swift,
|
||||
# cinder, and neutron).
|
||||
#
|
||||
# *NOTE*: Using the 3 *Identity API* does not necessarily mean any other
|
||||
# OpenStack API is version 3. For example, your cloud provider may implement
|
||||
# Image API v1.1, Block Storage API v2, and Compute API v2.0. OS_AUTH_URL is
|
||||
# only for the Identity API served through keystone.
|
||||
{% if region == 'SystemController' %}
|
||||
export OS_AUTH_URL={{ auth_url|align_auth_url }}
|
||||
{% else %}
|
||||
export OS_AUTH_URL={{ auth_url }}
|
||||
{% endif %}
|
||||
|
||||
# With the addition of Keystone we have standardized on the term **project**
|
||||
# as the entity that owns the resources.
|
||||
export OS_PROJECT_ID={{ tenant_id }}
|
||||
export OS_PROJECT_NAME="{{ tenant_name|shellfilter }}"
|
||||
export OS_USER_DOMAIN_NAME="{{ user_domain_name|shellfilter }}"
|
||||
if [ -z "$OS_USER_DOMAIN_NAME" ]; then unset OS_USER_DOMAIN_NAME; fi
|
||||
export OS_PROJECT_DOMAIN_ID="{{ project_domain_id|shellfilter }}"
|
||||
if [ -z "$OS_PROJECT_DOMAIN_ID" ]; then unset OS_PROJECT_DOMAIN_ID; fi
|
||||
|
||||
# unset v2.0 items in case set
|
||||
unset OS_TENANT_ID
|
||||
unset OS_TENANT_NAME
|
||||
|
||||
# In addition to the owning entity (tenant), OpenStack stores the entity
|
||||
# performing the action as the **user**.
|
||||
export OS_USERNAME="{{ user.username|shellfilter }}"
|
||||
|
||||
# With Keystone you pass the keystone password.
|
||||
echo "Please enter your OpenStack Password for project $OS_PROJECT_NAME as user $OS_USERNAME: "
|
||||
read -sr OS_PASSWORD_INPUT
|
||||
export OS_PASSWORD=$OS_PASSWORD_INPUT
|
||||
|
||||
# If your configuration has multiple regions, we set that information here.
|
||||
# OS_REGION_NAME is optional and only valid in certain environments.
|
||||
export OS_REGION_NAME="{{ region|shellfilter }}"
|
||||
# Don't leave a blank variable, unset it if it was empty
|
||||
if [ -z "$OS_REGION_NAME" ]; then unset OS_REGION_NAME; fi
|
||||
|
||||
export OS_INTERFACE={{ interface }}
|
||||
export OS_IDENTITY_API_VERSION={{ os_identity_api_version }}
|
|
@ -0,0 +1,16 @@
|
|||
#
|
||||
# Copyright (c) 2020 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from django import template
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.filter(name="align_auth_url")
|
||||
def align_auth_url(url):
|
||||
url_list = url.split(':')
|
||||
url_list[-1] = '5000/v3'
|
||||
return ':'.join(url_list)
|
|
@ -7,22 +7,24 @@
|
|||
# be installed in a specific order.
|
||||
#
|
||||
# Hacking should appear first in case something else depends on pep8
|
||||
hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
|
||||
hacking>=1.1.0,<=2.0.0 # Apache-2.0
|
||||
coverage>=3.6 # Apache-2.0
|
||||
django-nose>=1.4.4 # BSD
|
||||
mock>=2.0 # BSD
|
||||
mox3>=0.7.0 # Apache-2.0
|
||||
nodeenv>=0.9.4 # BSD License # BSD
|
||||
nose # LGPL
|
||||
nose-exclude # LGPL
|
||||
nosehtmloutput>=0.0.3 # Apache-2.0
|
||||
nosexcover # BSD
|
||||
openstack.nose-plugin>=0.7 # Apache-2.0
|
||||
oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
|
||||
requests>=2.10.0 # Apache-2.0
|
||||
selenium>=2.50.1 # Apache-2.0
|
||||
sphinx!=1.3b1,<1.3,>=1.2.1 # BSD
|
||||
testtools>=1.4.0 # MIT
|
||||
# This also needs xvfb library installed on your OS
|
||||
xvfbwrapper>=0.1.3 #license: MIT
|
||||
pyOpenSSL>=0.14
|
||||
bandit;python_version>="3.0"
|
||||
isort<5;python_version>="3.0"
|
||||
pylint<2.1.0;python_version<"3.0" # GPLv2
|
||||
pylint<2.4.0;python_version>="3.0" # GPLv2
|
||||
Django
|
||||
|
|
21
tox.ini
21
tox.ini
|
@ -37,9 +37,11 @@ commands =
|
|||
|
||||
[flake8]
|
||||
# H102 Apache 2.0 license header not found
|
||||
# NOTE(Eric Barrett): H102 raises a false positive when using the SPDX license header
|
||||
ignore = H102
|
||||
# H106 Don’t put vim configuration in source files (off by default).
|
||||
# W503 line break before binary operator
|
||||
# W504 line break after binary operator
|
||||
# E741 ambiguous variable name 'l'
|
||||
ignore = H102,W503,W504,E741
|
||||
# H106 Do not put vim configuration in source files (off by default).
|
||||
# H203 Use assertIs(Not)None to check for None (off by default).
|
||||
# H904 Delay string interpolations at logging calls (off by default).
|
||||
enable-extensions = H106,H203,H904
|
||||
|
@ -52,7 +54,7 @@ commands =
|
|||
flake8
|
||||
|
||||
[testenv:pylint]
|
||||
basepython = python2.7
|
||||
basepython = python3
|
||||
usedevelop = False
|
||||
skip_install = True
|
||||
deps = {[testenv]deps}
|
||||
|
@ -64,9 +66,8 @@ deps = {[testenv]deps}
|
|||
-e{[tox]stxdir}/nfv/nfv/nfv-client
|
||||
-e{[tox]stxdir}/ha/service-mgmt-client/sm-client
|
||||
-e{[tox]stxdir}/utilities/ceph/python-cephclient/python-cephclient
|
||||
horizon==15.2.0
|
||||
horizon
|
||||
requests-toolbelt
|
||||
pylint
|
||||
commands =
|
||||
pylint starlingx-dashboard/starlingx-dashboard/starlingx_dashboard --rcfile=./pylint.rc
|
||||
|
||||
|
@ -77,6 +78,7 @@ commands = {posargs}
|
|||
[testenv:docs]
|
||||
basepython = python3
|
||||
deps = -r{toxinidir}/doc/requirements.txt
|
||||
install_command = pip install -U {opts} {packages}
|
||||
commands =
|
||||
rm -rf doc/build
|
||||
sphinx-build -a -E -W -d doc/build/doctrees -b html doc/source doc/build/html
|
||||
|
@ -85,6 +87,7 @@ whitelist_externals = rm
|
|||
[testenv:releasenotes]
|
||||
basepython = python3
|
||||
deps = -r{toxinidir}/doc/requirements.txt
|
||||
install_command = pip install -U {opts} {packages}
|
||||
commands =
|
||||
rm -rf releasenotes/build
|
||||
sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
|
||||
|
@ -97,4 +100,10 @@ basepython = python3
|
|||
# Re-use the releasenotes venv
|
||||
envdir = {toxworkdir}/releasenotes
|
||||
deps = -r{toxinidir}/doc/requirements.txt
|
||||
install_command = pip install -U {opts} {packages}
|
||||
commands = reno new {posargs}
|
||||
|
||||
[testenv:bandit]
|
||||
basepython = python3
|
||||
description = Bandit code scan for *.py files under config folder
|
||||
commands = bandit -r {toxinidir}/ -x '**/.tox/**,**/.eggs/**' -lll
|
||||
|
|
Loading…
Reference in New Issue