Merge "Create a new Filesystems tab for hosts"

This commit is contained in:
Zuul 2019-08-13 15:58:40 +00:00 committed by Gerrit Code Review
commit 6f0db62cd0
11 changed files with 323 additions and 4 deletions

View File

@ -1593,6 +1593,14 @@ class ControllerFS(base.APIResourceWrapper):
return self._replicated
class HostFilesystem(base.APIResourceWrapper):
_attrs = ['uuid', 'id', 'name', 'size', 'logical_volume', 'forihostid',
'ihost_uuid']
def __init__(self, apiresource):
super(HostFilesystem, self).__init__(apiresource)
class CephMon(base.APIResourceWrapper):
"""..."""
_attrs = ['device_path', 'ceph_mon_gib', 'hostname',
@ -1837,6 +1845,24 @@ def get_cinder_backend(request):
return cinder_backends
def host_filesystems_list(request, host_id):
filesystems = cgtsclient(request).host_fs.list(host_id)
return [HostFilesystem(n) for n in filesystems]
def host_filesystems_update(request, host_id, **kwargs):
patch_list = []
for key, value in kwargs.items():
patch = []
patch.append({'op': 'replace', 'path': '/name', 'value': key})
patch.append({'op': 'replace', 'path': '/size', 'value': value})
patch_list.append(patch)
LOG.info("host_filesystems_update patch_list=%s", patch_list)
return cgtsclient(request).host_fs.update_many(host_id, patch_list)
def host_node_list(request, host_id):
nodes = cgtsclient(request).inode.list(host_id)
return [Node(n) for n in nodes]

View File

@ -0,0 +1,98 @@
#
# Copyright (c) 2019 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# vim: tabstop=4 shiftwidth=4 softtabstop=4
import logging
from django.core.urlresolvers import reverse # noqa
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms
from starlingx_dashboard import api as stx_api
LOG = logging.getLogger(__name__)
class UpdateFilesystems(forms.SelfHandlingForm):
host_id = forms.CharField(label=_("host_id"),
required=False,
widget=forms.widgets.HiddenInput)
host_uuid = forms.CharField(label=_("host_uuid"),
required=False,
widget=forms.widgets.HiddenInput)
backup = forms.IntegerField(
label=_("Backup Storage (GiB)"),
required=False,
help_text=_("Backup storage space in gibibytes."),
min_value=0)
docker = forms.IntegerField(
label=_("Docker Storage (GiB)"),
required=True,
help_text=_("Docker storage space in gibibytes."),
min_value=0)
kubelet = forms.IntegerField(
label=_("Kubelet Storage (GiB)"),
required=True,
help_text=_("Kubelet storage space in gibibytes."),
min_value=0)
scratch = forms.IntegerField(
label=_("Scratch Storage (GiB)"),
required=True,
help_text=_("Scratch storage space in gibibytes."),
min_value=0)
failure_url = 'horizon:admin:inventory:detail'
failure_message = 'Failed to update host filesystems configuration.'
def __init__(self, request, *args, **kwargs):
super(UpdateFilesystems, self).__init__(request, *args, **kwargs)
# The backup fs is only used on controller nodes. Removed from form if
# its not in the list.
if not kwargs['initial'].get('backup'):
del self.fields['backup']
def clean(self):
cleaned_data = super(UpdateFilesystems, self).clean()
return cleaned_data
def handle(self, request, data):
host_uuid = data['host_uuid']
data.pop('host_uuid')
data.pop('host_id')
new_data = {k.replace("_", "-"): v for k, v in data.items()}
try:
fs_list = stx_api.sysinv.host_filesystems_list(
self.request, host_uuid)
fs_data = {fs.name: fs.size for fs in fs_list}
for k, v in fs_data.items():
if new_data.get(k, None) == v:
del new_data[k]
if new_data:
stx_api.sysinv.host_filesystems_update(request,
host_uuid,
**new_data)
return True
except Exception as exc:
msg = _('Failed to update host filesystems (%(e)s).') \
% ({'e': exc})
LOG.info(msg)
redirect = reverse(self.failure_url, args=[host_uuid])
exceptions.handle(request, msg, redirect=redirect)

View File

@ -0,0 +1,44 @@
#
# Copyright (c) 2019 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import logging
from django.core.urlresolvers import reverse # noqa
from django.utils.translation import ugettext_lazy as _
from horizon import tables
LOG = logging.getLogger(__name__)
class UpdateFilesystems(tables.LinkAction):
name = "updatefilesystems"
verbose_name = _("Update Filesystems")
url = "horizon:admin:inventory:updatefilesystems"
classes = ("ajax-modal", "btn-edit")
def get_link_url(self, datum=None):
host_id = self.table.kwargs['host_id']
return reverse(self.url, args=(host_id,))
def allowed(self, request, datum):
return True
class FilesystemsTable(tables.DataTable):
name = tables.Column('name', verbose_name=_('Name'))
size = tables.Column('size', verbose_name=_('Size (GiB)'))
def get_object_id(self, datum):
return str(datum.uuid)
class Meta(object):
name = "filesystems"
verbose_name = _("Filesystems")
multi_select = False
table_actions = (UpdateFilesystems,)

View File

@ -0,0 +1,76 @@
#
# Copyright (c) 2019 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# vim: tabstop=4 shiftwidth=4 softtabstop=4
import logging
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms
from starlingx_dashboard import api as stx_api
from starlingx_dashboard.dashboards.admin.inventory.filesystems.forms \
import UpdateFilesystems
LOG = logging.getLogger(__name__)
class UpdateFilesystemsView(forms.ModalFormView):
form_class = UpdateFilesystems
template_name = 'admin/inventory/filesystems/update_filesystems_table.html'
success_url = 'horizon:admin:inventory:detail'
failure_url = 'horizon:admin:inventory:detail'
context_object_name = "filesystems"
def get_success_url(self):
return reverse(self.success_url,
args=(self.kwargs['host_id'],))
def get_failure_url(self):
return reverse(self.failure_url,
args=(self.kwargs['host_id'],))
def _get_object(self, *args, **kwargs):
if not hasattr(self, "_object"):
host_id = self.kwargs['host_id']
try:
host = stx_api.sysinv.host_get(self.request, host_id)
host.filesystems = stx_api.sysinv.host_filesystems_list(
self.request, host.uuid)
host.nodes = \
stx_api.sysinv.host_node_list(self.request, host.uuid)
self._object = host
self._object.host_id = host_id
except Exception as e:
LOG.exception(e)
redirect = reverse(self.failure_url,
args=host_id)
msg = _('Unable to retrieve host filesystems details')
exceptions.handle(self.request, msg, redirect=redirect)
return self._object
def get_context_data(self, **kwargs):
context = super(UpdateFilesystemsView, self).get_context_data(**kwargs)
host = self._get_object()
context['host_id'] = host.host_id
return context
def get_initial(self):
host = self._get_object()
fs_form_data = \
{fs.name.replace("-", "_"): fs.size for fs in host.filesystems}
fs_form_data.update({'host_uuid': host.uuid})
fs_form_data.update({'host_id': host.id})
return fs_form_data

View File

@ -20,6 +20,8 @@ from starlingx_dashboard.dashboards.admin.inventory.cpu_functions import \
tables as cpufunctions_tables
from starlingx_dashboard.dashboards.admin.inventory.devices import \
tables as device_tables
from starlingx_dashboard.dashboards.admin.inventory.filesystems import \
tables as filesystems_tables
from starlingx_dashboard.dashboards.admin.inventory.interfaces import \
tables as interface_tables
from starlingx_dashboard.dashboards.admin.inventory.kubernetes_labels import \
@ -699,8 +701,21 @@ class LabelsTab(tabs.TableTab):
return host.labels
class FilesystemsTab(tabs.TableTab):
table_classes = (filesystems_tables.FilesystemsTable, )
name = _("Filesystems")
slug = "filesystems"
template_name = ("admin/inventory/_detail_filesystems.html")
def get_filesystems_data(self):
host = self.tab_group.kwargs['host']
host.filesystems.sort(key=lambda f: (f.name))
return host.filesystems
class HostDetailTabs(tabs.TabGroup):
slug = "inventory_details"
tabs = (OverviewTab, CpuFunctionsTab, MemorysTab, StorageTab, PortsTab,
InterfacesTab, LldpTab, SensorTab, DevicesTab, LabelsTab, )
tabs = (OverviewTab, CpuFunctionsTab, MemorysTab, StorageTab,
FilesystemsTab, PortsTab, InterfacesTab, LldpTab, SensorTab,
DevicesTab, LabelsTab,)
sticky = True

View File

@ -0,0 +1,9 @@
{% load i18n sizeformat %}
{% block main %}
{% autoescape off %}
<div id="filesystems">
{{ filesystems_table.render }}
</div>
{% endautoescape %}
{% endblock %}

View File

@ -0,0 +1,32 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% block form_id %}edit_iconfig_form{% endblock %}
{% block form_action %}{% url 'horizon:admin:inventory:updatefilesystems' host_id %}{% endblock %}
{% block modal_id %}edit_iconfig_modal{% endblock %}
{% block modal-header %}{% trans "Edit Filesystems" %}{% endblock %}
{% block modal-body %}
<div class="left">
<fieldset>
{% include "horizon/common/_form_fields.html" %}
</fieldset>
</div>
<div class="right">
<h3>{% trans "Description" %}:</h3>
<p>{% trans "From here you can update the configuration of the host filesystems." %}</p>
<p>{% trans "WARNING: Filesystem sizes can not be decreased after configuration operation. " %}</p>
<p>{% trans "Major Alarms will be raised against the affected hosts until the configuration operation is successfully completed." %}</p>
</div>
{% endblock %}
{% block modal-footer %}
<a class="btn btn-default cancel" data-dismiss="modal">{% trans "Cancel" %}</a>
<input class="btn btn-primary btn-danger" type="submit" onclick="return confirm('WARNING:' +
'Filesystem sizes can not be decreased after configuration operation. ' +
'Major Alarms will be raised against the affected hosts until the configuration operation is successfully completed. ');"
value="{% trans "Save" %}" />
{% endblock %}

View File

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Edit Filesystem" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Edit Filesystem") %}
{% endblock page_header %}
{% block main %}
{% include "admin/system_config/_update_filesystems_table.html" %}
{% endblock %}

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2013-2018 Wind River Systems, Inc.
# Copyright (c) 2013-2019 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
@ -13,6 +13,8 @@ from starlingx_dashboard.dashboards.admin.inventory.cpu_functions import \
views as cpu_functions_views
from starlingx_dashboard.dashboards.admin.inventory.devices import \
views as device_views
from starlingx_dashboard.dashboards.admin.inventory.filesystems import \
views as fs_views
from starlingx_dashboard.dashboards.admin.inventory.interfaces.address import \
views as address_views
from starlingx_dashboard.dashboards.admin.inventory.interfaces.route import \
@ -155,5 +157,8 @@ urlpatterns = [
name='editpartition'),
url(r'^(?P<host_id>[^/]+)/assignlabel/$',
label_views.AssignLabelView.as_view(),
name='assignlabel')
name='assignlabel'),
url(r'^(?P<host_id>[^/]+)/updatefilesystems/$',
fs_views.UpdateFilesystemsView.as_view(),
name='updatefilesystems')
]

View File

@ -138,6 +138,9 @@ class DetailView(tabs.TabbedTableView):
host.partitions = stx_api.sysinv.host_disk_partition_list(
self.request, host.uuid)
host.filesystems = stx_api.sysinv.host_filesystems_list(
self.request, host.uuid)
# Translate partition state codes:
for p in host.partitions:
p.status = stx_api.sysinv.PARTITION_STATUS_MSG[p.status]