2008-08-08 01:37:16 +04:00
#
2013-10-28 00:59:46 +04:00
# Copyright (C) 2008, 2013 Red Hat, Inc.
2008-08-08 01:37:16 +04:00
# Copyright (C) 2008 Cole Robinson <crobinso@redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
#
2014-05-20 01:32:22 +04:00
import logging
2014-09-12 20:08:44 +04:00
import time
2014-05-20 01:32:22 +04:00
2013-09-29 17:31:39 +04:00
from virtinst import pollhelpers
2013-09-20 04:18:12 +04:00
from virtinst import StoragePool , StorageVolume
2013-08-09 17:23:01 +04:00
from virtinst import util
2013-07-12 18:53:30 +04:00
2014-09-13 00:10:45 +04:00
from . libvirtobject import vmmLibvirtObject
2013-09-20 04:18:12 +04:00
class vmmStorageVolume ( vmmLibvirtObject ) :
def __init__ ( self , conn , backend , key ) :
2013-09-23 16:34:50 +04:00
vmmLibvirtObject . __init__ ( self , conn , backend , key , StorageVolume )
2013-09-20 04:18:12 +04:00
##########################
# Required class methods #
##########################
2015-04-10 16:15:44 +03:00
def _conn_tick_poll_param ( self ) :
return None
def class_name ( self ) :
return " volume "
2013-09-20 04:18:12 +04:00
def _XMLDesc ( self , flags ) :
2014-05-20 01:32:22 +04:00
try :
return self . _backend . XMLDesc ( flags )
2017-05-05 19:47:21 +03:00
except Exception as e :
2014-05-20 01:32:22 +04:00
logging . debug ( " XMLDesc for vol= %s failed: %s " ,
self . _backend . key ( ) , e )
raise
2013-09-20 04:18:12 +04:00
2015-04-10 01:02:42 +03:00
def _get_backend_status ( self ) :
return self . _STATUS_ACTIVE
2015-04-10 16:15:44 +03:00
def tick ( self , stats_update = True ) :
2015-04-10 21:08:25 +03:00
# Deliberately empty
2015-04-10 16:15:44 +03:00
ignore = stats_update
2015-04-10 21:08:25 +03:00
def _init_libvirt_state ( self ) :
2015-04-11 00:50:06 +03:00
self . ensure_latest_xml ( )
2015-04-10 16:15:44 +03:00
2013-09-20 04:18:12 +04:00
###########
# Actions #
###########
def get_parent_pool ( self ) :
2014-06-03 01:17:47 +04:00
name = self . _backend . storagePoolLookupByVolume ( ) . name ( )
for pool in self . conn . list_pools ( ) :
if pool . get_name ( ) == name :
return pool
2013-09-20 04:18:12 +04:00
2013-09-30 23:23:14 +04:00
def delete ( self , force = True ) :
ignore = force
2013-09-20 04:18:12 +04:00
self . _backend . delete ( 0 )
self . _backend = None
#################
# XML accessors #
#################
2013-12-05 18:17:29 +04:00
def get_key ( self ) :
return self . get_xmlobj ( ) . key or " "
2013-09-20 04:18:12 +04:00
def get_target_path ( self ) :
2013-09-23 16:34:50 +04:00
return self . get_xmlobj ( ) . target_path or " "
2013-09-20 04:18:12 +04:00
def get_format ( self ) :
2013-09-23 16:34:50 +04:00
return self . get_xmlobj ( ) . format
2013-09-20 04:18:12 +04:00
def get_capacity ( self ) :
2013-09-23 16:34:50 +04:00
return self . get_xmlobj ( ) . capacity
2013-09-20 04:18:12 +04:00
def get_allocation ( self ) :
2013-09-23 16:34:50 +04:00
return self . get_xmlobj ( ) . allocation
2013-09-20 04:18:12 +04:00
def get_pretty_capacity ( self ) :
return util . pretty_bytes ( self . get_capacity ( ) )
def get_pretty_allocation ( self ) :
return util . pretty_bytes ( self . get_allocation ( ) )
2008-08-08 01:37:16 +04:00
2013-12-05 18:17:29 +04:00
def get_pretty_name ( self , pooltype ) :
name = self . get_name ( )
if pooltype != " iscsi " :
return name
key = self . get_key ( )
if not key :
return name
return " %s ( %s ) " % ( name , key )
2013-04-13 22:34:52 +04:00
2010-12-09 20:37:48 +03:00
class vmmStoragePool ( vmmLibvirtObject ) :
2012-05-14 17:24:56 +04:00
__gsignals__ = {
2018-03-15 15:10:09 +03:00
" refreshed " : ( vmmLibvirtObject . RUN_FIRST , None , [ ] )
2012-05-14 17:24:56 +04:00
}
2013-07-07 16:42:57 +04:00
def __init__ ( self , conn , backend , key ) :
2013-09-23 16:34:50 +04:00
vmmLibvirtObject . __init__ ( self , conn , backend , key , StoragePool )
2010-12-09 20:37:48 +03:00
2014-09-12 20:08:44 +04:00
self . _last_refresh_time = 0
2015-04-11 01:17:29 +03:00
self . _volumes = None
2013-07-07 16:05:23 +04:00
2013-09-20 04:18:12 +04:00
##########################
# Required class methods #
##########################
2015-04-10 16:15:44 +03:00
def _conn_tick_poll_param ( self ) :
return " pollpool "
def class_name ( self ) :
return " pool "
2010-12-09 20:37:48 +03:00
def _XMLDesc ( self , flags ) :
2013-07-07 16:42:57 +04:00
return self . _backend . XMLDesc ( flags )
2010-12-09 20:37:48 +03:00
def _define ( self , xml ) :
2013-07-07 16:42:57 +04:00
return self . conn . define_pool ( xml )
2016-06-15 00:52:40 +03:00
def _using_events ( self ) :
return self . conn . using_storage_pool_events
2015-04-10 01:02:42 +03:00
def _check_supports_isactive ( self ) :
return self . conn . check_support (
self . conn . SUPPORT_POOL_ISACTIVE , self . _backend )
def _get_backend_status ( self ) :
return self . _backend_get_active ( )
2008-08-08 01:37:16 +04:00
2015-04-10 16:15:44 +03:00
def tick ( self , stats_update = True ) :
ignore = stats_update
2015-04-10 02:03:27 +03:00
self . _refresh_status ( )
2013-09-20 04:18:12 +04:00
2015-04-10 21:08:25 +03:00
def _init_libvirt_state ( self ) :
self . tick ( )
2016-06-21 00:20:53 +03:00
if not self . conn . is_active ( ) :
# We only want to refresh a pool on initial conn startup,
# since the pools may be out of date. But if a storage pool
# shows up while the conn is connected, this means it was
# just 'defined' recently and doesn't need to be refreshed.
2016-06-22 22:58:07 +03:00
self . refresh ( _from_object_init = True )
2015-04-10 21:08:25 +03:00
for vol in self . get_volumes ( ) :
vol . init_libvirt_state ( )
2015-04-11 01:17:29 +03:00
def _invalidate_xml ( self ) :
vmmLibvirtObject . _invalidate_xml ( self )
self . _volumes = None
2008-08-08 01:37:16 +04:00
2015-04-10 01:02:42 +03:00
###########
# Actions #
###########
2013-07-07 19:06:15 +04:00
2015-04-10 01:27:45 +03:00
@vmmLibvirtObject.lifecycle_action
2008-08-08 01:37:16 +04:00
def start ( self ) :
2013-07-07 16:42:57 +04:00
self . _backend . create ( 0 )
2008-08-08 01:37:16 +04:00
2015-04-10 01:27:45 +03:00
@vmmLibvirtObject.lifecycle_action
2008-08-08 01:37:16 +04:00
def stop ( self ) :
2013-07-07 16:42:57 +04:00
self . _backend . destroy ( )
2008-08-08 01:37:16 +04:00
2015-04-10 01:27:45 +03:00
@vmmLibvirtObject.lifecycle_action
2013-10-01 02:26:43 +04:00
def delete ( self , force = True ) :
ignore = force
self . _backend . undefine ( )
2013-07-07 16:42:57 +04:00
self . _backend = None
2008-08-08 01:37:16 +04:00
2016-06-22 22:58:07 +03:00
def refresh ( self , _from_object_init = False ) :
2015-04-10 21:08:25 +03:00
"""
2016-06-22 22:58:07 +03:00
: param _from_object_init : Only used for the refresh ( ) call from
_init_libvirt_state . Tells us to not refresh the XML , since
we just updated it .
2015-04-10 21:08:25 +03:00
"""
2013-07-07 16:42:57 +04:00
if not self . is_active ( ) :
2010-04-21 18:56:06 +04:00
return
2013-07-07 16:42:57 +04:00
self . _backend . refresh ( 0 )
2016-06-22 22:58:07 +03:00
if self . _using_events ( ) and not _from_object_init :
# If we are using events, we let the event loop trigger
# the cache update for us. Except if from init_libvirt_state,
# we want the update to be done immediately
return
self . refresh_pool_cache_from_event_loop (
_from_object_init = _from_object_init )
def refresh_pool_cache_from_event_loop ( self , _from_object_init = False ) :
if not _from_object_init :
2015-04-11 00:50:06 +03:00
self . ensure_latest_xml ( )
2015-04-11 01:17:29 +03:00
self . _update_volumes ( force = True )
2014-09-12 02:59:27 +04:00
self . idle_emit ( " refreshed " )
2014-09-12 20:08:44 +04:00
self . _last_refresh_time = time . time ( )
2015-04-09 21:42:25 +03:00
def secs_since_last_refresh ( self ) :
return time . time ( ) - self . _last_refresh_time
2008-09-06 05:53:26 +04:00
2013-09-20 04:18:12 +04:00
###################
# Volume handling #
###################
2014-09-12 17:55:12 +04:00
def get_volumes ( self ) :
2015-04-11 01:17:29 +03:00
self . _update_volumes ( force = False )
2015-04-10 19:52:42 +03:00
return self . _volumes [ : ]
2013-09-20 04:18:12 +04:00
2014-06-03 01:17:47 +04:00
def get_volume ( self , key ) :
2015-04-10 19:52:42 +03:00
for vol in self . get_volumes ( ) :
if vol . get_connkey ( ) == key :
return vol
return None
2013-09-20 04:18:12 +04:00
2015-04-11 01:17:29 +03:00
def _update_volumes ( self , force ) :
2008-08-08 01:37:16 +04:00
if not self . is_active ( ) :
2015-04-10 19:52:42 +03:00
self . _volumes = [ ]
2008-08-08 01:37:16 +04:00
return
2015-04-11 01:17:29 +03:00
if not force and self . _volumes is not None :
return
2008-08-08 01:37:16 +04:00
2016-06-22 22:58:07 +03:00
keymap = dict ( ( o . get_connkey ( ) , o ) for o in self . _volumes or [ ] )
2014-09-12 19:55:34 +04:00
( ignore , ignore , allvols ) = pollhelpers . fetch_volumes (
2015-04-10 19:52:42 +03:00
self . conn . get_backend ( ) , self . get_backend ( ) , keymap ,
2013-09-29 17:31:39 +04:00
lambda obj , key : vmmStorageVolume ( self . conn , obj , key ) )
self . _volumes = allvols
2013-09-20 04:18:12 +04:00
2015-04-10 01:02:42 +03:00
#########################
# XML/config operations #
#########################
def set_autostart ( self , value ) :
self . _backend . setAutostart ( value )
def get_autostart ( self ) :
return self . _backend . autostart ( )
def can_change_alloc ( self ) :
typ = self . get_type ( )
2016-08-09 18:48:34 +03:00
return ( typ in [ StoragePool . TYPE_LOGICAL , StoragePool . TYPE_ZFS ] )
2015-04-10 01:02:42 +03:00
def supports_volume_creation ( self ) :
return self . get_xmlobj ( ) . supports_volume_creation ( )
2013-09-20 04:18:12 +04:00
def get_type ( self ) :
2013-09-23 16:34:50 +04:00
return self . get_xmlobj ( ) . type
2013-09-20 04:18:12 +04:00
def get_uuid ( self ) :
2013-09-23 16:34:50 +04:00
return self . get_xmlobj ( ) . uuid
2013-09-20 04:18:12 +04:00
def get_target_path ( self ) :
2013-09-23 16:34:50 +04:00
return self . get_xmlobj ( ) . target_path or " "
2013-09-20 04:18:12 +04:00
def get_allocation ( self ) :
2013-09-23 16:34:50 +04:00
return self . get_xmlobj ( ) . allocation
2013-09-20 04:18:12 +04:00
def get_available ( self ) :
2013-09-23 16:34:50 +04:00
return self . get_xmlobj ( ) . available
2013-09-20 04:18:12 +04:00
def get_capacity ( self ) :
2013-09-23 16:34:50 +04:00
return self . get_xmlobj ( ) . capacity
2013-09-20 04:18:12 +04:00
def get_pretty_allocation ( self ) :
return util . pretty_bytes ( self . get_allocation ( ) )
def get_pretty_available ( self ) :
return util . pretty_bytes ( self . get_available ( ) )
def get_pretty_capacity ( self ) :
return util . pretty_bytes ( self . get_capacity ( ) )