def run(self, params, args): if not len(args): raise ArgRequired(self, 'switch') name, enforce_sm = self.fillParams([ ('name', None), ('enforce_sm', False), ]) if name: name = name.lower() if name == 'default': name = 'Default' elif name != None: try: name = '0x{0:04x}'.format(int(name, 16)) except ValueError: raise ParamValue( self, 'name', 'a hex value between 0x0001 and 0x7ffe, or "default"') switches = self.getSwitchNames(args) switch_attrs = self.getHostAttrDict(switches) for switch in switches: if switch_attrs[switch].get('switch_type') != 'infiniband': raise CommandError( self, f'{switch} does not have a switch_type of "infiniband"') if self.str2bool(enforce_sm): enforce_subnet_manager(self, switches) format_str = ','.join(['%s'] * len(switches)) sw_select = ''' nodes.name, ib.part_name, ib.part_key, ib.options FROM nodes, ib_partitions ib WHERE nodes.name IN (%s) AND nodes.id=ib.switch''' % format_str vals = list(switches) if name: sw_select += ' AND ib.part_name=%s' vals.append(name) sw_select += ' ORDER BY nodes.name' self.beginOutput() for line in self.db.select(sw_select, vals): self.addOutput(line[0], (line[1], '0x{0:04x}'.format(line[2]), line[3])) self.endOutput( header=['switch', 'partition', 'partition key', 'options'])
def run(self, params, args): if not len(args): raise ArgRequired(self, 'switch') name, enforce_sm = self.fillParams([ ('name', None), ('enforce_sm', False), ]) if name: name = name.lower() if name == 'default': name = 'Default' elif name != None: try: name = '0x{0:04x}'.format(int(name, 16)) except ValueError: raise ParamValue( self, 'name', 'a hex value between 0x0001 and 0x7ffe, or "default"') switches = self.getSwitchNames(args) switch_attrs = self.getHostAttrDict(switches) for switch in switches: if switch_attrs[switch].get('switch_type') != 'infiniband': raise CommandError( self, f'{switch} does not have a switch_type of "infiniband"') if self.str2bool(enforce_sm): enforce_subnet_manager(self, switches) ids_sql = 'name, id FROM nodes WHERE name IN (%s)' % ','.join( ['%s'] * len(switches)) sw_ids = dict((row[0], row[1]) for row in self.db.select(ids_sql, tuple(switches))) format_str = ','.join(['%s'] * len(switches)) delete_stmt = ''' DELETE from ib_partitions WHERE switch IN (%s)''' % format_str vals = list(sw_ids.values()) if name: delete_stmt += ' AND ib_partitions.part_name=%s' vals.append(name) self.db.execute(delete_stmt, vals)
def run(self, params, args): if not len(args): raise ArgRequired(self, 'switch') name, enforce_sm = self.fillParams([ ('name', None), ('enforce_sm', False), ]) if name: name = name.lower() if name == 'default': name = 'Default' elif name != None: try: name = '0x{0:04x}'.format(int(name, 16)) except ValueError: raise ParamValue(self, 'name', 'a hex value between 0x0001 and 0x7ffe, or "default"') switches = self.getSwitchNames(args) switch_attrs = self.getHostAttrDict(switches) for switch in switches: if switch_attrs[switch].get('switch_type') != 'infiniband': raise CommandError(self, f'{switch} does not have a switch_type of "infiniband"') if self.str2bool(enforce_sm): enforce_subnet_manager(self, switches) ids_sql = 'name, id FROM nodes WHERE name IN (%s)' % ','.join(['%s'] * len(switches)) sw_ids = dict((row[0], row[1]) for row in self.db.select(ids_sql, tuple(switches))) format_str = ','.join(['%s'] * len(switches)) delete_stmt = ''' DELETE from ib_partitions WHERE switch IN (%s)''' % format_str vals = list(sw_ids.values()) if name: delete_stmt += ' AND ib_partitions.part_name=%s' vals.append(name) self.db.execute(delete_stmt, vals)
def run(self, params, args): if not len(args): raise ArgRequired(self, 'switch') name, options_param, enforce_sm, force_add = self.fillParams([ ('name', None, True), ('options', None), ('enforce_sm', False), ('force_add', True), ]) # force is really whether or not this command came from ADD vs SET stack_set = self.str2bool(force_add) name = name.lower() if name == 'default': name = 'Default' pkey = 0x7fff else: try: pkey = int(name, 16) name = '0x{0:04x}'.format(pkey) except ValueError: raise ParamValue( self, 'name', 'a hex value between 0x0001 and 0x7ffe, or "default"') parsed_options = [] if options_param: options = options_param.split() bad_options = [opt for opt in options if '=' not in opt] options = dict( opt.split('=') for opt in options_param.split() if '=' in opt) if 'ipoib' in options: parsed_options.append( f"ipoib={self.str2bool(options['ipoib'])}") del options['ipoib'] if 'defmember' in options and options['defmember'].lower() in [ 'limited', 'full' ]: parsed_options.append( f"defmember={options['defmember'].lower()}") del options['defmember'] if options: # if there's any leftover, error msg = 'The following are invalid partition options: ' raise CommandError( self, msg + ' '.join(f'{k}={v}' for k, v in options.items())) if bad_options: # if there's non-key value, error msg = 'The following are invalid partition options: ' raise CommandError(self, msg + ' '.join(bad_options)) parsed_options_str = ' '.join(parsed_options) switches = self.getSwitchNames(args) switch_attrs = self.getHostAttrDict(switches) for switch in switches: if switch_attrs[switch].get('switch_type') != 'infiniband': raise CommandError( self, f'{switch} does not have a switch_type of "infiniband"') if self.str2bool(enforce_sm): enforce_subnet_manager(self, switches) ids_sql = 'name, id FROM nodes WHERE name IN (%s)' % ','.join( ['%s'] * len(switches)) sw_ids = dict((row[0], row[1]) for row in self.db.select(ids_sql, tuple(switches))) sql_check = 'id, options FROM ib_partitions WHERE switch=%s AND part_name=%s' for switch in switches: # if doing an ADD, we want to ensure the partition doesn't already exist exists = self.db.select(sql_check, (sw_ids[switch], name)) # since there's already a switch dict, use that to store some temporary data switch_attrs[switch]['_part_opts'] = parsed_options_str if not exists: continue # since there's already a switch dict, use that to store some temporary data switch_attrs[switch]['_part_id'] = exists[0][0] if not stack_set: raise CommandError( self, f'partition "{name}" already exists on switch "{switch}"') if options_param is None: # if user supplied no options field, for existing keep the previous options field switch_attrs[switch]['_part_opts'] = exists[0][1] # if it already exists, we do an UPDATE instead sql_update = 'UPDATE ib_partitions SET switch=%s, part_key=%s, part_name=%s, options=%s WHERE switch=%s and id=%s' sql_insert = 'INSERT INTO ib_partitions (switch, part_key, part_name, options) VALUES (%s, %s, %s, %s)' for switch in switches: if stack_set and exists: self.db.execute( sql_update, (sw_ids[switch], pkey, name, switch_attrs[switch]['_part_opts'], sw_ids[switch], switch_attrs[switch]['_part_id'])) else: self.db.execute(sql_insert, (sw_ids[switch], pkey, name, switch_attrs[switch]['_part_opts']))
def run(self, params, args): if not len(args): raise ArgRequired(self, 'switch') name, options_param, enforce_sm, force_add = self.fillParams([ ('name', None, True), ('options', None), ('enforce_sm', False), ('force_add', True), ]) # force is really whether or not this command came from ADD vs SET stack_set = self.str2bool(force_add) name = name.lower() if name == 'default': name = 'Default' pkey = 0x7fff else: try: pkey = int(name, 16) name = '0x{0:04x}'.format(pkey) except ValueError: raise ParamValue(self, 'name', 'a hex value between 0x0001 and 0x7ffe, or "default"') parsed_options = [] if options_param: options = options_param.split() bad_options = [opt for opt in options if '=' not in opt] options = dict(opt.split('=') for opt in options_param.split() if '=' in opt) if 'ipoib' in options: parsed_options.append(f"ipoib={self.str2bool(options['ipoib'])}") del options['ipoib'] if 'defmember' in options and options['defmember'].lower() in ['limited', 'full']: parsed_options.append(f"defmember={options['defmember'].lower()}") del options['defmember'] if options: # if there's any leftover, error msg = 'The following are invalid partition options: ' raise CommandError(self, msg + ' '.join(f'{k}={v}' for k, v in options.items())) if bad_options: # if there's non-key value, error msg = 'The following are invalid partition options: ' raise CommandError(self, msg + ' '.join(bad_options)) parsed_options_str = ' '.join(parsed_options) switches = self.getSwitchNames(args) switch_attrs = self.getHostAttrDict(switches) for switch in switches: if switch_attrs[switch].get('switch_type') != 'infiniband': raise CommandError(self, f'{switch} does not have a switch_type of "infiniband"') if self.str2bool(enforce_sm): enforce_subnet_manager(self, switches) ids_sql = 'name, id FROM nodes WHERE name IN (%s)' % ','.join(['%s'] * len(switches)) sw_ids = dict((row[0], row[1]) for row in self.db.select(ids_sql, tuple(switches))) sql_check = 'id, options FROM ib_partitions WHERE switch=%s AND part_name=%s' for switch in switches: # if doing an ADD, we want to ensure the partition doesn't already exist exists = self.db.select(sql_check, (sw_ids[switch], name)) # since there's already a switch dict, use that to store some temporary data switch_attrs[switch]['_part_opts'] = parsed_options_str if not exists: continue # since there's already a switch dict, use that to store some temporary data switch_attrs[switch]['_part_id'] = exists[0][0] if not stack_set: raise CommandError(self, f'partition "{name}" already exists on switch "{switch}"') if options_param is None: # if user supplied no options field, for existing keep the previous options field switch_attrs[switch]['_part_opts'] = exists[0][1] # if it already exists, we do an UPDATE instead sql_update = 'UPDATE ib_partitions SET switch=%s, part_key=%s, part_name=%s, options=%s WHERE switch=%s and id=%s' sql_insert = 'INSERT INTO ib_partitions (switch, part_key, part_name, options) VALUES (%s, %s, %s, %s)' for switch in switches: if stack_set and exists: self.db.execute(sql_update, (sw_ids[switch], pkey, name, switch_attrs[switch]['_part_opts'], sw_ids[switch], switch_attrs[switch]['_part_id'])) else: self.db.execute(sql_insert, (sw_ids[switch], pkey, name, switch_attrs[switch]['_part_opts']))
def run(self, params, args): if not len(args): raise ArgRequired(self, 'switch') name, expanded, enforce_sm = self.fillParams([ ('name', None), ('expanded', False), ('enforce_sm', False), ]) expanded = self.str2bool(expanded) if name: name = name.lower() if name == 'default': name = 'Default' elif name != None: try: name = '0x{0:04x}'.format(int(name, 16)) except ValueError: raise ParamValue(self, 'name', 'a hex value between 0x0001 and 0x7ffe, or "default"') switches = self.getSwitchNames(args) switch_attrs = self.getHostAttrDict(switches) for switch in switches: if switch_attrs[switch].get('switch_type') != 'infiniband': raise CommandError(self, f'{switch} does not have a switch_type of "infiniband"') if self.str2bool(enforce_sm): enforce_subnet_manager(self, switches) sql_columns = 'swnodes.name AS switch, nodes.name AS host, networks.device, networks.mac, ib_p.part_name, ib_m.member_type' table_headers = ['switch', 'host', 'device', 'guid', 'partition', 'membership'] if expanded: sql_columns += ', ib_p.part_key, ib_p.options' table_headers.extend(['partition key', 'options']) format_str = ','.join(['%s'] * len(switches)) member_select = sql_columns + ''' FROM nodes swnodes, nodes, networks, ib_partitions ib_p, ib_memberships ib_m WHERE swnodes.name in (%s) AND swnodes.id=ib_m.switch AND nodes.id=networks.node AND networks.id=ib_m.interface AND ib_p.id=ib_m.part_name ''' % format_str vals = list(switches) if name: member_select += ' AND ib_p.part_name in (%s)' vals.append(name) member_select += ' ORDER BY switch, host, part_name' self.beginOutput() for line in self.db.select(member_select, vals): if expanded: line = list(line) line[6] = '0x{0:04x}'.format(line[6]) self.addOutput(line[0], (line[1:])) self.endOutput(header=table_headers)
def run(self, params, args): if len(args) != 1: raise ArgUnique(self, 'switch') name, guid, hostname, interface, membership, enforce_sm = self.fillParams( [ ('name', None, True), ('guid', None), ('member', None), ('interface', None), ('membership', 'limited'), ('enforce_sm', False), ]) if not guid and not hostname: raise CommandError( self, 'either guid or member and interface must be specified') if guid: guid = guid.lower() if hostname and not interface or interface and not hostname: raise CommandError(self, 'member and interface must both be specified') elif hostname and interface: ifaces = self.call('list.host.interface', [hostname]) for row in ifaces: if row['interface'] == interface: guid = row['mac'] break else: #nobreak raise CommandError( self, f'member has no interface named "{interface}"') name = name.lower() if name == 'default': name = 'Default' elif name != None: try: name = '0x{0:04x}'.format(int(name, 16)) except ValueError: raise ParamValue( self, 'name', 'a hex value between 0x0001 and 0x7ffe, or "default"') membership = membership.lower() if membership not in ['limited', 'full']: raise ParamValue(self, 'membership', 'either "limited" or "full"') switches = self.getSwitchNames(args) switch_attrs = self.getHostAttrDict(switches) for switch in switches: if switch_attrs[switch].get('switch_type') != 'infiniband': raise CommandError( self, f'{switch} does not have a switch_type of "infiniband"') if self.str2bool(enforce_sm): enforce_subnet_manager(self, switches) switch, = switches switch_id = self.db.select('id FROM nodes WHERE name=%s', switch)[0][0] # ensure the guid actually exists - guid should be unique across table guid_id = self.db.select('id FROM networks WHERE mac=%s', guid) try: guid_id = guid_id[0][0] except IndexError: raise CommandError( self, f'guid "{guid}" was not found in the interfaces table') # lookups using sql instead of api calls because all 'list switch partition' calls are expensive. # Ensure this partition exists on the switch if self.db.count( '(id) FROM ib_partitions WHERE part_name=%s AND switch=%s', (name, switch_id)) == 0: raise CommandError( self, f'partition {name} does not exist on switch {switch}') # Ensure this member does not already exist on the partition and switch if self.db.count( ''' (ib_m.id) FROM ib_memberships ib_m, ib_partitions ib_p, nodes, networks WHERE ib_m.switch=nodes.id AND nodes.name=%s AND networks.id=ib_m.interface AND ib_m.part_name=ib_p.id AND ib_p.part_name=%s AND networks.id=%s ''', (switch, name, guid_id)) > 0: raise CommandError( self, f'{guid} is already a member of switch partition {name}') self.db.execute( ''' INSERT INTO ib_memberships (switch, interface, part_name, member_type) VALUES (%s, %s, (SELECT id FROM ib_partitions WHERE part_name=%s AND switch=%s), %s) ''', (switch_id, guid_id, name, switch_id, membership))
def run(self, params, args): if len(args) != 1: raise ArgUnique(self, 'switch') name, guid, hostname, interface, membership, enforce_sm = self.fillParams([ ('name', None, True), ('guid', None), ('member', None), ('interface', None), ('membership', 'limited'), ('enforce_sm', False), ]) if not guid and not hostname: raise CommandError(self, 'either guid or member and interface must be specified') if guid: guid = guid.lower() if hostname and not interface or interface and not hostname: raise CommandError(self, 'member and interface must both be specified') elif hostname and interface: ifaces = self.call('list.host.interface', [hostname]) for row in ifaces: if row['interface'] == interface: guid = row['mac'] break else: #nobreak raise CommandError(self, f'member has no interface named "{interface}"') name = name.lower() if name == 'default': name = 'Default' elif name != None: try: name = '0x{0:04x}'.format(int(name, 16)) except ValueError: raise ParamValue(self, 'name', 'a hex value between 0x0001 and 0x7ffe, or "default"') membership = membership.lower() if membership not in ['limited', 'full']: raise ParamValue(self, 'membership', 'either "limited" or "full"') switches = self.getSwitchNames(args) switch_attrs = self.getHostAttrDict(switches) for switch in switches: if switch_attrs[switch].get('switch_type') != 'infiniband': raise CommandError(self, f'{switch} does not have a switch_type of "infiniband"') if self.str2bool(enforce_sm): enforce_subnet_manager(self, switches) switch, = switches switch_id = self.db.select('id FROM nodes WHERE name=%s', switch)[0][0] # ensure the guid actually exists - guid should be unique across table guid_id = self.db.select('id FROM networks WHERE mac=%s', guid) try: guid_id = guid_id[0][0] except IndexError: raise CommandError(self, f'guid "{guid}" was not found in the interfaces table') # lookups using sql instead of api calls because all 'list switch partition' calls are expensive. # Ensure this partition exists on the switch if self.db.count( '(id) FROM ib_partitions WHERE part_name=%s AND switch=%s', (name, switch_id)) == 0: raise CommandError(self, f'partition {name} does not exist on switch {switch}') # Determine if this member already exists on the partition and switch existing = False if self.db.count(''' (ib_m.id) FROM ib_memberships ib_m, ib_partitions ib_p, nodes, networks WHERE ib_m.switch=nodes.id AND nodes.name=%s AND networks.id=ib_m.interface AND ib_m.part_name=ib_p.id AND ib_p.part_name=%s AND networks.id=%s ''', (switch, name, guid_id)) > 0: existing = True insert_sql = ''' INSERT INTO ib_memberships (switch, interface, part_name, member_type) VALUES (%s, %s, (SELECT id FROM ib_partitions WHERE part_name=%s AND switch=%s), %s) ''' update_sql = ''' UPDATE ib_memberships SET switch=%s, interface=%s, part_name=(SELECT id FROM ib_partitions WHERE part_name=%s AND switch=%s), member_type=%s WHERE switch=%s AND part_name=(SELECT id FROM ib_partitions WHERE part_name=%s AND switch=%s) AND interface=%s ''' if existing: self.db.execute(update_sql, (switch_id, guid_id, name, switch_id, membership, switch_id, name, switch_id, guid_id)) else: self.db.execute(insert_sql, (switch_id, guid_id, name, switch_id, membership))
def run(self, params, args): if len(args) != 1: raise ArgUnique(self, 'switch') name, guid, hostname, interface, enforce_sm = self.fillParams([ ('name', None), ('guid', None), ('member', None), ('interface', None), ('enforce_sm', False), ]) if guid: guid = guid.lower() if hostname and not interface or interface and not hostname: raise CommandError(self, 'member and interface must both be specified') elif hostname and interface: ifaces = self.call('list.host.interface', [hostname]) for row in ifaces: if row['interface'] == interface: guid = row['mac'] break else: #nobreak raise CommandError( self, f'member has no interface named "{interface}"') if name: name = name.lower() if name == 'default': name = 'Default' elif name != None: try: name = '0x{0:04x}'.format(int(name, 16)) except ValueError: raise ParamValue( self, 'name', 'a hex value between 0x0001 and 0x7ffe, or "default"') switches = self.getSwitchNames(args) switch_attrs = self.getHostAttrDict(switches) for switch in switches: if switch_attrs[switch].get('switch_type') != 'infiniband': raise CommandError( self, f'{switch} does not have a switch_type of "infiniband"') if self.str2bool(enforce_sm): enforce_subnet_manager(self, switches) switch, = switches switch_id, = self.db.select('id FROM nodes WHERE name=%s', switch) vals = [switch_id[0]] delete_stmt = '''DELETE FROM ib_memberships''' where_clause = 'WHERE ib_memberships.switch=%s' if name: part_id = self.db.select( 'id FROM ib_partitions WHERE part_name=%s AND switch=%s', (name, switch_id)) if not part_id: raise CommandError( self, f'{name} is not a partition on {switches[0]}') where_clause += ' AND ib_memberships.part_name=%s' vals.append(part_id[0][0]) if guid: where_clause += ' AND ib_memberships.interface=(SELECT id FROM networks WHERE mac=%s)' vals.append(guid) self.db.execute(f'{delete_stmt} {where_clause}', vals)
def run(self, params, args): if len(args) != 1: raise ArgUnique(self, 'switch') name, guid, hostname, interface, enforce_sm = self.fillParams([ ('name', None), ('guid', None), ('member', None), ('interface', None), ('enforce_sm', False), ]) if guid: guid = guid.lower() if hostname and not interface or interface and not hostname: raise CommandError(self, 'member and interface must both be specified') elif hostname and interface: ifaces = self.call('list.host.interface', [hostname]) for row in ifaces: if row['interface'] == interface: guid = row['mac'] break else: #nobreak raise CommandError(self, f'member has no interface named "{interface}"') if name: name = name.lower() if name == 'default': name = 'Default' elif name != None: try: name = '0x{0:04x}'.format(int(name, 16)) except ValueError: raise ParamValue(self, 'name', 'a hex value between 0x0001 and 0x7ffe, or "default"') switches = self.getSwitchNames(args) switch_attrs = self.getHostAttrDict(switches) for switch in switches: if switch_attrs[switch].get('switch_type') != 'infiniband': raise CommandError(self, f'{switch} does not have a switch_type of "infiniband"') if self.str2bool(enforce_sm): enforce_subnet_manager(self, switches) switch, = switches switch_id, = self.db.select('id FROM nodes WHERE name=%s', switch) vals = [switch_id[0]] delete_stmt = '''DELETE FROM ib_memberships''' where_clause = 'WHERE ib_memberships.switch=%s' if name: part_id = self.db.select('id FROM ib_partitions WHERE part_name=%s AND switch=%s', (name, switch_id)) if not part_id: raise CommandError(self, f'{name} is not a partition on {switches[0]}') where_clause += ' AND ib_memberships.part_name=%s' vals.append(part_id[0][0]) if guid: where_clause += ' AND ib_memberships.interface=(SELECT id FROM networks WHERE mac=%s)' vals.append(guid) self.db.execute(f'{delete_stmt} {where_clause}', vals)
def run(self, params, args): if not len(args): raise ArgRequired(self, 'switch') name, expanded, enforce_sm = self.fillParams([ ('name', None), ('expanded', False), ('enforce_sm', False), ]) expanded = self.str2bool(expanded) if name: name = name.lower() if name == 'default': name = 'Default' elif name != None: try: name = '0x{0:04x}'.format(int(name, 16)) except ValueError: raise ParamValue( self, 'name', 'a hex value between 0x0001 and 0x7ffe, or "default"') switches = self.getSwitchNames(args) switch_attrs = self.getHostAttrDict(switches) for switch in switches: if switch_attrs[switch].get('switch_type') != 'infiniband': raise CommandError( self, f'{switch} does not have a switch_type of "infiniband"') if self.str2bool(enforce_sm): enforce_subnet_manager(self, switches) sql_columns = 'swnodes.name AS switch, nodes.name AS host, networks.device, networks.mac, ib_p.part_name, ib_m.member_type' table_headers = [ 'switch', 'host', 'device', 'guid', 'partition', 'membership' ] if expanded: sql_columns += ', ib_p.part_key, ib_p.options' table_headers.extend(['partition key', 'options']) format_str = ','.join(['%s'] * len(switches)) member_select = sql_columns + ''' FROM nodes swnodes, nodes, networks, ib_partitions ib_p, ib_memberships ib_m WHERE swnodes.name in (%s) AND swnodes.id=ib_m.switch AND nodes.id=networks.node AND networks.id=ib_m.interface AND ib_p.id=ib_m.part_name ''' % format_str vals = list(switches) if name: member_select += ' AND ib_p.part_name in (%s)' vals.append(name) member_select += ' ORDER BY switch, host, part_name' self.beginOutput() for line in self.db.select(member_select, vals): if expanded: line = list(line) line[6] = '0x{0:04x}'.format(line[6]) self.addOutput(line[0], (line[1:])) self.endOutput(header=table_headers)