Hi Hans,
Yes, I mentioned the new pylint remark in the second email. Sorry for this
inconvenient.
The result is below.
Pylint result
==========
$ pylint --rcfile=python/pylintrc python/samples/clm-tool
************* Module clm-tool
C: 1, 0: Invalid module name "clm-tool" (invalid-name)
Report
======
110 statements analysed.
Statistics by type
------------------
+---------+-------+-----------+-----------+------------+---------+
|type |number |old number |difference |%documented |%badname |
+=========+=======+===========+===========+============+=========+
|module |1 |1 |= |100.00 |100.00 |
+---------+-------+-----------+-----------+------------+---------+
|class |1 |1 |= |100.00 |0.00 |
+---------+-------+-----------+-----------+------------+---------+
|method |10 |10 |= |100.00 |0.00 |
+---------+-------+-----------+-----------+------------+---------+
|function |0 |0 |= |0 |0 |
+---------+-------+-----------+-----------+------------+---------+
External dependencies
---------------------
::
pyosaf
\-saAis (clm-tool)
\-utils
\-clm (clm-tool)
\-immom
\-accessor (clm-tool)
Raw metrics
-----------
+----------+-------+------+---------+-----------+
|type |number |% |previous |difference |
+==========+=======+======+=========+===========+
|code |121 |47.83 |121 |= |
+----------+-------+------+---------+-----------+
|docstring |84 |33.20 |84 |= |
+----------+-------+------+---------+-----------+
|comment |19 |7.51 |19 |= |
+----------+-------+------+---------+-----------+
|empty |29 |11.46 |29 |= |
+----------+-------+------+---------+-----------+
Duplication
-----------
+-------------------------+------+---------+-----------+
| |now |previous |difference |
+=========================+======+=========+===========+
|nb duplicated lines |0 |0 |= |
+-------------------------+------+---------+-----------+
|percent duplicated lines |0.000 |0.000 |= |
+-------------------------+------+---------+-----------+
Messages by category
--------------------
+-----------+-------+---------+-----------+
|type |number |previous |difference |
+===========+=======+=========+===========+
|convention |1 |1 |= |
+-----------+-------+---------+-----------+
|refactor |0 |0 |= |
+-----------+-------+---------+-----------+
|warning |0 |0 |= |
+-----------+-------+---------+-----------+
|error |0 |0 |= |
+-----------+-------+---------+-----------+
Messages
--------
+-------------+------------+
|message id |occurrences |
+=============+============+
|invalid-name |1 |
+-------------+------------+
------------------------------------------------------------------
Your code has been rated at 9.91/10 (previous run: 9.91/10, +0.00)
Thanks,
/Danh
-----Original Message-----
From: Hans Nordebäck [mailto:[email protected]]
Sent: Wednesday, December 20, 2017 2:18 PM
To: Danh Cong Vo <[email protected]>; [email protected];
Quyen Quoc Dao <[email protected]>
Cc: [email protected]
Subject: RE: [PATCH 1/1] pyosaf: Refactor clm-tool sample to make use of new
pyosaf utils [#2679]
Hi Danh,
ok, did you notice the new pylint remarks?
/Regards HansN
-----Original Message-----
From: Danh Vo [mailto:[email protected]]
Sent: den 20 december 2017 04:58
To: Hans Nordebäck <[email protected]>;
[email protected]; Quyen Quoc Dao <[email protected]>
Cc: [email protected]
Subject: RE: [PATCH 1/1] pyosaf: Refactor clm-tool sample to make use of new
pyosaf utils [#2679]
Hi Hans,
Thanks for your ack.
I run pylint with pylintrc in opensaf-code/python directory:
pylint --rcfile=python/pylintrc python/samples/clm-tool
Thanks,
/Danh
-----Original Message-----
From: Hans Nordebäck [mailto:[email protected]]
Sent: Tuesday, December 19, 2017 6:35 PM
To: Danh Vo <[email protected]>; [email protected];
[email protected]
Cc: [email protected]
Subject: Re: [PATCH 1/1] pyosaf: Refactor clm-tool sample to make use of new
pyosaf utils [#2679]
ack with a question, (review only). Have you run pylint on clm-tool?
There are new remarks such as Invalid variable name, Invalid constant name, Too
many arguments, etc.
/Thanks HansN
On 12/04/2017 08:46 AM, Danh Vo wrote:
> - Refactor clm-tool.
> - Add new function in clm util for sending node get.
> ---
> python/pyosaf/utils/clm/__init__.py | 125 +++++++++------
> python/samples/clm-tool | 309
> ++++++++++++++++++++++++++++--------
> 2 files changed, 322 insertions(+), 112 deletions(-)
>
> diff --git a/python/pyosaf/utils/clm/__init__.py
> b/python/pyosaf/utils/clm/__init__.py
> index 533a4b5..5461d4a 100644
> --- a/python/pyosaf/utils/clm/__init__.py
> +++ b/python/pyosaf/utils/clm/__init__.py
> @@ -44,6 +44,38 @@ saClmClusterNodeGetAsync =
> decorate(saClm.saClmClusterNodeGetAsync)
> saClmResponse_4 = decorate(saClm.saClmResponse_4)
>
>
> +class ClusterNode(object):
> + """ Class representing a CLM cluster node """
> +
> + def __init__(self, node_id, node_address, node_name,
> execution_environment,
> + member, boot_timestamp, initial_view_number):
> + """ Constructor for ClusterNode class
> +
> + Args:
> + node_id (SaClmNodeIdT): Node identifier
> + node_address (SaClmNodeAddressT): Node network communication
> + address
> + node_name (SaNameT): Node name
> + execution_environment (SaNameT): DN of the PLM execution
> + environment that hosts the node
> + member (SaBoolT): Indicate whether this is a CLM member node
> (True)
> + or not (False)
> + boot_timestamp (SaTimeT): Timestamp at which the node was last
> + booted
> + initial_view_number (SaUint64T): View number of the latest
> + membership transition when this configured node joined the
> + cluster membership
> + """
> + self.node_id = node_id
> + self.node_address_value = node_address.value
> + self.node_address_family = node_address.family
> + self.node_name = node_name.value
> + self.execution_environment = execution_environment
> + self.member = member
> + self.boot_timestamp = boot_timestamp
> + self.initial_view_number = initial_view_number
> +
> +
> class ClmAgentManager(object):
> """ This class manages the life cycle of a CLM agent, and also acts as
> a proxy handler for CLM callbacks """
> @@ -105,7 +137,7 @@ class ClmAgentManager(object):
> notification = notification_buffer.notification[i]
> clm_cluster_node = notification.clusterNode
> cluster_node = \
> - create_cluster_node_instance(clm_cluster_node)
> +
> + self.create_cluster_node_instance(clm_cluster_node)
> node_state = (cluster_node,
> notification.clusterChange)
>
> node_list.append(node_state) @@ -133,7 +165,7 @@
> class ClmAgentManager(object):
> error = c_error
>
> cluster_node = \
> - create_cluster_node_instance(c_cluster_node.contents)
> +
> + self.create_cluster_node_instance(c_cluster_node.contents)
>
> # Send the node info to user's callback function
> self.node_get_function(invocation, cluster_node, error)
> @@ -221,7 +253,7 @@ class ClmAgentManager(object):
> rc = saClmFinalize(self.handle)
> if rc != eSaAisErrorT.SA_AIS_OK:
> log_err("saClmFinalize FAILED - %s" %
> eSaAisErrorT.whatis(rc))
> - elif rc == eSaAisErrorT.SA_AIS_OK \
> + if rc == eSaAisErrorT.SA_AIS_OK \
> or rc == eSaAisErrorT.SA_AIS_ERR_BAD_HANDLE:
> # If the Finalize() call returned BAD_HANDLE, the handle
> should
> # already become stale and invalid, so we reset it anyway.
> @@ -229,6 +261,25 @@ class ClmAgentManager(object):
>
> return rc
>
> + @staticmethod
> + def create_cluster_node_instance(clm_cluster_node):
> + """ Create ClusterNode object from cluster node information
> +
> + Args:
> + clm_cluster_node (SaClmClusterNodeT): Cluster node
> + information
> +
> + Returns:
> + ClusterNode: An object containing cluster node information
> + """
> + return ClusterNode(
> + node_id=clm_cluster_node.nodeId,
> + node_address=clm_cluster_node.nodeAddress,
> + node_name=clm_cluster_node.nodeName,
> + execution_environment=clm_cluster_node.executionEnvironment,
> + member=clm_cluster_node.member,
> + boot_timestamp=clm_cluster_node.bootTimestamp,
> + initial_view_number=clm_cluster_node.initialViewNumber)
> +
>
> class ClmAgent(ClmAgentManager):
> """ This class acts as a high-level CLM agent, providing CLM
> functions to @@ -327,7 +378,8 @@ class ClmAgent(ClmAgentManager):
> notification = notification_buffer.notification[i]
> clm_cluster_node = notification.clusterNode
>
> - cluster_node = create_cluster_node_instance(clm_cluster_node)
> + cluster_node = \
> +
> + self.create_cluster_node_instance(clm_cluster_node)
>
> cluster_nodes.append(cluster_node)
> else:
> @@ -379,7 +431,7 @@ class ClmAgent(ClmAgentManager):
> """
> rc = saClmClusterTrackStop(self.handle)
> if rc != eSaAisErrorT.SA_AIS_OK:
> - log_err("saClmClusterTrack_4 FAILED - %s" %
> + log_err("saClmClusterTrackStop FAILED - %s" %
> eSaAisErrorT.whatis(rc))
>
> if rc == eSaAisErrorT.SA_AIS_ERR_BAD_HANDLE:
> @@ -415,56 +467,29 @@ class ClmAgent(ClmAgentManager):
>
> return rc
>
> -
> -class ClusterNode(object):
> - """ Class representing a CLM cluster node """
> -
> - def __init__(self, node_id, node_address, node_name,
> execution_environment,
> - member, boot_timestamp, initial_view_number):
> - """ Constructor for ClusterNode class
> + def get_node_info(self, node_id, time_out):
> + """ Get information of a specific cluster member node.
>
> Args:
> - node_id (SaClmNodeIdT): Node identifier
> - node_address (SaClmNodeAddressT): Node network communication
> - address
> - node_name (SaNameT): Node name
> - execution_environment (SaNameT): DN of the PLM execution
> - environment that hosts the node
> - member (SaBoolT): Indicate whether this is a CLM member node
> (True)
> - or not (False)
> - boot_timestamp (SaTimeT): Timestamp at which the node was last
> - booted
> - initial_view_number (SaUint64T): View number of the latest
> - membership transition when this configured node joined the
> - cluster membership
> - """
> - self.node_id = node_id
> - self.node_address_value = node_address.value
> - self.node_address_family = node_address.family
> - self.node_name = node_name.value
> - self.execution_environment = execution_environment
> - self.member = member
> - self.boot_timestamp = boot_timestamp
> - self.initial_view_number = initial_view_number
> -
> + node_id (SaClmNodeIdT): Node id
> + time_out (SaTimeT): Time-out (in nanosecond) for
> + saClmClusterNodeGet_4 operation
>
> -def create_cluster_node_instance(clm_cluster_node):
> - """ Create ClusterNode object from cluster node information
> + Returns:
> + SaAisErrorT: Return code of the saClmClusterNodeGet_4() API call.
> + ClusterNode: Node info or None if node with `node id` is not
> found.
> + """
> + clm_cluster_node = saClm.SaClmClusterNodeT_4()
>
> - Args:
> - clm_cluster_node (SaClmClusterNodeT): Cluster node information
> + rc = saClmClusterNodeGet_4(self.handle, node_id, time_out,
> + clm_cluster_node)
> + if rc != eSaAisErrorT.SA_AIS_OK:
> + log_err("saClmClusterNodeGet() FAILED - %s" %
> + eSaAisErrorT.whatis(rc))
> + return rc, None
>
> - Returns:
> - ClusterNode: An object containing cluster node information
> - """
> - return ClusterNode(
> - node_id=clm_cluster_node.nodeId,
> - node_address=clm_cluster_node.nodeAddress,
> - node_name=clm_cluster_node.nodeName,
> - execution_environment=clm_cluster_node.executionEnvironment,
> - member=clm_cluster_node.member,
> - boot_timestamp=clm_cluster_node.bootTimestamp,
> - initial_view_number=clm_cluster_node.initialViewNumber)
> + cluster_node = self.create_cluster_node_instance(clm_cluster_node)
> + return rc, cluster_node
>
>
> @deprecate
> diff --git a/python/samples/clm-tool b/python/samples/clm-tool index
> 89bf0d3..60dcc8f 100755
> --- a/python/samples/clm-tool
> +++ b/python/samples/clm-tool
> @@ -1,67 +1,252 @@
> #!/usr/bin/env python
> -
> +#####################################################################
> +#######
> +#
> +# (C) Copyright 2015 The OpenSAF Foundation # (C) Copyright 2017
> +Ericsson AB. All rights reserved.
> +#
> +# 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. This file and
> +program are licensed # under the GNU Lesser General Public License Version
> 2.1, February 1999.
> +# The complete license can be accessed from the following location:
> +# http://opensource.org/licenses/lgpl-license.php
> +# See the Copying file included with the OpenSAF distribution for
> +full # licensing terms.
> +#
> +# Author(s): Ericsson
> +#
> +#####################################################################
> +#######
> +"""
> +This is a SAF CLM utility which supports options to:
> + - Retrieve information about one or all CLM cluster member nodes.
> + - Track CLM cluster membership changes.
> + - Run clm-tool --help/-h for more detail on usage.
> +"""
> +from __future__ import print_function
> import argparse
> import sys
> +from select import select
>
> -from pyosaf import saAis, saClm, saImm
> -
> +from pyosaf.saAis import saAis, eSaAisErrorT, eSaDispatchFlagsT
> from pyosaf.utils import clm
> -
> -def dn_to_vm_name(vm_dn):
> - return vm_dn.split(',')[0].split('=')[1]
> -
> -def print_members(members):
> -
> - for node in members:
> - if node.member:
> - vm_name = dn_to_vm_name(node.node_name)
> - ip_address = node.node_address_value
> -
> - print " - %s %s" % (vm_name, ip_address)
> -
> -def membership_change(added, removed):
> - print "Info: Received cluster membership update"
> -
> - for node in added:
> - vm_name = dn_to_vm_name(node.node_name)
> -
> - print "INFO: %s joined the cluster" % vm_name
> -
> - for node in removed:
> - vm_name = dn_to_vm_name(node.node_name)
> -
> - print "INFO: %s left the cluster" % vm_name
> -
> -
> -if __name__ == "__main__":
> -
> - # Parse command line arguments
> - parser = argparse.ArgumentParser(
> - description='Listens to changes to objects of the given classes')
> -
> - group = parser.add_mutually_exclusive_group(required=True)
> -
> - group.add_argument('--snapshot', action="store_true",
> - help='shows a snapshot of the current membership
> list')
> - group.add_argument('--listen', action="store_true", help='listens to
> changes to all classes')
> -
> - args = parser.parse_args()
> -
> - # Initialize the CLM service
> - clm.initialize(track_fn=membership_change)
> -
> - if args.snapshot:
> - print "-" * 10 + " Members " + "-"*10
> -
> - members = clm.get_members()
> -
> - print_members(members)
> -
> - sys.exit(0)
> -
> - # Start tracking
> - clm.track()
> -
> - # Do dispatch forever
> - while True:
> - clm.saClmDispatch(clm.HANDLE,
> saAis.eSaDispatchFlagsT.SA_DISPATCH_BLOCKING)
> +from pyosaf.utils.immom.accessor import ImmOmAccessor
> +
> +
> +class ClmTool(object):
> + """ This class provides functions of the clm-tool. """
> + def __init__(self):
> + self.clm_agent = clm.ClmAgent()
> + self.clm_agent.init(self.membership_change)
> + self.sel_obj = self.clm_agent.get_selection_object()
> +
> + def print_members(self):
> + """ Print out the name and the IP address of all current member
> nodes.
> +
> + Returns:
> + Boolean: True if cluster members info is printed successfully.
> + Otherwise, it is False.
> +
> + """
> + print("-" * 10 + " Members " + "-" * 10)
> + rc, members = self.clm_agent.get_members()
> + if rc != eSaAisErrorT.SA_AIS_OK:
> + print("Failed to get current membership. rc:",
> + eSaAisErrorT.whatis(rc))
> + return False
> + else:
> + for node in members:
> + node_name = self.node_dn_to_node_name(node.node_name)
> + ip_address = node.node_address_value
> + print(" - %s %s" % (node_name, ip_address))
> +
> + return True
> +
> + def request_node_info(self, node_dn, time_out):
> + """ Request the information of a specific member node which is
> + identified by its DN.
> +
> + Args:
> + node_dn (str): The DN of SaClmNode class's object.
> + time_out (int): Timeout in nanosecond.
> +
> + Returns:
> + ClusterNode: Node info or None if node with `node_dn` is not
> found.
> + """
> + accessor = ImmOmAccessor()
> + accessor.init()
> +
> + rc, clm_node_object = accessor.get(node_dn)
> + if rc != eSaAisErrorT.SA_AIS_OK:
> + print("%s object does not exist" % node_dn)
> + return None
> +
> + node_id = clm_node_object["saClmNodeID"]
> + rc, mem_node_info = self.clm_agent.get_node_info(node_id, time_out)
> + if rc != eSaAisErrorT.SA_AIS_OK:
> + print("Failed to request node info. rc:",
> eSaAisErrorT.whatis(rc))
> + return None
> +
> + return mem_node_info
> +
> + def start_tracking(self, track_type):
> + """ Start tracking member nodes.
> +
> + Args:
> + track_type (SaUint8T): Type of cluster membership
> + tracking
> +
> + Returns:
> + Boolean: True if it starts tracking successfully. Otherwise, it
> is
> + False.
> + """
> + rc = self.clm_agent.track_start(track_type)
> + if rc != eSaAisErrorT.SA_AIS_OK:
> + print("Failed to start tracking. rc:", eSaAisErrorT.whatis(rc))
> + return False
> +
> + return True
> +
> + def stop_tracking(self):
> + """ Stop tracking member nodes.
> +
> + Returns:
> + Boolean: True if it stops tracking successfully. Otherwise, it is
> + False.
> + """
> + rc = self.clm_agent.track_stop()
> + if rc != eSaAisErrorT.SA_AIS_OK:
> + print("Failed to stop tracking. rc:", eSaAisErrorT.whatis(rc))
> + return False
> +
> + return True
> +
> + def dispatch(self, dispatch_flag):
> + """ Dispatch message to appropriate callback.
> +
> + Args:
> + dispatch_flag (eSaDispatchFlagsT): Flags specifying dispatch
> mode.
> +
> + Returns:
> + Boolean: True if it dispatches message successfully. Otherwise,
> it
> + is False.
> + """
> + rc = self.clm_agent.dispatch(dispatch_flag)
> + if rc != eSaAisErrorT.SA_AIS_OK:
> + print("Failed to dispatch message. rc:", eSaAisErrorT.whatis(rc))
> + return False
> +
> + return True
> +
> + def finalize(self):
> + """ Finalize the clm agent.
> +
> + Returns:
> + Boolean: True if it clm agent finalizes successfully. Otherwise,
> it
> + is False.
> + """
> + rc = self.clm_agent.finalize()
> + if rc != eSaAisErrorT.SA_AIS_OK:
> + print("Failed to finalize ClmAgent. rc:",
> eSaAisErrorT.whatis(rc))
> + return False
> +
> + return True
> +
> + def membership_change(self, node_list, invocation, step,
> + num_of_members, error):
> + """ Callback to handle membership change event.
> +
> + Args:
> + node_list (tuple): A list of tuple which contain cluster node
> info
> + and cluster node change type.
> + invocation (SaInvocationT): A particular invocation of the
> + callback function.
> + step (SaClmChangeStepT): Indicates the tracking step in which
> + the callback is invoked.
> + num_of_members (SaUint32T): The current number of members in the
> + cluster membership.
> + error (SaAisErrorT): indicates if the CLM was able to perform the
> + requested operation.
> + """
> +
> + print('-' * 10 + 'Membership Change' + '-' * 10)
> + print("Changed nodes:")
> + for node in node_list:
> + self.print_node_info(node[0])
> + print("\tNode change state:", node[1])
> + print("\t" + "-" * 10)
> +
> + print("Invocation:", invocation)
> + print("Step:", step)
> + print("Number of members:", num_of_members)
> + print("Error code:", eSaAisErrorT.whatis(error))
> +
> + @staticmethod
> + def print_node_info(cluster_node):
> + """ Print information of a cluster node.
> +
> + Args:
> + cluster_node (ClusterNode): ClusterNode object which is printed.
> + """
> + print("\tNode ID:", cluster_node.node_id)
> + print("\tNode Address:", cluster_node.node_address_value)
> + print("\tNode Address Family:", cluster_node.node_address_family)
> + print("\tNode Name:", cluster_node.node_name)
> + print("\tExecution Environment:",
> + 'None' if cluster_node.execution_environment.length == 0
> + else cluster_node.execution_environment.value)
> + print("\tMember:", 'Yes' if cluster_node.member == 1 else 'No')
> + print("\tBoot Timestamp:", cluster_node.boot_timestamp)
> + print("\tView Number:", cluster_node.initial_view_number)
> +
> + @staticmethod
> + def node_dn_to_node_name(node_dn):
> + """ Convert from node's DN to node's name.
> +
> + Args:
> + node_dn (str): DN of a SaClmNode object.
> +
> + Returns:
> + str: Name of node.
> + """
> + return node_dn.split(',')[0].split('=')[1]
> +
> +
> +# Main
> +parser = argparse.ArgumentParser(description='This is a SAF CLM utility used
> '
> + 'to view/track CLM cluster '
> + 'membership.') group =
> +parser.add_mutually_exclusive_group(required=True)
> +group.add_argument('-s', '--show', action="store_true",
> + help='print info of all current cluster member
> +nodes.') group.add_argument('-n', '--nodeinfo', type=str,
> + help="print info of a specific cluster member
> +node.") group.add_argument('-t', '--track', action="store_true",
> + help='track changes in cluster membership.')
> +
> +clm_tool = ClmTool()
> +result = True
> +
> +args = parser.parse_args()
> +if args.show:
> + result = clm_tool.print_members() elif args.nodeinfo:
> + node_info = clm_tool.request_node_info(args.nodeinfo, 6000000000)
> + if node_info is not None:
> + clm_tool.print_node_info(node_info)
> + else:
> + result = False
> +elif args.track:
> + fds = [clm_tool.sel_obj.value]
> + result = clm_tool.start_tracking(saAis.SA_TRACK_CHANGES)
> +
> + try:
> + while result:
> + ioe = select(fds, [], [])
> + for fd in ioe[0]:
> + if fd == clm_tool.sel_obj.value:
> + result = clm_tool.dispatch(
> + eSaDispatchFlagsT.SA_DISPATCH_ALL)
> + except KeyboardInterrupt:
> + clm_tool.stop_tracking()
> +
> +clm_tool.finalize()
> +sys.exit(0 if result else 1)
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel