From 13cc0f986f2e16e7bfa5f3226ea2b5d6954bafbc Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 21 Jun 2021 18:40:11 -0400 Subject: [PATCH] Implement SR-IOV VF config set Also fixes some random bugs, adds proper interface sorting, and assorted tweaks. --- api-daemon/pvcapid/flaskapi.py | 87 +++++++++++++ api-daemon/pvcapid/helper.py | 18 +++ client-cli/cli_lib/network.py | 52 +++++++- client-cli/pvc.py | 44 ++++++- daemon-common/common.py | 23 ++++ daemon-common/network.py | 110 ++++++++++++++-- debian/changelog | 227 +-------------------------------- node-daemon/pvcnoded/Daemon.py | 4 +- 8 files changed, 322 insertions(+), 243 deletions(-) diff --git a/api-daemon/pvcapid/flaskapi.py b/api-daemon/pvcapid/flaskapi.py index dc9cc588..2bca5f8c 100755 --- a/api-daemon/pvcapid/flaskapi.py +++ b/api-daemon/pvcapid/flaskapi.py @@ -2923,6 +2923,93 @@ class API_SRIOV_VF_Element(Resource): else: 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//') diff --git a/api-daemon/pvcapid/helper.py b/api-daemon/pvcapid/helper.py index bf6f345f..81ce3093 100755 --- a/api-daemon/pvcapid/helper.py +++ b/api-daemon/pvcapid/helper.py @@ -1034,6 +1034,24 @@ def sriov_vf_list(zkhandler, node, pf=None): 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 # diff --git a/client-cli/cli_lib/network.py b/client-cli/cli_lib/network.py index 2a410872..4ae9cdd6 100644 --- a/client-cli/cli_lib/network.py +++ b/client-cli/cli_lib/network.py @@ -385,7 +385,7 @@ def net_sriov_pf_list(config, node): List all PFs on NODE API endpoint: GET /api/v1/sriov/pf/ - API arguments: node=node + API arguments: node={node} API schema: [{json_data_object},{json_data_object},etc.] """ 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', '') +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// + 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): """ List all VFs on NODE, optionally limited by PF API endpoint: GET /api/v1/sriov/vf/ - API arguments: node=node, pf=pf + API arguments: node={node}, pf={pf} API schema: [{json_data_object},{json_data_object},etc.] """ params = dict() @@ -843,7 +890,6 @@ def format_list_sriov_pf(pf_list): if len(nice_vfs_list) > 1: for idx in range(1, len(nice_vfs_list)): - print(idx) pf_list_output.append('{bold}\ {pf_phy: <{pf_phy_length}} \ {pf_mtu: <{pf_mtu_length}} \ diff --git a/client-cli/pvc.py b/client-cli/pvc.py index 7495530b..cfc57c51 100755 --- a/client-cli/pvc.py +++ b/client-cli/pvc.py @@ -2156,6 +2156,39 @@ def net_sriov_vf(): # pvc network sriov vf set ############################################################################### @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( 'node' ) @@ -2163,14 +2196,15 @@ def net_sriov_vf(): 'vf' ) @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. """ - retcode, retdata = pvc_network.net_sriov_vf_list(config, node, pf) - if retcode: - retdata = pvc_network.format_list_sriov_vf(retdata) - cleanup(retcode, retdata) + 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: + cleanup(False, 'At least one configuration property must be specified to update.') + + 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) ############################################################################### diff --git a/daemon-common/common.py b/daemon-common/common.py index f26f1966..6271cc85 100644 --- a/daemon-common/common.py +++ b/daemon-common/common.py @@ -26,6 +26,7 @@ import subprocess import signal from json import loads from re import match as re_match +from re import split as re_split from distutils.util import strtobool from threading import Thread from shlex import split as shlex_split @@ -685,3 +686,25 @@ def removeIPAddress(ipaddr, cidrnetmask, 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) diff --git a/daemon-common/network.py b/daemon-common/network.py index d895408d..aedadb6a 100644 --- a/daemon-common/network.py +++ b/daemon-common/network.py @@ -21,6 +21,8 @@ import re +import daemon_lib.common as common + # # Cluster search functions @@ -641,8 +643,7 @@ def getSRIOVPFInformation(zkhandler, node, pf): retcode, vf_list = get_list_sriov_vf(zkhandler, node, pf) if retcode: - unsorted_vfs = [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)))) + vfs = common.sortInterfaceNames([vf['phy'] for vf in vf_list if vf['pf'] == pf]) else: vfs = [] @@ -675,6 +676,9 @@ def get_list_sriov_pf(zkhandler, node): 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)) mtu = zkhandler.read(('node.sriov.vf', node, 'sriov_vf.mtu', 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)) 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)) - 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)) + 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)) 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)) @@ -699,8 +703,8 @@ def getSRIOVVFInformation(zkhandler, node, vf): 'vlan_qos': vlan_qos, 'tx_rate_min': tx_rate_min, 'tx_rate_max': tx_rate_max, - 'spoof_check': spoof_check, 'link_state': link_state, + 'spoof_check': spoof_check, 'trust': trust, 'query_rss': query_rss, }, @@ -713,16 +717,26 @@ def getSRIOVVFInformation(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) 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 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_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: retcode, vf_information = get_info_sriov_vf(zkhandler, node, phy) if retcode: @@ -735,9 +749,87 @@ def get_list_sriov_vf(zkhandler, node, pf=None): 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): - pass +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): + # 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): - 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 diff --git a/debian/changelog b/debian/changelog index 47d24aca..f50f9601 100644 --- a/debian/changelog +++ b/debian/changelog @@ -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 - * [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" + * Unstable revision for commit e13baf8 - -- Joshua M. Boniface Mon, 14 Jun 2021 18:06:27 -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 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 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 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 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 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 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 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 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 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 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 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 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 Thu, 19 Nov 2020 10:48:28 -0500 - -pvc (0.9.6-0) unstable; urgency=high - - * Fixes bug with migrations - - -- Joshua M. Boniface 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 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 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 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 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 Thu, 29 Oct 2020 12:15:28 -0400 - -pvc (0.9.0-0) unstable; urgency=high - - * Numerous bugfixes and improvements - - -- Joshua Boniface 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 Thu, 15 Oct 2020 11:02:24 -0400 - -pvc (0.8-0) unstable; urgency=medium - - * Numerous bugfixes and improvements - - -- Joshua Boniface Tue, 11 Aug 2020 12:12:07 -0400 - -pvc (0.7-0) unstable; urgency=medium - - * Numerous bugfixes and improvements - - -- Joshua Boniface 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 Sat, 08 Feb 2020 18:26:58 -0500 - -pvc (0.5-0) unstable; urgency=medium - - * First public release - - -- Joshua Boniface 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 Sat, 13 Oct 2018 10:40:14 -0400 - -pvc (0.3-1) unstable; urgency=medium - - * Code and package reorganization pending additional daemons - - -- Joshua Boniface Wed, 12 Sep 2018 12:08:28 -0400 - -pvc (0.2-1) unstable; urgency=medium - - * Minor version bump with stability fixes - - -- Joshua Boniface Wed, 18 Jul 2018 02:18:25 -0400 - -pvc (0.1-1) unstable; urgency=medium - - * Initial packaging release - - -- Joshua Boniface Sun, 17 Jun 2018 02:40:39 -0400 + -- Joshua Boniface Mon, 21 Jun 2021 18:22:08 -0400 diff --git a/node-daemon/pvcnoded/Daemon.py b/node-daemon/pvcnoded/Daemon.py index e9bafcc8..14a45791 100644 --- a/node-daemon/pvcnoded/Daemon.py +++ b/node-daemon/pvcnoded/Daemon.py @@ -1160,11 +1160,11 @@ if enable_networking: # SR-IOV VF objects # This is a ChildrenWatch just for consistency; the list never changes at runtime @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 # 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) sriov_vf_list = sorted(new_sriov_vf_list)