Ejemplo n.º 1
0
	def run(self, params, args):
		host = self.getSingleHost(args)

		(name, ) = self.fillParams([
			('name', None, True)
		])

		if not is_valid_hostname(name):
			raise ParamValue(self, 'name', 'a valid hostname label')

		if name in self.getHostnames():
			raise CommandError(self, 'name already exists')

		self.db.execute('update nodes set name=%s where name=%s', (name, host))
Ejemplo n.º 2
0
	def run(self, params, args):
		hosts = self.getHosts(args)

		(action, nukedisks, nukecontroller, sync) = self.fillParams([
			('action', None, True),
			('nukedisks', None, False),
			('nukecontroller', None, False),
			('sync', True)
		])

		sync = self.str2bool(sync)
		if action not in ['os', 'install']:
			raise ParamValue(self, 'action', 'one of: os, install')

		# Get the mapping of hosts with boot actions and thier PK
		hosts_with_boot = {row[0]: row[1] for row in self.db.select(
			'nodes.name, nodes.id from nodes, boot where nodes.id=boot.node'
		)}

		for host in hosts:
			if host in hosts_with_boot:
				self.db.execute(
					'update boot set action=%s where node=%s',
					(action, hosts_with_boot[host])
				)
			else:
				self.db.execute("""
					insert into boot(action, node) values (
						%s, (select id from nodes where name=%s)
					)
				""", (action, host))

		if nukedisks is not None:
			args = hosts.copy()
			args.extend([
				'attr=nukedisks', 'value=%s' % self.str2bool(nukedisks)
			])

			self.command('set.host.attr', args)

		if nukecontroller is not None:
			args = hosts.copy()
			args.extend([
				'attr=nukecontroller', 'value=%s' % self.str2bool(nukecontroller)
			])

			self.command('set.host.attr', args)

		if sync:
			self.command('sync.host.boot', hosts)
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
	def run(self, params, args):
		(scope, device, mountpoint) = self.fillParams([
			('scope', 'global'), ('device', None), ('mountpoint', None)])
		oses = []
		appliances = []
		hosts = []
		name = None
		accepted_scopes = ['global', 'os', 'appliance', 'host']

		# Some checking that we got usable input.:
		if scope not in accepted_scopes:
			raise ParamValue(self, '%s' % params, 'one of the following: %s' % accepted_scopes )
		elif scope == 'global' and len(args) >= 1:
			raise ArgError(self, '%s' % args, 'unexpected, please provide a scope: %s' % accepted_scopes)
		elif scope == 'global' and (device is None and mountpoint is None):
			raise ParamRequired(self, 'device OR mountpoint')
		elif scope != 'global' and len(args) < 1:
			raise ArgRequired(self, '%s name' % scope)

		if scope == "os":
			oses = self.getOSNames(args)
		elif scope == "appliance":
			appliances = self.getApplianceNames(args)
		elif scope == "host":
			hosts = self.getHostnames(args)

		if scope != 'global':
			name = args[0]

		#
		# look up the id in the appropriate 'scope' table
		#
		tableid = -1
		tablename = {"os":"oses", "appliance":"appliances", "host":"nodes"}
		if scope != 'global':
			self.db.execute("""select id from %s where
				name = '%s' """ % (tablename[scope], name))
			tableid, = self.db.fetchone()

		deletesql = """delete from storage_partition where
			scope = '%s' and tableid = %s """ % (scope, tableid)

		if device and device != '*':
			deletesql += """ and device = '%s'""" % device

		if mountpoint and mountpoint != '*':
			deletesql += """ and mountpoint = '%s'""" % mountpoint

		self.db.execute(deletesql)
Ejemplo n.º 5
0
	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'])
Ejemplo n.º 6
0
    def getBootActionTypeOS(self, params, args):
        if not len(args):
            raise ArgRequired(self, 'action')
        if len(args) != 1:
            raise ArgUnique(self, 'action')
        b_action = args[0]

        (b_type, b_os) = self.fillParams([('type', None, True), ('os', '')])

        if b_type not in ['os', 'install']:
            raise ParamValue(self, 'type', '"os" or "install"')

        if not b_os:
            b_os = self.os

        if b_os:
            b_os = self.getOSNames([b_os])[0]

        return (b_action, b_type, b_os)
Ejemplo n.º 7
0
	def run(self, params, args):

		(req_action, req_type, req_sync) = self.fillParams([
			('action', None, True),
			('type', None, True),
			('sync', True)
		])

		if not len(args):
			raise ArgRequired(self, 'host')

		req_sync   = self.str2bool(req_sync)
		req_type   = req_type.lower()
		req_action = req_action.lower()
		types      = { 'os'     : 'osaction',
			       'install': 'installaction' }

		if req_type not in types.keys():
			raise ParamValue(self, 'type', 'one of: %s' % ', '.join(types.keys()))

		exists = False
		for row in self.call('list.bootaction', [ req_action, 
							  'type=%s' % req_type ]):
			exists = True
		if not exists:
			raise CommandError(self, 'bootaction %s does not exist' % req_action)

		hosts = self.getHostnames(args)
		for host in hosts:
			self.db.execute(
				"""
				update nodes
				set 
				%s = (select id from bootnames where name='%s' and type='%s')
				where nodes.name = '%s'
				""" % (types[req_type], req_action, req_type, host))

		if req_sync:
			self.command('sync.host.boot', hosts)
Ejemplo n.º 8
0
    def getBootActionTypeOS(self, params, args):
        if not len(args):
            raise ArgRequired(self, 'action')
        if len(args) != 1:
            raise ArgUnique(self, 'action')

        b_action = args[0]

        (b_type, b_os) = self.fillParams([('type', None, True), ('os', '')])

        if b_type not in ['os', 'install']:
            raise ParamValue(self, 'type', '"os" or "install"')

        # If bootaction type is not os, then get the default
        # os so code doesn't break.
        if not b_os and b_type != 'os':
            b_os = self.os

        if b_os:
            b_os = self.getOSNames([b_os])[0]

        return (b_action, b_type, b_os)
Ejemplo n.º 9
0
    def run(self, params, args):
        filename, processor = self.fillParams([('file', None, True),
                                               ('processor', 'default')])

        if not filename:
            raise ParamValue(self, 'file', 'valid csv filename')
        if not os.path.exists(filename):
            raise CommandError(self, 'file "%s" does not exist' % filename)

        #
        # implementations can't return values
        #
        self.hosts = {}
        self.runImplementation('load_%s' % processor, (filename, ))

        args = self.hosts
        self.runPlugins(args)

        #
        # checkin the spreadsheet
        #
        sheetsdir = '/export/stack/spreadsheets'
        if not os.path.exists(sheetsdir):
            os.makedirs(sheetsdir)

        RCSdir = '%s/RCS' % sheetsdir
        if not os.path.exists(RCSdir):
            os.makedirs(RCSdir)

        sheetsfile = '%s/%s' % (sheetsdir, os.path.basename(filename))
        if not os.path.exists(sheetsfile) or not \
         os.path.samefile(filename, sheetsfile):
            shutil.copyfile(filename, '%s' % sheetsfile)

        cmd = 'date | /opt/stack/bin/ci "%s"' % sheetsfile
        os.system(cmd)

        cmd = '/opt/stack/bin/co -f -l "%s"' % sheetsfile
        os.system(cmd)
Ejemplo n.º 10
0
	def run(self, params, args):
		scope = None
		oses = []
		appliances = []
		hosts = []

		if len(args) == 0:
			scope = 'global'
		elif len(args) == 1:
			try:
				oses = self.getOSNames(args)
			except:
				oses = []

			try:
				appliances = self.getApplianceNames(args)
			except:
				appliances = []

			try:
				hosts = self.getHostnames(args)
			except:
				hosts = []
		else:
			raise CommandError(self, 'must supply zero or one argument')

		if not scope:
			if args[0] in oses:
				scope = 'os'
			elif args[0] in appliances:
				scope = 'appliance'
			elif args[0] in hosts:
				scope = 'host'

		if not scope:
			raise CommandError(self, 'argument "%s" must be a valid os, appliance name or host name' % args[0])

		if scope == 'global':
			name = 'global'
		else:
			name = args[0]

		adapter, enclosure, slot, hotspare, raidlevel, arrayid, options, force = self.fillParams([
			('adapter', None),
			('enclosure', None),
			('slot', None),
			('hotspare', None),
			('raidlevel', None),
			('arrayid', None, True),
			('options', ''),
			('force', 'n')
			])

		if not hotspare and not slot:
			raise ParamRequired(self, [ 'slot', 'hotspare' ])
		if arrayid != 'global' and not raidlevel:
			raise ParamRequired(self, 'raidlevel')

		if adapter:
			try:
				adapter = int(adapter)
			except:
				raise ParamType(self, 'adapter', 'integer')
			if adapter < 0:
				raise ParamValue(self, 'adapter', '>= 0')
		else:
			adapter = -1

		if enclosure:
			try:
				enclosure = int(enclosure)
			except:
				raise ParamType(self, 'enclosure', 'integer')
			if enclosure < 0:
				raise ParamValue(self, 'enclosure', '>= 0')
		else:
			enclosure = -1

		slots = []
		if slot:
			for s in slot.split(','):
				if s == '*':
					#
					# represent '*' in the database as '-1'
					#
					s = -1
				else:
					try:
						s = int(s)
					except:
						raise ParamType(self, 'slot', 'integer')
					if s < 0:
						raise ParamValue(self, 'slot', '>= 0')
					if s in slots:
						raise ParamError(self, 'slot', ' "%s" is listed twice' % s)
				slots.append(s)

		hotspares = []
		if hotspare:
			for h in hotspare.split(','):
				try:
					h = int(h)
				except:	
					raise ParamType(self, 'hotspare', 'integer')
				if h < 0:
					raise ParamValue(self, 'hostspare', '>= 0')
				if h in hotspares:
					raise ParamError(self, 'hostspare', ' "%s" is listed twice' % h)
				hotspares.append(h)

		if arrayid in [ 'global', '*' ]:
			pass
		else:
			try:
				arrayid = int(arrayid)
			except:
				raise ParamType(self, 'arrayid', 'integer')
			if arrayid < 1:
				raise ParamValue(self, 'arrayid', '>= 0')

		if arrayid == 'global' and len(hotspares) == 0:
			raise ParamError(self, 'arrayid', 'is "global" with no hotspares. Please supply at least one hotspare')

		#
		# look up the id in the appropriate 'scope' table
		#
		tableid = None
		if scope == 'global':
			tableid = -1
		elif scope == 'appliance':
			self.db.execute("""select id from appliances where
				name = '%s' """ % name)
			tableid, = self.db.fetchone()
		elif scope == 'host':
			self.db.execute("""select id from nodes where
				name = '%s' """ % name)
			tableid, = self.db.fetchone()

		#
		# make sure the specification doesn't already exist
		#
		force = self.str2bool(force)
		for slot in slots:
			if not force:
				self.checkIt(name, scope, tableid, adapter, enclosure,
					slot)
		for hotspare in hotspares:
			if not force:
				self.checkIt(name, scope, tableid, adapter, enclosure,
					hotspare)

		if arrayid == 'global':
			arrayid = -1
		elif arrayid == '*':
			arrayid = -2

		#
		# now add the specifications to the database
		#
		for slot in slots:
			self.db.execute("""insert into storage_controller
				(scope, tableid, adapter, enclosure, slot,
				raidlevel, arrayid, options) values ('%s', %s, %s, %s,
				%s, %s, %s, '%s') """ % (scope, tableid, adapter,
				enclosure, slot, raidlevel, arrayid, options))

		for hotspare in hotspares:
			raidlevel = -1
			if arrayid == 'global':
				arrayid = -1

			self.db.execute("""insert into storage_controller
				(scope, tableid, adapter, enclosure, slot,
				raidlevel, arrayid, options) values ('%s', %s, %s, %s,
				%s, %s, %s, '%s') """ % (scope, tableid, adapter,
				enclosure, hotspare, raidlevel, arrayid, options))
Ejemplo n.º 11
0
    def run(self, params, args):
        scope = None
        oses = []
        appliances = []
        hosts = []

        if len(args) == 0:
            scope = 'global'
        elif len(args) == 1:
            try:
                oses = self.getOSNames(args)
            except:
                oses = []

            try:
                appliances = self.getApplianceNames(args)
            except:
                appliances = []

            try:
                hosts = self.getHostnames(args)
            except:
                hosts = []
        else:
            raise ArgRequired(self, 'scope')

        if not scope:
            if args[0] in oses:
                scope = 'os'
            elif args[0] in appliances:
                scope = 'appliance'
            elif args[0] in hosts:
                scope = 'host'

        if not scope:
            raise ArgValue(self, 'scope',
                           'valid os, appliance name or host name')

        if scope == 'global':
            name = 'global'
        else:
            name = args[0]

        device, size, fstype, mountpt, options, partid = \
         self.fillParams([
          ('device', None, True),
          ('size', None),
          ('type', None),
          ('mountpoint', None),
          ('options', None),
          ('partid', None),
          ])

        if not device:
            raise ParamRequired(self, 'device')

        # Validate size
        if size:
            try:
                s = int(size)
            except:
                #
                # If mountpoint is 'swap' then allow
                # 'hibernate', 'recommended' as sizes.
                #
                if mountpt == 'swap' and \
                 size not in ['recommended', 'hibernation']:
                    raise ParamType(self, 'size', 'integer')
            if s < 0:
                raise ParamValue(self, 'size', '>= 0')

        # Validate partid
        if partid:
            try:
                p = int(partid)
            except:
                partid = None

            if p < 1:
                raise ParamValue(self, 'partid', '>= 0')

            partid = p

        #
        # look up the id in the appropriate 'scope' table
        #
        tableid = None
        if scope == 'global':
            tableid = -1
        elif scope == 'appliance':
            self.db.execute("""select id from appliances where
				name = '%s' """ % name)
            tableid, = self.db.fetchone()
        elif scope == 'host':
            self.db.execute("""select id from nodes where
				name = '%s' """ % name)
            tableid, = self.db.fetchone()

        #
        # make sure the specification for mountpt doesn't already exist
        #
        if mountpt:
            self.checkIt(device, scope, tableid, mountpt)

        if not options:
            options = ""

        #
        # now add the specifications to the database
        #
        sqlvars = "Scope, TableID, device, Mountpoint, Size, FsType, Options"
        sqldata = "'%s', %s, '%s', '%s', %s, '%s', '%s'" % \
         (scope, tableid, device, mountpt, size, fstype, options)

        if partid:
            sqlvars += ", PartID"
            sqldata += ", %s" % partid

        self.db.execute("""insert into storage_partition
			(%s) values (%s) """ % (sqlvars, sqldata))
Ejemplo n.º 12
0
    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))
Ejemplo n.º 13
0
    def run(self, params, args):
        scope = None
        oses = []
        appliances = []
        hosts = []

        if len(args) == 0:
            scope = 'global'
        elif len(args) == 1:
            try:
                oses = self.getOSNames(args)
            except:
                oses = []

            try:
                appliances = self.getApplianceNames(args)
            except:
                appliances = []

            try:
                hosts = self.getHostnames(args)
            except:
                hosts = []
        else:
            raise ArgError(self, 'scope', 'must be unique or missing')

        if not scope:
            if args[0] in oses:
                scope = 'os'
            elif args[0] in appliances:
                scope = 'appliance'
            elif args[0] in hosts:
                scope = 'host'

        if not scope:
            raise ParamValue(self, 'scope',
                             'valid os, appliance name or host name')

        if scope == 'global':
            name = None
        else:
            name = args[0]

        device, mountpoint = self.fillParams([('device', None),
                                              ('mountpoint', None)])

        #
        # look up the id in the appropriate 'scope' table
        #
        tableid = None
        if scope == 'global':
            tableid = -1
        elif scope == 'appliance':
            self.db.execute("""select id from appliances where
				name = '%s' """ % name)
            tableid, = self.db.fetchone()
        elif scope == 'host':
            self.db.execute("""select id from nodes where
				name = '%s' """ % name)
            tableid, = self.db.fetchone()

        deletesql = """delete from storage_partition where
			scope = '%s' and tableid = %s """ % (scope, tableid)

        if device and device != '*':
            deletesql += """ and device = '%s'""" % device

        if mountpoint and mountpoint != '*':
            deletesql += """ and mountpoint = '%s'""" % mountpoint

        self.db.execute(deletesql)
Ejemplo n.º 14
0
    def run(self, params, args):
        scope = None
        oses = []
        appliances = []
        hosts = []

        if len(args) == 0:
            scope = 'global'
        elif len(args) == 1:
            try:
                oses = self.getOSNames(args)
            except:
                oses = []

            try:
                appliances = self.getApplianceNames(args)
            except:
                appliances = []

            try:
                hosts = self.getHostnames(args)
            except:
                hosts = []
        else:
            raise ArgRequired(self, 'scope')

        if not scope:
            if args[0] in oses:
                scope = 'os'
            elif args[0] in appliances:
                scope = 'appliance'
            elif args[0] in hosts:
                scope = 'host'

        if not scope:
            raise ArgValue(self, 'scope',
                           'a valid os, appliance name or host name')

        if scope == 'global':
            name = None
        else:
            name = args[0]

        adapter, enclosure, slot = self.fillParams([('adapter', None),
                                                    ('enclosure', None),
                                                    ('slot', None, True)])

        if adapter and adapter != '*':
            try:
                adapter = int(adapter)
            except:
                raise ParamType(self, 'adapter', 'integer')
            if adapter < 0:
                raise ParamValue(self, 'adapter', '>= 0')
        else:
            adapter = -1

        if enclosure and enclosure != '*':
            try:
                enclosure = int(enclosure)
            except:
                raise ParamType(self, 'enclosure', 'integer')
            if enclosure < 0:
                raise ParamValue(self, 'enclosure', '>= 0')
        else:
            enclosure = -1

        slots = []
        if slot and slot != '*':
            for s in slot.split(','):
                try:
                    s = int(s)
                except:
                    raise ParamType(self, 'slot', 'integer')
                if s < 0:
                    raise ParamValue(self, 'slot', '>= 0')
                if s in slots:
                    raise ParamError(self, 'slot', '"%s" is listed twice' % s)
                slots.append(s)

        #
        # look up the id in the appropriate 'scope' table
        #
        tableid = None
        if scope == 'global':
            tableid = -1
        elif scope == 'appliance':
            self.db.execute("""select id from appliances where
				name = '%s' """ % name)
            tableid, = self.db.fetchone()
        elif scope == 'host':
            self.db.execute("""select id from nodes where
				name = '%s' """ % name)
            tableid, = self.db.fetchone()

        deletesql = """delete from storage_controller where
			scope = '%s' and tableid = %s """ % (scope, tableid)

        if adapter != -1:
            deletesql += ' and adapter = %s' % adapter

        if enclosure != -1:
            deletesql += ' and enclosure = %s' % enclosure

        if slot != '*':
            for slot in slots:
                dsql = '%s and slot = %s' % (deletesql, slot)
                self.db.execute(dsql)
        else:
            self.db.execute(deletesql)
Ejemplo n.º 15
0
    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)
Ejemplo n.º 16
0
    def run(self, params, args):

        # Parse Params
        (cmd, managed, x11, t, d, collate, n, method) = self.fillParams([
            ('command', None, True),  # Command
            ('managed', 'y'),  # Run on Managed Hosts only
            ('x11', 'n'),  # Run without X11
            ('timeout', '0'),  # Set timeout for commands
            ('delay', '0'),  # Set delay between each thread
            ('collate', 'y'),  # Collate output
            ('threads', self.getAttr('run.host.threads')),
            ('method', self.getAttr('run.host.impl'))
        ])
        #  Check that a command was even input:
        if cmd == '':
            raise ParamValue(self, 'cmd', 'string with contents')
        # Get list of hosts to run the command on
        self.hosts = self.getHostnames(args, self.str2bool(managed))
        self.run_hosts = self.getRunHosts(self.hosts)

        # Get timeout for commands
        try:
            self.timeout = int(t)
        except:
            raise ParamType(self, 'timeout', 'integer')
        if self.timeout < 0:
            raise ParamValue(self, 'timeout', '> 0')

        # Get Number of threads to run concurrently
        if n is None:
            self.numthreads = 0
        else:
            try:
                self.numthreads = int(n)
            except:
                raise ParamType(self, 'threads', 'integer')
            if self.numthreads < 0:
                raise ParamValue(self, 'threads', '> 0')

        # Get time to pause between subsequent threads
        try:
            self.delay = float(d)
        except:
            raise ParamType(self, 'delay', 'float')

        # Check if we want to unset the Display
        if not self.str2bool(x11):
            try:
                del os.environ['DISPLAY']
            except KeyError:
                pass

        # Get the command
        self.cmd = cmd

        # Get the implementation to run. By default, run SSH
        if method is None:
            method = 'ssh'

        # Check if we should collate the output
        self.collate = self.str2bool(collate)

        if self.collate:
            self.beginOutput()

        self.runImplementation(method, [self.hosts, cmd])

        if self.collate:
            self.endOutput(header=['host', 'output'], trimOwner=False)
Ejemplo n.º 17
0
    def run(self, params, args):
        scope = None
        oses = []
        appliances = []
        hosts = []

        globalOnly, = self.fillParams([('globalOnly', 'n')])
        globalOnlyFlag = self.str2bool(globalOnly)

        if len(args) == 0:
            scope = 'global'
        elif len(args) == 1:
            try:
                oses = self.getOSNames(args)
            except:
                oses = []

            try:
                appliances = self.getApplianceNames()
            except:
                appliances = []

            try:
                hosts = self.getHostnames()
            except:
                hosts = []

        else:
            raise ArgError(self, 'scope', 'must be unique or missing')

        if not scope:
            if args[0] in oses:
                scope = 'os'
            elif args[0] in appliances:
                scope = 'appliance'
            elif args[0] in hosts:
                scope = 'host'
        if not scope:
            raise ParamValue(self, 'scope',
                             'valid os, appliance name or host name')

        query = None
        if scope == 'global':
            if globalOnlyFlag:
                query = """select scope, device, mountpoint, size, fstype, options, partid
					from storage_partition
					where scope = 'global'
					order by device,partid,fstype, size"""
            else:
                query = """(select scope, device, mountpoint, size, fstype, options, partid
					from storage_partition where scope = 'global') UNION ALL
					(select a.name, p.device, p.mountpoint, p.size,
					p.fstype, p.options, p.partid from storage_partition as p inner join
					nodes as a on p.tableid=a.id where p.scope='host') UNION ALL
					(select a.name, p.device, p.mountpoint, p.size,
					p.fstype, p.options, p.partid from storage_partition as p inner join
					appliances as a on p.tableid=a.id where
					p.scope='appliance') order by scope,device,partid,size,fstype"""
        elif scope == 'os':
            query = """select scope, device, mountpoint, size, fstype, options, partid
				from storage_partition where scope = "os" and tableid = (select id
				from oses where name = %s) order by device,partid,fstype,size"""
        elif scope == 'appliance':
            query = """select scope, device, mountpoint, size, fstype, options, partid
				from storage_partition where scope = "appliance"
				and tableid = (select id from appliances
				where name = %s) order by device,partid,fstype, size"""
        elif scope == 'host':
            query = """select scope, device, mountpoint, size, fstype, options, partid
				from storage_partition where scope="host" and
				tableid = (select id from nodes
				where name = %s) order by device,partid,fstype, size"""

        if not query:
            return

        self.beginOutput()

        if scope == 'global':
            self.db.execute(query)
        else:
            self.db.execute(query, [args[0]])

        for name, device, mountpoint, size, fstype, options, partid in self.db.fetchall(
        ):
            if size == -1:
                size = "recommended"
            elif size == -2:
                size = "hibernation"

            if name == "host" or name == "appliance" or name == "os":
                name = args[0]

            if mountpoint == 'None':
                mountpoint = None

            if fstype == 'None':
                fstype = None

            if partid == 0:
                partid = None

            self.addOutput(name,
                           [device, partid, mountpoint, size, fstype, options])

        self.endOutput(header=[
            'scope', 'device', 'partid', 'mountpoint', 'size', 'fstype',
            'options'
        ],
                       trimOwner=False)
Ejemplo n.º 18
0
	def run(self, params, args):
		# Get the scope and make sure the args are valid
		scope, = self.fillParams([('scope', 'global')])
		scope_mappings = self.getScopeMappings(args, scope)

		# Now validate the params
		adapter, enclosure, slot, hotspare, raidlevel, arrayid, options = self.fillParams([
			('adapter', None),
			('enclosure', None),
			('slot', None),
			('hotspare', None),
			('raidlevel', None),
			('arrayid', None, True),
			('options', '')
		])

		# Gotta have either a hotspare list or a slot list
		if not hotspare and not slot:
			raise ParamRequired(self, ['slot', 'hotspare'])

		# Non-global arrays need a raid level
		if arrayid != 'global' and not raidlevel:
			raise ParamRequired(self, 'raidlevel')

		# Make sure the adapter is an integer greater than 0, if it exists
		if adapter:
			try:
				adapter = int(adapter)
			except:
				raise ParamType(self, 'adapter', 'integer')

			if adapter < 0:
				raise ParamValue(self, 'adapter', '>= 0')
		else:
			adapter = -1

		# Make sure the enclosure is an integer greater than 0, if it exists
		if enclosure:
			try:
				enclosure = int(enclosure)
			except:
				raise ParamType(self, 'enclosure', 'integer')

			if enclosure < 0:
				raise ParamValue(self, 'enclosure', '>= 0')
		else:
			enclosure = -1

		# Parse the slots
		slots = []
		if slot:
			for s in slot.split(','):
				# Make sure the slot is valid
				if s == '*':
					# Represent '*' in the database as '-1'
					s = -1
				else:
					try:
						s = int(s)
					except:
						raise ParamType(self, 'slot', 'integer')

					if s < 0:
						raise ParamValue(self, 'slot', '>= 0')

					if s in slots:
						raise ParamError(
							self, 'slot', f'"{s}" is listed twice'
						)

				# Needs to be unique in the scope
				for scope_mapping in scope_mappings:
					# Check that the route is unique for the scope
					if self.db.count("""
						(storage_controller.id)
						FROM storage_controller,scope_map
						WHERE storage_controller.scope_map_id = scope_map.id
						AND storage_controller.adapter = %s
						AND storage_controller.enclosure = %s
						AND storage_controller.slot = %s
						AND scope_map.scope = %s
						AND scope_map.appliance_id <=> %s
						AND scope_map.os_id <=> %s
						AND scope_map.environment_id <=> %s
						AND scope_map.node_id <=> %s
					""", (adapter, enclosure, s, *scope_mapping)) != 0:
		 				raise CommandError(
							self,
							f'disk specification for "{adapter}/'
							f'{enclosure}/{s}" already exists'
						)

				# Looks good
				slots.append(s)

		# Parse the hotspares
		hotspares = []
		if hotspare:
			for h in hotspare.split(','):
				# Make sure the hotspare is valid
				try:
					h = int(h)
				except:
					raise ParamType(self, 'hotspare', 'integer')

				if h < 0:
					raise ParamValue(self, 'hotspare', '>= 0')

				if h in hotspares:
					raise ParamError(
						self, 'hotspare', f'"{h}" is listed twice'
					)

				if h in slots:
					raise ParamError(
						self, 'hotspare', f'"{h}" is listed in slots'
					)

				# Needs to be unique in the scope
				for scope_mapping in scope_mappings:
					# Check that the route is unique for the scope
					if self.db.count("""
						(storage_controller.id)
						FROM storage_controller,scope_map
						WHERE storage_controller.scope_map_id = scope_map.id
						AND storage_controller.adapter = %s
						AND storage_controller.enclosure = %s
						AND storage_controller.slot = %s
						AND scope_map.scope = %s
						AND scope_map.appliance_id <=> %s
						AND scope_map.os_id <=> %s
						AND scope_map.environment_id <=> %s
						AND scope_map.node_id <=> %s
					""", (adapter, enclosure, h, *scope_mapping)) != 0:
		 				raise CommandError(
							self,
							f'disk specification for "{adapter}/'
							f'{enclosure}/{h}" already exists'
						)

				# Looks good
				hotspares.append(h)

		# Check the arrayid
		if arrayid not in {'global', '*'}:
			try:
				arrayid = int(arrayid)
			except:
				raise ParamType(self, 'arrayid', 'integer')

			if arrayid < 1:
				raise ParamValue(self, 'arrayid', '>= 1')

		if arrayid == 'global' and len(hotspares) == 0:
			raise ParamError(self, 'arrayid', 'is "global" with no hotspares')

		# Special encodings for arrayid
		if arrayid == 'global':
			arrayid = -1
		elif arrayid == '*':
			arrayid = -2

		# Everything is valid, add the data for each scope_mapping
		for scope_mapping in scope_mappings:
			# Add the slots
			for slot in slots:
				# First add the scope mapping
				self.db.execute("""
					INSERT INTO scope_map(
						scope, appliance_id, os_id, environment_id, node_id
					)
					VALUES (%s, %s, %s, %s, %s)
				""", scope_mapping)

				# Then add the slot controller entry
				self.db.execute("""
					INSERT INTO storage_controller(
						scope_map_id, adapter, enclosure, slot,
						raidlevel, arrayid, options
					)
					VALUES (LAST_INSERT_ID(), %s, %s, %s, %s, %s, %s)
				""", (adapter, enclosure, slot, raidlevel, arrayid, options))

			# And add the hotspares
			for hotspare in hotspares:
				# First add the scope mapping
				self.db.execute("""
					INSERT INTO scope_map(
						scope, appliance_id, os_id, environment_id, node_id
					)
					VALUES (%s, %s, %s, %s, %s)
				""", scope_mapping)

				# Then add the hotspare controller entry
				self.db.execute("""
					INSERT INTO storage_controller(
						scope_map_id, adapter, enclosure, slot,
						raidlevel, arrayid, options
					)
					VALUES (LAST_INSERT_ID(), %s, %s, %s, '-1', %s, %s)
				""", (adapter, enclosure, hotspare, arrayid, options))
Ejemplo n.º 19
0
    def run(self, params, args):
        scope = None
        oses = []
        appliances = []
        hosts = []

        if len(args) == 0:
            scope = 'global'
        elif len(args) == 1:
            try:
                oses = self.getOSNames(args)
            except:
                oses = []

            try:
                appliances = self.getApplianceNames(args)
            except:
                appliances = []

            try:
                hosts = self.getHostnames(args)
            except:
                hosts = []
        else:
            raise ArgRequired(self, 'scope')

        if not scope:
            if args[0] in oses:
                scope = 'os'
            elif args[0] in appliances:
                scope = 'appliance'
            elif args[0] in hosts:
                scope = 'host'

        if not scope:
            raise ArgValue(self, 'scope',
                           'valid os, appliance name or host name')

        if scope == 'global':
            name = 'global'
        else:
            name = args[0]

        device, size, fstype, mountpt, options, partid = self.fillParams([
            ('device', None, True),
            ('size', None, True),
            ('type', None),
            ('mountpoint', None),
            ('options', None),
            ('partid', None),
        ])

        if not device:
            raise ParamRequired(self, 'device')

        if not size:
            raise ParamRequired(self, 'size')

        # Validate size
        try:
            s = int(size)
            if s < 0:
                raise ParamValue(self, 'size', '>= 0')
        except:
            # If mountpoint is 'swap' then allow
            # 'hibernate', 'recommended' as sizes
            if mountpt == 'swap' and size not in [
                    'recommended', 'hibernation'
            ]:
                raise ParamType(self, 'size', 'integer')
            else:
                raise ParamType(self, 'size', 'integer')

        # Validate partid
        if partid:
            try:
                p = int(partid)
            except ValueError:
                raise ParamValue(self, 'partid', 'an integer')

            if p < 1:
                raise ParamValue(self, 'partid', '>= 0')

            partid = p
        else:
            partid = 0

        # Look up the id in the appropriate 'scope' table
        if scope == 'appliance':
            tableid = self.db.select('id from appliances where name=%s',
                                     [name])[0][0]
        elif scope == 'os':
            tableid = self.db.select('id from oses where name=%s',
                                     [name])[0][0]
        elif scope == 'host':
            tableid = self.db.select('id from nodes where name=%s',
                                     [name])[0][0]
        else:
            tableid = -1

        # Make sure the specification for mountpt doesn't already exist
        if mountpt:
            self.checkIt(device, scope, tableid, mountpt)
        else:
            # Preserve the existing behavior (sad panda)
            mountpt = 'None'

        # Preserve the existing behavior (sad panda)
        if not fstype:
            fstype = 'None'

        if not options:
            options = ""

        # Now add the specifications to the database
        self.db.execute(
            """
			INSERT INTO storage_partition(
				Scope, TableID, device, Mountpoint,
				Size, FsType, Options, PartID
			)
			VALUES(%s, %s, %s, %s, %s, %s, %s, %s)
		""", (scope, tableid, device, mountpt, size, fstype, options, partid))
Ejemplo n.º 20
0
	def run(self, params, args):

		if not len(args):
			raise ArgRequired(self, 'host')

		(action, nukedisks, nukecontroller, sync) = self.fillParams([
			('action', None, True),
			('nukedisks', None, False),
			('nukecontroller', None, False),
			('sync', True)
		])
		
		sync    = self.str2bool(sync)
		actions = [ 'os', 'install' ]
		if action not in actions:
			raise ParamValue(self, 'action', 'one of: %s' % ', '.join(actions))


		boot = {}
		for h, a in self.db.select(
				"""
				n.name, b.action from 
				nodes n, boot b where
				n.id = b.node
				"""):
			boot[h] = a

		hosts = self.getHostnames(args)
		if not hosts:
			return

		for host in hosts:
			if host in boot.keys():
				self.db.execute(
					"""
					update boot set action = '%s'
					where node = (select id from nodes where name = '%s')
					""" % (action, host))
			else:
				self.db.execute(
					"""
					insert into boot (action, node) values 
					(
					'%s',
					(select id from nodes where name = '%s')
					) 
					""" % (action, host))

		args = hosts.copy()
		if len(args) > 0:
			if nukedisks is not None:
				nukedisks = self.str2bool(nukedisks)
				args.extend(['attr=nukedisks', 'value=%s' % nukedisks])
				self.command('set.host.attr',args)
			if nukecontroller is not None:
				nukecontroller = self.str2bool(nukecontroller)
				args.extend(['attr=nukecontroller', 'value=%s' % nukecontroller])
				self.command('set.host.attr',args)

		if sync:
			self.command('sync.host.boot', hosts)
Ejemplo n.º 21
0
    def run(self, params, args):
        # Get the scope and make sure the args are valid
        scope, = self.fillParams([('scope', 'global')])
        scope_mappings = self.getScopeMappings(args, scope)

        # Now validate the params
        device, size, fstype, mountpoint, options, partid = self.fillParams([
            ('device', None, True),
            ('size', None, True),
            ('type', None),
            ('mountpoint', None),
            ('options', None),
            ('partid', None),
        ])

        if not device:
            raise ParamRequired(self, 'device')

        if not size:
            raise ParamRequired(self, 'size')

        # Validate size
        if mountpoint == 'swap' and size in ['recommended', 'hibernation']:
            if size == 'recommended':
                size = -1
            else:
                size = -2
        else:
            try:
                size = int(size)
            except:
                raise ParamType(self, 'size', 'integer')

            if size < 0:
                raise ParamValue(self, 'size', '>= 0')

        # Validate partid
        if partid:
            try:
                partid = int(partid)
            except ValueError:
                raise ParamType(self, 'partid', 'integer')

            if partid < 1:
                raise ParamValue(self, 'partid', '>= 0')
        else:
            partid = 0

        # Make sure the specification for mountpoint doesn't already exist
        if mountpoint:
            # Needs to be unique in the scope
            for scope_mapping in scope_mappings:
                # Check that the route is unique for the scope
                if self.db.count(
                        """
					(storage_partition.id)
					FROM storage_partition,scope_map
					WHERE storage_partition.scope_map_id = scope_map.id
					AND storage_partition.device = %s
					AND storage_partition.mountpoint = %s
					AND scope_map.scope = %s
					AND scope_map.appliance_id <=> %s
					AND scope_map.os_id <=> %s
					AND scope_map.environment_id <=> %s
					AND scope_map.node_id <=> %s
				""", (device, mountpoint, *scope_mapping)) != 0:
                    raise CommandError(
                        self, f'partition specification for device "{device}" '
                        f'and mount point "{mountpoint}" already exists')
        else:
            mountpoint = None

        if not fstype:
            fstype = None

        if not options:
            options = ""

        # Everything is valid, add the data for each scope_mapping
        for scope_mapping in scope_mappings:
            # First add the scope mapping
            self.db.execute(
                """
				INSERT INTO scope_map(
					scope, appliance_id, os_id, environment_id, node_id
				)
				VALUES (%s, %s, %s, %s, %s)
			""", scope_mapping)

            # Then add the storage partition entry
            self.db.execute(
                """
				INSERT INTO storage_partition(
					scope_map_id, device, mountpoint,
					size, fstype, options, partid
				)
				VALUES (LAST_INSERT_ID(), %s, %s, %s, %s, %s, %s)
			""", (device, mountpoint, size, fstype, options, partid))
Ejemplo n.º 22
0
    def run(self, params, args):
        scope = None
        oses = []
        appliances = []
        hosts = []

        if len(args) == 0:
            scope = 'global'
        elif len(args) == 1:
            try:
                oses = self.getOSNames(args)
            except:
                oses = []

            try:
                appliances = self.getApplianceNames()
            except:
                appliances = []

            try:
                hosts = self.getHostnames()
            except:
                hosts = []

        else:
            raise ArgError(self, 'scope', 'must be unique or missing')

        if not scope:
            if args[0] in oses:
                scope = 'os'
            elif args[0] in appliances:
                scope = 'appliance'
            elif args[0] in hosts:
                scope = 'host'

        if not scope:
            raise ParamValue(self, 'scope',
                             'valid os, appliance name or host name')

        query = None
        if scope == 'global':
            query = """select adapter, enclosure, slot, raidlevel,
				arrayid, options from storage_controller 
				where scope = 'global'
				order by enclosure, adapter, slot"""
        elif scope == 'os':
            #
            # not currently supported
            #
            return
        elif scope == 'appliance':
            query = """select adapter, enclosure, slot,
				raidlevel, arrayid, options
				from storage_controller where
				scope = "appliance" and tableid = (select
				id from appliances
				where name = '%s')
				order by enclosure, adapter, slot""" % args[0]
        elif scope == 'host':
            query = """select adapter, enclosure, slot,
				raidlevel, arrayid, options
				from storage_controller where
				scope = "host" and tableid = (select
				id from nodes where name = '%s')
				order by enclosure, adapter, slot""" % args[0]

        if not query:
            return

        name = None
        if scope == 'global':
            name = 'global'
        elif scope in ['appliance', 'host']:
            name = args[0]

        self.beginOutput()

        self.db.execute(query)

        i = 0
        for row in self.db.fetchall():
            adapter, enclosure, slot, raidlevel, arrayid, options = row

            if i > 0:
                name = None
            if adapter == -1:
                adapter = None
            if enclosure == -1:
                enclosure = None
            if slot == -1:
                slot = '*'
            if raidlevel == '-1':
                raidlevel = 'hotspare'
            if arrayid == -1:
                arrayid = 'global'
            elif arrayid == -2:
                arrayid = '*'
            # Remove leading and trailing double quotes
            options = options.strip("\"")

            self.addOutput(
                name, [enclosure, adapter, slot, raidlevel, arrayid, options])

            i += 1

        self.endOutput(header=[
            'scope', 'enclosure', 'adapter', 'slot', 'raidlevel', 'arrayid',
            'options'
        ],
                       trimOwner=False)
Ejemplo n.º 23
0
    def run(self, params, args):
        # Get the scope and make sure the args are valid
        scope, = self.fillParams([('scope', 'global')])
        scope_mappings = self.getScopeMappings(args, scope)

        # Now validate the params
        adapter, enclosure, slot = self.fillParams([('adapter', None),
                                                    ('enclosure', None),
                                                    ('slot', None, True)])

        # Make sure the adapter is an integer greater than 0, if it exists
        if adapter and adapter != '*':
            try:
                adapter = int(adapter)
            except:
                raise ParamType(self, 'adapter', 'integer')

            if adapter < 0:
                raise ParamValue(self, 'adapter', '>= 0')
        else:
            adapter = None

        # Make sure the enclosure is an integer greater than 0, if it exists
        if enclosure and enclosure != '*':
            try:
                enclosure = int(enclosure)
            except:
                raise ParamType(self, 'enclosure', 'integer')

            if enclosure < 0:
                raise ParamValue(self, 'enclosure', '>= 0')
        else:
            enclosure = None

        # Parse the slots
        slots = []
        if slot:
            for s in slot.split(','):
                # Make sure the slot is valid
                if s == '*':
                    # We're removing them all
                    s = None
                else:
                    try:
                        s = int(s)
                    except:
                        raise ParamType(self, 'slot', 'integer')

                    if s < 0:
                        raise ParamValue(self, 'slot', '>= 0')

                    if s in slots:
                        raise ParamError(self, 'slot',
                                         f'"{s}" is listed twice')

                # Looks good
                slots.append(s)

        scope_ids = []
        for scope_mapping in scope_mappings:
            for slot in slots:
                # Check that the controller configuration exists for the scope
                query = """
					scope_map.id FROM storage_controller,scope_map
					WHERE storage_controller.scope_map_id = scope_map.id
					AND scope_map.scope = %s
					AND scope_map.appliance_id <=> %s
					AND scope_map.os_id <=> %s
					AND scope_map.environment_id <=> %s
					AND scope_map.node_id <=> %s
				"""
                values = list(scope_mapping)

                # 0 might be valid so need to check for None
                if adapter is not None:
                    query += " AND storage_controller.adapter = %s"
                    values.append(adapter)

                if enclosure is not None:
                    query += " AND storage_controller.enclosure = %s"
                    values.append(enclosure)

                if slot is not None:
                    query += " AND storage_controller.slot = %s"
                    values.append(slot)

                rows = self.db.select(query, values)
                if not rows:
                    if adapter is None:
                        adapter = '*'
                    if enclosure is None:
                        enclosure = '*'
                    if slot is None:
                        slot = '*'

                    raise CommandError(
                        self, f'disk specification for "{adapter}/'
                        f'{enclosure}/{slot}" doesn\'t exist')

                scope_ids.extend(flatten(rows))

        # Controller disk specifications existed for all the scope mappings,
        # so delete them.
        # Note: We just delete the scope mapping, the ON DELETE CASCADE takes
        # care of removing the storage_controller table entries for us.
        self.db.execute('delete from scope_map where id in %s', (scope_ids, ))
Ejemplo n.º 24
0
    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']))
Ejemplo n.º 25
0
    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)