Example #1
0
    def walk(self, oid):
        """
        Perform an SNMP walk

        Params
        -----
        oid : string
              The starting OID
        """
        version = '-v1'
        if self.version == 2:
            version = '-v2'

        args = [
            snmpwalk_cmd, '-t', '120', version, '-c', self.readCommunity,
            self.host, oid
        ]
        Log.debug(100, ' '.join(args))
        (output, exitcode) = Command.run(args)

        values = None
        if exitcode == 0 and output:
            values = []
            for line in output:
                line.rstrip('\n')
                if len(line) > 0:
                    values.append(self.parseSNMPLine(line))

        return values
Example #2
0
    def clone(self, params):
        if params is None:
            raise ValueError('zfs clone function received no parameters')

        command = ['clone']

        snapshot     = params.get('src', None)
        properties   = params.get('properties', None)
        dest         = params.get('dst', None)
        createParent = params.get('createParent', None)

        if not snapshot:
            raise ValueError('zfs clone function needs a snapshot parameter')

        if not dest:
            raise ValueError('zfs clone function needs a dest parameter')

        if createParent:
            command.append('-p')

        if not properties is None:
            for property, value in properties.iteritems():
                command.append('-o')
                command.append('%s=%s' % (property, value))

        command.append(snapshot)
        command.append(dest)

        if self.all.has_key(snapshot):
            if self.all.has_key(dest):
                Log.info('%s already exists. Not creating clone' % dest)
            else:
                self.run(command)
        else:
            raise ValueError('Snapshot %s does not exist, clone %s cannot be created' % (snapshot, dest))
Example #3
0
    def create_tpg(self, target, tag):
        tpg_list = self.target[target.wwn]['tpg']
        tpg_list_tag = tpg_list.get(tag, None)

        if tpg_list_tag is None:
            Log.info('creating tpg (%s, %s)' % (target, tag))

            # Create and configure the target portal group
            tpg = TPG(target, tag)
            tpg.set_attribute("authentication", 0)
            tpg.enable = 1

            # Set up the list of TPGs for this target
            tpg_list[tag] = {
                'tpg': tpg,
                'acl': {'mapped_lun': {}},
                'lun': {},
                'portal': {}
            }
        else:
            Log.info('tpg (%s, %s) already exists, not creating' %
                     (target, tag))
            tpg = tpg_list[tag]['tpg']

        return tpg
Example #4
0
    def parseSNMPLine(self, line):
        """
        Private member, parses a line of output from snmpwalk

        Returns
        -------
        A tuple (oid, value)
        """
        oid = None
        value = None
        # Split the line on the first '=' character
        parts = line.split('=', 1)
        if len(parts) == 2:
            oid = parts[0].rstrip().lstrip()
            value = parts[1].rstrip().lstrip()

            valueParts = value.split(':', 1)

            if len(valueParts) == 2:
                type = valueParts[0].rstrip().lstrip()
                value = valueParts[1].rstrip().lstrip()

                if type == 'STRING':
                    value = value.rstrip('"').lstrip('"')
            else:
                Log.error('Cannot parse SNMP value: "%s"' % (valueType))
        else:
            Log.error('Cannot parse SNMP key/value pair: "%s"' % (line))

        return (oid, value)
Example #5
0
    def parseSNMPLine(self, line):
        """
        Private member, parses a line of output from snmpwalk

        Returns
        -------
        A tuple (oid, value)
        """
        oid = None
        value = None
        # Split the line on the first '=' character
        parts = line.split('=', 1)
        if len(parts) == 2:
            oid = parts[0].rstrip().lstrip()
            value = parts[1].rstrip().lstrip()

            valueParts = value.split(':', 1)

            if len(valueParts) == 2:
                type = valueParts[0].rstrip().lstrip()
                value = valueParts[1].rstrip().lstrip()

                if type == 'STRING':
                    value = value.rstrip('"').lstrip('"')
            else:
                Log.error('Cannot parse SNMP value: "%s"' % (valueType))
        else:
            Log.error('Cannot parse SNMP key/value pair: "%s"' % (line))

        return (oid, value)
Example #6
0
    def walk(self, oid):
        """
        Perform an SNMP walk

        Params
        -----
        oid : string
              The starting OID
        """
        version = '-v1'
        if self.version == 2:
            version = '-v2'

        args = [snmpwalk_cmd, '-t', '120', version, '-c', self.readCommunity, self.host, oid]
        Log.debug(100, ' '.join(args))
        (output, exitcode) = Command.run(args)

        values = None
        if exitcode == 0 and output:
            values = []
            for line in output:
                line.rstrip('\n')
                if len(line) > 0:
                    values.append(self.parseSNMPLine(line))

        return values
Example #7
0
    def putDocument(self, docId, params):
        """
        PUT a document on the CouchDB server. If the document
        already exists, you will need to pass in a _rev param
        with the revision you would like to update. The
        saveDocument() method handles this for you, if all
        you want to do is save a document, regardless of whether
        or not it already exists.

        Params
        ------
        docId  : string
                 The unique ID of the document
        params : dictionary
                 A dictionary of parameters that define the document
        """
        path = '/%s/%s' % (self.db, docId.replace(' ', '+'))
        Log.debug(100, 'Putting %s' % path)
        connection = httplib.HTTPConnection(self.host, self.port)
        connection.connect()
        params['updatedAt'] = CouchDB.now()
        connection.request('PUT', path,
                           json.dumps(params),
                           {
                               'Content-Type': 'application/json'
                           })

        result = json.loads(connection.getresponse().read())

        if result.has_key(u'error'):
            Log.error('PUT %s: %s' % (path, result))

        return result
Example #8
0
    def __init__(self, params):
        Log.info('params: %s' % params)

        required = ['target_ip', 'target_wwn', 'target_lun', 'target_part', 'console_port', 'console_speed', 'console_params', 'ctrl_iface', 'ctrl_mac', 'initiator_fqdn', 'initiator_wwn']
        missing = []

        for arg in required:
            if params.get(arg, None) is None:
                missing.append(arg)

        Log.info(params)

        if len(missing) == 1:
            raise ValueError('Missing parameter: %s' % missing[0])
        elif len(missing) > 1:
            raise ValueError('Missing parameters: %s' % ', '.join(missing))

        params['device'] = self.iscsi_device(params)
        params['chroot'] = self.chroot_dir(params)
        
        # Something outside this library lowercase the wwn, so 
        # we lowercase the input to stay consistent
        params['target_wwn'] = params['target_wwn'].lower()

        self.prep(params)
Example #9
0
    def powerState(self):
        """
        Get the power state for all slots
        """
        walkAttr = 'remoteControlBladePowerState'
        oid = 'BLADE-MIB::%s' % walkAttr

        # Start async snmpwalk. This call returns immediately
        # and spawns a background thread to perform the SNMPWalk
        snmpWalk = SNMPWalk.withConfigFile(self.host, oid)

        state = []

        # While the snmpwalk is running
        while not snmpWalk.eof:
            # Get snmp oid/value pairs off the queue
            while not snmpWalk.queue.empty():
                (oid, value) = snmpWalk.queue.get()
                (mibName, attr, lastOctet) = snmpWalk.extractOidParts(oid)

                if attr == walkAttr:
                    if value == 'on(1)':
                        state.append(1)
                    else:
                        state.append(0)
        snmpWalk.join()
        Log.debug(100, 'ch %03d power state: %s' % (self.num, state))
        return state
Example #10
0
    def powerState(self):
        """
        Get the power state for all slots
        """
        walkAttr = 'remoteControlBladePowerState'
        oid = 'BLADE-MIB::%s' % walkAttr

        # Start async snmpwalk. This call returns immediately
        # and spawns a background thread to perform the SNMPWalk
        snmpWalk = SNMPWalk.withConfigFile(self.host, oid)

        state = []

        # While the snmpwalk is running
        while not snmpWalk.eof:
            # Get snmp oid/value pairs off the queue
            while not snmpWalk.queue.empty():
                (oid, value) = snmpWalk.queue.get()
                (mibName, attr, lastOctet) = snmpWalk.extractOidParts(oid)

                if attr == walkAttr:
                    if value == 'on(1)':
                        state.append(1)
                    else:
                        state.append(0)
        snmpWalk.join()
        Log.debug(100, 'ch %03d power state: %s' % (self.num, state))
        return state
Example #11
0
    def retrieveWithMac(cls, couch, mac):
        """
        Find a slot that matches the specified mac address

        Params
        ------
        couch:  object
                couch database connection
        mac:    string
                The mac address for which to search

        Returns
        -------
        Dictionary of key/value pairs for the slot that matches the specified mac address
        """
        if mac == 'not available' or mac == 'not installed':
            return None

        output = couch.getView('slot', 'mac_to_slot', mac)
        Log.debug(200, output)
        if output and len(output) > 0:
            key, value = output.popitem()
            if value:
                return value

        return None
Example #12
0
    def create_tpg(self, target, tag):
        tpg_list = self.target[target.wwn]['tpg']
        tpg_list_tag = tpg_list.get(tag, None)

        if tpg_list_tag is None:
            Log.info('creating tpg (%s, %s)' % (target, tag))

            # Create and configure the target portal group
            tpg = TPG(target, tag)
            tpg.set_attribute("authentication", 0)
            tpg.enable = 1

            # Set up the list of TPGs for this target
            tpg_list[tag] = {
                'tpg': tpg,
                'acl': {
                    'mapped_lun': {}
                },
                'lun': {},
                'portal': {}
            }
        else:
            Log.info('tpg (%s, %s) already exists, not creating' %
                     (target, tag))
            tpg = tpg_list[tag]['tpg']

        return tpg
Example #13
0
    def getViewDict(self, design, view, params = {}):
        """
        Get a view, return the results as a dictionary of key => values.
        If the particular key occurs multiple times, then the value will 
        be an array of values for that key

        Params
        ------
        design:  string
                 The design document name
        view:    string
                 The view name
        params:  dictv
                 Dictionary of parameters:
                   key: The key to which results will be limited
                   start: The starting key for the range to which results will be
                             limited
                   end:   The ending key for the range to which results will be limited
                   includeDocs: Set this to anything, and the entire document will
                                be returned as the value

        Returns
        -------
        A dictionary of view key/value pairs. If no results were returned, then
        None is returned
        """
        path = self.getViewPath(design, view, params)
        Log.debug(10, 'Getting view path %s' % path)
        output = self.getDocument(path)
        results = {}

        if output.has_key(u'total_rows'):
            Log.debug(10, '%s returned %s rows' % (path, output[u'total_rows']))

        if output.has_key(u'rows'):
            for row in output[u'rows']:
                key   = row[u'key']
                value = row.get(u'value', None)
                if params.has_key('includeDocs'):
                    value = row.get(u'doc', None)

                # If this key is already in the results, then append this value
                # to the list
                if results.has_key(key):
                    storedValue = results[key]

                    # If the stored value is a dict, change to an array of dicts
                    if isinstance(storedValue, (frozenset, list, set, tuple)):
                        storedValue.append(value)
                        value = storedValue
                    else:
                        value = [storedValue, value]

                results[key] = value

        # If no results, then return a None object
        if len(results) <= 0:
            results = {}

        return results
Example #14
0
    def discoverIncorrectBIOSSettings(cls, expectedFilename, dumpCmd):
        """
        Discover incorrect BIOS settings
        
        Params
        ------
        expectedFilename: string
        A filename of expected bios settings

        dumpCmd: array
        Command to dump bios settings

        Returns
        A dictionary of key value pairs of incorrect bios settings
        """

        try:
            # Read expected bios settings
            expectedFile = Blade.openFile(expectedFilename)
            expected = Blade.parseBios(expectedFile)

            # Read actual bios settings
            (actualFile, exitcode) = Command.run(dumpCmd)
            actual = Blade.parseBios(actualFile)

            return Blade.compareBiosSettings(expected, actual)
        except (OSError, IOError) as e:
            Log.error(str(e))
            sys.exit(1)

        return None
Example #15
0
    def retrieveWithMac(cls, couch, mac):
        """
        Find a slot that matches the specified mac address

        Params
        ------
        couch:  object
                couch database connection
        mac:    string
                The mac address for which to search

        Returns
        -------
        Dictionary of key/value pairs for the slot that matches the specified mac address
        """
        if mac == 'not available' or mac == 'not installed':
            return None

        output = couch.getView('slot', 'mac_to_slot', mac)
        Log.debug(200, output)
        if output and len(output) > 0:
            key, value = output.popitem()
            if value:
                return value

        return None
Example #16
0
    def discoverIncorrectBIOSSettings(cls, expectedFilename, dumpCmd):
        """
        Discover incorrect BIOS settings
        
        Params
        ------
        expectedFilename: string
        A filename of expected bios settings

        dumpCmd: array
        Command to dump bios settings

        Returns
        A dictionary of key value pairs of incorrect bios settings
        """

        try:
            # Read expected bios settings
            expectedFile = Blade.openFile(expectedFilename)
            expected = Blade.parseBios(expectedFile)

            # Read actual bios settings
            (actualFile, exitcode) = Command.run(dumpCmd)
            actual = Blade.parseBios(actualFile)

            return Blade.compareBiosSettings(expected, actual)
        except (OSError, IOError) as e:
            Log.error(str(e))
            sys.exit(1)

        return None
Example #17
0
 def powerCycle(self):
     """
     Power cycle all slots
     """
     if self.ping():
         for slot in range(1, 15):
             self.powerCycleSlot(slot)
     else:
         Log.info('%s not pingable, cannot power cycle all blades' % self.host)
Example #18
0
 def collectChassisInfo(self, snmp):
     """
     Retrieve chassis information
     """
     for (attr, oid) in self.chassisOidDict.items():
         values = snmp.walk(oid)
         if values:
             Log.debug(10, '%s: %s' % (attr, values[0][1]))
             setattr(self, attr, values[0][1])
Example #19
0
 def collectChassisInfo(self, snmp):
     """
     Retrieve chassis information
     """ 
     for (attr, oid) in self.chassisOidDict.items():
         values = snmp.walk(oid)
         if values:
             Log.debug(10, '%s: %s' % (attr, values[0][1]))
             setattr(self, attr, values[0][1])
Example #20
0
    def create(self, params):
        '''zfs create
        
        params -- { name: name,
                    properties:   {property: value, p2: v2, ...},
                    volume:       {size: size, sparse: true|false}
                    createParent: true or false} }
        '''
        # If no arguments provided, return immediately
        if params is None:
            raise ValueError('zfs create function received no parameters')

        command = ['create']

        name         = params.get('name', None)
        properties   = params.get('properties', None)
        volume       = params.get('volume', None)
        createParent = params.get('createParent', None)

        if not name:
            raise ValueError('zfs create function needs a name parameter')

        if createParent:
            command.append('-p')

        if not properties is None:
            for property, value in properties.iteritems():
                command.append('-o')
                command.append('%s=%s' % (property, value))

        if not volume is None:
            size = volume.get('size', None)
            sparse = volume.get('sparse', None)

            if not size:
                raise ValueError('Volumes must have a size attribute')

            command.append('-V')
            command.append(size)

            if sparse and sparse != False:
                command.append('-s')

        command.append(name)

        # Flag is set if the dataset is created
        created = None
        if self.all.has_key(name):
            if volume:
                Log.info('%s already exists. Not creating volume' % name)
            else:
                Log.info('%s already exists. Not creating filesystem' % name)
        else:
            self.run(command)
            created = True

        return created
Example #21
0
    def create_mapped_lun(self, acl, num, lun):
        mapped_lun = None
        if not list(acl.mapped_luns):
            Log.info('creating mapped lun (%s, %s, %s)' % (acl, num, lun))
            mapped_lun = MappedLUN(acl, num, lun)
        else:
            Log.info('mapped lun (%s, %s, %s) already exists' %
                     (acl, num, lun))

        return mapped_lun
Example #22
0
    def create_mapped_lun(self, acl, num, lun):
        mapped_lun = None
        if not list(acl.mapped_luns):
            Log.info('creating mapped lun (%s, %s, %s)' % (acl, num, lun))
            mapped_lun = MappedLUN(acl, num, lun)
        else:
            Log.info('mapped lun (%s, %s, %s) already exists' %
                     (acl, num, lun))

        return mapped_lun
Example #23
0
 def run(self, args):
     '''Run a zfs command'''
     cmd = args
     cmd.insert(0, self.zfs)
     output = ''
     try:
         Log.info(' '.join(cmd))
         output = subprocess.check_output(cmd, stderr=subprocess.STDOUT).split('\n')
     except subprocess.CalledProcessError, e:
         raise ValueError(str(e.output))
Example #24
0
 def powerCycle(self):
     """
     Power cycle all slots
     """
     if self.ping():
         for slot in range(1, 15):
             self.powerCycleSlot(slot)
     else:
         Log.info('%s not pingable, cannot power cycle all blades' %
                  self.host)
Example #25
0
 def create_task(self, job_type_name):
     try:
         args = self.array_parser.parse_args()
         details = LUNCloneJob.with_args(args, job_type_name)
         Log.info('%s job %s added to queue' % (job_type_name, details.id))
         return {'status': 'ok', 'job_id': details.id}, 201
     except (Exception), e:
         Log.error('%s:\n%s' % (str(e), traceback.format_exc()))
         return {'status': str(e),
                 'stacktrace': traceback.format_exc()}, 501
Example #26
0
    def collectAndClearEventLog(self, couch):
        log = {}

        # OIDs to retrieve
        oids = ['BLADE-MIB::readEnhancedEventLogAttribute', 'BLADE-MIB::readEnhancedEventLogMessage']

        # Get the mapping of blade serial numbers to blade document ids
        serialNumberToDocId = Blade.serialNumberToDocId(couch)

        for oid in oids:

            # Start async snmpwalk. This call returns immediately
            # and spawns a background thread to perform the SNMPWalk
            snmpWalk = SNMPWalk.withConfigFile(self.host, oid)

            # While the snmpwalk is running
            while not snmpWalk.eof:
                # Get snmp oid/value pairs off the queue
                while not snmpWalk.queue.empty():
                    (oid, value) = snmpWalk.queue.get()
                    (mibName, oidBase, lastOctet) = snmpWalk.extractOidParts(oid)

                    if oidBase != 'readEnhancedEventLogNumber':
                        # Start with an empty dictionary
                        dict = {}

                        # Get the existing log entry, if it exists
                        if log.has_key(lastOctet):
                            dict = log[lastOctet]

                        # Update the dictionary with this line from the snmpwalk
                        if oidBase == 'readEnhancedEventLogAttribute':
                            dict.update(self.parseEventLogAttribute(value, serialNumberToDocId))
                        else:
                            match = re.search('^Text:(.*)$', value)
                            if match:
                                value = match.group(1)

                            dict.update({'message': value})

                        # Update the log entry list
                        log[lastOctet] = dict

                        # On the final snmp walk command, create CouchDB objects
                        if dict and oidBase == 'readEnhancedEventLogMessage':
                            logEntry = LogEntry(dict)
                            logEntry.persist(couch)

            # Join snmpwalk background thread
            snmpWalk.join()
        
        snmp = SNMP.withConfigFile(self.host)
        snmp.set('BLADE-MIB::clearEventLog.0', 'i', '1')

        Log.info('%s system log entries collected from %s' % (len(log), self.name))
Example #27
0
    def run(self, args):
        '''Run a command, capture stderr and report the exception, if an exception happens'''
        Log.info('%s' % ' '.join(args))

        pipes = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = pipes.communicate()

        if pipes.returncode != 0:
            # an error happened!
            err_msg = "%s. Code: %s" % (stderr.strip(), pipes.returncode)
            raise Exception(err_msg)
Example #28
0
    def run(cls, args):
        output = None
        exitCode = 0
        try:
            Log.debug(100, ' '.join(args))
            proc = Popen(args, stdout=PIPE)
            output = proc.communicate()[0].split('\n')
            exitCode = proc.returncode
        except (OSError) as e:
            Log.error(str(e))

        return (output, exitCode)
Example #29
0
    def powerOnOff(self, func):
        """
        Power on / off all slots in the chassis

        func:  int
               0 = off, 1 = on, 2 = soft off
        """
        if self.ping():
            for slot in range(1, 15):
                self.powerOnOffSlot(slot, func)
        else:
            Log.info('%s is not pingable, cannot apply power func %d all slots' % (self.host, func))
Example #30
0
    def run(cls, args):
        output = None
        exitCode = 0
        try:
            Log.debug(100, " ".join(args))
            proc = Popen(args, stdout=PIPE)
            output = proc.communicate()[0].split("\n")
            exitCode = proc.returncode
        except (OSError) as e:
            Log.error(str(e))

        return (output, exitCode)
Example #31
0
    def delete_block_store(self, name):
        store = self.block_store.get(name)

        # If blockstore doesn't exist, do not proceed
        if store is None:
            Log.info('No block store %s. Not deleting' % name)
            return

        Log.info('deleting block store %s' % (name))

        # Delete the block store. The backing device, file, etc,  still exists
        store.delete()
        del self.block_store[name]
Example #32
0
    def delete_block_store(self, name):
        store = self.block_store.get(name)

        # If blockstore doesn't exist, do not proceed
        if store is None:
            Log.info('No block store %s. Not deleting' % name)
            return

        Log.info('deleting block store %s' % (name))

        # Delete the block store. The backing device, file, etc,  still exists
        store.delete()
        del self.block_store[name]
Example #33
0
    def getView(self, design, view, key = None):
        """
        Get a view

        Params
        ------
        design:  string
                 The design document name
        view:    string
                 The view name
        key:     string (optional)
                 a key to select

        Returns
        -------
        A dictionary of view key/value pairs. If no results were returned, then
        None is returned
        """
        path = '_design/%s/_view/%s' % (design, view)

        if key:
            path = '%s?key="%s"' % (path, key)

        output = self.getDocument(path)
        results = {}

        if output.has_key(u'total_rows'):
            Log.debug(10, '%s returned %s rows' % (path, output[u'total_rows']))

        if output.has_key(u'rows'):
            for row in output[u'rows']:
                value = row[u'value']
                key   = row[u'key']

                if results.has_key(key):
                    storedValue = results[key]

                    # If the stored value is a dict, change to an array of dicts
                    if isinstance(storedValue, (frozenset, list, set, tuple)):
                        storedValue.append(value)
                        value = storedValue
                    else:
                        value = [storedValue, value]

                results[key] = value

        # If no results, then return a None object
        if len(results) <= 0:
            results = {}

        return results
Example #34
0
    def process(self):
        try:
            errors = []
            for task in LUNCloneJob.pending():
                try:
                    Log.info('%s job %s started' %
                             (task.job_type.code, task.id))
                    task.set_status_start_job()

                    if task.is_create():
                        self.create_clones(task)
                    else:
                        self.delete_clones(task)

                    task.set_status_complete()
                    Log.info('%s job %s completed' %
                             (task.job_type.code, task.id))

                except (Exception), e:
                    error = u'%s:\n%s' % (str(e), traceback.format_exc())
                    Log.error('%s job %s failed' %
                              (task.job_type.code, task.id))
                    Log.error(error)
                    task.set_status_failed(error)
                    errors.append(task.error)

            if len(errors) > 0:
                message = {'message': errors}
                return {'status': 'error',
                        'errors': errors}
Example #35
0
    def remove_clone(self, task, zfs, args):
        # If deleteClones = true, then the dst parameter is also required.
        deleteClones = args.get('deleteClones', None)

        if deleteClones:
            if args.get('dst', None) is None:
                message = {'message': 'deleteClones parameter requires dst '
                                      'parameter'}
                return message

            zfs.destroy(args)
        else:
            Log.info('Delete task %s did not specify deleteClones param for %s'
                     % (task.id, args[u'dst']))
Example #36
0
    def snapshot(self, params):
        if params is None:
            raise ValueError('zfs snapshot function received no parameters')

        name = params.get('name', None)

        if name is None:
            raise ValueError('zfs snapshot function needs a name parameter')

        if not self.all.has_key(name):
            command = ['snapshot', name]
            self.run(command)
        else:
            Log.info('%s already exists. Not creating snapshot' % name)
Example #37
0
    def process(self):
        try:
            errors = []
            for task in LUNCloneJob.pending():
                try:
                    Log.info('%s job %s started' %
                             (task.job_type.code, task.id))
                    task.set_status_start_job()

                    if task.is_create():
                        self.create_clones(task)
                    else:
                        self.delete_clones(task)

                    task.set_status_complete()
                    Log.info('%s job %s completed' %
                             (task.job_type.code, task.id))

                except (Exception), e:
                    error = u'%s:\n%s' % (str(e), traceback.format_exc())
                    Log.error('%s job %s failed' %
                              (task.job_type.code, task.id))
                    Log.error(error)
                    task.set_status_failed(error)
                    errors.append(task.error)

            if len(errors) > 0:
                message = {'message': errors}
                return {'status': 'error', 'errors': errors}
Example #38
0
    def powerOnOff(self, func):
        """
        Power on / off all slots in the chassis

        func:  int
               0 = off, 1 = on, 2 = soft off
        """
        if self.ping():
            for slot in range(1, 15):
                self.powerOnOffSlot(slot, func)
        else:
            Log.info(
                '%s is not pingable, cannot apply power func %d all slots' %
                (self.host, func))
Example #39
0
    def run(self):
        """
        Perform an SNMP walk
        """
        version = '-v1'
        if self.version == 2:
            version = '-v2'

        command = [
            snmpwalk_cmd, '-t', '120', version, '-c', self.readCommunity,
            self.host, self.oid
        ]
        Log.debug(100, ' '.join(command))

        # Launch the command as subprocess.
        process = subprocess.Popen(command,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)

        # Launch the asynchronous readers of the process' stdout and stderr.
        stdoutQueue = Queue.Queue()
        stdoutReader = AsynchronousFileReader(process.stdout, stdoutQueue)
        stdoutReader.start()
        stderrQueue = Queue.Queue()
        stderrReader = AsynchronousFileReader(process.stderr, stderrQueue)
        stderrReader.start()

        # Check the queues if we received some output (until there is nothing more to get).
        while not stdoutReader.eof() or not stderrReader.eof():
            # Show what we received from standard output.
            while not stdoutQueue.empty():
                line = stdoutQueue.get()
                self.queue.put(self.split(line))

            # Show what we received from standard error.
            while not stderrQueue.empty():
                line = stderrQueue.get()
                print 'Received line on standard error: ' + repr(line)

            # Sleep a bit before asking the readers again.
            time.sleep(.1)

        # Let's be tidy and join the threads we've started.
        stdoutReader.join()
        stderrReader.join()

        # Close subprocess' file descriptors.
        process.stdout.close()
        process.stderr.close()
Example #40
0
    def bladeInfo(self, snmp, inOid):
        """
        Retrieve information about blades in a chassis
        """
        values = snmp.walk(inOid)
        slotValues = []
        for (oid, value) in values:
            slot = snmp.extractLastOctet(oid)
            if slot:
                slotValues.append( (slot, value) )
                
                if not slotValues:
                    Log.error('No results for %s %s' % (host, inOid))

        return slotValues
Example #41
0
    def bladeInfo(self, snmp, inOid):
        """
        Retrieve information about blades in a chassis
        """
        values = snmp.walk(inOid)
        slotValues = []
        for (oid, value) in values:
            slot = snmp.extractLastOctet(oid)
            if slot:
                slotValues.append((slot, value))

                if not slotValues:
                    Log.error('No results for %s %s' % (host, inOid))

        return slotValues
Example #42
0
    def create_portal(self, tpg, ip, port):
        portal = None
        portal_id = self.get_portal_id(ip, port)
        wwn = tpg.parent_target.wwn
        portal_list = self.target[wwn]['tpg'][tpg.tag]['portal']

        if portal_id in portal_list:
            Log.info('portal %s already exists, not creating' % (portal_id))
            portal = portal_list[portal_id]
        else:
            Log.info('creating portal (%s, %s, %s)' % (tpg, ip, port))
            portal = NetworkPortal(tpg, ip, port)
            portal_list[portal_id] = portal

        return portal
Example #43
0
    def create_acl(self, tpg, initiator_name):
        acl = None
        wwn = tpg.parent_target.wwn
        acl_list = self.target[wwn]['tpg'][tpg.tag]['acl']

        if initiator_name in acl_list:
            Log.info('acl (%s, %s) already exists, not creating' %
                     (tpg, initiator_name))
            acl = acl_list[initiator_name]
        else:
            Log.info('creating acl (%s, %s)' % (tpg, initiator_name))
            acl = NodeACL(tpg, initiator_name)
            acl_list[initiator_name] = acl

        return acl
Example #44
0
    def create_portal(self, tpg, ip, port):
        portal = None
        portal_id = self.get_portal_id(ip, port)
        wwn = tpg.parent_target.wwn
        portal_list = self.target[wwn]['tpg'][tpg.tag]['portal']

        if portal_id in portal_list:
            Log.info('portal %s already exists, not creating' % (portal_id))
            portal = portal_list[portal_id]
        else:
            Log.info('creating portal (%s, %s, %s)' % (tpg, ip, port))
            portal = NetworkPortal(tpg, ip, port)
            portal_list[portal_id] = portal

        return portal
Example #45
0
    def create_acl(self, tpg, initiator_name):
        acl = None
        wwn = tpg.parent_target.wwn
        acl_list = self.target[wwn]['tpg'][tpg.tag]['acl']

        if initiator_name in acl_list:
            Log.info('acl (%s, %s) already exists, not creating' %
                     (tpg, initiator_name))
            acl = acl_list[initiator_name]
        else:
            Log.info('creating acl (%s, %s)' % (tpg, initiator_name))
            acl = NodeACL(tpg, initiator_name)
            acl_list[initiator_name] = acl

        return acl
Example #46
0
    def destroy(self, params):
        # Verify that parameters were received
        if params is None:
            raise ValueError('zfs destroy function received no parameters')

        # Get the name
        name = params.get('dst', None)

        if not name:
            raise ValueError('zfs destroy function needs a name parameter')

        if self.all.has_key(name):
            command = ['destroy', name]
            self.run(command)
        else:
            Log.info('%s does not exist. Cannot destroy' % name)
Example #47
0
    def create_lun(self, tpg, blockstore):
        wwn = tpg.parent_target.wwn
        lun_list = self.target[wwn]['tpg'][tpg.tag]['lun']
        lun = lun_list.get(blockstore.name, None)

        if lun is None:
            Log.info('creating lun %s, blockstore %s' % (tpg, blockstore))
            # Create the LUN
            lun = LUN(tpg, 0, blockstore)
            # Add it to the local data structure for tracking LUNs
            lun_list[blockstore.name] = lun
        else:
            # LUN already exists
            Log.info('lun %s already exists, not creating' % (blockstore.name))

        return lun
Example #48
0
    def delete(self, params):
        """
        Delete a document. Params must have an _id and _rev param
        """
        path = '/%s/%s?rev=%s' % (self.db, params['_id'].replace(' ', '+'), params['_rev'].replace(' ', '+'))
        Log.debug(10, 'DELETE %s' % path)
        connection = httplib.HTTPConnection(self.host, self.port)
        connection.connect()
        connection.request('DELETE', path)
        result = json.loads(connection.getresponse().read())

        if result.has_key(u'error'):
            if result[u'error'] != u'not_found':
                Log.error('GET %s: %s' % (path, result))

        return result
Example #49
0
    def create_lun(self, tpg, blockstore):
        wwn = tpg.parent_target.wwn
        lun_list = self.target[wwn]['tpg'][tpg.tag]['lun']
        lun = lun_list.get(blockstore.name, None)

        if lun is None:
            Log.info('creating lun %s, blockstore %s' % (tpg, blockstore))
            # Create the LUN
            lun = LUN(tpg, 0, blockstore)
            # Add it to the local data structure for tracking LUNs
            lun_list[blockstore.name] = lun
        else:
            # LUN already exists
            Log.info('lun %s already exists, not creating' % (blockstore.name))

        return lun
Example #50
0
    def create_target(self, wwn):
        target_dict = self.target.get(wwn, None)
        target = None

        if target_dict is None:
            Log.info('creating target with wwn %s' % (wwn))
            # The wwn will be lowercased automatically by something
            # outside this library. I'm not sure if its RTSLib or
            # the underlying Linux target system
            target = Target(self.iscsi, wwn)
            # Add target to data structure, initialize empty child nodes
            self.target[wwn] = {'target': target, 'tpg': {}}
        else:
            Log.info('target %s already exists, not creating' % (wwn))
            target = target_dict['target']

        return target
Example #51
0
    def remove_clone(self, task, zfs, args):
        # If deleteClones = true, then the dst parameter is also required.
        deleteClones = args.get('deleteClones', None)

        if deleteClones:
            if args.get('dst', None) is None:
                message = {
                    'message': 'deleteClones parameter requires dst '
                    'parameter'
                }
                return message

            zfs.destroy(args)
        else:
            Log.info(
                'Delete task %s did not specify deleteClones param for %s' %
                (task.id, args[u'dst']))
Example #52
0
    def allBladesFailToNetboot(cls, couch):
        """
        Find a list of chassis where all blades failed to netboot
        
        Params
        ------
        couch:   object
                 A CouchDB object

        Returns
        -------
        A list of chassis docId
        """

        results = couch.getView('blade', 'failed_netboot')

        chassis = {}
        failedChassis = []

        for bladeDocId in results:
            slotInfo = Slot.retrieveWithMac(couch, bladeDocId)

            chassisDocId = None
            slotNum = None

            if slotInfo:
                Log.debug(200, 'slotInfo: %s' % slotInfo)
                if slotInfo.has_key(u'chassisDocId'):
                    chassisDocId = slotInfo[u'chassisDocId']

                if slotInfo.has_key(u'num'):
                    slotNum = slotInfo[u'num']

            if chassisDocId and slotInfo:
                if chassis.has_key(chassisDocId):
                    chassis[chassisDocId].append(slotNum)
                else:
                    chassis[chassisDocId] = [slotNum]

        for chassisDocId in sorted(chassis.iterkeys()):
            slots = chassis[chassisDocId]
            if len(slots) >= 14:
                failedChassis.append(chassisDocId)

        return failedChassis
Example #53
0
    def mount(self, params):
        '''Mount an image
    
        Parameters
        ----------
        params : string
            Image parameter dictionary
        '''
        chroot = params['chroot']
        device = params['device']

        Log.info('device %s' % device)

        # Sanity check, destination shouldn't be a file
        if os.path.isfile(chroot):
            log_error_node(params, '%s is a file, can not mount %s at this location' % (chroot, device, params['vnode_name']))
            return

        # Make sure the destination exists
        if not os.path.exists(chroot):
            log_info_node(params, 'mkdir %s' % chroot)
            os.makedirs(chroot)

        # If the destination is already mounted, then
        # no need to mount again. It's likely the correctly mounted
        # device from a previous prep run that died
        if not os.path.ismount(chroot):
            log_info_node(params, 'mount %s %s' % (device, chroot))
            self.run([mount_cmd, device, chroot])
        else:
            log_info_node(params, '%s already mounted, hoping for the best' % chroot)

        # Mount /sys, /proc and /dev in image chroot
        bind_mounts = ['/sys', '/proc', '/dev']

        if not os.path.ismount(chroot):
            log_error_node(params, 'mount of %s failed, cannot mount %s in chroot' % (chroot, bind_mounts))
        else:
            for bind_mount in bind_mounts:
                dest = chroot + bind_mount
                log_info_node(params, 'mount -o bind %s %s' % (bind_mount, dest))
                self.run([mount_cmd, '-o', 'bind', bind_mount, dest])
Example #54
0
    def getDocument(self, docId):
        """
        GET a document from the server

        Params
        ------
        docId : string
                The unique ID of the document
        """
        path = '/%s/%s' % (self.db, docId.replace(' ', '+'))
        connection = httplib.HTTPConnection(self.host, self.port)
        connection.connect()
        connection.request('GET', path)
        result = json.loads( connection.getresponse().read())

        if result.has_key(u'error'):
            if result[u'error'] != u'not_found':
                Log.error('GET %s: %s' % (path, result))

        return result