def setup_commands(self, parser): subcmds = [ Commands.Subcommands.List, Commands.Subcommands.SetProperty, Commands.Subcommands.ListProperties, Commands.Subcommands.DrbdOptions, Commands.Subcommands.DrbdPeerDeviceOptions, ResourceConnectionCommands.Path ] res_conn_parser = parser.add_parser( Commands.RESOURCE_CONN, aliases=["rc"], formatter_class=argparse.RawTextHelpFormatter, description="Resource connection subcommands") subp = res_conn_parser.add_subparsers( title="resource connection commands", metavar="", description=Commands.Subcommands.generate_desc(subcmds)) rescon_groubby = [x.name for x in ResourceConnectionCommands._headers] res_group_completer = Commands.show_group_completer( rescon_groubby, "groupby") p_lresconn = subp.add_parser( Commands.Subcommands.List.LONG, aliases=[Commands.Subcommands.List.SHORT], description= 'Prints a list of all resource connections for the given resource. ' + 'By default, the list is printed as a human readable table.') p_lresconn.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lresconn.add_argument( '-g', '--groupby', nargs='+', choices=rescon_groubby).completer = res_group_completer p_lresconn.add_argument( 'resource_name', help="Resource name").completer = self.resource_completer p_lresconn.set_defaults(func=self.list) # show properties p_sp = subp.add_parser( Commands.Subcommands.ListProperties.LONG, aliases=[Commands.Subcommands.ListProperties.SHORT], description= "Prints all properties of the given resource connection.") p_sp.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_sp.add_argument('node_name_a', help="Node name source of the connection." ).completer = self.node_completer p_sp.add_argument('node_name_b', help="Node name target of the connection." ).completer = self.node_completer p_sp.add_argument( 'resource_name', help="Resource name").completer = self.resource_completer p_sp.set_defaults(func=self.print_props) # set properties p_setprop = subp.add_parser( Commands.Subcommands.SetProperty.LONG, aliases=[Commands.Subcommands.SetProperty.SHORT], formatter_class=argparse.RawTextHelpFormatter, description='Sets properties for the given resource connection.') p_setprop.add_argument('node_name_a', help="Node name source of the connection." ).completer = self.node_completer p_setprop.add_argument('node_name_b', help="Node name target of the connection." ).completer = self.node_completer p_setprop.add_argument( 'resource_name', type=str, help='Name of the resource').completer = self.resource_completer Commands.add_parser_keyvalue(p_setprop, "rsc-conn") p_setprop.set_defaults(func=self.set_props) # drbd peer device options p_drbd_peer_opts = subp.add_parser( Commands.Subcommands.DrbdOptions.LONG, aliases=[ Commands.Subcommands.DrbdOptions.SHORT, Commands.Subcommands.DrbdPeerDeviceOptions.LONG, Commands.Subcommands.DrbdPeerDeviceOptions.SHORT ], description=DrbdOptions.description("peer-device")) p_drbd_peer_opts.add_argument('node_a', type=str, help="1. Node in the node connection" ).completer = self.node_completer p_drbd_peer_opts.add_argument('node_b', type=str, help="2. Node in the node connection" ).completer = self.node_completer p_drbd_peer_opts.add_argument( 'resource_name', type=str, help="Resource name").completer = self.resource_completer DrbdOptions.add_arguments(p_drbd_peer_opts, self.OBJECT_NAME) p_drbd_peer_opts.set_defaults(func=self.drbd_opts) # Path commands path_subcmds = [ Commands.Subcommands.Create, Commands.Subcommands.List, Commands.Subcommands.Delete ] path_parser = subp.add_parser( ResourceConnectionCommands.Path.LONG, formatter_class=argparse.RawTextHelpFormatter, aliases=[ResourceConnectionCommands.Path.SHORT], description="%s subcommands" % ResourceConnectionCommands.Path.LONG) path_subp = path_parser.add_subparsers( title="%s subcommands" % Commands.Subcommands.Interface.LONG, metavar="", description=Commands.Subcommands.generate_desc(path_subcmds)) # create path path_create = path_subp.add_parser( Commands.Subcommands.Create.LONG, aliases=[Commands.Subcommands.Create.SHORT], description='Creates a new resource connection path') path_create.add_argument( "node_a", type=str, help="1. Node of the connection").completer = self.node_completer path_create.add_argument( "node_b", type=str, help="2. Node of the connection").completer = self.node_completer path_create.add_argument( "resource_name", type=str, help="Resource name").completer = self.resource_completer path_create.add_argument("path_name", help="Name of the created path") path_create.add_argument("netinterface_a", help="Netinterface name to use for 1. node" ).completer = self.netif_completer path_create.add_argument( "netinterface_b", help="Netinterface name to use for the 2. node" ).completer = self.netif_completer path_create.set_defaults(func=self.path_create) # delete path path_delete = path_subp.add_parser( Commands.Subcommands.Delete.LONG, aliases=[Commands.Subcommands.Delete.SHORT], description='Deletes an existing resource connection path') path_delete.add_argument( "node_a", type=str, help="1. Node of the connection").completer = self.node_completer path_delete.add_argument( "node_b", type=str, help="2. Node of the connection").completer = self.node_completer path_delete.add_argument( "resource_name", type=str, help="Resource name").completer = self.resource_completer path_delete.add_argument("path_name", help="Name of the created path") path_delete.set_defaults(func=self.path_delete) # list path path_list = path_subp.add_parser( Commands.Subcommands.List.LONG, aliases=[Commands.Subcommands.List.SHORT], description='List all existing resource connection paths') path_list.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') path_list.add_argument( "node_a", type=str, help="1. Node of the connection").completer = self.node_completer path_list.add_argument( "node_b", type=str, help="2. Node of the connection").completer = self.node_completer path_list.add_argument( "resource_name", type=str, help="Resource name").completer = self.resource_completer path_list.set_defaults(func=self.path_list) self.check_subcommands(path_subp, path_subcmds) self.check_subcommands(subp, subcmds)
def setup_commands(self, parser): subcmds = [ Commands.Subcommands.Create, Commands.Subcommands.Modify, Commands.Subcommands.List, Commands.Subcommands.Delete, Commands.Subcommands.SetProperty, Commands.Subcommands.ListProperties, Commands.Subcommands.DrbdOptions, Commands.Subcommands.Spawn, Commands.Subcommands.QueryMaxVlmSize, Commands.Subcommands.Adjust ] # Resource group subcommands res_grp_parser = parser.add_parser( Commands.RESOURCE_GRP, aliases=["rg"], formatter_class=argparse.RawTextHelpFormatter, description="Resource group subcommands") res_grp_subp = res_grp_parser.add_subparsers( title="resource group subcommands", metavar="", description=Commands.Subcommands.generate_desc(subcmds)) # ------------ CREATE START p_new_res_grp = res_grp_subp.add_parser( Commands.Subcommands.Create.LONG, aliases=[Commands.Subcommands.Create.SHORT], description='Defines a Linstor resource group for use with linstor.' ) p_new_res_grp.add_argument('-d', '--description', help="Description for the resource group.") self.add_auto_select_argparse_arguments(p_new_res_grp, use_place_count=True) p_new_res_grp.add_argument('name', type=str, help='Name of the resource group.') p_new_res_grp.set_defaults(func=self.create) # ------------ CREATE END # ------------ MODIFY START p_mod_res_grp = res_grp_subp.add_parser( Commands.Subcommands.Modify.LONG, aliases=[Commands.Subcommands.Modify.SHORT], description='Modifies a Linstor resource group') p_mod_res_grp.add_argument('-d', '--description', help="Description for the resource group.") self.add_auto_select_argparse_arguments(p_mod_res_grp, use_place_count=True) p_mod_res_grp.add_argument('name', help='Name of the resource group' ).completer = self.resource_grp_completer p_mod_res_grp.set_defaults(func=self.modify) # ------------ MODIFY END # ------------ DELETE START p_rm_res_grp = res_grp_subp.add_parser( Commands.Subcommands.Delete.LONG, aliases=[Commands.Subcommands.Delete.SHORT], description=" Removes a resource group from the linstor cluster.") p_rm_res_grp.add_argument('name', help='Name of the resource group to delete' ).completer = self.resource_grp_completer p_rm_res_grp.set_defaults(func=self.delete) # ------------ DELETE END # ------------ LIST START rsc_grp_groupby = [x.name.lower() for x in self._rsc_grp_headers] rsc_grp_group_completer = Commands.show_group_completer( rsc_grp_groupby, "groupby") p_lrscgrps = res_grp_subp.add_parser( Commands.Subcommands.List.LONG, aliases=[Commands.Subcommands.List.SHORT], description='Prints a list of all resource groups known to ' 'linstor. By default, the list is printed as a human readable table.' ) p_lrscgrps.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lrscgrps.add_argument( '-g', '--groupby', nargs='+', choices=rsc_grp_groupby, type=str.lower).completer = rsc_grp_group_completer p_lrscgrps.add_argument('-r', '--resource-groups', nargs='+', type=str, help='Filter by list of resource groups' ).completer = self.resource_grp_completer p_lrscgrps.add_argument('--props', nargs='+', type=str, help='Filter list by object properties') p_lrscgrps.set_defaults(func=self.list) # ------------ LIST END # ------------ LISTPROPS START p_sp = res_grp_subp.add_parser( Commands.Subcommands.ListProperties.LONG, aliases=[Commands.Subcommands.ListProperties.SHORT], description="Prints all properties of the given resource group.") p_sp.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_sp.add_argument( 'name', help="Resource group for which to print the properties" ).completer = self.resource_grp_completer p_sp.set_defaults(func=self.print_props) # ------------ LISTPROPS END # ------------ SETPROPS START p_setprop = res_grp_subp.add_parser( Commands.Subcommands.SetProperty.LONG, aliases=[Commands.Subcommands.SetProperty.SHORT], formatter_class=argparse.RawTextHelpFormatter, description='Sets properties for the given resource group.') p_setprop.add_argument('name', type=str, help='Name of the resource group' ).completer = self.resource_grp_completer Commands.add_parser_keyvalue(p_setprop, self.OBJECT_NAME) p_setprop.set_defaults(func=self.set_props) # ------------ SETPROPS END # ------------ SETDRBDOPTS START p_drbd_opts = res_grp_subp.add_parser( Commands.Subcommands.DrbdOptions.LONG, aliases=[Commands.Subcommands.DrbdOptions.SHORT], description=DrbdOptions.description("resource")) p_drbd_opts.add_argument( 'name', type=str, help="Resource group name").completer = self.resource_grp_completer DrbdOptions.add_arguments(p_drbd_opts, self.OBJECT_NAME) p_drbd_opts.set_defaults(func=self.set_drbd_opts) # ------------ SETDRBDOPTS END # ------------ SPAWN START p_spawn = res_grp_subp.add_parser( Commands.Subcommands.Spawn.LONG, aliases=[Commands.Subcommands.Spawn.SHORT], description= "Spawns new resource with the settings of the resource group.") p_spawn.add_argument('-p', '--partial', action='store_true', help="Allow mismatching volume sizes.") p_spawn.add_argument( '-d', '--definition-only', action='store_true', help="Do not auto-place resource, only create definitions") p_spawn.add_argument('resource_group_name', help="Resource group name to spawn from." ).completer = self.resource_grp_completer p_spawn.add_argument( 'resource_definition_name', help= "New Resource definition name to create. Will be ignored if EXTERNAL_NAME is set." ) p_spawn.add_argument('--external-name', type=str, help="User specified name") p_spawn.add_argument('volume_sizes', nargs='*') p_spawn.set_defaults(func=self.spawn) # ------------ SPAWN END # ------------ QMVS START p_qmvs = res_grp_subp.add_parser( Commands.Subcommands.QueryMaxVlmSize.LONG, aliases=[Commands.Subcommands.QueryMaxVlmSize.SHORT], description="Queries maximum volume size for a given resource-group" ) p_qmvs.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_qmvs.add_argument( 'resource_group_name', help="Resource group name to read auto-config settings from" ).completer = self.resource_grp_completer p_qmvs.set_defaults(func=self.qmvs) # ------------ QMVS END # ------------ ADJUST START p_adjust = res_grp_subp.add_parser( Commands.Subcommands.Adjust.LONG, aliases=[Commands.Subcommands.Adjust.SHORT], description= "Adjusts all resource-definition of the given resource-group.\n" "CAUTION: This operation might take a long time and even exceed the default 5 min timeout!" ) p_adjust.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_adjust.add_argument( 'resource_group_name', nargs="?", default=None, help= "Resource group to adjust. If omitted, all resource groups will be adjusted" ).completer = self.resource_grp_completer # p_adjust.add_argument('-o', '--overprovision', # help='Multiplier of thin storage pool\'s free space. Default: 2.0') p_adjust.set_defaults(func=self.adjust) # ------------ ADJUST END self.check_subcommands(res_grp_subp, subcmds)
def setup_commands(self, parser): # Node subcommands subcmds = [ Commands.Subcommands.Create, NodeCommands.CreateOpenFlexTarget, Commands.Subcommands.List, Commands.Subcommands.Delete, Commands.Subcommands.Lost, Commands.Subcommands.Describe, Commands.Subcommands.Interface, Commands.Subcommands.Info, Commands.Subcommands.SetProperty, Commands.Subcommands.ListProperties, Commands.Subcommands.Modify, NodeCommands.Reconnect, Commands.Subcommands.Restore ] node_parser = parser.add_parser( Commands.NODE, aliases=["n"], formatter_class=argparse.RawTextHelpFormatter, description="Node subcommands" ) node_subp = node_parser.add_subparsers( title="Node commands", metavar="", description=Commands.Subcommands.generate_desc(subcmds) ) node_types = [ apiconsts.VAL_NODE_TYPE_CTRL, apiconsts.VAL_NODE_TYPE_AUX, apiconsts.VAL_NODE_TYPE_CMBD, apiconsts.VAL_NODE_TYPE_STLT ] # create node p_new_node = node_subp.add_parser( Commands.Subcommands.Create.LONG, aliases=[Commands.Subcommands.Create.SHORT], description='Creates a node entry for a node that participates in the linstor cluster.' ) p_new_node.add_argument('-p', '--port', type=rangecheck(1, 65535), help='default: Satellite %s for %s; Controller %s for %s; %s for %s' % ( apiconsts.DFLT_STLT_PORT_PLAIN, apiconsts.VAL_NETCOM_TYPE_PLAIN, apiconsts.DFLT_CTRL_PORT_PLAIN, apiconsts.VAL_NETCOM_TYPE_PLAIN, apiconsts.DFLT_CTRL_PORT_SSL, apiconsts.VAL_NETCOM_TYPE_SSL)) ntype_def = apiconsts.VAL_NODE_TYPE_STLT p_new_node.add_argument('--node-type', choices=[x.lower() for x in node_types], default=apiconsts.VAL_NODE_TYPE_STLT, type=str.lower, help='Node type (default: %s)' % ntype_def.lower()) ctype_def = apiconsts.VAL_NETCOM_TYPE_PLAIN p_new_node.add_argument('--communication-type', choices=(apiconsts.VAL_NETCOM_TYPE_PLAIN.lower(), apiconsts.VAL_NETCOM_TYPE_SSL.lower()), default=ctype_def, type=str.lower, help='Communication type (default: %s)' % ctype_def.lower()) itype_def = apiconsts.VAL_NETIF_TYPE_IP p_new_node.add_argument('--interface-type', choices=(apiconsts.VAL_NETIF_TYPE_IP.lower(),), type=str.lower, default=itype_def, help='Interface type (default: %s)' % itype_def.lower()) iname_def = 'default' p_new_node.add_argument('--interface-name', default=iname_def, help='Interface name (default: %s)' % iname_def) p_new_node.add_argument( 'name', help='Name of the new node, must match the nodes hostname', type=str) p_new_node.add_argument( 'ip', nargs='?', help='IP address of the new node, if not specified it will be resolved by the name.' ).completer = ip_completer("name") p_new_node.set_defaults(func=self.create) # openflex create p_create_of_target = node_subp.add_parser( NodeCommands.CreateOpenFlexTarget.LONG, aliases=[NodeCommands.CreateOpenFlexTarget.SHORT], description='Creates a virtual on controller openflex target node.' ) p_create_of_target.add_argument( 'node_name', help='Name of the new openflex target node', type=str ) p_create_of_target.add_argument('stor_dev_host', help='OpenFlex storage device host') p_create_of_target.add_argument('stor_dev', help='OpenFlex storage device id') p_create_of_target.set_defaults(func=self.create_of_target) # modify node p_modify_node = node_subp.add_parser( Commands.Subcommands.Modify.LONG, aliases=[Commands.Subcommands.Modify.SHORT], description='Modify a node' ) p_modify_node.add_argument( '--node-type', '-t', choices=[x.lower() for x in node_types], type=str.lower, default=apiconsts.VAL_NODE_TYPE_STLT, help='Node type (default: %s)' % ntype_def.lower() ) p_modify_node.add_argument( 'node_name', help='Name of the node to modify.' ).completer = self.node_completer p_modify_node.set_defaults(func=self.modify_node) # describe-node p_desc_node = node_subp.add_parser( Commands.Subcommands.Describe.LONG, aliases=[Commands.Subcommands.Describe.SHORT], description='describe a node (or all nodes), list storage pools, resources and volumes under this node, ' 'in this order') p_desc_node.add_argument( 'name', nargs='?', help='Name of the node to be described. With no name, all nodes are described' ).completer = self.node_completer p_desc_node.set_defaults(func=self.describe) # remove-node p_rm_node = node_subp.add_parser( Commands.Subcommands.Delete.LONG, aliases=[Commands.Subcommands.Delete.SHORT], description='Removes a node from the linstor cluster. ' 'All linstor resources that are still deployed on the specified ' 'node are marked for undeployment, and the node entry is marked for ' "removal from linstor's data tables. The specified node is " 'expected to undeploy all resources. As soon as all resources have been ' 'undeployed from the node, the node entry is removed from ' "linstor's data tables.") p_rm_node.add_argument( '--async', action='store_true', help='Deprecated, kept for compatibility' ) p_rm_node.add_argument('name', help='Name of the node to remove').completer = self.node_completer p_rm_node.set_defaults(func=self.delete) # lost-node p_lost_node = node_subp.add_parser( Commands.Subcommands.Lost.LONG, aliases=[Commands.Subcommands.Lost.SHORT], description='Removes an unrecoverable node from the linstor cluster. ' 'All linstor resources attached to this node will be deleted from the database.' ) p_lost_node.add_argument( '--async', action='store_true', help='Deprecated, kept for compatibility' ) p_lost_node.add_argument( 'name', help='Name of the node to delete.').completer = self.node_completer p_lost_node.set_defaults(func=self.lost) # reconnect node(s) p_recon_node = node_subp.add_parser( NodeCommands.Reconnect.LONG, aliases=[NodeCommands.Reconnect.SHORT], description='Reconnect a node reinitializing the nodes state.' ) p_recon_node.add_argument( 'nodes', nargs="+", help='List of nodes to reconnect.' ).completer = self.node_completer p_recon_node.set_defaults(func=self.reconnect) # Interface commands netif_subcmds = [ Commands.Subcommands.Create, Commands.Subcommands.List, Commands.Subcommands.Modify, Commands.Subcommands.Delete ] interface_parser = node_subp.add_parser( Commands.Subcommands.Interface.LONG, formatter_class=argparse.RawTextHelpFormatter, aliases=[Commands.Subcommands.Interface.SHORT], description="%s subcommands" % Commands.Subcommands.Interface.LONG) interface_subp = interface_parser.add_subparsers( title="%s subcommands" % Commands.Subcommands.Interface.LONG, metavar="", description=Commands.Subcommands.generate_desc(netif_subcmds)) # create net interface p_create_netinterface = interface_subp.add_parser( Commands.Subcommands.Create.LONG, aliases=[Commands.Subcommands.Create.SHORT], description='Creates and adds a new netinterface to a given node.' ' If port is specified this net interface is used as satellite port' ) p_create_netinterface.add_argument( '-p', '--port', type=rangecheck(1, 65535), help='Port to use for satellite connections' ) p_create_netinterface.add_argument( '--communication-type', choices=(apiconsts.VAL_NETCOM_TYPE_PLAIN.lower(), apiconsts.VAL_NETCOM_TYPE_SSL.lower()), type=str.lower, default=ctype_def, help='Communication type (default: %s)' % ctype_def.lower() ) p_create_netinterface.add_argument( '--active', action='store_true', help='Create this net interface as the active satellite connection' ) p_create_netinterface.add_argument( "node_name", help="Name of the node to add the net interface" ).completer = self.node_completer p_create_netinterface.add_argument("interface_name", help="Interface name") p_create_netinterface.add_argument('ip', help='New IP address for the network interface') p_create_netinterface.set_defaults(func=self.create_netif) # modify net interface p_mod_netif = interface_subp.add_parser( Commands.Subcommands.Modify.LONG, aliases=[Commands.Subcommands.Modify.SHORT], description='Change the ip listen address of a netinterface on the given node.' ) p_mod_netif.add_argument( '-p', '--port', type=rangecheck(1, 65535), help='Port to use for satellite connections' ) p_mod_netif.add_argument( '--communication-type', choices=(apiconsts.VAL_NETCOM_TYPE_PLAIN.lower(), apiconsts.VAL_NETCOM_TYPE_SSL.lower()), type=str.lower, default=ctype_def, help='Communication type (default: %s)' % ctype_def.lower() ) p_mod_netif.add_argument( '--active', action='store_true', help='Set this net interface as the active satellite connection' ) p_mod_netif.add_argument('--ip', help='New IP address for the network interface') p_mod_netif.add_argument("node_name", help="Name of the node").completer = self.node_completer p_mod_netif.add_argument("interface_name", help="Interface to change").completer = self.netif_completer p_mod_netif.set_defaults(func=self.modify_netif) # delete net interface p_delete_netinterface = interface_subp.add_parser( Commands.Subcommands.Delete.LONG, aliases=[Commands.Subcommands.Delete.SHORT], description='Delete a netinterface from a node.' ) p_delete_netinterface.add_argument( "node_name", help="Name of the node to remove the net interface" ).completer = self.node_completer p_delete_netinterface.add_argument( "interface_name", nargs='+', help="Interface name" ).completer = self.netif_completer p_delete_netinterface.set_defaults(func=self.delete_netif) # list nodes node_groupby = [x.name.lower() for x in self._node_headers] node_group_completer = Commands.show_group_completer(node_groupby, "groupby") p_lnodes = node_subp.add_parser( Commands.Subcommands.List.LONG, aliases=[Commands.Subcommands.List.SHORT], description='Prints a list of all cluster nodes known to linstor. ' 'By default, the list is printed as a human readable table.') p_lnodes.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lnodes.add_argument('-g', '--groupby', nargs='+', type=str.lower, choices=node_groupby).completer = node_group_completer p_lnodes.add_argument('-n', '--nodes', nargs='+', type=str, help='Filter by list of nodes').completer = self.node_completer p_lnodes.add_argument('--show-aux-props', action="store_true", help='Show aux properties for nodes') p_lnodes.add_argument('--props', nargs='+', type=str, help='Filter list by object properties') p_lnodes.set_defaults(func=self.list) # list info p_info_node = node_subp.add_parser( Commands.Subcommands.Info.LONG, aliases=[Commands.Subcommands.Info.SHORT], description='Prints detailed info for all cluster nodes known to linstor. ' 'By default, the list is printed as a human readable table.' ) p_info_node.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_info_node.add_argument( '-n', '--nodes', nargs='+', type=str, help='Filter by list of nodes' ).completer = self.node_completer p_info_node.set_defaults(func=self.info) # list netinterface p_lnetif = interface_subp.add_parser( Commands.Subcommands.List.LONG, aliases=[Commands.Subcommands.List.SHORT], description='Prints a list of netinterfaces of a node.' ) p_lnetif.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lnetif.add_argument( 'node_name', help='Node name for which to print the net interfaces' ).completer = self.node_completer p_lnetif.set_defaults(func=self.list_netinterfaces) # show properties p_sp = node_subp.add_parser( Commands.Subcommands.ListProperties.LONG, aliases=[Commands.Subcommands.ListProperties.SHORT], description="Prints all properties of the given node.") p_sp.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_sp.add_argument( 'node_name', help="Node for which to print the properties").completer = self.node_completer p_sp.set_defaults(func=self.print_props) # set properties p_setp = node_subp.add_parser( Commands.Subcommands.SetProperty.LONG, aliases=[Commands.Subcommands.SetProperty.SHORT], formatter_class=argparse.RawTextHelpFormatter, description="Set a property on the given node." ) p_setp.add_argument( 'node_name', help="Node for which to set the property" ).completer = self.node_completer Commands.add_parser_keyvalue(p_setp, "node") p_setp.set_defaults(func=self.set_props) # restore evicted node p_restore_node = node_subp.add_parser( Commands.Subcommands.Restore.LONG, aliases=[Commands.Subcommands.Restore.SHORT], formatter_class=argparse.RawTextHelpFormatter, description="Restore an evicted node." ) p_restore_node.add_argument( 'node_name', help="Evicted node to restore" ).completer = self.node_completer p_restore_node.set_defaults(func=self.restore_node) self.check_subcommands(interface_subp, netif_subcmds) self.check_subcommands(node_subp, subcmds)
def setup_commands(self, parser): """ :param argparse.ArgumentParser parser: :return: """ subcmds = [ Commands.Subcommands.Create, Commands.Subcommands.List, Commands.Subcommands.ListVolumes, Commands.Subcommands.Delete, Commands.Subcommands.SetProperty, Commands.Subcommands.ListProperties, Commands.Subcommands.DrbdPeerDeviceOptions ] # Resource subcommands res_parser = parser.add_parser( Commands.RESOURCE, aliases=["r"], formatter_class=argparse.RawTextHelpFormatter, description="Resouce subcommands") res_subp = res_parser.add_subparsers( title="resource commands", metavar="", description=Commands.Subcommands.generate_desc(subcmds)) # new-resource p_new_res = res_subp.add_parser( Commands.Subcommands.Create.LONG, aliases=[Commands.Subcommands.Create.SHORT], description='Deploys a resource definition to a node.') p_new_res.add_argument('--storage-pool', '-s', type=namecheck(STORPOOL_NAME), help="Storage pool name to use." ).completer = self.storage_pool_dfn_completer p_new_res.add_argument('--diskless', '-d', action="store_true", help='Should the resource be diskless') p_new_res.add_argument( '--async', action='store_true', help='Do not wait for deployment on satellites before returning') p_new_res.add_argument( '--auto-place', type=int, metavar="REPLICA_COUNT", help='Auto place a resource to a specified number of nodes') p_new_res.add_argument( '--do-not-place-with', type=namecheck(RES_NAME), nargs='+', metavar="RESOURCE_NAME", help= 'Try to avoid nodes that already have a given resource deployed.' ).completer = self.resource_completer p_new_res.add_argument( '--do-not-place-with-regex', type=str, metavar="RESOURCE_REGEX", help='Try to avoid nodes that already have a resource ' + 'deployed whos name is matching the given regular expression.') p_new_res.add_argument( '--replicas-on-same', nargs='+', default=[], metavar="AUX_NODE_PROPERTY", help= 'Tries to place resources on nodes with the same given auxiliary node property values.' ) p_new_res.add_argument( '--replicas-on-different', nargs='+', default=[], metavar="AUX_NODE_PROPERTY", help= 'Tries to place resources on nodes with a different value for the given auxiliary node property.' ) p_new_res.add_argument( '--diskless-on-remaining', action="store_true", help='Will add a diskless resource on all non replica nodes.') p_new_res.add_argument('node_name', type=namecheck(NODE_NAME), nargs='*', help='Name of the node to deploy the resource' ).completer = self.node_completer p_new_res.add_argument('resource_definition_name', type=namecheck(RES_NAME), help='Name of the resource definition' ).completer = self.resource_dfn_completer p_new_res.set_defaults(func=self.create) # remove-resource p_rm_res = res_subp.add_parser( Commands.Subcommands.Delete.LONG, aliases=[Commands.Subcommands.Delete.SHORT], description='Removes a resource. ' 'The resource is undeployed from the node ' "and the resource entry is marked for removal from linstor's data " 'tables. After the node has undeployed the resource, the resource ' "entry is removed from linstor's data tables.") p_rm_res.add_argument( '-q', '--quiet', action="store_true", help= 'Unless this option is used, linstor will issue a safety question ' 'that must be answered with yes, otherwise the operation is canceled.' ) p_rm_res.add_argument( '--async', action='store_true', help='Do not wait for deployment on satellites before returning') p_rm_res.add_argument( 'node_name', nargs="+", help='Name of the node').completer = self.node_completer p_rm_res.add_argument('name', help='Name of the resource to delete' ).completer = self.resource_completer p_rm_res.set_defaults(func=self.delete) resgroupby = [x.name for x in ResourceCommands._resource_headers] res_group_completer = Commands.show_group_completer( resgroupby, "groupby") p_lreses = res_subp.add_parser( Commands.Subcommands.List.LONG, aliases=[Commands.Subcommands.List.SHORT], description='Prints a list of all resource definitions known to ' 'linstor. By default, the list is printed as a human readable table.' ) p_lreses.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lreses.add_argument( '-g', '--groupby', nargs='+', choices=resgroupby).completer = res_group_completer p_lreses.add_argument('-r', '--resources', nargs='+', type=namecheck(RES_NAME), help='Filter by list of resources' ).completer = self.resource_completer p_lreses.add_argument( '-n', '--nodes', nargs='+', type=namecheck(NODE_NAME), help='Filter by list of nodes').completer = self.node_completer p_lreses.set_defaults(func=self.list) # list volumes p_lvlms = res_subp.add_parser( Commands.Subcommands.ListVolumes.LONG, aliases=[Commands.Subcommands.ListVolumes.SHORT], description='Prints a list of all volumes.') p_lvlms.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lvlms.add_argument( '-n', '--nodes', nargs='+', type=namecheck(NODE_NAME), help='Filter by list of nodes').completer = self.node_completer p_lvlms.add_argument('-s', '--storpools', nargs='+', type=namecheck(STORPOOL_NAME), help='Filter by list of storage pools' ).completer = self.storage_pool_completer p_lvlms.add_argument('-r', '--resources', nargs='+', type=namecheck(RES_NAME), help='Filter by list of resources' ).completer = self.resource_completer p_lvlms.set_defaults(func=self.list_volumes) # show properties p_sp = res_subp.add_parser( Commands.Subcommands.ListProperties.LONG, aliases=[Commands.Subcommands.ListProperties.SHORT], description="Prints all properties of the given resource.") p_sp.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_sp.add_argument('node_name', help="Node name where the resource is deployed." ).completer = self.node_completer p_sp.add_argument( 'resource_name', help="Resource name").completer = self.resource_completer p_sp.set_defaults(func=self.print_props) # set properties p_setprop = res_subp.add_parser( Commands.Subcommands.SetProperty.LONG, aliases=[Commands.Subcommands.SetProperty.SHORT], description= 'Sets properties for the given resource on the given node.') p_setprop.add_argument('node_name', type=namecheck(NODE_NAME), help='Node name where resource is deployed.' ).completer = self.node_completer p_setprop.add_argument( 'name', type=namecheck(RES_NAME), help='Name of the resource').completer = self.resource_completer Commands.add_parser_keyvalue(p_setprop, "resource") p_setprop.set_defaults(func=self.set_props) # drbd peer device options p_drbd_peer_opts = res_subp.add_parser( Commands.Subcommands.DrbdPeerDeviceOptions.LONG, aliases=[Commands.Subcommands.DrbdPeerDeviceOptions.SHORT], description="Set drbd peer-device options.") p_drbd_peer_opts.add_argument('node_a', type=namecheck(NODE_NAME), help="1. Node in the node connection" ).completer = self.node_completer p_drbd_peer_opts.add_argument('node_b', type=namecheck(NODE_NAME), help="1. Node in the node connection" ).completer = self.node_completer p_drbd_peer_opts.add_argument( 'resource_name', type=namecheck(RES_NAME), help="Resource name").completer = self.resource_completer DrbdOptions.add_arguments(p_drbd_peer_opts, [ x for x in DrbdOptions.drbd_options()['options'] if DrbdOptions. drbd_options()['options'][x]['category'] == 'peer-device-options' ]) p_drbd_peer_opts.set_defaults(func=self.drbd_peer_opts) self.check_subcommands(res_subp, subcmds)
def setup_commands(self, parser): # Node subcommands subcmds = [ Commands.Subcommands.Create, Commands.Subcommands.List, Commands.Subcommands.Delete, Commands.Subcommands.Lost, Commands.Subcommands.Describe, Commands.Subcommands.Interface, Commands.Subcommands.SetProperty, Commands.Subcommands.ListProperties ] node_parser = parser.add_parser( Commands.NODE, aliases=["n"], formatter_class=argparse.RawTextHelpFormatter, description="Node subcommands") node_subp = node_parser.add_subparsers( title="Node commands", metavar="", description=Commands.Subcommands.generate_desc(subcmds)) # create node p_new_node = node_subp.add_parser( Commands.Subcommands.Create.LONG, aliases=[Commands.Subcommands.Create.SHORT], description= 'Creates a node entry for a node that participates in the ' 'linstor cluster.') p_new_node.add_argument( '-p', '--port', type=rangecheck(1, 65535), help='default: Satellite %s for %s; Controller %s for %s; %s for %s' % (DFLT_STLT_PORT_PLAIN, VAL_NETCOM_TYPE_PLAIN, DFLT_CTRL_PORT_PLAIN, VAL_NETCOM_TYPE_PLAIN, DFLT_CTRL_PORT_SSL, VAL_NETCOM_TYPE_SSL)) ntype_def = VAL_NODE_TYPE_STLT p_new_node.add_argument('--node-type', choices=(VAL_NODE_TYPE_CTRL, VAL_NODE_TYPE_AUX, VAL_NODE_TYPE_CMBD, VAL_NODE_TYPE_STLT), default=VAL_NODE_TYPE_STLT, help='Node type (default: %s)' % ntype_def) ctype_def = VAL_NETCOM_TYPE_PLAIN p_new_node.add_argument( '--communication-type', choices=(VAL_NETCOM_TYPE_PLAIN, VAL_NETCOM_TYPE_SSL), default=ctype_def, help='Communication type (default: %s)' % ctype_def) itype_def = VAL_NETIF_TYPE_IP p_new_node.add_argument('--interface-type', choices=(VAL_NETIF_TYPE_IP, ), default=itype_def, help='Interface type (default: %s)' % itype_def) iname_def = 'default' p_new_node.add_argument('--interface-name', default=iname_def, help='Interface name (default: %s)' % iname_def) p_new_node.add_argument( 'name', help='Name of the new node, must match the nodes hostname', type=namecheck(NODE_NAME)) p_new_node.add_argument( 'ip', help='IP address of the new node').completer = ip_completer("name") p_new_node.set_defaults(func=self.create) #describe-node p_desc_node = node_subp.add_parser( Commands.Subcommands.Describe.LONG, aliases=[Commands.Subcommands.Describe.SHORT], description= 'describe a node (or all nodes), list storage pools, resources and volumes under this node, ' 'in this order') p_desc_node.add_argument( 'name', nargs='?', help= 'Name of the node to be described. With no name, all nodes are described' ).completer = self.node_completer p_desc_node.set_defaults(func=self.describe) # remove-node p_rm_node = node_subp.add_parser( Commands.Subcommands.Delete.LONG, aliases=[Commands.Subcommands.Delete.SHORT], description='Removes a node from the linstor cluster. ' 'All linstor resources that are still deployed on the specified ' 'node are marked for undeployment, and the node entry is marked for ' "removal from linstor's data tables. The specified node is " 'expected to undeploy all resources. As soon as all resources have been ' 'undeployed from the node, the node entry is removed from ' "linstor's data tables.") p_rm_node.add_argument( '-q', '--quiet', action="store_true", help= 'Unless this option is used, linstor will issue a safety question ' 'that must be answered with yes, otherwise the operation is canceled.' ) p_rm_node.add_argument( 'name', help='Name of the node to remove').completer = self.node_completer p_rm_node.set_defaults(func=self.delete) # lost-node p_lost_node = node_subp.add_parser( Commands.Subcommands.Lost.LONG, aliases=[Commands.Subcommands.Lost.SHORT], description= 'Removes an unrecoverable node from the linstor cluster. ' 'All linstor resources attached to this node will be deleted from the database.' ) p_lost_node.add_argument( 'name', help='Name of the node to delete.').completer = self.node_completer p_lost_node.set_defaults(func=self.lost) # Interface commands netif_subcmds = [ Commands.Subcommands.Create, Commands.Subcommands.List, Commands.Subcommands.Modify, Commands.Subcommands.Delete ] interface_parser = node_subp.add_parser( Commands.Subcommands.Interface.LONG, formatter_class=argparse.RawTextHelpFormatter, aliases=[Commands.Subcommands.Interface.SHORT], description="%s subcommands" % Commands.Subcommands.Interface.LONG) interface_subp = interface_parser.add_subparsers( title="%s subcommands" % Commands.Subcommands.Interface.LONG, metavar="", description=Commands.Subcommands.generate_desc(netif_subcmds)) # create net interface p_create_netinterface = interface_subp.add_parser( Commands.Subcommands.Create.LONG, aliases=[Commands.Subcommands.Create.SHORT], description= 'Creates and adds a new netinterface to a given node. If port is specified this netinterface ' 'is used as satellite port') p_create_netinterface.add_argument( '-p', '--port', type=rangecheck(1, 65535), help='Port to use for satellite connections') p_create_netinterface.add_argument( '--communication-type', choices=(VAL_NETCOM_TYPE_PLAIN, VAL_NETCOM_TYPE_SSL), default=ctype_def, help='Communication type (default: %s)' % ctype_def) p_create_netinterface.add_argument( "node_name", help="Name of the node to add the net interface" ).completer = self.node_completer p_create_netinterface.add_argument("interface_name", help="Interface name") p_create_netinterface.add_argument( 'ip', help='New IP address for the network interface') p_create_netinterface.set_defaults(func=self.create_netif) # modify net interface p_mod_netif = interface_subp.add_parser( Commands.Subcommands.Modify.LONG, aliases=[Commands.Subcommands.Modify.SHORT], description= 'Change the ip listen address of a netinterface on the given node.' ) p_mod_netif.add_argument('-p', '--port', type=rangecheck(1, 65535), help='Port to use for satellite connections') p_mod_netif.add_argument( '--communication-type', choices=(VAL_NETCOM_TYPE_PLAIN, VAL_NETCOM_TYPE_SSL), default=ctype_def, help='Communication type (default: %s)' % ctype_def) p_mod_netif.add_argument( "node_name", help="Name of the node").completer = self.node_completer p_mod_netif.add_argument( "interface_name", help="Interface name to change").completer = self.netif_completer p_mod_netif.add_argument( 'ip', help='New IP address for the network interface') p_mod_netif.set_defaults(func=self.modify_netif) # delete net interface p_delete_netinterface = interface_subp.add_parser( Commands.Subcommands.Delete.LONG, aliases=[Commands.Subcommands.Delete.SHORT], description='Delete a netinterface from a node.') p_delete_netinterface.add_argument( "node_name", help="Name of the node to remove the net interface" ).completer = self.node_completer p_delete_netinterface.add_argument( "interface_name", nargs='+', help="Interface name").completer = self.netif_completer p_delete_netinterface.set_defaults(func=self.delete_netif) # list nodes node_groupby = [x.name for x in self._node_headers] node_group_completer = Commands.show_group_completer( node_groupby, "groupby") p_lnodes = node_subp.add_parser( Commands.Subcommands.List.LONG, aliases=[Commands.Subcommands.List.SHORT], description='Prints a list of all cluster nodes known to linstor. ' 'By default, the list is printed as a human readable table.') p_lnodes.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lnodes.add_argument( '-g', '--groupby', nargs='+', choices=node_groupby).completer = node_group_completer p_lnodes.add_argument( '-N', '--nodes', nargs='+', type=namecheck(NODE_NAME), help='Filter by list of nodes').completer = self.node_completer p_lnodes.set_defaults(func=self.list) # list netinterface p_lnetif = interface_subp.add_parser( Commands.Subcommands.List.LONG, aliases=[Commands.Subcommands.List.SHORT], description='Prints a list of netinterfaces from a node.') p_lnetif.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lnetif.add_argument( 'node_name', help='Node name for which to print the net interfaces' ).completer = self.node_completer p_lnetif.set_defaults(func=self.list_netinterfaces) # show properties p_sp = node_subp.add_parser( Commands.Subcommands.ListProperties.LONG, aliases=[Commands.Subcommands.ListProperties.SHORT], description="Prints all properties of the given node.") p_sp.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_sp.add_argument('node_name', help="Node for which to print the properties" ).completer = self.node_completer p_sp.set_defaults(func=self.print_props) # set properties p_setp = node_subp.add_parser( Commands.Subcommands.SetProperty.LONG, aliases=[Commands.Subcommands.SetProperty.SHORT], description="Set a property on the given node.") p_setp.add_argument('node_name', help="Node for which to set the property" ).completer = self.node_completer Commands.add_parser_keyvalue(p_setp, "node") p_setp.set_defaults(func=self.set_props) self.check_subcommands(interface_subp, netif_subcmds) self.check_subcommands(node_subp, subcmds)
def setup_commands(self, parser): subcmds = [ Commands.Subcommands.Create, Commands.Subcommands.List, Commands.Subcommands.Delete, Commands.Subcommands.SetProperty, Commands.Subcommands.ListProperties, Commands.Subcommands.DrbdOptions ] # volume group subcommands vlm_grp_parser = parser.add_parser( Commands.VOLUME_GRP, aliases=["vg"], formatter_class=argparse.RawTextHelpFormatter, description="Resource definition subcommands") vlm_grp_subp = vlm_grp_parser.add_subparsers( title="resource definition subcommands", metavar="", description=Commands.Subcommands.generate_desc(subcmds)) # ------------ CREATE START p_new_vlm_grp = vlm_grp_subp.add_parser( Commands.Subcommands.Create.LONG, aliases=[Commands.Subcommands.Create.SHORT], description='Defines a Linstor volume group for use with linstor.') p_new_vlm_grp.add_argument('name', type=str, help='Name of the resource group.') p_new_vlm_grp.add_argument('-n', '--vlmnr', type=int) p_new_vlm_grp.set_defaults(func=self.create) # ------------ CREATE END # ------------ DELETE START p_rm_vlm_grp = vlm_grp_subp.add_parser( Commands.Subcommands.Delete.LONG, aliases=[Commands.Subcommands.Delete.SHORT], description=" Removes a volume group from the linstor cluster.") p_rm_vlm_grp.add_argument('name', help='Name of the resource group' ).completer = self.resource_grp_completer p_rm_vlm_grp.add_argument('volume_nr', type=int, help="Volume number to delete.") p_rm_vlm_grp.set_defaults(func=self.delete) # ------------ DELETE END # ------------ LIST START vlm_grp_groupby = [x.name for x in self._vlm_grp_headers] vlm_grp_group_completer = Commands.show_group_completer( vlm_grp_groupby, "groupby") p_lvlmgrps = vlm_grp_subp.add_parser( Commands.Subcommands.List.LONG, aliases=[Commands.Subcommands.List.SHORT], description= 'Prints a list of all volume groups for a resource group known to ' 'linstor. By default, the list is printed as a human readable table.' ) p_lvlmgrps.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lvlmgrps.add_argument( '-g', '--groupby', nargs='+', choices=vlm_grp_groupby).completer = vlm_grp_group_completer p_lvlmgrps.add_argument('-R', '--resources', nargs='+', type=str, help='Filter by list of resource groups' ).completer = self.resource_grp_completer p_lvlmgrps.add_argument('name', help="Resource group name.") p_lvlmgrps.set_defaults(func=self.list) # ------------ LIST END # ------------ LISTPROPS START p_sp = vlm_grp_subp.add_parser( Commands.Subcommands.ListProperties.LONG, aliases=[Commands.Subcommands.ListProperties.SHORT], description="Prints all properties of the given volume group.") p_sp.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_sp.add_argument( 'name', help="Resource group for which to print the properties" ).completer = self.resource_grp_completer p_sp.add_argument('volume_nr', type=int, help="Volume number") p_sp.set_defaults(func=self.print_props) # ------------ LISTPROPS END # ------------ SETPROPS START p_setprop = vlm_grp_subp.add_parser( Commands.Subcommands.SetProperty.LONG, aliases=[Commands.Subcommands.SetProperty.SHORT], formatter_class=argparse.RawTextHelpFormatter, description='Sets properties for the given volume group.') p_setprop.add_argument('name', type=str, help='Name of the resource group') p_setprop.add_argument('volume_nr', type=int, help="Volume number") Commands.add_parser_keyvalue(p_setprop, self.OBJECT_NAME) p_setprop.set_defaults(func=self.set_props) # ------------ SETPROPS END # ------------ SETDRBDOPTS START p_drbd_opts = vlm_grp_subp.add_parser( Commands.Subcommands.DrbdOptions.LONG, aliases=[Commands.Subcommands.DrbdOptions.SHORT], description=DrbdOptions.description("resource")) p_drbd_opts.add_argument( 'name', type=str, help="Resource group name").completer = self.resource_grp_completer p_drbd_opts.add_argument('volume_nr', type=int, help="Volume number") DrbdOptions.add_arguments(p_drbd_opts, self.OBJECT_NAME) p_drbd_opts.set_defaults(func=self.set_drbd_opts) # ------------ SETDRBDOPTS END self.check_subcommands(vlm_grp_subp, subcmds)
def setup_commands(self, parser): subcmds = [ Commands.Subcommands.Create, Commands.Subcommands.MakeAvailable, Commands.Subcommands.List, Commands.Subcommands.ListVolumes, Commands.Subcommands.Delete, Commands.Subcommands.SetProperty, Commands.Subcommands.ListProperties, Commands.Subcommands.DrbdPeerDeviceOptions, Commands.Subcommands.ToggleDisk, Commands.Subcommands.CreateTransactional, Commands.Subcommands.Activate, Commands.Subcommands.Deactivate, Commands.Subcommands.Involved ] # Resource subcommands res_parser = parser.add_parser( Commands.RESOURCE, aliases=["r"], formatter_class=argparse.RawTextHelpFormatter, description="Resouce subcommands") res_subp = res_parser.add_subparsers( title="resource commands", metavar="", description=Commands.Subcommands.generate_desc(subcmds) ) # new-resource p_new_res = res_subp.add_parser( Commands.Subcommands.Create.LONG, aliases=[Commands.Subcommands.Create.SHORT], description='Deploys a resource definition to a node.') p_new_res.add_argument( '--diskless', '-d', action="store_true", help='DEPRECATED. Use --nvme-initiator or --drbd-diskless instead' ) p_new_res.add_argument( '--node-id', type=int, help='Override the automatic selection of DRBD node ID' ) p_new_res.add_argument( '--async', action='store_true', help='Deprecated, kept for compatibility' ) p_new_res.add_argument( '--nvme-initiator', action="store_true", help='Mark this resource as initiator' ) p_new_res.add_argument( '--drbd-diskless', action="store_true", help='Mark this resource as drbd diskless' ) p_new_res.add_argument( '--inactive', action="store_true", help="Marks the resource created as inactive" ) self.add_auto_select_argparse_arguments(p_new_res) p_new_res.add_argument( 'node_name', type=str, nargs='*', help='Name of the node to deploy the resource').completer = self.node_completer p_new_res.add_argument( 'resource_definition_name', type=str, help='Name of the resource definition').completer = self.resource_dfn_completer p_new_res.set_defaults(func=self.create, allowed_states=[DefaultState, ResourceCreateTransactionState]) # make available p_mkavial = res_subp.add_parser( Commands.Subcommands.MakeAvailable.LONG, aliases=[Commands.Subcommands.MakeAvailable.SHORT], description='Make a resource available on a node, noop if already exists.') p_mkavial.add_argument( '--diskful', action="store_true", help='Make the resource diskful on the node.' ) p_mkavial.add_argument( '-l', '--layer-list', type=self.layer_data_check, help="Comma separated layer list, order is from left to right top-down " "This means the top most layer is on the left. " "Possible layers are: " + ",".join(linstor.Linstor.layer_list())) p_mkavial.add_argument( 'node_name', type=str, help='Name of the node to deploy the resource').completer = self.node_completer p_mkavial.add_argument( 'resource_name', type=str, help='Name of the resource definition').completer = self.resource_dfn_completer p_mkavial.set_defaults(func=self.make_available) # remove-resource p_rm_res = res_subp.add_parser( Commands.Subcommands.Delete.LONG, aliases=[Commands.Subcommands.Delete.SHORT], description='Removes a resource. ' 'The resource is undeployed from the node ' "and the resource entry is marked for removal from linstor's data " 'tables. After the node has undeployed the resource, the resource ' "entry is removed from linstor's data tables.") p_rm_res.add_argument( '--async', action='store_true', help='Deprecated, kept for compatibility' ) p_rm_res.add_argument('node_name', nargs="+", help='Name of the node').completer = self.node_completer p_rm_res.add_argument('name', help='Name of the resource to delete').completer = self.resource_completer p_rm_res.set_defaults(func=self.delete) resgroupby = [x.name.lower() for x in ResourceCommands._resource_headers] res_group_completer = Commands.show_group_completer(resgroupby, "groupby") p_lreses = res_subp.add_parser( Commands.Subcommands.List.LONG, aliases=[Commands.Subcommands.List.SHORT], description='Prints a list of all resource definitions known to ' 'linstor. By default, the list is printed as a human readable table.') p_lreses.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lreses.add_argument( '-g', '--groupby', nargs='+', choices=resgroupby, type=str.lower).completer = res_group_completer p_lreses.add_argument( '-r', '--resources', nargs='+', type=str, help='Filter by list of resources').completer = self.resource_completer p_lreses.add_argument( '-n', '--nodes', nargs='+', type=str, help='Filter by list of nodes').completer = self.node_completer p_lreses.add_argument( '-a', '--all', action="store_true", help='Show all resources.') p_lreses.add_argument( '--faulty', action="store_true", help='Only show faulty resource.') p_lreses.add_argument('--props', nargs='+', type=str, help='Filter list by object properties') p_lreses.set_defaults(func=self.list) p_involved = res_subp.add_parser( Commands.Subcommands.Involved.LONG, aliases=[Commands.Subcommands.Involved.SHORT], description='Prints a list of resourced involved on a given node') p_involved.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_involved.add_argument('-i', '--inuse', action="store_true", help='Only show resource bundles that are used.') p_involved.add_argument( '-d', '--diskless-inuse', action="store_true", help='Only show resource bundles that have a diskless in-use.') p_involved.add_argument( '-m', '--min-diskful', type=int, default=None, help='Only show resource bundles that have less diskful replicas.') p_involved.add_argument( 'node', type=str, help='Node name where a resource is used').completer = self.node_completer p_involved.set_defaults(func=self.involved) # list volumes p_lvlms = res_subp.add_parser( Commands.Subcommands.ListVolumes.LONG, aliases=[Commands.Subcommands.ListVolumes.SHORT], description='Prints a list of all volumes.' ) p_lvlms.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lvlms.add_argument( '-n', '--nodes', nargs='+', type=str, help='Filter by list of nodes').completer = self.node_completer p_lvlms.add_argument('-s', '--storage-pools', nargs='+', type=str, help='Filter by list of storage pools').completer = self.storage_pool_completer p_lvlms.add_argument( '-r', '--resources', nargs='+', type=str, help='Filter by list of resources').completer = self.resource_completer p_lvlms.add_argument( '-a', '--all', action="store_true", help='Show all resources.' ) p_lvlms.set_defaults(func=self.list_volumes) # show properties p_sp = res_subp.add_parser( Commands.Subcommands.ListProperties.LONG, aliases=[Commands.Subcommands.ListProperties.SHORT], description="Prints all properties of the given resource.") p_sp.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_sp.add_argument( 'node_name', help="Node name where the resource is deployed.").completer = self.node_completer p_sp.add_argument( 'resource_name', help="Resource name").completer = self.resource_completer p_sp.set_defaults(func=self.print_props) # set properties p_setprop = res_subp.add_parser( Commands.Subcommands.SetProperty.LONG, aliases=[Commands.Subcommands.SetProperty.SHORT], formatter_class=argparse.RawTextHelpFormatter, description='Sets properties for the given resource on the given node.') p_setprop.add_argument( 'node_name', type=str, help='Node name where resource is deployed.').completer = self.node_completer p_setprop.add_argument( 'name', type=str, help='Name of the resource' ).completer = self.resource_completer Commands.add_parser_keyvalue(p_setprop, "resource") p_setprop.set_defaults(func=self.set_props) # drbd peer device options p_drbd_peer_opts = res_subp.add_parser( Commands.Subcommands.DrbdPeerDeviceOptions.LONG, aliases=[Commands.Subcommands.DrbdPeerDeviceOptions.SHORT], description=DrbdOptions.description("peer-device") ) p_drbd_peer_opts.add_argument( 'node_a', type=str, help="1. Node in the node connection" ).completer = self.node_completer p_drbd_peer_opts.add_argument( 'node_b', type=str, help="1. Node in the node connection" ).completer = self.node_completer p_drbd_peer_opts.add_argument( 'resource_name', type=str, help="Resource name" ).completer = self.resource_completer DrbdOptions.add_arguments(p_drbd_peer_opts, self.CONN_OBJECT_NAME) p_drbd_peer_opts.set_defaults(func=self.drbd_peer_opts) # toggle-disk p_toggle_disk = res_subp.add_parser( Commands.Subcommands.ToggleDisk.LONG, aliases=[Commands.Subcommands.ToggleDisk.SHORT], description='Toggles a resource between diskless and having disks.') p_toggle_disk_group_storage = p_toggle_disk.add_mutually_exclusive_group(required=False) p_toggle_disk_group_storage.add_argument( '--storage-pool', '-s', type=str, help="Add disks to a diskless resource using this storage pool name" ).completer = self.storage_pool_dfn_completer p_toggle_disk_group_storage.add_argument( '--default-storage-pool', '--dflt', action='store_true', help="Add disks to a diskless resource using the storage pools determined from the properties of the " "objects to which the volumes belong" ) p_toggle_disk_group_storage.add_argument( '--diskless', '-d', action='store_true', help="Remove the disks from a resource (toggles --drbd-diskless)" ) p_toggle_disk.add_argument( '--async', action='store_true', help='Deprecated, kept for compatibility' ) p_toggle_disk.add_argument( '--migrate-from', type=str, metavar="MIGRATION_SOURCE", help='Name of the node on which the resource should be deleted once the sync is complete. ' 'Only applicable when adding a disk to a diskless resource. ' 'The command will complete once the new disk has been added; ' 'the deletion will occur later in the background.' ).completer = self.node_completer p_toggle_disk.add_argument( 'node_name', type=str, help='Node name where resource is deployed' ).completer = self.node_completer p_toggle_disk.add_argument( 'name', type=str, help='Name of the resource' ).completer = self.resource_dfn_completer p_toggle_disk.set_defaults(func=self.toggle_disk, parser=p_toggle_disk) # activate/deactivate resource commands p_activate = res_subp.add_parser( Commands.Subcommands.Activate.LONG, aliases=[Commands.Subcommands.Activate.SHORT], description='Activate a resource.') p_activate.add_argument( 'node_name', type=str, help='Node name of the resource').completer = self.node_completer p_activate.add_argument( 'resource_name', type=str, help='Name of the resource').completer = self.resource_dfn_completer p_activate.set_defaults(func=self.activate) p_deactivate = res_subp.add_parser( Commands.Subcommands.Deactivate.LONG, aliases=[Commands.Subcommands.Deactivate.SHORT], description='Deactivate a resource.') p_deactivate.add_argument( 'node_name', type=str, help='Node name of the resource').completer = self.node_completer p_deactivate.add_argument( 'resource_name', type=str, help='Name of the resource').completer = self.resource_dfn_completer p_deactivate.set_defaults(func=self.deactivate) # resource creation transaction commands transactional_create_subcmds = [ Commands.Subcommands.Begin, Commands.Subcommands.Abort, Commands.Subcommands.Commit ] transactional_create_parser = res_subp.add_parser( Commands.Subcommands.CreateTransactional.LONG, formatter_class=argparse.RawTextHelpFormatter, aliases=[Commands.Subcommands.CreateTransactional.SHORT], description="%s subcommands" % Commands.Subcommands.CreateTransactional.LONG) transactional_create_subp = transactional_create_parser.add_subparsers( title="%s subcommands" % Commands.Subcommands.CreateTransactional.LONG, description=Commands.Subcommands.generate_desc(transactional_create_subcmds)) # begin resource creation transaction p_transactional_create_begin = transactional_create_subp.add_parser( Commands.Subcommands.Begin.LONG, aliases=[Commands.Subcommands.Begin.SHORT], description='Start group of resources to create in a single transaction.') p_transactional_create_begin.add_argument( '--terminate-on-error', action='store_true', help='Abort the transaction when any command fails' ) p_transactional_create_begin.set_defaults(func=self.transactional_create_begin) # abort resource creation transaction p_transactional_create_abort = transactional_create_subp.add_parser( Commands.Subcommands.Abort.LONG, aliases=[Commands.Subcommands.Abort.SHORT], description='Abort resource creation transaction.') p_transactional_create_abort.set_defaults( func=self.transactional_create_abort, allowed_states=[ResourceCreateTransactionState]) # commit resource creation transaction p_transactional_create_commit = transactional_create_subp.add_parser( Commands.Subcommands.Commit.LONG, aliases=[Commands.Subcommands.Commit.SHORT], description='Create resources defined in the current resource creation transaction.') p_transactional_create_commit.add_argument( '--async', action='store_true', help='Deprecated, kept for compatibility' ) p_transactional_create_commit.set_defaults( func=self.transactional_create_commit, allowed_states=[ResourceCreateTransactionState]) self.check_subcommands(transactional_create_subp, transactional_create_subcmds) self.check_subcommands(res_subp, subcmds)
def setup_commands(self, parser): # volume definition subcommands subcmds = [ Commands.Subcommands.Create, Commands.Subcommands.List, Commands.Subcommands.Delete, Commands.Subcommands.SetSize, Commands.Subcommands.SetProperty, Commands.Subcommands.ListProperties, Commands.Subcommands.DrbdOptions ] vol_def_parser = parser.add_parser( Commands.VOLUME_DEF, aliases=["vd"], formatter_class=argparse.RawTextHelpFormatter, description="Volume definition subcommands") vol_def_subp = vol_def_parser.add_subparsers( title="Volume definition commands", metavar="", description=Commands.Subcommands.generate_desc(subcmds)) p_new_vol = vol_def_subp.add_parser( Commands.Subcommands.Create.LONG, aliases=[Commands.Subcommands.Create.SHORT], description='Defines a volume with a capacity of size for use with ' 'linstore. If the resource resname exists already, a new volume is ' 'added to that resource, otherwise the resource is created automatically ' 'with default settings. Unless minornr is specified, a minor number for ' "the volume's DRBD block device is assigned automatically by the " 'linstor server.') p_new_vol.add_argument('--storage-pool', '-s', type=namecheck(STORPOOL_NAME), help="Storage pool name to use." ).completer = self.storage_pool_dfn_completer p_new_vol.add_argument('-n', '--vlmnr', type=int) p_new_vol.add_argument('-m', '--minor', type=int) p_new_vol.add_argument( '--encrypt', action="store_true", help="Encrypt created volumes using cryptsetup.") p_new_vol.add_argument('resource_name', type=namecheck(RES_NAME), help='Name of an existing resource' ).completer = self.resource_dfn_completer p_new_vol.add_argument( 'size', help=VolumeDefinitionCommands.VOLUME_SIZE_HELP ).completer = VolumeDefinitionCommands.size_completer p_new_vol.set_defaults(func=self.create) # remove-volume definition p_rm_vol = vol_def_subp.add_parser( Commands.Subcommands.Delete.LONG, aliases=[Commands.Subcommands.Delete.SHORT], description= 'Removes a volume definition from the linstor cluster, and removes ' 'the volume definition from the resource definition. The volume is ' 'undeployed from all nodes and the volume entry is marked for removal ' "from the resource definition in linstor's data tables. After all " 'nodes have undeployed the volume, the volume entry is removed from ' 'the resource definition.') p_rm_vol.add_argument( '-q', '--quiet', action="store_true", help= 'Unless this option is used, linstor will issue a safety question ' 'that must be answered with yes, otherwise the operation is canceled.' ) p_rm_vol.add_argument('resource_name', help='Resource name of the volume definition' ).completer = self.resource_dfn_completer p_rm_vol.add_argument('volume_nr', type=int, help="Volume number to delete.") p_rm_vol.set_defaults(func=self.delete) # list volume definitions vlm_dfn_groupby = [x.name for x in self._vlm_dfn_headers] vlm_dfn_group_completer = Commands.show_group_completer( vlm_dfn_groupby, "groupby") p_lvols = vol_def_subp.add_parser( Commands.Subcommands.List.LONG, aliases=[Commands.Subcommands.List.SHORT], description= ' Prints a list of all volume definitions known to linstor. ' 'By default, the list is printed as a human readable table.') p_lvols.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lvols.add_argument( '-g', '--groupby', nargs='+', choices=vlm_dfn_groupby).completer = vlm_dfn_group_completer p_lvols.add_argument('-R', '--resources', nargs='+', type=namecheck(RES_NAME), help='Filter by list of resources' ).completer = self.resource_dfn_completer p_lvols.set_defaults(func=self.list) # show properties p_sp = vol_def_subp.add_parser( Commands.Subcommands.ListProperties.LONG, aliases=[Commands.Subcommands.ListProperties.SHORT], description="Prints all properties of the given volume definition." ) p_sp.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_sp.add_argument( 'resource_name', help="Resource name").completer = self.resource_dfn_completer p_sp.add_argument('volume_nr', type=int, help="Volume number") p_sp.set_defaults(func=self.print_props) # set properties p_setprop = vol_def_subp.add_parser( Commands.Subcommands.SetProperty.LONG, aliases=[Commands.Subcommands.SetProperty.SHORT], description='Sets properties for the given volume definition.') p_setprop.add_argument( 'resource_name', help="Resource name").completer = self.resource_dfn_completer p_setprop.add_argument('volume_nr', type=int, help="Volume number") Commands.add_parser_keyvalue(p_setprop, "volume-definition") p_setprop.set_defaults(func=self.set_props) p_drbd_opts = vol_def_subp.add_parser( Commands.Subcommands.DrbdOptions.LONG, aliases=[Commands.Subcommands.DrbdOptions.SHORT], description="Set drbd volume options.") p_drbd_opts.add_argument( 'resource_name', type=namecheck(RES_NAME), help="Resource name").completer = self.resource_dfn_completer p_drbd_opts.add_argument('volume_nr', type=int, help="Volume number") DrbdOptions.add_arguments(p_drbd_opts, [ x for x in DrbdOptions.drbd_options()['options'] if x in DrbdOptions.drbd_options()['filters']['volume'] ]) p_drbd_opts.set_defaults(func=self.set_drbd_opts) # set size p_set_size = vol_def_subp.add_parser( Commands.Subcommands.SetSize.LONG, aliases=[Commands.Subcommands.SetSize.SHORT], description='Change the size of a volume. ' 'Decreasing the size is only supported when the resource definition does not have any ' 'resources. ' 'Increasing the size is supported even when the resource definition has resources. ' 'Filesystems present on the volumes will not be resized.') p_set_size.add_argument('resource_name', type=namecheck(RES_NAME), help='Name of an existing resource' ).completer = self.resource_dfn_completer p_set_size.add_argument('volume_nr', type=int, help="Volume number") p_set_size.add_argument( 'size', help=VolumeDefinitionCommands.VOLUME_SIZE_HELP ).completer = VolumeDefinitionCommands.size_completer p_set_size.set_defaults(func=self.set_volume_size) self.check_subcommands(vol_def_subp, subcmds)
def setup_commands(self, parser): # Storage pool subcommands subcmds = [ Commands.Subcommands.Create, Commands.Subcommands.List, Commands.Subcommands.Delete, Commands.Subcommands.SetProperty, Commands.Subcommands.ListProperties ] sp_parser = parser.add_parser( Commands.STORAGE_POOL, aliases=["sp"], formatter_class=argparse.RawTextHelpFormatter, description="Storage pool subcommands") sp_subp = sp_parser.add_subparsers( title="Storage pool commands", metavar="", description=Commands.Subcommands.generate_desc(subcmds) ) # new-storpol p_new_storpool = sp_subp.add_parser( Commands.Subcommands.Create.LONG, aliases=[Commands.Subcommands.Create.SHORT], description='Defines a Linstor storage pool for use with Linstor.') p_new_storpool.add_argument( 'node_name', type=namecheck(NODE_NAME), help='Name of the node for the new storage pool').completer = self.node_completer p_new_storpool.add_argument('name', type=namecheck(STORPOOL_NAME), help='Name of the new storage pool') p_new_storpool.add_argument( 'driver', choices=StoragePoolCommands.driver_completer(""), help='Name of the driver used for the new storage pool').completer = StoragePoolCommands.driver_completer p_new_storpool.add_argument( 'driver_pool_name', type=str, nargs='?', help='Volume group/pool to use, e.g. drbdpool. ' 'For \'lvm\', the volume group; ' 'for \'lvmthin\', the full name of the thin pool, namely VG/LV; ' 'for \'zfs\', the zPool.') p_new_storpool.set_defaults(func=self.create) # remove-storpool # TODO description p_rm_storpool = sp_subp.add_parser( Commands.Subcommands.Delete.LONG, aliases=[Commands.Subcommands.Delete.SHORT], description=' Removes a storage pool ') p_rm_storpool.add_argument( '-q', '--quiet', action="store_true", help='Unless this option is used, linstor will issue a safety question ' 'that must be answered with yes, otherwise the operation is canceled.') p_rm_storpool.add_argument( 'node_name', nargs="+", help='Name of the Node where the storage pool exists.').completer = self.node_completer p_rm_storpool.add_argument('name', help='Name of the storage pool to delete').completer = self.storage_pool_completer p_rm_storpool.set_defaults(func=self.delete) # list storpool storpoolgroupby = [x.name for x in self._stor_pool_headers] storpool_group_completer = Commands.show_group_completer(storpoolgroupby, "groupby") p_lstorpool = sp_subp.add_parser( Commands.Subcommands.List.LONG, aliases=[Commands.Subcommands.List.SHORT], description='Prints a list of all storage pool known to ' 'linstor. By default, the list is printed as a human readable table.') p_lstorpool.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lstorpool.add_argument('-g', '--groupby', nargs='+', choices=storpoolgroupby).completer = storpool_group_completer p_lstorpool.add_argument('-s', '--storpools', nargs='+', type=namecheck(STORPOOL_NAME), help='Filter by list of storage pools').completer = self.storage_pool_completer p_lstorpool.add_argument('-n', '--nodes', nargs='+', type=namecheck(NODE_NAME), help='Filter by list of nodes').completer = self.node_completer p_lstorpool.set_defaults(func=self.list) # show properties p_sp = sp_subp.add_parser( Commands.Subcommands.ListProperties.LONG, aliases=[Commands.Subcommands.ListProperties.SHORT], description="Prints all properties of the given storage pool.") p_sp.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_sp.add_argument( 'node_name', type=namecheck(NODE_NAME), help='Name of the node for the storage pool').completer = self.node_completer p_sp.add_argument( 'storage_pool_name', help="Storage pool for which to print the properties").completer = self.storage_pool_completer p_sp.set_defaults(func=self.print_props) # set properties p_setprop = sp_subp.add_parser( Commands.Subcommands.SetProperty.LONG, aliases=[Commands.Subcommands.SetProperty.SHORT], description='Sets properties for the given storage pool on the given node.') p_setprop.add_argument( 'node_name', type=namecheck(NODE_NAME), help='Name of the node for the storage pool').completer = self.node_completer p_setprop.add_argument( 'name', type=namecheck(STORPOOL_NAME), help='Name of the storage pool' ).completer = self.storage_pool_completer Commands.add_parser_keyvalue(p_setprop, 'storagepool') p_setprop.set_defaults(func=self.set_props) self.check_subcommands(sp_subp, subcmds)
def setup_commands(self, parser): subcmds = [ Commands.Subcommands.Create, Commands.Subcommands.List, Commands.Subcommands.Delete, Commands.Subcommands.SetProperty, Commands.Subcommands.ListProperties, Commands.Subcommands.DrbdOptions ] # Resource subcommands res_def_parser = parser.add_parser( Commands.RESOURCE_DEF, aliases=["rd"], formatter_class=argparse.RawTextHelpFormatter, description="Resource definition subcommands") res_def_subp = res_def_parser.add_subparsers( title="resource definition subcommands", metavar="", description=Commands.Subcommands.generate_desc(subcmds) ) p_new_res_dfn = res_def_subp.add_parser( Commands.Subcommands.Create.LONG, aliases=[Commands.Subcommands.Create.SHORT], description='Defines a Linstor resource definition for use with linstor.') p_new_res_dfn.add_argument('-p', '--port', type=rangecheck(1, 65535)) # p_new_res_dfn.add_argument('-s', '--secret', type=str) p_new_res_dfn.add_argument('name', type=namecheck(RES_NAME), help='Name of the new resource definition') p_new_res_dfn.set_defaults(func=self.create) # remove-resource definition # TODO description p_rm_res_dfn = res_def_subp.add_parser( Commands.Subcommands.Delete.LONG, aliases=[Commands.Subcommands.Delete.SHORT], description=" Removes a resource definition " "from the linstor cluster. The resource is undeployed from all nodes " "and the resource entry is marked for removal from linstor's data " "tables. After all nodes have undeployed the resource, the resource " "entry is removed from linstor's data tables.") p_rm_res_dfn.add_argument('-q', '--quiet', action="store_true", help='Unless this option is used, linstor will issue a safety question ' 'that must be answered with yes, otherwise the operation is canceled.') p_rm_res_dfn.add_argument( 'name', nargs="+", help='Name of the resource to delete').completer = self.resource_dfn_completer p_rm_res_dfn.set_defaults(func=self.delete) rsc_dfn_groupby = [x.name for x in self._rsc_dfn_headers] rsc_dfn_group_completer = Commands.show_group_completer(rsc_dfn_groupby, "groupby") p_lrscdfs = res_def_subp.add_parser( Commands.Subcommands.List.LONG, aliases=[Commands.Subcommands.List.SHORT], description='Prints a list of all resource definitions known to ' 'linstor. By default, the list is printed as a human readable table.') p_lrscdfs.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lrscdfs.add_argument('-g', '--groupby', nargs='+', choices=rsc_dfn_groupby).completer = rsc_dfn_group_completer p_lrscdfs.add_argument('-R', '--resources', nargs='+', type=namecheck(RES_NAME), help='Filter by list of resources').completer = self.resource_dfn_completer p_lrscdfs.set_defaults(func=self.list) # show properties p_sp = res_def_subp.add_parser( Commands.Subcommands.ListProperties.LONG, aliases=[Commands.Subcommands.ListProperties.SHORT], description="Prints all properties of the given resource definitions.") p_sp.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_sp.add_argument( 'resource_name', help="Resource definition for which to print the properties" ).completer = self.resource_dfn_completer p_sp.set_defaults(func=self.print_props) # set properties p_setprop = res_def_subp.add_parser( Commands.Subcommands.SetProperty.LONG, aliases=[Commands.Subcommands.SetProperty.SHORT], description='Sets properties for the given resource definition.') p_setprop.add_argument('name', type=namecheck(RES_NAME), help='Name of the resource definition') Commands.add_parser_keyvalue(p_setprop, 'resource-definition') p_setprop.set_defaults(func=self.set_props) # drbd options p_drbd_opts = res_def_subp.add_parser( Commands.Subcommands.DrbdOptions.LONG, aliases=[Commands.Subcommands.DrbdOptions.SHORT], description="Set drbd resource options." ) p_drbd_opts.add_argument( 'resource_name', type=namecheck(RES_NAME), help="Resource name" ).completer = self.resource_dfn_completer DrbdOptions.add_arguments( p_drbd_opts, [x for x in DrbdOptions.drbd_options()['options'] if x in DrbdOptions.drbd_options()['filters']['resource']] ) p_drbd_opts.set_defaults(func=self.set_drbd_opts) self.check_subcommands(res_def_subp, subcmds)
def setup_commands(self, parser): subcmds = [ Commands.Subcommands.Create, Commands.Subcommands.Modify, Commands.Subcommands.List, Commands.Subcommands.Delete, Commands.Subcommands.SetProperty, Commands.Subcommands.ListProperties, Commands.Subcommands.DrbdOptions ] # Resource definition subcommands res_def_parser = parser.add_parser( Commands.RESOURCE_DEF, aliases=["rd"], formatter_class=argparse.RawTextHelpFormatter, description="Resource definition subcommands") res_def_subp = res_def_parser.add_subparsers( title="resource definition subcommands", metavar="", description=Commands.Subcommands.generate_desc(subcmds)) p_new_res_dfn = res_def_subp.add_parser( Commands.Subcommands.Create.LONG, aliases=[Commands.Subcommands.Create.SHORT], description= 'Defines a Linstor resource definition for use with linstor.') p_new_res_dfn.add_argument('-p', '--port', type=rangecheck(1, 65535)) p_new_res_dfn.add_argument('-e', '--external-name', type=str, help='User specified name.') # p_new_res_dfn.add_argument('-s', '--secret', type=str) p_new_res_dfn.add_argument( '-l', '--layer-list', type=self.layer_data_check, help="Comma separated layer list, order is from right to left. " "This means the top most layer is on the left. " "Possible layers are: " + ",".join(linstor.Linstor.layer_list())) p_new_res_dfn.add_argument('--peer-slots', type=rangecheck(1, 31), help='(DRBD) peer slots for new resources') p_new_res_dfn.add_argument( '--resource-group', help="Attach the resource definition to this resource group" ).completer = self.resource_grp_completer p_new_res_dfn.add_argument( 'name', nargs="?", type=str, help= 'Name of the new resource definition. Will be ignored if EXTERNAL_NAME is set.' ) p_new_res_dfn.set_defaults(func=self.create) # modify-resource definition p_mod_res_dfn = res_def_subp.add_parser( Commands.Subcommands.Modify.LONG, aliases=[Commands.Subcommands.Modify.SHORT], description='Modifies a Linstor resource definition') p_mod_res_dfn.add_argument('--peer-slots', type=rangecheck(1, 31), help='(DRBD) peer slots for new resources') p_mod_res_dfn.add_argument('name', help='Name of the resource definition' ).completer = self.resource_dfn_completer p_mod_res_dfn.set_defaults(func=self.modify) # remove-resource definition # TODO description p_rm_res_dfn = res_def_subp.add_parser( Commands.Subcommands.Delete.LONG, aliases=[Commands.Subcommands.Delete.SHORT], description=" Removes a resource definition " "from the linstor cluster. The resource is undeployed from all nodes " "and the resource entry is marked for removal from linstor's data " "tables. After all nodes have undeployed the resource, the resource " "entry is removed from linstor's data tables.") p_rm_res_dfn.add_argument( '--async', action='store_true', help= 'Do not wait for actual deletion on satellites before returning') p_rm_res_dfn.add_argument('name', nargs="+", help='Name of the resource to delete' ).completer = self.resource_dfn_completer p_rm_res_dfn.set_defaults(func=self.delete) rsc_dfn_groupby = [x.name for x in self._rsc_dfn_headers] rsc_dfn_group_completer = Commands.show_group_completer( rsc_dfn_groupby, "groupby") p_lrscdfs = res_def_subp.add_parser( Commands.Subcommands.List.LONG, aliases=[Commands.Subcommands.List.SHORT], description='Prints a list of all resource definitions known to ' 'linstor. By default, the list is printed as a human readable table.' ) p_lrscdfs.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lrscdfs.add_argument( '-g', '--groupby', nargs='+', choices=rsc_dfn_groupby).completer = rsc_dfn_group_completer p_lrscdfs.add_argument('-r', '--resource-definitions', nargs='+', type=str, help='Filter by list of resource definitions' ).completer = self.resource_dfn_completer p_lrscdfs.add_argument('-e', '--external-name', action="store_true", help='Show user specified name.') p_lrscdfs.set_defaults(func=self.list) # show properties p_sp = res_def_subp.add_parser( Commands.Subcommands.ListProperties.LONG, aliases=[Commands.Subcommands.ListProperties.SHORT], description= "Prints all properties of the given resource definitions.") p_sp.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_sp.add_argument( 'resource_name', help="Resource definition for which to print the properties" ).completer = self.resource_dfn_completer p_sp.set_defaults(func=self.print_props) # set properties p_setprop = res_def_subp.add_parser( Commands.Subcommands.SetProperty.LONG, aliases=[Commands.Subcommands.SetProperty.SHORT], formatter_class=argparse.RawTextHelpFormatter, description='Sets properties for the given resource definition.') p_setprop.add_argument('name', type=str, help='Name of the resource definition') Commands.add_parser_keyvalue(p_setprop, 'resource-definition') p_setprop.set_defaults(func=self.set_props) # drbd options p_drbd_opts = res_def_subp.add_parser( Commands.Subcommands.DrbdOptions.LONG, aliases=[Commands.Subcommands.DrbdOptions.SHORT], description=DrbdOptions.description("resource")) p_drbd_opts.add_argument( 'resource_name', type=str, help="Resource name").completer = self.resource_dfn_completer DrbdOptions.add_arguments(p_drbd_opts, self.OBJECT_NAME) p_drbd_opts.set_defaults(func=self.set_drbd_opts) self.check_subcommands(res_def_subp, subcmds)
def setup_commands(self, parser): # Storage pool subcommands subcmds = [ Commands.Subcommands.Create, Commands.Subcommands.List, Commands.Subcommands.Delete, Commands.Subcommands.SetProperty, Commands.Subcommands.ListProperties ] sp_parser = parser.add_parser( Commands.STORAGE_POOL, aliases=["sp"], formatter_class=argparse.RawTextHelpFormatter, description="Storage pool subcommands") sp_subp = sp_parser.add_subparsers( title="Storage pool commands", metavar="", description=Commands.Subcommands.generate_desc(subcmds)) subcmd_create = [ StoragePoolCommands.Lvm, StoragePoolCommands.LvmThin, StoragePoolCommands.Zfs, StoragePoolCommands.ZfsThin, StoragePoolCommands.Diskless, StoragePoolCommands.File, StoragePoolCommands.FileThin, StoragePoolCommands.SPDK, StoragePoolCommands.RemoteSPDK, StoragePoolCommands.OpenFlex, StoragePoolCommands.Exos ] sp_c_parser = sp_subp.add_parser( Commands.Subcommands.Create.LONG, aliases=[Commands.Subcommands.Create.SHORT], formatter_class=argparse.RawTextHelpFormatter, description='Defines a Linstor storage pool for use with Linstor.') create_subp = sp_c_parser.add_subparsers( title="Storage pool create commands", metavar="", description=Commands.Subcommands.generate_desc(subcmd_create)) p_new_lvm_pool = create_subp.add_parser( StoragePoolCommands.Lvm.LONG, aliases=[StoragePoolCommands.Lvm.SHORT], description='Create a lvm storage pool') self._create_pool_args(p_new_lvm_pool) p_new_lvm_pool.add_argument('driver_pool_name', type=str, help='The Lvm volume group to use.') p_new_lvm_pool.set_defaults(func=self.create, driver=linstor.StoragePoolDriver.LVM) p_new_spdk_pool = create_subp.add_parser( StoragePoolCommands.SPDK.LONG, aliases=[StoragePoolCommands.SPDK.SHORT], description='Create a spdk storage pool') self._create_pool_args(p_new_spdk_pool) p_new_spdk_pool.add_argument( 'driver_pool_name', type=str, help='The Spdk logical volume store to use.') p_new_spdk_pool.set_defaults(func=self.create, driver=linstor.StoragePoolDriver.SPDK) p_new_remote_spdk_pool = create_subp.add_parser( StoragePoolCommands.RemoteSPDK.LONG, aliases=[StoragePoolCommands.RemoteSPDK.SHORT], description='Create a remote-spdk storage pool') self._create_pool_args(p_new_remote_spdk_pool) p_new_remote_spdk_pool.add_argument( 'driver_pool_name', type=str, help='The remote Spdk logical volume store to use.') p_new_remote_spdk_pool.set_defaults( func=self.create, driver=linstor.StoragePoolDriver.REMOTE_SPDK) p_new_lvm_thin_pool = create_subp.add_parser( StoragePoolCommands.LvmThin.LONG, aliases=[StoragePoolCommands.LvmThin.SHORT], description='Create a lvm thin storage pool') self._create_pool_args(p_new_lvm_thin_pool) p_new_lvm_thin_pool.add_argument( 'driver_pool_name', type=str, help= 'The LvmThin volume group to use. The full name of the thin pool, namely VG/LV' ) p_new_lvm_thin_pool.set_defaults( func=self.create, driver=linstor.StoragePoolDriver.LVMThin) p_new_zfs_pool = create_subp.add_parser( StoragePoolCommands.Zfs.LONG, aliases=[StoragePoolCommands.Zfs.SHORT], description='Create a zfs storage pool') self._create_pool_args(p_new_zfs_pool) p_new_zfs_pool.add_argument('driver_pool_name', type=str, help='The name of the zpool to use.') p_new_zfs_pool.set_defaults(func=self.create, driver=linstor.StoragePoolDriver.ZFS) p_new_zfsthin_pool = create_subp.add_parser( StoragePoolCommands.ZfsThin.LONG, aliases=[StoragePoolCommands.ZfsThin.SHORT], description='Create a zfs storage pool') self._create_pool_args(p_new_zfsthin_pool) p_new_zfsthin_pool.add_argument('driver_pool_name', type=str, help='The name of the zpool to use.') p_new_zfsthin_pool.set_defaults( func=self.create, driver=linstor.StoragePoolDriver.ZFSThin) p_new_diskless_pool = create_subp.add_parser( StoragePoolCommands.Diskless.LONG, aliases=[StoragePoolCommands.Diskless.SHORT], description='Create a diskless pool') self._create_pool_args(p_new_diskless_pool, shared_space=False, external_locking=False) p_new_diskless_pool.set_defaults( func=self.create, driver=linstor.StoragePoolDriver.Diskless, driver_pool_name=None) p_new_file_pool = create_subp.add_parser( StoragePoolCommands.File.LONG, aliases=[StoragePoolCommands.File.SHORT], description='Create a file storage pool') self._create_pool_args(p_new_file_pool) p_new_file_pool.add_argument('driver_pool_name', type=str, help='The directory to use.') p_new_file_pool.set_defaults(func=self.create, driver=linstor.StoragePoolDriver.FILE) p_new_file_thin_pool = create_subp.add_parser( StoragePoolCommands.FileThin.LONG, aliases=[StoragePoolCommands.FileThin.SHORT], description='Create a file thin storage pool') self._create_pool_args(p_new_file_thin_pool) p_new_file_thin_pool.add_argument('driver_pool_name', type=str, help='The directory to use.') p_new_file_thin_pool.set_defaults( func=self.create, driver=linstor.StoragePoolDriver.FILEThin) p_new_openflex_pool = create_subp.add_parser( StoragePoolCommands.OpenFlex.LONG, aliases=[StoragePoolCommands.OpenFlex.SHORT], description='Create an openflex storage pool') self._create_pool_args(p_new_openflex_pool, shared_space=False) p_new_openflex_pool.add_argument('driver_pool_name', type=str, help='OpenFlex pool index') p_new_openflex_pool.set_defaults( func=self.create, driver=linstor.StoragePoolDriver.OPENFLEX_TARGET) p_new_exos_pool = create_subp.add_parser( StoragePoolCommands.Exos.LONG, aliases=[StoragePoolCommands.Exos.SHORT], description='Create an EXOS storage pool') self._create_pool_args(p_new_exos_pool) p_new_exos_pool.add_argument('enclosure_name', type=str, help='Enclosure name') p_new_exos_pool.add_argument('pool_sn', type=str, help='Exos Pool Serial Number') p_new_exos_pool.set_defaults(func=self.create_exos, driver=linstor.StoragePoolDriver.EXOS) # END CREATE SUBCMDS # remove-storpool p_rm_storpool = sp_subp.add_parser( Commands.Subcommands.Delete.LONG, aliases=[Commands.Subcommands.Delete.SHORT], description=' Removes a storage pool ') p_rm_storpool.add_argument( '-q', '--quiet', action="store_true", help= 'Unless this option is used, linstor will issue a safety question ' 'that must be answered with yes, otherwise the operation is canceled.' ) p_rm_storpool.add_argument( 'node_name', nargs="+", help='Name of the Node where the storage pool exists.' ).completer = self.node_completer p_rm_storpool.add_argument('name', help='Name of the storage pool to delete' ).completer = self.storage_pool_completer p_rm_storpool.set_defaults(func=self.delete) # list storpool storpoolgroupby = [x.name.lower() for x in self._stor_pool_headers] storpool_group_completer = Commands.show_group_completer( storpoolgroupby, "groupby") p_lstorpool = sp_subp.add_parser( Commands.Subcommands.List.LONG, aliases=[Commands.Subcommands.List.SHORT], description='Prints a list of all storage pool known to ' 'linstor. By default, the list is printed as a human readable table.' ) p_lstorpool.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lstorpool.add_argument( '-g', '--groupby', nargs='+', choices=storpoolgroupby, type=str.lower).completer = storpool_group_completer p_lstorpool.add_argument('-s', '--storage-pools', nargs='+', type=str, help='Filter by list of storage pools' ).completer = self.storage_pool_completer p_lstorpool.add_argument( '-n', '--nodes', nargs='+', type=str, help='Filter by list of nodes').completer = self.node_completer p_lstorpool.add_argument('--props', nargs='+', type=str, help='Filter list by object properties') p_lstorpool.set_defaults(func=self.list) # show properties p_sp = sp_subp.add_parser( Commands.Subcommands.ListProperties.LONG, aliases=[Commands.Subcommands.ListProperties.SHORT], description="Prints all properties of the given storage pool.") p_sp.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_sp.add_argument('node_name', type=str, help='Name of the node for the storage pool' ).completer = self.node_completer p_sp.add_argument('storage_pool_name', help="Storage pool for which to print the properties" ).completer = self.storage_pool_completer p_sp.set_defaults(func=self.print_props) # set properties p_setprop = sp_subp.add_parser( Commands.Subcommands.SetProperty.LONG, aliases=[Commands.Subcommands.SetProperty.SHORT], formatter_class=argparse.RawTextHelpFormatter, description= 'Sets properties for the given storage pool on the given node.') p_setprop.add_argument('node_name', type=str, help='Name of the node for the storage pool' ).completer = self.node_completer p_setprop.add_argument('name', type=str, help='Name of the storage pool' ).completer = self.storage_pool_completer Commands.add_parser_keyvalue(p_setprop, 'storagepool') p_setprop.set_defaults(func=self.set_props) self.check_subcommands(create_subp, subcmd_create) self.check_subcommands(sp_subp, subcmds)
def setup_commands(self, parser): subcmds = [ Commands.Subcommands.Create, Commands.Subcommands.AutoPlace, Commands.Subcommands.Modify, Commands.Subcommands.List, Commands.Subcommands.Delete, Commands.Subcommands.SetProperty, Commands.Subcommands.ListProperties, Commands.Subcommands.DrbdOptions, Commands.Subcommands.Clone, Commands.Subcommands.WaitSync, ] # Resource definition subcommands res_def_parser = parser.add_parser( Commands.RESOURCE_DEF, aliases=["rd"], formatter_class=argparse.RawTextHelpFormatter, description="Resource definition subcommands") res_def_subp = res_def_parser.add_subparsers( title="resource definition subcommands", metavar="", description=Commands.Subcommands.generate_desc(subcmds)) p_new_res_dfn = res_def_subp.add_parser( Commands.Subcommands.Create.LONG, aliases=[Commands.Subcommands.Create.SHORT], description= 'Defines a Linstor resource definition for use with linstor.') p_new_res_dfn.add_argument('-p', '--port', type=rangecheck(1, 65535)) p_new_res_dfn.add_argument('-e', '--external-name', type=str, help='User specified name.') # p_new_res_dfn.add_argument('-s', '--secret', type=str) p_new_res_dfn.add_argument( '-l', '--layer-list', type=self.layer_data_check, help="Comma separated layer list, order is from right to left. " "This means the top most layer is on the left. " "Possible layers are: " + ",".join(linstor.Linstor.layer_list())) p_new_res_dfn.add_argument('--peer-slots', type=rangecheck(1, 31), help='(DRBD) peer slots for new resources') p_new_res_dfn.add_argument( '--resource-group', help="Attach the resource definition to this resource group" ).completer = self.resource_grp_completer p_new_res_dfn.add_argument( 'name', nargs="?", type=str, help= 'Name of the new resource definition. Will be ignored if EXTERNAL_NAME is set.' ) p_new_res_dfn.set_defaults(func=self.create) p_auto_place = res_def_subp.add_parser( Commands.Subcommands.AutoPlace.LONG, aliases=[Commands.Subcommands.AutoPlace.SHORT], description='Auto place a resource definition') self.add_auto_select_argparse_arguments(p_auto_place, use_place_count=True) p_auto_place.add_argument( 'resource_definition_name', help='Name of the resource definition to auto place') p_auto_place.add_argument('--nvme-initiator', action="store_true", help='Mark this resource as initiator') p_auto_place.add_argument('--drbd-diskless', action="store_true", help='Mark this resource as drbd diskless') p_auto_place.set_defaults(func=self.auto_place) # modify-resource definition p_mod_res_dfn = res_def_subp.add_parser( Commands.Subcommands.Modify.LONG, aliases=[Commands.Subcommands.Modify.SHORT], description='Modifies a Linstor resource definition') p_mod_res_dfn.add_argument('--peer-slots', type=rangecheck(1, 31), help='(DRBD) peer slots for new resources') p_mod_res_dfn.add_argument( '--resource-group', help='Change resource group to the given one.' ).completer = self.resource_grp_completer p_mod_res_dfn.add_argument('name', help='Name of the resource definition' ).completer = self.resource_dfn_completer p_mod_res_dfn.set_defaults(func=self.modify) # remove-resource definition p_rm_res_dfn = res_def_subp.add_parser( Commands.Subcommands.Delete.LONG, aliases=[Commands.Subcommands.Delete.SHORT], description=" Removes a resource definition " "from the linstor cluster. The resource is undeployed from all nodes " "and the resource entry is marked for removal from linstor's data " "tables. After all nodes have undeployed the resource, the resource " "entry is removed from linstor's data tables.") p_rm_res_dfn.add_argument('--async', action='store_true', help='Deprecated, kept for compatibility') p_rm_res_dfn.add_argument('name', nargs="+", help='Name of the resource to delete' ).completer = self.resource_dfn_completer p_rm_res_dfn.set_defaults(func=self.delete) rsc_dfn_groupby = [x.name.lower() for x in self._rsc_dfn_headers] rsc_dfn_group_completer = Commands.show_group_completer( rsc_dfn_groupby, "groupby") p_clone_rscdfn = res_def_subp.add_parser( Commands.Subcommands.Clone.LONG, aliases=[Commands.Subcommands.Clone.SHORT], description= "Clones a resource definition with all resources and volumes(including data)." ) p_clone_rscdfn.add_argument('-e', '--external-name', type=str, help='User specified name.') p_clone_rscdfn.add_argument('--no-wait', action="store_true", help="Wait till cloning is done.") p_clone_rscdfn.add_argument( '--wait-timeout', type=int, help="Wait this seconds for the clone to finish.") p_clone_rscdfn.add_argument( '--use-zfs-clone', action="store_true", default=None, help= "Use ZFS clone instead send/recv, but have a dependent snapshot") p_clone_rscdfn.add_argument('source_resource', help="Source resource definition name" ).completer = self.resource_dfn_completer p_clone_rscdfn.add_argument( 'clone_name', nargs="?", type=str, help='Name of the new resource definition. ' 'Will be ignored if EXTERNAL_NAME is set.') p_clone_rscdfn.set_defaults(func=self.clone) p_wait_sync = res_def_subp.add_parser( Commands.Subcommands.WaitSync.LONG, aliases=[Commands.Subcommands.WaitSync.SHORT], description= "Wait till the given resource is synced or e.g. ready to be resized." ) p_wait_sync.add_argument( '--wait-timeout', type=int, help="Wait this seconds for the clone to finish.") p_wait_sync.add_argument("resource_name", help="Resource name to be checked." ).completer = self.resource_dfn_completer p_wait_sync.set_defaults(func=self.wait_sync) p_lrscdfs = res_def_subp.add_parser( Commands.Subcommands.List.LONG, aliases=[Commands.Subcommands.List.SHORT], description='Prints a list of all resource definitions known to ' 'linstor. By default, the list is printed as a human readable table.' ) p_lrscdfs.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_lrscdfs.add_argument( '-g', '--groupby', nargs='+', choices=rsc_dfn_groupby, type=str.lower).completer = rsc_dfn_group_completer p_lrscdfs.add_argument('-r', '--resource-definitions', nargs='+', type=str, help='Filter by list of resource definitions' ).completer = self.resource_dfn_completer p_lrscdfs.add_argument('-e', '--external-name', action="store_true", help='Show user specified name.') p_lrscdfs.add_argument('--props', nargs='+', type=str, help='Filter list by object properties') p_lrscdfs.set_defaults(func=self.list) # show properties p_sp = res_def_subp.add_parser( Commands.Subcommands.ListProperties.LONG, aliases=[Commands.Subcommands.ListProperties.SHORT], description= "Prints all properties of the given resource definitions.") p_sp.add_argument('-p', '--pastable', action="store_true", help='Generate pastable output') p_sp.add_argument( 'resource_name', help="Resource definition for which to print the properties" ).completer = self.resource_dfn_completer p_sp.set_defaults(func=self.print_props) # set properties p_setprop = res_def_subp.add_parser( Commands.Subcommands.SetProperty.LONG, aliases=[Commands.Subcommands.SetProperty.SHORT], formatter_class=argparse.RawTextHelpFormatter, description='Sets properties for the given resource definition.') p_setprop.add_argument('name', type=str, help='Name of the resource definition') Commands.add_parser_keyvalue(p_setprop, 'resource-definition') p_setprop.set_defaults(func=self.set_props) # drbd options p_drbd_opts = res_def_subp.add_parser( Commands.Subcommands.DrbdOptions.LONG, aliases=[Commands.Subcommands.DrbdOptions.SHORT], description=DrbdOptions.description("resource")) p_drbd_opts.add_argument( 'resource_name', type=str, help="Resource name").completer = self.resource_dfn_completer DrbdOptions.add_arguments(p_drbd_opts, self.OBJECT_NAME) p_drbd_opts.set_defaults(func=self.set_drbd_opts) self.check_subcommands(res_def_subp, subcmds)