Implement SR-IOV VF config set

Also fixes some random bugs, adds proper interface sorting, and assorted
tweaks.
This commit is contained in:
Joshua Boniface 2021-06-21 18:40:11 -04:00
parent e13baf8bd3
commit 13cc0f986f
8 changed files with 322 additions and 243 deletions

View File

@ -2923,6 +2923,93 @@ class API_SRIOV_VF_Element(Resource):
else: else:
return {'message': "No VF '{}' found on node '{}'".format(vf, node)}, 404 return {'message': "No VF '{}' found on node '{}'".format(vf, node)}, 404
@RequestParser([
{'name': 'vlan_id'},
{'name': 'vlan_qos'},
{'name': 'tx_rate_min'},
{'name': 'tx_rate_max'},
{'name': 'link_state', 'choices': ('auto', 'enable', 'disable'), 'helptext': "A valid state must be specified"},
{'name': 'spoof_check'},
{'name': 'trust'},
{'name': 'query_rss'},
])
@Authenticator
def put(self, node, vf, reqargs):
"""
Set the configuration of {vf} on {node}
---
tags:
- network / sriov
parameters:
- in: query
name: vlan_id
type: integer
required: false
description: The vLAN ID for vLAN tagging (0 is disabled)
- in: query
name: vlan_qos
type: integer
required: false
description: The vLAN QOS priority (0 is disabled)
- in: query
name: tx_rate_min
type: integer
required: false
description: The minimum TX rate (0 is disabled)
- in: query
name: tx_rate_max
type: integer
required: false
description: The maximum TX rate (0 is disabled)
- in: query
name: link_state
type: string
required: false
description: The administrative link state
enum:
- auto
- enable
- disable
- in: query
name: spoof_check
type: boolean
required: false
description: Enable or disable spoof checking
- in: query
name: trust
type: boolean
required: false
description: Enable or disable VF user trust
- in: query
name: query_rss
type: boolean
required: false
description: Enable or disable query RSS support
responses:
200:
description: OK
schema:
type: object
id: Message
400:
description: Bad request
schema:
type: object
id: Message
"""
return api_helper.update_sriov_vf_config(
node,
vf,
reqargs.get('vlan_id', None),
reqargs.get('vlan_qos', None),
reqargs.get('tx_rate_min', None),
reqargs.get('tx_rate_max', None),
reqargs.get('link_state', None),
reqargs.get('spoof_check', None),
reqargs.get('trust', None),
reqargs.get('query_rss', None),
)
api.add_resource(API_SRIOV_VF_Element, '/sriov/vf/<node>/<vf>') api.add_resource(API_SRIOV_VF_Element, '/sriov/vf/<node>/<vf>')

View File

@ -1034,6 +1034,24 @@ def sriov_vf_list(zkhandler, node, pf=None):
return retdata, retcode return retdata, retcode
@ZKConnection(config)
def update_sriov_vf_config(zkhandler, node, vf, vlan_id, vlan_qos, tx_rate_min, tx_rate_max, link_state, spoof_check, trust, query_rss):
"""
Update configuration of a VF on NODE.
"""
retflag, retdata = pvc_network.set_sriov_vf_config(zkhandler, node, vf, vlan_id, vlan_qos, tx_rate_min, tx_rate_max, link_state, spoof_check, trust, query_rss)
if retflag:
retcode = 200
else:
retcode = 400
output = {
'message': retdata.replace('\"', '\'')
}
return output, retcode
# #
# Ceph functions # Ceph functions
# #

View File

@ -385,7 +385,7 @@ def net_sriov_pf_list(config, node):
List all PFs on NODE List all PFs on NODE
API endpoint: GET /api/v1/sriov/pf/<node> API endpoint: GET /api/v1/sriov/pf/<node>
API arguments: node=node API arguments: node={node}
API schema: [{json_data_object},{json_data_object},etc.] API schema: [{json_data_object},{json_data_object},etc.]
""" """
response = call_api(config, 'get', '/sriov/pf/{}'.format(node)) response = call_api(config, 'get', '/sriov/pf/{}'.format(node))
@ -396,12 +396,59 @@ def net_sriov_pf_list(config, node):
return False, response.json().get('message', '') return False, response.json().get('message', '')
def net_sriov_vf_set(config, node, vf, vlan_id, vlan_qos, tx_rate_min, tx_rate_max, link_state, spoof_check, trust, query_rss):
"""
Mdoify configuration of a SR-IOV VF
API endpoint: PUT /api/v1/sriov/vf/<node>/<vf>
API arguments: vlan_id={vlan_id}, vlan_qos={vlan_qos}, tx_rate_min={tx_rate_min}, tx_rate_max={tx_rate_max},
link_state={link_state}, spoof_check={spoof_check}, trust={trust}, query_rss={query_rss}
API schema: {"message": "{data}"}
"""
params = dict()
# Update any params that we've sent
if vlan_id is not None:
params['vlan_id'] = vlan_id
if vlan_qos is not None:
params['vlan_qos'] = vlan_qos
if tx_rate_min is not None:
params['tx_rate_min'] = tx_rate_min
if tx_rate_max is not None:
params['tx_rate_max'] = tx_rate_max
if link_state is not None:
params['link_state'] = link_state
if spoof_check is not None:
params['spoof_check'] = spoof_check
if trust is not None:
params['trust'] = trust
if query_rss is not None:
params['query_rss'] = query_rss
# Write the new configuration to the API
response = call_api(config, 'put', '/sriov/vf/{node}/{vf}'.format(node=node, vf=vf), params=params)
if response.status_code == 200:
retstatus = True
else:
retstatus = False
return retstatus, response.json().get('message', '')
def net_sriov_vf_list(config, node, pf=None): def net_sriov_vf_list(config, node, pf=None):
""" """
List all VFs on NODE, optionally limited by PF List all VFs on NODE, optionally limited by PF
API endpoint: GET /api/v1/sriov/vf/<node> API endpoint: GET /api/v1/sriov/vf/<node>
API arguments: node=node, pf=pf API arguments: node={node}, pf={pf}
API schema: [{json_data_object},{json_data_object},etc.] API schema: [{json_data_object},{json_data_object},etc.]
""" """
params = dict() params = dict()
@ -843,7 +890,6 @@ def format_list_sriov_pf(pf_list):
if len(nice_vfs_list) > 1: if len(nice_vfs_list) > 1:
for idx in range(1, len(nice_vfs_list)): for idx in range(1, len(nice_vfs_list)):
print(idx)
pf_list_output.append('{bold}\ pf_list_output.append('{bold}\
{pf_phy: <{pf_phy_length}} \ {pf_phy: <{pf_phy_length}} \
{pf_mtu: <{pf_mtu_length}} \ {pf_mtu: <{pf_mtu_length}} \

View File

@ -2156,6 +2156,39 @@ def net_sriov_vf():
# pvc network sriov vf set # pvc network sriov vf set
############################################################################### ###############################################################################
@click.command(name='set', short_help='Set VF device properties.') @click.command(name='set', short_help='Set VF device properties.')
@click.option(
'--vlan-id', 'vlan_id', default=None, show_default=False,
help='The vLAN ID for vLAN tagging.'
)
@click.option(
'--qos-prio', 'vlan_qos', default=None, show_default=False,
help='The vLAN QOS priority.'
)
@click.option(
'--tx-min', 'tx_rate_min', default=None, show_default=False,
help='The minimum TX rate.'
)
@click.option(
'--tx-max', 'tx_rate_max', default=None, show_default=False,
help='The maximum TX rate.'
)
@click.option(
'--link-state', 'link_state', default=None, show_default=False,
type=click.Choice(['auto', 'enable', 'disable']),
help='The administrative link state.'
)
@click.option(
'--spoof-check/--no-spoof-check', 'spoof_check', is_flag=True, default=None, show_default=False,
help='Enable or disable spoof checking.'
)
@click.option(
'--trust/--no-trust', 'trust', is_flag=True, default=None, show_default=False,
help='Enable or disable VF user trust.'
)
@click.option(
'--query-rss/--no-query-rss', 'query_rss', is_flag=True, default=None, show_default=False,
help='Enable or disable query RSS support.'
)
@click.argument( @click.argument(
'node' 'node'
) )
@ -2163,14 +2196,15 @@ def net_sriov_vf():
'vf' 'vf'
) )
@cluster_req @cluster_req
def net_sriov_vf_set(node, pf): def net_sriov_vf_set(node, vf, vlan_id, vlan_qos, tx_rate_min, tx_rate_max, link_state, spoof_check, trust, query_rss):
""" """
Set a property of SR-IOV VF on NODE. Set a property of SR-IOV VF on NODE.
""" """
retcode, retdata = pvc_network.net_sriov_vf_list(config, node, pf) if vlan_id is None and vlan_qos is None and tx_rate_min is None and tx_rate_max is None and link_state is None and spoof_check is None and trust is None and query_rss is None:
if retcode: cleanup(False, 'At least one configuration property must be specified to update.')
retdata = pvc_network.format_list_sriov_vf(retdata)
cleanup(retcode, retdata) retcode, retmsg = pvc_network.net_sriov_vf_set(config, node, vf, vlan_id, vlan_qos, tx_rate_min, tx_rate_max, link_state, spoof_check, trust, query_rss)
cleanup(retcode, retmsg)
############################################################################### ###############################################################################

View File

@ -26,6 +26,7 @@ import subprocess
import signal import signal
from json import loads from json import loads
from re import match as re_match from re import match as re_match
from re import split as re_split
from distutils.util import strtobool from distutils.util import strtobool
from threading import Thread from threading import Thread
from shlex import split as shlex_split from shlex import split as shlex_split
@ -685,3 +686,25 @@ def removeIPAddress(ipaddr, cidrnetmask, dev):
dev dev
) )
) )
#
# Sort a set of interface names (e.g. ens1f1v10)
#
def sortInterfaceNames(interface_names):
# We can't handle non-list inputs
if not isinstance(interface_names, list):
return interface_names
def atoi(text):
return int(text) if text.isdigit() else text
def natural_keys(text):
"""
alist.sort(key=natural_keys) sorts in human order
http://nedbatchelder.com/blog/200712/human_sorting.html
(See Toothy's implementation in the comments)
"""
return [atoi(c) for c in re_split(r'(\d+)', text)]
return sorted(interface_names, key=natural_keys)

View File

@ -21,6 +21,8 @@
import re import re
import daemon_lib.common as common
# #
# Cluster search functions # Cluster search functions
@ -641,8 +643,7 @@ def getSRIOVPFInformation(zkhandler, node, pf):
retcode, vf_list = get_list_sriov_vf(zkhandler, node, pf) retcode, vf_list = get_list_sriov_vf(zkhandler, node, pf)
if retcode: if retcode:
unsorted_vfs = [vf['phy'] for vf in vf_list if vf['pf'] == pf] vfs = common.sortInterfaceNames([vf['phy'] for vf in vf_list if vf['pf'] == pf])
vfs = sorted(unsorted_vfs, key=lambda k: int(''.join(re.findall(r'[0-9]', k))))
else: else:
vfs = [] vfs = []
@ -675,6 +676,9 @@ def get_list_sriov_pf(zkhandler, node):
def getSRIOVVFInformation(zkhandler, node, vf): def getSRIOVVFInformation(zkhandler, node, vf):
if not zkhandler.exists(('node.sriov.vf', node, 'sriov_vf', vf)):
return []
pf = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.pf', vf)) pf = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.pf', vf))
mtu = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.mtu', vf)) mtu = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.mtu', vf))
mac = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.mac', vf)) mac = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.mac', vf))
@ -682,8 +686,8 @@ def getSRIOVVFInformation(zkhandler, node, vf):
vlan_qos = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.vlan_qos', vf)) vlan_qos = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.vlan_qos', vf))
tx_rate_min = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.tx_rate_min', vf)) tx_rate_min = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.tx_rate_min', vf))
tx_rate_max = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.tx_rate_max', vf)) tx_rate_max = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.tx_rate_max', vf))
spoof_check = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.spoof_check', vf))
link_state = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.link_state', vf)) link_state = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.link_state', vf))
spoof_check = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.spoof_check', vf))
trust = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.trust', vf)) trust = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.trust', vf))
query_rss = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.query_rss', vf)) query_rss = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.config.query_rss', vf))
used = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.used', vf)) used = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.used', vf))
@ -699,8 +703,8 @@ def getSRIOVVFInformation(zkhandler, node, vf):
'vlan_qos': vlan_qos, 'vlan_qos': vlan_qos,
'tx_rate_min': tx_rate_min, 'tx_rate_min': tx_rate_min,
'tx_rate_max': tx_rate_max, 'tx_rate_max': tx_rate_max,
'spoof_check': spoof_check,
'link_state': link_state, 'link_state': link_state,
'spoof_check': spoof_check,
'trust': trust, 'trust': trust,
'query_rss': query_rss, 'query_rss': query_rss,
}, },
@ -713,16 +717,26 @@ def getSRIOVVFInformation(zkhandler, node, vf):
def get_info_sriov_vf(zkhandler, node, vf): def get_info_sriov_vf(zkhandler, node, vf):
# Verify node is valid
valid_node = common.verifyNode(zkhandler, node)
if not valid_node:
return False, 'ERROR: Specified node "{}" is invalid.'.format(node)
vf_information = getSRIOVVFInformation(zkhandler, node, vf) vf_information = getSRIOVVFInformation(zkhandler, node, vf)
if not vf_information: if not vf_information:
return False, 'ERROR: Could not get information about SR-IOV VF "{}" on node "{}"'.format(vf, node) return False, 'ERROR: Could not find SR-IOV VF "{}" on node "{}"'.format(vf, node)
return True, vf_information return True, vf_information
def get_list_sriov_vf(zkhandler, node, pf=None): def get_list_sriov_vf(zkhandler, node, pf=None):
# Verify node is valid
valid_node = common.verifyNode(zkhandler, node)
if not valid_node:
return False, 'ERROR: Specified node "{}" is invalid.'.format(node)
vf_list = list() vf_list = list()
vf_phy_list = sorted(zkhandler.children(('node.sriov.vf', node))) vf_phy_list = common.sortInterfaceNames(zkhandler.children(('node.sriov.vf', node)))
for phy in vf_phy_list: for phy in vf_phy_list:
retcode, vf_information = get_info_sriov_vf(zkhandler, node, phy) retcode, vf_information = get_info_sriov_vf(zkhandler, node, phy)
if retcode: if retcode:
@ -735,9 +749,87 @@ def get_list_sriov_vf(zkhandler, node, pf=None):
return True, vf_list return True, vf_list
def set_sriov_vf_config(zkhandler, node, vf, vlan_id=None, vlan_qos=None, tx_rate_min=None, tx_rate_max=None, spoof_check=None, link_state=None, trust=None, query_rss=None): def set_sriov_vf_config(zkhandler, node, vf, vlan_id=None, vlan_qos=None, tx_rate_min=None, tx_rate_max=None, link_state=None, spoof_check=None, trust=None, query_rss=None):
pass # Verify node is valid
valid_node = common.verifyNode(zkhandler, node)
if not valid_node:
return False, 'ERROR: Specified node "{}" is invalid.'.format(node)
# Verify VF is valid
vf_information = getSRIOVVFInformation(zkhandler, node, vf)
if not vf_information:
return False, 'ERROR: Could not find SR-IOV VF "{}" on node "{}".'.format(vf, node)
update_list = list()
if vlan_id is not None:
update_list.append((('node.sriov.vf', node, 'sriov_vf.config.vlan_id', vf), vlan_id))
if vlan_qos is not None:
update_list.append((('node.sriov.vf', node, 'sriov_vf.config.vlan_qos', vf), vlan_qos))
if tx_rate_min is not None:
update_list.append((('node.sriov.vf', node, 'sriov_vf.config.tx_rate_min', vf), tx_rate_min))
if tx_rate_max is not None:
update_list.append((('node.sriov.vf', node, 'sriov_vf.config.tx_rate_max', vf), tx_rate_max))
if link_state is not None:
update_list.append((('node.sriov.vf', node, 'sriov_vf.config.link_state', vf), link_state))
if spoof_check is not None:
update_list.append((('node.sriov.vf', node, 'sriov_vf.config.spoof_check', vf), spoof_check))
if trust is not None:
update_list.append((('node.sriov.vf', node, 'sriov_vf.config.trust', vf), trust))
if query_rss is not None:
update_list.append((('node.sriov.vf', node, 'sriov_vf.config.query_rss', vf), query_rss))
if len(update_list) < 1:
return False, 'ERROR: No changes to apply.'
result = zkhandler.write(update_list)
if result:
return True, 'Successfully modified configuration of SR-IOV VF "{}" on node "{}".'.format(vf, node)
else:
return False, 'Failed to modify configuration of SR-IOV VF "{}" on node "{}".'.format(vf, node)
def set_sriov_vf_vm(zkhandler, node, vf, vm_name, vm_macaddr): def set_sriov_vf_vm(zkhandler, node, vf, vm_name, vm_macaddr):
pass # Verify node is valid
valid_node = common.verifyNode(zkhandler, node)
if not valid_node:
return False
# Verify VF is valid
vf_information = getSRIOVVFInformation(zkhandler, node, vf)
if not vf_information:
return False
zkhandler.write([
(('node.sriov.vf', node, 'sriov_vf.used', vf), 'True'),
(('node.sriov.vf', node, 'sriov_vf.used_by', vf), vm_name),
(('node.sriov.vf', node, 'sriov_vf.mac', vf), vm_macaddr),
])
return True
def unset_sriov_vf_vm(zkhandler, node, vf):
# Verify node is valid
valid_node = common.verifyNode(zkhandler, node)
if not valid_node:
return False
# Verify VF is valid
vf_information = getSRIOVVFInformation(zkhandler, node, vf)
if not vf_information:
return False
zkhandler.write([
(('node.sriov.vf', node, 'sriov_vf.used', vf), 'False'),
(('node.sriov.vf', node, 'sriov_vf.used_by', vf), ''),
])
return True

227
debian/changelog vendored
View File

@ -1,226 +1,5 @@
pvc (0.9.20-0) unstable; urgency=high pvc (0.9.20~git~git-e13baf8) unstable; urgency=medium
* [Daemons] Implemented a Zookeeper schema handler and version 0 schema * Unstable revision for commit e13baf8
* [Daemons] Completes major refactoring of codebase to make use of the schema handler
* [Daemons] Adds support for dynamic chema changges and "hot reloading" of pvcnoded processes
* [Daemons] Adds a functional testing script for verifying operation against a test cluster
* [Daemons, CLI] Fixes several minor bugs found by the above script
* [Daemons, CLI] Add support for Debian 11 "Bullseye"
-- Joshua M. Boniface <joshua@boniface.me> Mon, 14 Jun 2021 18:06:27 -0400 -- Joshua Boniface <joshua@boniface.me> Mon, 21 Jun 2021 18:22:08 -0400
pvc (0.9.19-0) unstable; urgency=high
* [CLI] Corrects some flawed conditionals
* [API] Disables SQLAlchemy modification tracking functionality (not used by us)
* [Daemons] Implements new zkhandler module for improved reliability and reusability
* [Daemons] Refactors some code to use new zkhandler module
* [API, CLI] Adds support for "none" migration selector (uses cluster default instead)
* [Daemons] Moves some configuration keys to new /config tree
* [Node Daemon] Increases initial lock timeout for VM migrations to avoid out-of-sync potential
* [Provisioner] Support storing and using textual cluster network labels ("upstream", "storage", "cluster") in templates
* [API] Avoid duplicating existing node states
-- Joshua M. Boniface <joshua@boniface.me> Sun, 06 Jun 2021 01:47:41 -0400
pvc (0.9.18-0) unstable; urgency=high
* Adds VM rename functionality to API and CLI client
-- Joshua M. Boniface <joshua@boniface.me> Sun, 23 May 2021 17:23:10 -0400
pvc (0.9.17-0) unstable; urgency=high
* [CLI] Fixes bugs in log follow output
-- Joshua M. Boniface <joshua@boniface.me> Wed, 19 May 2021 17:06:29 -0400
pvc (0.9.16-0) unstable; urgency=high
* Improves some CLI help messages
* Skips empty local cluster in CLI
* Adjusts how confirmations happen during VM modify restarts
* Fixes bug around corrupted VM log files
* Fixes bug around subprocess pipe exceptions
-- Joshua M. Boniface <joshua@boniface.me> Mon, 10 May 2021 01:13:21 -0400
pvc (0.9.15-0) unstable; urgency=high
* [CLI] Adds additional verification (--yes) to several VM management commands
* [CLI] Adds a method to override --yes/confirmation requirements via envvar (PVC_UNSAFE)
* [CLI] Adds description fields to PVC clusters in CLI
-- Joshua M. Boniface <joshua@boniface.me> Thu, 08 Apr 2021 13:37:47 -0400
pvc (0.9.14-0) unstable; urgency=high
* Fixes bugs around cloned volume provisioning
* Fixes some minor visual bugs
* Minor license update (from GPL3+ to GPL3)
* Adds qemu-guest-agent support to provisioner-created VMs by default
-- Joshua M. Boniface <joshua@boniface.me> Tue, 30 Mar 2021 10:27:37 -0400
pvc (0.9.13-0) unstable; urgency=high
* Adds nicer startup messages for daemons
* Adds additional API field for stored_bytes to pool stats
* Fixes sorting issues with snapshot lists
* Fixes missing increment/decrement of snapshot_count on volumes
* Fixes bad calls in pool element API endpoints
* Fixes inconsistent bytes_tohuman behaviour in daemons
* Adds validation and maximum volume size on creation (must be smaller than the pool free space)
-- Joshua M. Boniface <joshua@boniface.me> Wed, 17 Feb 2021 11:33:28 -0500
pvc (0.9.12-0) unstable; urgency=high
* Fixes a bug in the pvcnoded service unit file causing a Zookeeper startup race condition
-- Joshua M. Boniface <joshua@boniface.me> Thu, 28 Jan 2021 16:29:58 -0500
pvc (0.9.11-0) unstable; urgency=high
* Documentation updates
* Adds VNC information to VM info
* Goes back to external Ceph commands for disk usage
-- Joshua M. Boniface <joshua@boniface.me> Tue, 05 Jan 2021 15:58:26 -0500
pvc (0.9.10-0) unstable; urgency=high
* Moves OSD stats uploading to primary, eliminating reporting failures while hosts are down
* Documentation updates
* Significantly improves RBD locking behaviour in several situations, eliminating cold-cluster start issues and failed VM boot-ups after crashes
* Fixes some timeout delays with fencing
* Fixes bug in validating YAML provisioner userdata
-- Joshua M. Boniface <joshua@boniface.me> Tue, 15 Dec 2020 10:45:15 -0500
pvc (0.9.9-0) unstable; urgency=high
* Adds documentation updates
* Removes single-element list stripping and fixes surrounding bugs
* Adds additional fields to some API endpoints for ease of parsing by clients
* Fixes bugs with network configuration
-- Joshua M. Boniface <joshua@boniface.me> Wed, 09 Dec 2020 02:20:20 -0500
pvc (0.9.8-0) unstable; urgency=high
* Adds support for cluster backup/restore
* Moves location of `init` command in CLI to make room for the above
* Cleans up some invalid help messages from the API
-- Joshua M. Boniface <joshua@boniface.me> Tue, 24 Nov 2020 12:26:57 -0500
pvc (0.9.7-0) unstable; urgency=high
* Fixes bug with provisioner system template modifications
-- Joshua M. Boniface <joshua@boniface.me> Thu, 19 Nov 2020 10:48:28 -0500
pvc (0.9.6-0) unstable; urgency=high
* Fixes bug with migrations
-- Joshua M. Boniface <joshua@boniface.me> Tue, 17 Nov 2020 13:01:54 -0500
pvc (0.9.5-0) unstable; urgency=high
* Fixes bug with line count in log follow
* Fixes bug with disk stat output being None
* Adds short pretty health output
* Documentation updates
-- Joshua M. Boniface <joshua@boniface.me> Tue, 17 Nov 2020 12:34:04 -0500
pvc (0.9.4-0) unstable; urgency=high
* Fixes major bug in OVA parser
-- Joshua M. Boniface <joshua@boniface.me> Tue, 10 Nov 2020 15:33:50 -0500
pvc (0.9.3-0) unstable; urgency=high
* Fixes bugs with image & OVA upload parsing
-- Joshua M. Boniface <joshua@boniface.me> Mon, 09 Nov 2020 10:28:15 -0500
pvc (0.9.2-0) unstable; urgency=high
* Major linting of the codebase with flake8; adds linting tools
* Implements CLI-based modification of VM vCPUs, memory, networks, and disks without directly editing XML
* Fixes bug where `pvc vm log -f` would show all 1000 lines before starting
* Fixes bug in default provisioner libvirt schema (`drive` -> `driver` typo)
-- Joshua M. Boniface <joshua@boniface.me> Sun, 08 Nov 2020 02:03:29 -0500
pvc (0.9.1-0) unstable; urgency=high
* Added per-VM migration method feature
* Fixed bug with provisioner system template listing
-- Joshua Boniface <joshua@boniface.me> Thu, 29 Oct 2020 12:15:28 -0400
pvc (0.9.0-0) unstable; urgency=high
* Numerous bugfixes and improvements
-- Joshua Boniface <joshua@boniface.me> Sun, 18 Oct 2020 14:31:00 -0400
pvc (0.8-1) unstable; urgency=high
* Fix bug with IPv6 being enabled on bridged interfaces
-- Joshua Boniface <joshua@boniface.me> Thu, 15 Oct 2020 11:02:24 -0400
pvc (0.8-0) unstable; urgency=medium
* Numerous bugfixes and improvements
-- Joshua Boniface <joshua@boniface.me> Tue, 11 Aug 2020 12:12:07 -0400
pvc (0.7-0) unstable; urgency=medium
* Numerous bugfixes and improvements
-- Joshua Boniface <joshua@boniface.me> Sat, 15 Feb 2020 23:24:17 -0500
pvc (0.6-0) unstable; urgency=medium
* Numerous improvements, implementation of provisioner and API client
-- Joshua Boniface <joshua@boniface.me> Sat, 08 Feb 2020 18:26:58 -0500
pvc (0.5-0) unstable; urgency=medium
* First public release
-- Joshua Boniface <joshua@boniface.me> Thu, 08 Aug 2019 20:55:51 -0400
pvc (0.4-0) unstable; urgency=medium
* Unification of all daemons into node daemon
* Numerous client tweaks
-- Joshua Boniface <joshua@boniface.me> Sat, 13 Oct 2018 10:40:14 -0400
pvc (0.3-1) unstable; urgency=medium
* Code and package reorganization pending additional daemons
-- Joshua Boniface <joshua@boniface.me> Wed, 12 Sep 2018 12:08:28 -0400
pvc (0.2-1) unstable; urgency=medium
* Minor version bump with stability fixes
-- Joshua Boniface <joshua@boniface.me> Wed, 18 Jul 2018 02:18:25 -0400
pvc (0.1-1) unstable; urgency=medium
* Initial packaging release
-- Joshua Boniface <joshua@boniface.me> Sun, 17 Jun 2018 02:40:39 -0400

View File

@ -1160,11 +1160,11 @@ if enable_networking:
# SR-IOV VF objects # SR-IOV VF objects
# This is a ChildrenWatch just for consistency; the list never changes at runtime # This is a ChildrenWatch just for consistency; the list never changes at runtime
@zkhandler.zk_conn.ChildrenWatch(zkhandler.schema.path('node.sriov.vf', myhostname)) @zkhandler.zk_conn.ChildrenWatch(zkhandler.schema.path('node.sriov.vf', myhostname))
def update_sriov_pfs(new_sriov_vf_list): def update_sriov_vfs(new_sriov_vf_list):
global sriov_vf_list, d_sriov_vf global sriov_vf_list, d_sriov_vf
# Add VFs to the list # Add VFs to the list
for vf in sorted(new_sriov_vf_list): for vf in common.sortInterfaceNames(new_sriov_vf_list):
d_sriov_vf[vf] = SRIOVVFInstance.SRIOVVFInstance(vf, zkhandler, config, logger, this_node) d_sriov_vf[vf] = SRIOVVFInstance.SRIOVVFInstance(vf, zkhandler, config, logger, this_node)
sriov_vf_list = sorted(new_sriov_vf_list) sriov_vf_list = sorted(new_sriov_vf_list)