Merge "Create new host_fs postgres table"

This commit is contained in:
Zuul 2019-07-02 19:53:46 +00:00 committed by Gerrit Code Review
commit 77b492c2e7
13 changed files with 519 additions and 16 deletions

View File

@ -1,2 +1,2 @@
SRC_DIR="sysinv" SRC_DIR="sysinv"
TIS_PATCH_VER=325 TIS_PATCH_VER=326

View File

@ -17,7 +17,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.
# #
@ -146,12 +146,14 @@ class AgentManager(service.PeriodicService):
self._iconfig_read_config_reported = None self._iconfig_read_config_reported = None
self._ihost_personality = None self._ihost_personality = None
self._ihost_uuid = "" self._ihost_uuid = ""
self._ihost_rootfs_device = ""
self._agent_throttle = 0 self._agent_throttle = 0
self._mgmt_ip = None self._mgmt_ip = None
self._prev_disk = None self._prev_disk = None
self._prev_partition = None self._prev_partition = None
self._prev_lvg = None self._prev_lvg = None
self._prev_pv = None self._prev_pv = None
self._prev_fs = None
self._subfunctions = None self._subfunctions = None
self._subfunctions_configured = False self._subfunctions_configured = False
self._notify_subfunctions_alarm_clear = False self._notify_subfunctions_alarm_clear = False
@ -745,6 +747,7 @@ class AgentManager(service.PeriodicService):
self._ihost_uuid = ihost['uuid'] self._ihost_uuid = ihost['uuid']
self._ihost_personality = ihost['personality'] self._ihost_personality = ihost['personality']
self._mgmt_ip = ihost['mgmt_ip'] self._mgmt_ip = ihost['mgmt_ip']
self._ihost_rootfs_device = ihost['rootfs_device']
if os.path.isfile(tsc.PLATFORM_CONF_FILE): if os.path.isfile(tsc.PLATFORM_CONF_FILE):
# read the platform config file and check for UUID # read the platform config file and check for UUID
@ -1157,8 +1160,8 @@ class AgentManager(service.PeriodicService):
LOG.debug("SysInv Agent Audit running.") LOG.debug("SysInv Agent Audit running.")
if force_updates: if force_updates:
LOG.debug("SysInv Agent Audit force updates: (%s)" % LOG.info("SysInv Agent Audit force updates: (%s)" %
(', '.join(force_updates))) (', '.join(force_updates)))
self._update_ttys_dcd_status(icontext, self._ihost_uuid) self._update_ttys_dcd_status(icontext, self._ihost_uuid)
if self._agent_throttle > 5: if self._agent_throttle > 5:
@ -1182,7 +1185,7 @@ class AgentManager(service.PeriodicService):
self._prev_disk = None self._prev_disk = None
# if this audit is requested by conductor, clear # if this audit is requested by conductor, clear
# previous states for disk, lvg and pv to force an update # previous states for disk, lvg, pv and fs to force an update
if force_updates: if force_updates:
if constants.DISK_AUDIT_REQUEST in force_updates: if constants.DISK_AUDIT_REQUEST in force_updates:
self._prev_disk = None self._prev_disk = None
@ -1192,6 +1195,8 @@ class AgentManager(service.PeriodicService):
self._prev_pv = None self._prev_pv = None
if constants.PARTITION_AUDIT_REQUEST in force_updates: if constants.PARTITION_AUDIT_REQUEST in force_updates:
self._prev_partition = None self._prev_partition = None
if constants.FILESYSTEM_AUDIT_REQUEST in force_updates:
self._prev_fs = None
# Update disks # Update disks
idisk = self._idisk_operator.idisk_get() idisk = self._idisk_operator.idisk_get()
@ -1250,6 +1255,55 @@ class AgentManager(service.PeriodicService):
self._prev_lvg = None self._prev_lvg = None
pass pass
# Update the filesystems
# Get the supported filesystems for this host
filesystems = []
# check if the scratch fs is supported for current host
if utils.is_filesystem_supported(constants.FILESYSTEM_NAME_SCRATCH, self._ihost_personality):
scratch_lv_size = utils.get_controller_fs_scratch_size()
data = {
'name': constants.FILESYSTEM_NAME_SCRATCH,
'size': scratch_lv_size,
'logical_volume': constants.FILESYSTEM_LV_DICT[
constants.FILESYSTEM_NAME_SCRATCH]
}
filesystems.append(data)
# check if the backup fs is supported for current host
if utils.is_filesystem_supported(constants.FILESYSTEM_NAME_BACKUP, self._ihost_personality):
backup_lv_size = utils.get_controller_fs_backup_size(self._ihost_rootfs_device)
data = {
'name': constants.FILESYSTEM_NAME_BACKUP,
'size': backup_lv_size,
'logical_volume': constants.FILESYSTEM_LV_DICT[
constants.FILESYSTEM_NAME_BACKUP]
}
filesystems.append(data)
# check if the docker fs is supported for current host
if utils.is_filesystem_supported(constants.FILESYSTEM_NAME_DOCKER, self._ihost_personality):
data = {
'name': constants.FILESYSTEM_NAME_DOCKER,
'size': constants.KUBERNETES_DOCKER_STOR_SIZE,
'logical_volume': constants.FILESYSTEM_LV_DICT[
constants.FILESYSTEM_NAME_DOCKER]
}
filesystems.append(data)
if filesystems and ((self._prev_fs is None) or (self._prev_fs != filesystems)):
try:
rpcapi.create_host_filesystems(icontext,
self._ihost_uuid,
filesystems)
self._prev_fs = filesystems
except exception.SysinvException:
LOG.exception("Sysinv Agent exception updating fs"
"conductor.")
self._prev_fs = None
pass
self._report_config_applied(icontext) self._report_config_applied(icontext)
if os.path.isfile(tsc.PLATFORM_CONF_FILE): if os.path.isfile(tsc.PLATFORM_CONF_FILE):

View File

@ -526,6 +526,26 @@ FILESYSTEM_LV_DICT = {
FILESYSTEM_NAME_PATCH_VAULT: 'patch-vault-lv', FILESYSTEM_NAME_PATCH_VAULT: 'patch-vault-lv',
} }
FILESYSTEM_CONTROLLER_SUPPORTED_LIST = [
FILESYSTEM_NAME_SCRATCH,
FILESYSTEM_NAME_BACKUP,
FILESYSTEM_NAME_DOCKER,
]
FILESYSTEM_WORKER_SUPPORTED_LIST = [
FILESYSTEM_NAME_DOCKER,
]
FILESYSTEM_STORAGE_SUPPORTED_LIST = [
FILESYSTEM_NAME_DOCKER,
]
FILESYSTEM_HOSTS_SUPPORTED_LIST_DICT = {
CONTROLLER: FILESYSTEM_CONTROLLER_SUPPORTED_LIST,
WORKER: FILESYSTEM_WORKER_SUPPORTED_LIST,
STORAGE: FILESYSTEM_STORAGE_SUPPORTED_LIST,
}
SUPPORTED_LOGICAL_VOLUME_LIST = FILESYSTEM_LV_DICT.values() SUPPORTED_LOGICAL_VOLUME_LIST = FILESYSTEM_LV_DICT.values()
SUPPORTED_FILEYSTEM_LIST = [ SUPPORTED_FILEYSTEM_LIST = [
@ -594,10 +614,12 @@ DISK_AUDIT_REQUEST = "audit_disk"
LVG_AUDIT_REQUEST = "audit_lvg" LVG_AUDIT_REQUEST = "audit_lvg"
PV_AUDIT_REQUEST = "audit_pv" PV_AUDIT_REQUEST = "audit_pv"
PARTITION_AUDIT_REQUEST = "audit_partition" PARTITION_AUDIT_REQUEST = "audit_partition"
FILESYSTEM_AUDIT_REQUEST = "audit_fs"
CONTROLLER_AUDIT_REQUESTS = [DISK_AUDIT_REQUEST, CONTROLLER_AUDIT_REQUESTS = [DISK_AUDIT_REQUEST,
LVG_AUDIT_REQUEST, LVG_AUDIT_REQUEST,
PV_AUDIT_REQUEST, PV_AUDIT_REQUEST,
PARTITION_AUDIT_REQUEST] PARTITION_AUDIT_REQUEST,
FILESYSTEM_AUDIT_REQUEST]
# Interface definitions # Interface definitions
NETWORK_TYPE_NONE = 'none' NETWORK_TYPE_NONE = 'none'

View File

@ -1,6 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4 # vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2013-2018 Wind River Systems, Inc. # Copyright (c) 2013-2019 Wind River Systems, Inc.
# Copyright 2010 United States Government as represented by the # Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration. # Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved. # All Rights Reserved.
@ -1364,3 +1364,11 @@ class UnsupportedAssignedInterfaceDataNetworkType(Conflict):
class UnsupportedRemovedInterfaceDataNetworkType(Conflict): class UnsupportedRemovedInterfaceDataNetworkType(Conflict):
message = _("Cannot remove datanetwork with type '%(network_type)s' " message = _("Cannot remove datanetwork with type '%(network_type)s' "
"from an interface.") "from an interface.")
class FilesystemAlreadyExists(Conflict):
message = _("A Host FS with name %(name)s already exists.")
class FilesystemNotFound(NotFound):
message = _("No Host FS with id %(fs_id)s not found")

View File

@ -1605,6 +1605,16 @@ def get_dhcp_client_iaid(mac_address):
return hwaddr[2] << 24 | hwaddr[3] << 16 | hwaddr[4] << 8 | hwaddr[5] return hwaddr[2] << 24 | hwaddr[3] << 16 | hwaddr[4] << 8 | hwaddr[5]
def is_filesystem_supported(fs, personality):
""" Check to see if a filesystem is supported for the host personality.
"""
if personality in constants.FILESYSTEM_HOSTS_SUPPORTED_LIST_DICT:
if fs in constants.FILESYSTEM_HOSTS_SUPPORTED_LIST_DICT[personality]:
return True
return False
def get_controller_fs_scratch_size(): def get_controller_fs_scratch_size():
""" Get the filesystem scratch size setup by kickstart. """ Get the filesystem scratch size setup by kickstart.
""" """
@ -1636,6 +1646,38 @@ def get_controller_fs_scratch_size():
return scratch_gib return scratch_gib
def get_controller_fs_backup_size(rootfs_device):
""" Get the filesystem backup size.
"""
disk_size = get_disk_capacity_mib(rootfs_device)
disk_size = int(disk_size / 1024)
if disk_size > constants.DEFAULT_SMALL_DISK_SIZE:
LOG.debug("Disk size : %s ... large disk defaults" % disk_size)
database_storage = constants.DEFAULT_DATABASE_STOR_SIZE
cgcs_lv_size = constants.DEFAULT_CGCS_STOR_SIZE
backup_lv_size = database_storage + cgcs_lv_size + \
constants.BACKUP_OVERHEAD
elif disk_size >= constants.MINIMUM_DISK_SIZE:
LOG.debug("Disk size : %s ... small disk defaults" % disk_size)
# Due to the small size of the disk we can't provide the
# proper amount of backup space which is (database + cgcs_lv
# + BACKUP_OVERHEAD) so we are using a smaller default.
backup_lv_size = constants.DEFAULT_SMALL_BACKUP_STOR_SIZE
else:
LOG.info("Disk size : %s ... disk too small" % disk_size)
raise exception.SysinvException("Disk size requirements not met.")
return backup_lv_size
def get_cgts_vg_free_space(): def get_cgts_vg_free_space():
"""Determine free space in cgts-vg""" """Determine free space in cgts-vg"""

View File

@ -3299,6 +3299,61 @@ class ConductorManager(service.PeriodicService):
return return
def create_host_filesystems(self, context,
ihost_uuid, fs_dict_array):
"""Create a filesystems for an ihost with the supplied data.
This method allows records for filesystems for ihost to be
created.
:param context: an admin context
:param ihost_uuid: ihost uuid unique id
:param fs_dict_array: initial values for filesystems group objects
:returns: pass or fail
"""
ihost_uuid.strip()
try:
ihost = self.dbapi.ihost_get(ihost_uuid)
except exception.ServerNotFound:
LOG.exception("Invalid ihost_uuid %s" % ihost_uuid)
return
host_fs_list = self.dbapi.host_fs_get_by_ihost(ihost_uuid)
forihostid = ihost['id']
for fs in fs_dict_array:
fs_dict = {
'forihostid': forihostid,
}
fs_dict.update(fs)
found = False
for host_fs in host_fs_list:
if host_fs.name == fs['name']:
found = True
LOG.debug("Host FS '%s' already exists" % fs['name'])
if host_fs.size != fs['size']:
LOG.info("Host FS uuid: %s changed size from %s to %s",
host_fs.uuid, host_fs.size, fs['size'])
# Update the database
try:
self.dbapi.host_fs_update(host_fs.id, fs_dict)
except Exception:
LOG.exception("Host FS Update failed")
break
if not found:
try:
LOG.info("Creating Host FS:%s:%s %d for host id %d" %
(fs_dict['name'], fs_dict['logical_volume'],
fs_dict['size'], fs_dict['forihostid']))
self.dbapi.host_fs_create(forihostid, fs_dict)
except Exception:
LOG.exception("Host FS Creation failed")
return
def _fill_partition_info(self, db_part, ipart): def _fill_partition_info(self, db_part, ipart):
db_part_dict = db_part.as_dict() db_part_dict = db_part.as_dict()
keys = ['start_mib', 'end_mib', 'size_mib', 'type_name', 'type_guid'] keys = ['start_mib', 'end_mib', 'size_mib', 'type_name', 'type_guid']
@ -4157,7 +4212,7 @@ class ConductorManager(service.PeriodicService):
@periodic_task.periodic_task(spacing=CONF.conductor.audit_interval) @periodic_task.periodic_task(spacing=CONF.conductor.audit_interval)
def _agent_update_request(self, context): def _agent_update_request(self, context):
""" """
Check DB for inventory objects with an inconsistent state and Check DB for inventory objects with an inconsistent state and
request an update from sysinv agent. request an update from sysinv agent.
Currently requesting updates for: Currently requesting updates for:
- ipv: if state is not 'provisioned' - ipv: if state is not 'provisioned'
@ -4209,6 +4264,9 @@ class ConductorManager(service.PeriodicService):
ilvgs = self.dbapi.ilvg_get_by_ihost(host.uuid) ilvgs = self.dbapi.ilvg_get_by_ihost(host.uuid)
if not ilvgs: if not ilvgs:
update_hosts_dict(host.id, constants.LVG_AUDIT_REQUEST) update_hosts_dict(host.id, constants.LVG_AUDIT_REQUEST)
host_fs = self.dbapi.host_fs_get_by_ihost(host.uuid)
if not host_fs:
update_hosts_dict(host.id, constants.FILESYSTEM_AUDIT_REQUEST)
# Check partitions. # Check partitions.
partitions = self.dbapi.partition_get_all() partitions = self.dbapi.partition_get_all()

View File

@ -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-2018 Wind River Systems, Inc. # Copyright (c) 2013-2019 Wind River Systems, Inc.
# #
""" """
@ -176,6 +176,24 @@ class ConductorAPI(sysinv.openstack.common.rpc.proxy.RpcProxy):
self.make_msg('create_controller_filesystems', self.make_msg('create_controller_filesystems',
rootfs_device=rootfs_device)) rootfs_device=rootfs_device))
def create_host_filesystems(self, context, ihost_uuid, fs_dict_array):
"""Create or update the filesystem for an ihost with the supplied
data.
This method allows records for a filesystem for ihost to be
created, or updated.
:param context: an admin context
:param ihost_uuid: ihost uuid unique id
:param fs_dict_array: initial values for the filesystems
:returns: pass or fail
"""
return self.call(context,
self.make_msg('create_host_filesystems',
ihost_uuid=ihost_uuid,
fs_dict_array=fs_dict_array))
def get_ihost_by_macs(self, context, ihost_macs): def get_ihost_by_macs(self, context, ihost_macs):
"""Finds ihost db entry based upon the mac list """Finds ihost db entry based upon the mac list

View File

@ -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-2018 Wind River Systems, Inc. # Copyright (c) 2013-2019 Wind River Systems, Inc.
# #
@ -2228,9 +2228,10 @@ class Connection(object):
:param values: A dict containing several items used to identify :param values: A dict containing several items used to identify
and track the controller_fs. and track the controller_fs.
Example: Example:
values = {'name': constants.DEFAULT_DOCKER_STOR_SIZE, values = {'name': constants.FILESYSTEM_NAME_DOCKER,
'size': 30, 'size': 30,
'logical_volume': constants.FILESYSTEM_NAME_LV_DICT, 'logical_volume': constants.FILESYSTEM_LV_DICT[
constants.FILESYSTEM_NAME_DOCKER],
'replicated': False} 'replicated': False}
:returns: A controller_fs. :returns: A controller_fs.
""" """
@ -4339,3 +4340,86 @@ class Connection(object):
:param uuid: The uuid of an interface network association. :param uuid: The uuid of an interface network association.
""" """
@abc.abstractmethod
def host_fs_create(self, forihostid, values):
"""Create a new filesystem for a host.
:param forihostid: uuid or id of an ihost
:param values: A dict containing several items used to identify
and track the filesystem.
Example:
values = {'name': constants.FILESYSTEM_NAME_DOCKER,
'size': 30,
'logical_volume': constants.FILESYSTEM_LV_DICT[
constants.FILESYSTEM_NAME_DOCKER],
'forihostid': 1}
:returns: A filesystem.
"""
@abc.abstractmethod
def host_fs_get(self, fs_id):
"""Return a filesystem.
:param fs_id: The id or uuid of a filesystem.
:returns: A filesystem.
"""
@abc.abstractmethod
def host_fs_get_all(self, forihostid=None):
"""Return filesystems.
:param forihostid: The id or uuid of an ihost.
:returns: filesystem.
"""
@abc.abstractmethod
def host_fs_get_list(self, limit=None, marker=None,
sort_key=None, sort_dir=None):
"""Return a list of filesystems.
:param limit: Maximum number of filesystems to return.
:param marker: the last item of the previous page; we return the next
result set.
:param sort_key: Attribute by which results should be sorted.
:param sort_dir: direction in which results should be sorted.
(asc, desc)
"""
@abc.abstractmethod
def host_fs_get_by_ihost(self, ihost, limit=None,
marker=None, sort_key=None,
sort_dir=None):
"""List all the filesystems for a given ihost.
:param ihost: The id or uuid of an ihost.
:param marker: the last item of the previous page; we return the next
result set.
:param sort_key: Attribute by which results should be sorted
:param sort_dir: direction in which results should be sorted
(asc, desc)
:returns: A list of filesystems.
"""
@abc.abstractmethod
def host_fs_update(self, fs_id, values):
"""Update properties of a filesystem.
:param fs_id: The id or uuid of an filesystem.
:param values: Dict of values to update. May be a partial list.
Example:
values = {'name': constants.FILESYSTEM_NAME_DOCKER,
'size': 30,
'logical_volume': constants.FILESYSTEM_LV_DICT[
constants.FILESYSTEM_NAME_DOCKER
],
'forihostid': 1}
:returns: A filesystem.
"""
@abc.abstractmethod
def host_fs_destroy(self, fs_id):
"""Destroy a filesystem.
:param fs_id: The id or uuid of a filesystem.
"""

View File

@ -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.
# #
"""SQLAlchemy storage backend.""" """SQLAlchemy storage backend."""
@ -148,7 +148,8 @@ def add_identity_filter(query, value,
use_sensorgroupname=False, use_sensorgroupname=False,
use_sensorname=False, use_sensorname=False,
use_cluster_uuid=False, use_cluster_uuid=False,
use_pciaddr=False): use_pciaddr=False,
use_fsname=False):
"""Adds an identity filter to a query. """Adds an identity filter to a query.
Filters results by ID, if supplied value is a valid integer. Filters results by ID, if supplied value is a valid integer.
@ -189,6 +190,8 @@ def add_identity_filter(query, value,
return query.filter_by(sensorname=value) return query.filter_by(sensorname=value)
elif use_pciaddr: elif use_pciaddr:
return query.filter_by(pciaddr=value) return query.filter_by(pciaddr=value)
elif use_fsname:
return query.filter_by(name=value)
else: else:
return query.filter_by(hostname=value) return query.filter_by(hostname=value)
@ -1121,6 +1124,25 @@ def add_label_filter_by_host(query, hostid):
return query.filter(models.ihost.uuid == hostid) return query.filter(models.ihost.uuid == hostid)
def add_host_fs_filter(query, value):
"""Adds an fs-specific filter to a query.
:param query: Initial query to add filter to.
:param value: Value for filtering results by.
:return: Modified query.
"""
return add_identity_filter(query, value, use_fsname=True)
def add_host_fs_filter_by_ihost(query, value):
if utils.is_int_like(value):
return query.filter_by(forihostid=value)
else:
query = query.join(models.ihost,
models.HostFs.forihostid == models.ihost.id)
return query.filter(models.ihost.uuid == value)
class Connection(api.Connection): class Connection(api.Connection):
"""SqlAlchemy connection.""" """SqlAlchemy connection."""
@ -7934,3 +7956,82 @@ class Connection(api.Connection):
@objects.objectify(objects.interface_datanetwork) @objects.objectify(objects.interface_datanetwork)
def interface_datanetwork_query(self, values): def interface_datanetwork_query(self, values):
return self._interface_datanetwork_query(values) return self._interface_datanetwork_query(values)
def _host_fs_get(self, fs_id):
query = model_query(models.HostFs)
query = add_identity_filter(query, fs_id)
try:
result = query.one()
except NoResultFound:
raise exception.FilesystemNotFound(fs_id=fs_id)
return result
@objects.objectify(objects.host_fs)
def host_fs_create(self, forihostid, values):
if not values.get('uuid'):
values['uuid'] = uuidutils.generate_uuid()
values['forihostid'] = int(forihostid)
fs = models.HostFs()
fs.update(values)
with _session_for_write() as session:
try:
session.add(fs)
session.flush()
except db_exc.DBDuplicateEntry:
raise exception.FilesystemAlreadyExists(
name=values['name'], host=forihostid)
return self._host_fs_get(values['uuid'])
@objects.objectify(objects.host_fs)
def host_fs_get_all(self, forihostid=None):
query = model_query(models.HostFs, read_deleted="no")
if forihostid:
query = query.filter_by(forihostid=forihostid)
return query.all()
@objects.objectify(objects.host_fs)
def host_fs_get(self, fs_id):
return self._host_fs_get(fs_id)
@objects.objectify(objects.host_fs)
def host_fs_get_list(self, limit=None, marker=None,
sort_key=None, sort_dir=None):
return _paginate_query(models.HostFs, limit, marker,
sort_key, sort_dir)
@objects.objectify(objects.host_fs)
def host_fs_get_by_ihost(self, ihost, limit=None, marker=None,
sort_key=None, sort_dir=None):
query = model_query(models.HostFs)
query = add_host_fs_filter_by_ihost(query, ihost)
return _paginate_query(models.HostFs, limit, marker,
sort_key, sort_dir, query)
@objects.objectify(objects.host_fs)
def host_fs_update(self, fs_id, values):
with _session_for_write() as session:
query = model_query(models.HostFs, read_deleted="no",
session=session)
query = add_host_fs_filter(query, fs_id)
count = query.update(values, synchronize_session='fetch')
if count != 1:
raise exception.FilesystemNotFound(fs_id=fs_id)
return query.one()
def host_fs_destroy(self, fs_id):
with _session_for_write() as session:
# Delete physically since it has unique columns
if uuidutils.is_uuid_like(fs_id):
model_query(models.HostFs, read_deleted="no",
session=session).\
filter_by(uuid=fs_id).\
delete()
else:
model_query(models.HostFs, read_deleted="no").\
filter_by(id=fs_id).\
delete()

View File

@ -0,0 +1,61 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (c) 2019 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
from sqlalchemy import DateTime, String, Integer
from sqlalchemy import Column, MetaData, Table, ForeignKey
from sysinv.openstack.common import log
ENGINE = 'InnoDB'
CHARSET = 'utf8'
LOG = log.getLogger(__name__)
def upgrade(migrate_engine):
"""
This database upgrade creates a new host_fs table for storing
filesystem info for a host.
"""
meta = MetaData()
meta.bind = migrate_engine
Table('i_host',
meta,
Column('id', Integer, primary_key=True, nullable=False),
mysql_engine=ENGINE, mysql_charset=CHARSET, autoload=True)
# Define and create the host_fs table.
fs_app = Table(
'host_fs',
meta,
Column('created_at', DateTime),
Column('updated_at', DateTime),
Column('deleted_at', DateTime),
Column('id', Integer, primary_key=True, nullable=False),
Column('uuid', String(36), unique=True),
Column('name', String(255)),
Column('size', Integer),
Column('logical_volume', String(64)),
Column('forihostid', Integer,
ForeignKey('i_host.id', ondelete='CASCADE')),
mysql_engine=ENGINE,
mysql_charset=CHARSET,
)
fs_app.create()
def downgrade(migrate_engine):
meta = MetaData()
meta.bind = migrate_engine
# Downgrade is unsupported in this release.
raise NotImplementedError('SysInv database downgrade is unsupported.')

View File

@ -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.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -1721,3 +1721,17 @@ class KubeAppReleases(Base):
app_id = Column(Integer, ForeignKey('kube_app.id', ondelete='CASCADE')) app_id = Column(Integer, ForeignKey('kube_app.id', ondelete='CASCADE'))
kube_app = relationship("KubeApp", lazy="joined", join_depth=1) kube_app = relationship("KubeApp", lazy="joined", join_depth=1)
UniqueConstraint('release', 'namespace', 'app_id', name='u_app_release_namespace') UniqueConstraint('release', 'namespace', 'app_id', name='u_app_release_namespace')
class HostFs(Base):
__tablename__ = 'host_fs'
id = Column(Integer, primary_key=True)
uuid = Column(String(36))
name = Column(String(64))
size = Column(Integer)
logical_volume = Column(String(64))
forihostid = Column(Integer, ForeignKey('i_host.id', ondelete='CASCADE'))
host = relationship("ihost", lazy="joined", join_depth=1)

View File

@ -12,7 +12,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.
# #
@ -88,6 +88,7 @@ from sysinv.objects import storage_file
from sysinv.objects import storage_external from sysinv.objects import storage_external
from sysinv.objects import storage_tier from sysinv.objects import storage_tier
from sysinv.objects import storage_ceph_external from sysinv.objects import storage_ceph_external
from sysinv.objects import host_fs
def objectify(klass): def objectify(klass):
@ -185,6 +186,7 @@ label = label.Label
kube_app = kube_app.KubeApp kube_app = kube_app.KubeApp
kube_app_releases = kube_app_releases.KubeAppReleases kube_app_releases = kube_app_releases.KubeAppReleases
datanetwork = datanetwork.DataNetwork datanetwork = datanetwork.DataNetwork
host_fs = host_fs.HostFS
__all__ = (system, __all__ = (system,
cluster, cluster,
@ -254,6 +256,7 @@ __all__ = (system,
kube_app_releases, kube_app_releases,
datanetwork, datanetwork,
interface_network, interface_network,
host_fs,
# alias objects for RPC compatibility # alias objects for RPC compatibility
ihost, ihost,
ilvg, ilvg,

View File

@ -0,0 +1,38 @@
#
# Copyright (c) 2019 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# coding=utf-8
#
from sysinv.db import api as db_api
from sysinv.objects import base
from sysinv.objects import utils
class HostFS(base.SysinvObject):
dbapi = db_api.get_instance()
fields = {
'id': int,
'uuid': utils.str_or_none,
'name': utils.str_or_none,
'size': utils.int_or_none,
'logical_volume': utils.str_or_none,
'forihostid': int,
'ihost_uuid': utils.str_or_none,
}
_foreign_fields = {'ihost_uuid': 'host:uuid'}
@base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
return cls.dbapi.host_fs_get(uuid)
def save_changes(self, context, updates):
self.dbapi.host_fs_update(self.uuid, updates)