def handle_facts_disks(dev, facts, is_virtual=False): disks = {} _cur_key = None for k, v in facts.iteritems(): if not k.startswith('disk_'): continue k = k[5:] if k.endswith('_product'): _cur_key = 'product' k = k[:-8] elif k.endswith('_revision'): _cur_key = 'revision' k = k[:-9] elif k.endswith('_size'): _cur_key = 'size' k = k[:-5] elif k.endswith('_vendor'): _cur_key = 'vendor' k = k[:-7] elif k.endswith('_serial'): _cur_key = 'serial' k = k[:-7] else: continue disks.setdefault(k, {})[_cur_key] = v.strip() for label, disk in disks.iteritems(): try: if 'size' not in disk or not int(disk['size']): continue except ValueError: continue if disk['vendor'].lower() in DISK_VENDOR_BLACKLIST: continue if disk['product'].lower() in DISK_PRODUCT_BLACKLIST: continue sn = disk.get('serial', '').strip() if sn: stor, created = Storage.concurrent_get_or_create(device=dev, sn=sn) else: stor, created = Storage.concurrent_get_or_create(device=dev, mount_point=label, sn=None) stor.size = disk['size'] = int(int(disk['size']) / 1024 / 1024) stor.label = '{} {} {}'.format(disk['vendor'].strip(), disk['product'].strip(), disk['revision'].strip()) extra = """Vendor: {vendor} Product: {product} Firmware Revision: {revision} Size: {size}""".format(**disk) stor.model, c = ComponentModel.concurrent_get_or_create( size=stor.size, speed=0, type=ComponentType.disk.id, family=disk['vendor'].strip(), extra_hash=hashlib.md5(extra).hexdigest(), extra=extra) stor.model.name = '{} {}MiB'.format(stor.label, stor.size) stor.model.save(priority=SAVE_PRIORITY) stor.save(priority=SAVE_PRIORITY)
def handle_facts_disks(dev, facts, is_virtual=False): disks = {} _cur_key = None for k, v in facts.iteritems(): if not k.startswith('disk_'): continue k = k[5:] if k.endswith('_product'): _cur_key = 'product' k = k[:-8] elif k.endswith('_revision'): _cur_key = 'revision' k = k[:-9] elif k.endswith('_size'): _cur_key = 'size' k = k[:-5] elif k.endswith('_vendor'): _cur_key = 'vendor' k = k[:-7] elif k.endswith('_serial'): _cur_key = 'serial' k = k[:-7] else: continue disks.setdefault(k, {})[_cur_key] = v.strip() for label, disk in disks.iteritems(): try: if 'size' not in disk or not int(disk['size']): continue except ValueError: continue if disk['vendor'].lower() in DISK_VENDOR_BLACKLIST: continue if disk['product'].lower() in DISK_PRODUCT_BLACKLIST: continue sn = disk.get('serial', '').strip() if sn: stor, created = Storage.concurrent_get_or_create( device=dev, sn=sn) else: stor, created = Storage.concurrent_get_or_create( device=dev, mount_point=label, sn=None) stor.size = disk['size'] = int(int(disk['size']) / 1024 / 1024) stor.label = '{} {} {}'.format( disk['vendor'].strip(), disk['product'].strip(), disk['revision'].strip()) extra = """Vendor: {vendor} Product: {product} Firmware Revision: {revision} Size: {size}""".format(**disk) stor.model, c = ComponentModel.concurrent_get_or_create( size=stor.size, speed=0, type=ComponentType.disk.id, family=disk['vendor'].strip(), extra_hash=hashlib.md5(extra).hexdigest(), extra=extra) stor.model.name = '{} {}MiB'.format(stor.label, stor.size) stor.model.save(priority=SAVE_PRIORITY) stor.save(priority=SAVE_PRIORITY)
def _save_storage(dev, data): detected_storage = [] for disk in data: model_name = "{} {}".format( disk['manufacturer'], disk['model'] ) size = int(int(disk['size']) / 1024 / 1024 / 1024) model, _ = ComponentModel.create( ComponentType.disk, size=size, family=model_name, priority=SAVE_PRIORITY, ) storage, _ = Storage.concurrent_get_or_create( device=dev, sn=disk['sn'], mount_point=None, ) storage.model = model storage.label = model.name storage.size = size storage.save(priority=SAVE_PRIORITY) detected_storage.append(storage.pk) dev.storage_set.exclude(pk__in=detected_storage).delete()
def handle_smartctl(dev, disks, priority=0): for disk_handle, disk in disks.iteritems(): if not disk.get("serial_number") or disk.get("device_type") != "disk": continue if {"user_capacity", "vendor", "product", "transport_protocol"} - set(disk.keys()): # not all required keys present continue if disk["vendor"].lower() in DISK_VENDOR_BLACKLIST: continue if disk["product"].lower() in DISK_PRODUCT_BLACKLIST: continue stor, created = Storage.concurrent_get_or_create(device=dev, sn=disk["serial_number"], mount_point=None) stor.device = dev size_value, size_unit, rest = disk["user_capacity"].split(" ", 2) size_value = size_value.replace(",", "") stor.size = int(int(size_value) / units.size_divisor[size_unit]) stor.speed = int(disk.get("rotational_speed", 0)) label_meta = [" ".join(disk["vendor"].split()), disk["product"]] if "transport_protocol" in disk: label_meta.append(disk["transport_protocol"]) stor.label = " ".join(label_meta) disk_default = dict( vendor="unknown", product="unknown", revision="unknown", transport_protocol="unknown", user_capacity="unknown", ) disk_default.update(disk) stor.model, c = ComponentModel.create( ComponentType.disk, size=stor.size, speed=stor.speed, family=stor.label, priority=priority ) stor.save(priority=priority)
def save_storage(storage, dev): mount_points = [] for s in storage: if not s.get('sn'): continue stor, created = Storage.concurrent_get_or_create(device=dev, sn=s.get('sn')) try: stor.size = int(s.get('size')) except ValueError: pass stor.label = s.get('label') model = '{} {}MiB'.format(stor.label, stor.size) stor.mount_point = s.get('mountpoint') mount_points.append(stor.mount_point) extra = '' stor.model, c = ComponentModel.concurrent_get_or_create( size=stor.size, type=ComponentType.disk.id, speed=0, cores=0, extra=extra, extra_hash=hashlib.md5(extra).hexdigest(), family=model) stor.model.name = model stor.model.save(priority=SAVE_PRIORITY) stor.save(priority=SAVE_PRIORITY) dev.storage_set.exclude(mount_point__in=mount_points).delete()
def handle_hpacu(dev, disks, priority=0): for disk_handle, disk in disks.iteritems(): if not disk.get('serial_number'): continue stor, created = Storage.concurrent_get_or_create(device=dev, sn=disk['serial_number']) stor.device = dev size_value, size_unit = disk['size'].split() stor.size = int(float(size_value) / units.size_divisor[size_unit]) stor.speed = int(disk.get('rotational_speed', 0)) stor.label = '{} {}'.format(' '.join(disk['model'].split()), disk['interface_type']) disk_default = dict( model = 'unknown', firmware_revision = 'unknown', interface_type = 'unknown', size = 'unknown', rotational_speed = 'unknown', status = 'unknown', ) disk_default.update(disk) extra = """Model: {model} Firmware Revision: {firmware_revision} Interface: {interface_type} Size: {size} Rotational Speed: {rotational_speed} Status: {status}""".format(**disk_default) stor.model, c = ComponentModel.concurrent_get_or_create( size=stor.size, speed=stor.speed, type=ComponentType.disk.id, family='', extra_hash=hashlib.md5(extra).hexdigest(), extra=extra) stor.model.name = '{} {}MiB'.format(stor.label, stor.size) stor.model.save(priority=priority) stor.save(priority=priority)
def handle_hpacu(dev, disks, priority=0): for disk_handle, disk in disks.iteritems(): if not disk.get('serial_number'): continue stor, created = Storage.concurrent_get_or_create( device=dev, sn=disk['serial_number'], mount_point=None, ) stor.device = dev size_value, size_unit = disk['size'].split() stor.size = int(float(size_value) / units.size_divisor[size_unit]) stor.speed = int(disk.get('rotational_speed', 0)) stor.label = '{} {}'.format(' '.join(disk['model'].split()), disk['interface_type']) disk_default = dict( model='unknown', firmware_revision='unknown', interface_type='unknown', size='unknown', rotational_speed='unknown', status='unknown', ) disk_default.update(disk) stor.model, c = ComponentModel.create( ComponentType.disk, size=stor.size, speed=stor.speed, family=stor.label, priority=priority, ) stor.save(priority=priority)
def parse_megaraid(facts, dev): disks = {} for k, value in facts.iteritems(): m = MEGARAID_REGEX.match(k) if not m: continue controller = m.group(1) disk = m.group(2) property = m.group(3) disks.setdefault((controller, disk), {})[property] = value.strip() for (controller_handle, disk_handle), disk in disks.iteritems(): disk['vendor'], disk['product'], disk['serial_number'] = \ _handle_inquiry_data(disk.get('inquiry_data', ''), controller_handle, disk_handle) if not disk.get('serial_number') or disk.get('media_type') not in ('Hard Disk Device', 'Solid State Device'): continue if {'coerced_size', 'vendor', 'product', 'pd_type'} - \ set(disk.keys()): # not all required keys present continue if disk['vendor'].lower() in DISK_VENDOR_BLACKLIST: continue if disk['product'].lower() in DISK_PRODUCT_BLACKLIST: continue stor, created = Storage.concurrent_get_or_create(device=dev, sn=disk['serial_number']) stor.device = dev size_value, size_unit, rest = disk['coerced_size'].split(' ', 2) size_value = size_value.replace(',', '') stor.size = int(float(size_value) / units.size_divisor[size_unit]) stor.speed = int(disk.get('rotational_speed', 0)) label_meta = [' '.join(disk['vendor'].split()), disk['product']] if 'pd_type' in disk: label_meta.append(disk['pd_type']) stor.label = ' '.join(label_meta) disk_default = dict( vendor = 'unknown', product = 'unknown', device_firmware_level = 'unknown', pd_type = 'unknown', coerced_size = 'unknown', ) disk_default.update(disk) extra = """Model: {vendor} {product} Firmware Revision: {device_firmware_level} Interface: {pd_type} Size: {coerced_size} """.format(**disk_default) stor.model, c = ComponentModel.concurrent_get_or_create( size=stor.size, speed=stor.speed, type=ComponentType.disk.id, family='', extra_hash=hashlib.md5(extra).hexdigest(), extra=extra) stor.model.name = '{} {}MiB'.format(stor.label, stor.size) stor.model.save(priority=SAVE_PRIORITY) stor.save(priority=SAVE_PRIORITY)
def save_storage(storage, dev): mount_points = [] for item in storage: sn = item.get('sn') mount_point = item.get('mountpoint') if not sn or not mount_point: continue label = item.get('label') try: size = int(item.get('size')) except ValueError: continue model_name = '{} {}MiB'.format(label, size) model, c = ComponentModel.create( ComponentType.disk, size=size, family=model_name, priority=SAVE_PRIORITY, ) stor = None try: stor = Storage.objects.get(device=dev, mount_point=mount_point) if stor.sn != sn: try: stor_found_by_sn = Storage.objects.get(sn=sn) if all((stor_found_by_sn.model == model, stor_found_by_sn.size == size, stor_found_by_sn.label == label)): stor.mount_point = None stor.save(priotity=SAVE_PRIORITY) stor = stor_found_by_sn stor.device = dev stor.mount_point = mount_point else: stor = None except Storage.DoesNotExist: stor.sn = sn except Storage.DoesNotExist: try: stor = Storage.objects.get(sn=sn) if all((stor.model == model, stor.size == size, stor.label == label)): stor.device = dev stor.mount_point = mount_point else: stor = None except Storage.DoesNotExist: stor = Storage(device=dev, mount_point=mount_point, sn=sn) if stor: stor.model = model stor.label = label stor.size = size stor.save(priority=SAVE_PRIORITY) mount_points.append(mount_point) dev.storage_set.exclude(mount_point__in=mount_points).update( mount_point=None)
def handle_lshw_storage(dev, lshw, is_virtual=False, priority=0): mount_points, storages = get_storage_from_lshw(lshw) dev.storage_set.filter(mount_point__in=mount_points).delete() for storage in storages: if storage['sn']: stor, created = Storage.concurrent_get_or_create(sn=storage['sn'], device=dev) stor.mount_point = storage['mount_point'] else: stor, created = Storage.concurrent_get_or_create( sn=None, device=dev, mount_point=storage['mount_point']) stor.size = storage['size'] stor.speed = storage['speed'] stor.label = storage['label'] stor.model, c = ComponentModel.concurrent_get_or_create( size=stor.size, speed=stor.speed, type=ComponentType.disk.id, family='', extra_hash=hashlib.md5(storage['extra']).hexdigest()) stor.model.extra = storage['extra'] stor.model.name = '{} {}MiB'.format(stor.label, stor.size) stor.model.save(priority=priority) stor.save(priority=priority)
def handle_megaraid(dev, disks, priority=0): for (controller_handle, disk_handle), disk in disks.iteritems(): disk['vendor'], disk['product'], disk['serial_number'] = \ _handle_inquiry_data( disk.get('inquiry_data', ''), controller_handle, disk_handle ) if not disk.get('serial_number') or disk.get('media_type') not in ( 'Hard Disk Device', 'Solid State Device'): continue if {'coerced_size', 'vendor', 'product', 'pd_type'} - \ set(disk.keys()): # not all required keys present continue if disk['vendor'].lower() in DISK_VENDOR_BLACKLIST: continue if disk['product'].lower() in DISK_PRODUCT_BLACKLIST: continue stor, created = Storage.concurrent_get_or_create( device=dev, sn=disk['serial_number']) stor.device = dev size_value, size_unit, rest = disk['coerced_size'].split(' ', 2) size_value = size_value.replace(',', '') stor.size = int(float(size_value) / units.size_divisor[size_unit]) stor.speed = int(disk.get('rotational_speed', 0)) label_meta = [' '.join(disk['vendor'].split()), disk['product']] if 'pd_type' in disk: label_meta.append(disk['pd_type']) stor.label = ' '.join(label_meta) disk_default = dict( vendor='unknown', product='unknown', device_firmware_level='unknown', pd_type='unknown', coerced_size='unknown', ) disk_default.update(disk) extra = """Model: {vendor} {product} Firmware Revision: {device_firmware_level} Interface: {pd_type} Size: {coerced_size} """.format(**disk_default) stor.model, c = ComponentModel.concurrent_get_or_create( size=stor.size, speed=stor.speed, type=ComponentType.disk.id, family='', extra_hash=hashlib.md5(extra).hexdigest(), extra=extra) stor.model.name = '{} {}MiB'.format(stor.label, stor.size) stor.model.save(priority=priority) stor.save(priority=priority)
def handle_facts_disks(dev, facts, is_virtual=False): disks = {} _cur_key = None for k, v in facts.iteritems(): if not k.startswith('disk_'): continue k = k[5:] if k.endswith('_product'): _cur_key = 'product' k = k[:-8] elif k.endswith('_revision'): _cur_key = 'revision' k = k[:-9] elif k.endswith('_size'): _cur_key = 'size' k = k[:-5] elif k.endswith('_vendor'): _cur_key = 'vendor' k = k[:-7] elif k.endswith('_serial'): _cur_key = 'serial' k = k[:-7] else: continue disks.setdefault(k, {})[_cur_key] = v.strip() for label, disk in disks.iteritems(): try: if 'size' not in disk or not int(disk['size']): continue except ValueError: continue if disk['vendor'].lower() in DISK_VENDOR_BLACKLIST: continue if disk['product'].lower() in DISK_PRODUCT_BLACKLIST: continue sn = disk.get('serial', '').strip() stor, created = Storage.concurrent_get_or_create( device=dev, mount_point=label, sn=sn if sn else None, ) stor.size = disk['size'] = int(int(disk['size']) / 1024 / 1024) stor.label = '{} {} {}'.format( disk['vendor'].strip(), disk['product'].strip(), disk['revision'].strip()) stor.model, c = ComponentModel.create( ComponentType.disk, size=stor.size, family=disk['vendor'].strip(), priority=SAVE_PRIORITY, ) stor.save(priority=SAVE_PRIORITY)
def handle_facts_disks(dev, facts, is_virtual=False): disks = {} _cur_key = None for k, v in facts.iteritems(): if not k.startswith('disk_'): continue k = k[5:] if k.endswith('_product'): _cur_key = 'product' k = k[:-8] elif k.endswith('_revision'): _cur_key = 'revision' k = k[:-9] elif k.endswith('_size'): _cur_key = 'size' k = k[:-5] elif k.endswith('_vendor'): _cur_key = 'vendor' k = k[:-7] elif k.endswith('_serial'): _cur_key = 'serial' k = k[:-7] else: continue disks.setdefault(k, {})[_cur_key] = v.strip() for label, disk in disks.iteritems(): try: if 'size' not in disk or not int(disk['size']): continue except ValueError: continue if disk['vendor'].lower() in DISK_VENDOR_BLACKLIST: continue if disk['product'].lower() in DISK_PRODUCT_BLACKLIST: continue sn = disk.get('serial', '').strip() stor, created = Storage.concurrent_get_or_create( device=dev, mount_point=label, sn=sn if sn else None, ) stor.size = disk['size'] = int(int(disk['size']) / 1024 / 1024) stor.label = '{} {} {}'.format(disk['vendor'].strip(), disk['product'].strip(), disk['revision'].strip()) stor.model, c = ComponentModel.create( ComponentType.disk, size=stor.size, family=disk['vendor'].strip(), priority=SAVE_PRIORITY, ) stor.save(priority=SAVE_PRIORITY)
def handle_lshw_storage(dev, lshw, is_virtual=False, priority=0): mount_points, storages = get_storage_from_lshw(lshw) dev.storage_set.filter(mount_point__in=mount_points).delete() for storage in storages: sn = storage["sn"] if storage["sn"] else None stor, created = Storage.concurrent_get_or_create(sn=sn, mount_point=storage["mount_point"], device=dev) stor.size = storage["size"] stor.speed = storage["speed"] stor.label = storage["label"] stor.model, c = ComponentModel.create( ComponentType.disk, size=stor.size, speed=stor.speed, family=stor.label, priority=priority ) stor.save(priority=priority)
def parse_smartctl(facts, dev): disks = {} for k, value in facts.iteritems(): m = SMARTCTL_REGEX.match(k) if not m: continue disk = m.group(1) property = m.group(2) disks.setdefault(disk, {})[property] = value.strip() for disk_handle, disk in disks.iteritems(): if not disk.get('serial_number') or disk.get('device_type') != 'disk': continue if {'user_capacity', 'vendor', 'product', 'transport_protocol'} - \ set(disk.keys()): # not all required keys present continue if disk['vendor'].lower() in DISK_VENDOR_BLACKLIST: continue if disk['product'].lower() in DISK_PRODUCT_BLACKLIST: continue stor, created = Storage.concurrent_get_or_create(device=dev, sn=disk['serial_number']) stor.device = dev size_value, size_unit, rest = disk['user_capacity'].split(' ', 2) size_value = size_value.replace(',', '') stor.size = int(int(size_value) / units.size_divisor[size_unit]) stor.speed = int(disk.get('rotational_speed', 0)) label_meta = [' '.join(disk['vendor'].split()), disk['product']] if 'transport_protocol' in disk: label_meta.append(disk['transport_protocol']) stor.label = ' '.join(label_meta) disk_default = dict( vendor = 'unknown', product = 'unknown', revision = 'unknown', transport_protocol = 'unknown', user_capacity = 'unknown', ) disk_default.update(disk) extra = """Model: {vendor} {product} Firmware Revision: {revision} Interface: {transport_protocol} Size: {user_capacity} """.format(**disk_default) stor.model, c = ComponentModel.concurrent_get_or_create( size=stor.size, speed=stor.speed, type=ComponentType.disk.id, family='', extra_hash=hashlib.md5(extra).hexdigest(), extra=extra) stor.model.name = '{} {}MiB'.format(stor.label, stor.size) stor.model.save(priority=SAVE_PRIORITY) stor.save(priority=SAVE_PRIORITY)
def handle_megaraid(dev, disks, priority=0): for (controller_handle, disk_handle), disk in disks.iteritems(): disk['vendor'], disk['product'], disk['serial_number'] = \ _handle_inquiry_data( disk.get('inquiry_data', ''), controller_handle, disk_handle) if not disk.get('serial_number') or disk.get('media_type') not in ( 'Hard Disk Device', 'Solid State Device'): continue if {'coerced_size', 'vendor', 'product', 'pd_type'} - \ set(disk.keys()): # not all required keys present continue if disk['vendor'].lower() in DISK_VENDOR_BLACKLIST: continue if disk['product'].lower() in DISK_PRODUCT_BLACKLIST: continue stor, created = Storage.concurrent_get_or_create( device=dev, sn=disk['serial_number'], mount_point=None, ) stor.device = dev size_value, size_unit, rest = disk['coerced_size'].split(' ', 2) size_value = size_value.replace(',', '') stor.size = int(float(size_value) / units.size_divisor[size_unit]) stor.speed = int(disk.get('rotational_speed', 0)) label_meta = [' '.join(disk['vendor'].split()), disk['product']] if 'pd_type' in disk: label_meta.append(disk['pd_type']) stor.label = ' '.join(label_meta) disk_default = dict( vendor='unknown', product='unknown', device_firmware_level='unknown', pd_type='unknown', coerced_size='unknown', ) disk_default.update(disk) stor.model, c = ComponentModel.create( ComponentType.disk, size=stor.size, speed=stor.speed, family=stor.label, priority=priority, ) stor.save(priority=priority)
def handle_megaraid(dev, disks, priority=0): for (controller_handle, disk_handle), disk in disks.iteritems(): disk['vendor'], disk['product'], disk['serial_number'] = \ _handle_inquiry_data( disk.get('inquiry_data', ''), controller_handle, disk_handle ) if not disk.get('serial_number') or disk.get('media_type') not in ( 'Hard Disk Device', 'Solid State Device'): continue if {'coerced_size', 'vendor', 'product', 'pd_type'} - \ set(disk.keys()): # not all required keys present continue if disk['vendor'].lower() in DISK_VENDOR_BLACKLIST: continue if disk['product'].lower() in DISK_PRODUCT_BLACKLIST: continue stor, created = Storage.concurrent_get_or_create( device=dev, sn=disk['serial_number'], mount_point=None, ) stor.device = dev size_value, size_unit, rest = disk['coerced_size'].split(' ', 2) size_value = size_value.replace(',', '') stor.size = int(float(size_value) / units.size_divisor[size_unit]) stor.speed = int(disk.get('rotational_speed', 0)) label_meta = [' '.join(disk['vendor'].split()), disk['product']] if 'pd_type' in disk: label_meta.append(disk['pd_type']) stor.label = ' '.join(label_meta) disk_default = dict( vendor='unknown', product='unknown', device_firmware_level='unknown', pd_type='unknown', coerced_size='unknown', ) disk_default.update(disk) stor.model, c = ComponentModel.create( ComponentType.disk, size=stor.size, speed=stor.speed, family=stor.label, priority=priority, ) stor.save(priority=priority)
def handle_smartctl(dev, disks, priority=0): for disk_handle, disk in disks.iteritems(): if not disk.get('serial_number') or disk.get('device_type') != 'disk': continue if {'user_capacity', 'vendor', 'product', 'transport_protocol'} - \ set(disk.keys()): # not all required keys present continue if disk['vendor'].lower() in DISK_VENDOR_BLACKLIST: continue if disk['product'].lower() in DISK_PRODUCT_BLACKLIST: continue stor, created = Storage.concurrent_get_or_create( device=dev, sn=disk['serial_number']) stor.device = dev size_value, size_unit, rest = disk['user_capacity'].split(' ', 2) size_value = size_value.replace(',', '') stor.size = int(int(size_value) / units.size_divisor[size_unit]) stor.speed = int(disk.get('rotational_speed', 0)) label_meta = [' '.join(disk['vendor'].split()), disk['product']] if 'transport_protocol' in disk: label_meta.append(disk['transport_protocol']) stor.label = ' '.join(label_meta) disk_default = dict( vendor='unknown', product='unknown', revision='unknown', transport_protocol='unknown', user_capacity='unknown', ) disk_default.update(disk) extra = """Model: {vendor} {product} Firmware Revision: {revision} Interface: {transport_protocol} Size: {user_capacity} """.format(**disk_default) stor.model, c = ComponentModel.concurrent_get_or_create( size=stor.size, speed=stor.speed, type=ComponentType.disk.id, family='', extra_hash=hashlib.md5(extra).hexdigest(), extra=extra) stor.model.name = '{} {}MiB'.format(stor.label, stor.size) stor.model.save(priority=priority) stor.save(priority=priority)
def save_storage(storage, dev): mount_points = [] for item in storage: sn = item.get("sn") mount_point = item.get("mountpoint") if not sn or not mount_point: continue label = item.get("label") try: size = int(item.get("size")) except ValueError: continue model_name = "{} {}MiB".format(label, size) model, c = ComponentModel.create(ComponentType.disk, size=size, family=model_name, priority=SAVE_PRIORITY) stor = None try: stor = Storage.objects.get(device=dev, mount_point=mount_point) if stor.sn != sn: try: stor_found_by_sn = Storage.objects.get(sn=sn) if all( ( stor_found_by_sn.model == model, stor_found_by_sn.size == size, stor_found_by_sn.label == label, ) ): stor.mount_point = None stor.save(priotity=SAVE_PRIORITY) stor = stor_found_by_sn stor.device = dev stor.mount_point = mount_point else: stor = None except Storage.DoesNotExist: stor.sn = sn except Storage.DoesNotExist: try: stor = Storage.objects.get(sn=sn) if all((stor.model == model, stor.size == size, stor.label == label)): stor.device = dev stor.mount_point = mount_point else: stor = None except Storage.DoesNotExist: stor = Storage(device=dev, mount_point=mount_point, sn=sn) if stor: stor.model = model stor.label = label stor.size = size stor.save(priority=SAVE_PRIORITY) mount_points.append(mount_point) dev.storage_set.exclude(mount_point__in=mount_points).update(mount_point=None)
def parse_hpacu(facts, dev): disks = {} for k, value in facts.iteritems(): m = HPACU_GENERAL_REGEX.match(k) if not m: continue n = HPACU_LOGICAL_PHYSICAL_REGEX.match(m.group(2)) physical_disk = n.group(1) if n else None property = n.group(2) if n else m.group(2) if not physical_disk: continue disks.setdefault(physical_disk, {})[property] = value.strip() for disk_handle, disk in disks.iteritems(): if not disk.get('serial_number'): continue stor, created = Storage.concurrent_get_or_create(device=dev, sn=disk['serial_number']) stor.device = dev size_value, size_unit = disk['size'].split() stor.size = int(float(size_value) / units.size_divisor[size_unit]) stor.speed = int(disk.get('rotational_speed', 0)) stor.label = '{} {}'.format(' '.join(disk['model'].split()), disk['interface_type']) disk_default = dict( model = 'unknown', firmware_revision = 'unknown', interface_type = 'unknown', size = 'unknown', rotational_speed = 'unknown', status = 'unknown', ) disk_default.update(disk) extra = """Model: {model} Firmware Revision: {firmware_revision} Interface: {interface_type} Size: {size} Rotational Speed: {rotational_speed} Status: {status}""".format(**disk_default) stor.model, c = ComponentModel.concurrent_get_or_create( size=stor.size, speed=stor.speed, type=ComponentType.disk.id, family='', extra_hash=hashlib.md5(extra).hexdigest(), extra=extra) stor.model.name = '{} {}MiB'.format(stor.label, stor.size) stor.model.save(priority=SAVE_PRIORITY) stor.save(priority=SAVE_PRIORITY)
def handle_smartctl(dev, disks, priority=0): for disk_handle, disk in disks.iteritems(): if not disk.get('serial_number') or disk.get('device_type') != 'disk': continue if {'user_capacity', 'vendor', 'product', 'transport_protocol'} - \ set(disk.keys()): # not all required keys present continue if disk['vendor'].lower() in DISK_VENDOR_BLACKLIST: continue if disk['product'].lower() in DISK_PRODUCT_BLACKLIST: continue stor, created = Storage.concurrent_get_or_create( device=dev, sn=disk['serial_number'], mount_point=None, ) stor.device = dev size_value, size_unit, rest = disk['user_capacity'].split(' ', 2) size_value = size_value.replace(',', '') stor.size = int(int(size_value) / units.size_divisor[size_unit]) stor.speed = int(disk.get('rotational_speed', 0)) label_meta = [' '.join(disk['vendor'].split()), disk['product']] if 'transport_protocol' in disk: label_meta.append(disk['transport_protocol']) stor.label = ' '.join(label_meta) disk_default = dict( vendor='unknown', product='unknown', revision='unknown', transport_protocol='unknown', user_capacity='unknown', ) disk_default.update(disk) stor.model, c = ComponentModel.create( ComponentType.disk, size=stor.size, speed=stor.speed, family=stor.label, priority=priority, ) stor.save(priority=priority)
def handle_3ware(dev, disks, priority=0): for disk_handle, disk in disks.iteritems(): if not disk.get("serial"): continue stor, created = Storage.concurrent_get_or_create(device=dev, sn=disk["serial"], mount_point=None) stor.device = dev size_value, size_unit, trash = disk["capacity"].split(None, 2) stor.size = int(float(size_value) / units.size_divisor[size_unit]) stor.label = disk["model"] disk_default = dict( model="unknown", firmware_revision="unknown", interface_type="unknown", size="unknown", rotational_speed="unknown", status="unknown", ) disk_default.update(disk) stor.model, c = ComponentModel.create(ComponentType.disk, size=stor.size, family=stor.label, priority=priority) stor.save(priority=priority)
def test_disks(self): model = ComponentModel( type=ComponentType.disk, name="HP DG0300BALVP SAS 307200MiB, 10000RPM", ) model.save() Storage( sn="abc3", device=self.device, label="ziew", mount_point="/dev/hda", model=model, size=307200, ).save() data = get_device_data(Device.objects.get(sn='123456789')) disks = data['disks'] self.assertEqual(len(disks), 1) self.assertEqual(disks[0]['size'], 307200) self.assertEqual(disks[0]['serial_number'], "abc3") self.assertEqual(disks[0]['mount_point'], "/dev/hda")
def create_device(device, cpu=None, memory=None, storage=None): dev = Device.create( model=device.get('model'), model_name=device.get('model_name'), model_type=device.get('model_type'), sn=device.get('sn'), venture=device.get('venture'), parent=device.get('parent'), price=device.get('price'), deprecation_kind=device.get('deprecation_kind'), purchase_date=device.get('purchase_date'), ) dev.name = device.get('name') dev.save() if cpu: model = create_model(device, cpu, ComponentType.processor) for cpu in duplicate_item(cpu): Processor( device=dev, model=model, label=cpu.get('label'), ).save() if memory: model = create_model(device, memory, ComponentType.memory) for memory in duplicate_item(memory): Memory( device=dev, model=model, speed=memory.get('speed'), size=memory.get('size'), label=memory.get('label'), ).save() if storage: model = create_model(device, storage, ComponentType.disk) for storage in duplicate_item(storage): Storage( device=dev, model=model, label=storage.get('label'), ).save() return dev
def handle_lshw_storage(dev, lshw, is_virtual=False, priority=0): mount_points, storages = get_storage_from_lshw(lshw) dev.storage_set.filter(mount_point__in=mount_points).delete() for storage in storages: sn = storage['sn'] if storage['sn'] else None stor, created = Storage.concurrent_get_or_create( sn=sn, mount_point=storage['mount_point'], device=dev, ) stor.size = storage['size'] stor.speed = storage['speed'] stor.label = storage['label'] stor.model, c = ComponentModel.create( ComponentType.disk, size=stor.size, speed=stor.speed, family=stor.label, priority=priority, ) stor.save(priority=priority)
def _save_storage(dev, data): detected_storage = [] for disk in data: model_name = "{} {}".format(disk['manufacturer'], disk['model']) size = int(int(disk['size']) / 1024 / 1024 / 1024) model, _ = ComponentModel.create( ComponentType.disk, size=size, family=model_name, priority=SAVE_PRIORITY, ) storage, _ = Storage.concurrent_get_or_create( device=dev, sn=disk['sn'], mount_point=None, ) storage.model = model storage.label = model.name storage.size = size storage.save(priority=SAVE_PRIORITY) detected_storage.append(storage.pk) dev.storage_set.exclude(pk__in=detected_storage).delete()
def save_storage(storage, dev): mount_points = [] for s in storage: if not s.get('sn'): continue stor, created = Storage.concurrent_get_or_create(device=dev, sn=s.get('sn')) try: stor.size = int(s.get('size')) except ValueError: pass stor.label = s.get('label') model = '{} {}MiB'.format(stor.label, stor.size) stor.mount_point = s.get('mountpoint') mount_points.append(stor.mount_point) extra = '' stor.model, c = ComponentModel.concurrent_get_or_create(size=stor.size, type=ComponentType.disk.id, speed=0, cores=0, extra=extra, extra_hash=hashlib.md5(extra).hexdigest(), family=model) stor.model.name = model stor.model.save(priority=SAVE_PRIORITY) stor.save(priority=SAVE_PRIORITY) dev.storage_set.exclude(mount_point__in=mount_points).delete()
def handle_hpacu(dev, disks, priority=0): for disk_handle, disk in disks.iteritems(): if not disk.get("serial_number"): continue stor, created = Storage.concurrent_get_or_create(device=dev, sn=disk["serial_number"], mount_point=None) stor.device = dev size_value, size_unit = disk["size"].split() stor.size = int(float(size_value) / units.size_divisor[size_unit]) stor.speed = int(disk.get("rotational_speed", 0)) stor.label = "{} {}".format(" ".join(disk["model"].split()), disk["interface_type"]) disk_default = dict( model="unknown", firmware_revision="unknown", interface_type="unknown", size="unknown", rotational_speed="unknown", status="unknown", ) disk_default.update(disk) stor.model, c = ComponentModel.create( ComponentType.disk, size=stor.size, speed=stor.speed, family=stor.label, priority=priority ) stor.save(priority=priority)
def handle_megaraid(dev, disks, priority=0): for (controller_handle, disk_handle), disk in disks.iteritems(): disk["vendor"], disk["product"], disk["serial_number"] = _handle_inquiry_data( disk.get("inquiry_data", ""), controller_handle, disk_handle ) if not disk.get("serial_number") or disk.get("media_type") not in ("Hard Disk Device", "Solid State Device"): continue if {"coerced_size", "vendor", "product", "pd_type"} - set(disk.keys()): # not all required keys present continue if disk["vendor"].lower() in DISK_VENDOR_BLACKLIST: continue if disk["product"].lower() in DISK_PRODUCT_BLACKLIST: continue stor, created = Storage.concurrent_get_or_create(device=dev, sn=disk["serial_number"], mount_point=None) stor.device = dev size_value, size_unit, rest = disk["coerced_size"].split(" ", 2) size_value = size_value.replace(",", "") stor.size = int(float(size_value) / units.size_divisor[size_unit]) stor.speed = int(disk.get("rotational_speed", 0)) label_meta = [" ".join(disk["vendor"].split()), disk["product"]] if "pd_type" in disk: label_meta.append(disk["pd_type"]) stor.label = " ".join(label_meta) disk_default = dict( vendor="unknown", product="unknown", device_firmware_level="unknown", pd_type="unknown", coerced_size="unknown", ) disk_default.update(disk) stor.model, c = ComponentModel.create( ComponentType.disk, size=stor.size, speed=stor.speed, family=stor.label, priority=priority ) stor.save(priority=priority)
def handle_lshw_storage(dev, lshw, is_virtual=False, priority=0): storages = [] for storage in jpath.get_all('..disk', lshw): if not storage: continue if isinstance(storage, list): storages.extend(storage) else: storages.append(storage) storages.sort(key=get_logical_name) mount_points = set() for stor in storages: if 'logicalname' not in stor: continue ln = stor['logicalname'] if isinstance(ln, list): mount_points.update(ln) else: mount_points.add(ln) dev.storage_set.filter(mount_point__in=mount_points).delete() for storage in storages: if 'size' in storage: size = storage['size'] elif 'capacity' in storage: size = storage['capacity'] else: # empty slot continue sn = unicode(storage.get('serial') or '') or None if not sn or sn.startswith('QM000') or \ storage.get('vendor', '').strip().lower() in DISK_VENDOR_BLACKLIST or \ storage.get('product', '').strip().lower() in DISK_PRODUCT_BLACKLIST: continue if sn: stor, created = Storage.concurrent_get_or_create(sn=sn, device=dev) stor.mount_point = storage.get('logicalname', None) else: stor, created = Storage.concurrent_get_or_create( sn=None, device=dev, mount_point=storage.get('logicalname', None)) stor.size = int(size['value']) stor.size /= units.size_divisor[size['units']] stor.size = int(stor.size) stor.speed = 0 if storage.get('vendor', '').strip(): stor.label = storage['vendor'].strip() + ' ' else: stor.label = '' if storage.get('product', '').strip(): stor.label += storage['product'].strip() elif storage.get('description', '').strip(): stor.label += storage['description'].strip() else: stor.label += 'Generic disk' caps = storage['capabilities'] extra = "\n".join([ ": ".join((unicode(key), unicode(caps[key]) or '')) for key in sorted(caps.keys()) ]) stor.model, c = ComponentModel.concurrent_get_or_create( size=stor.size, speed=stor.speed, type=ComponentType.disk.id, family='', extra_hash=hashlib.md5(extra).hexdigest(), extra=extra) stor.model.name = '{} {}MiB'.format(stor.label, stor.size) stor.model.save(priority=priority) stor.save(priority=priority)
def _add_virtual_machine(ssh, vmid, parent, master, storages, hypervisor_ip): stdin, stdout, stderr = ssh.exec_command("cat /etc/qemu-server/%d.conf" % vmid) lines = stdout.readlines() if not lines: # Proxmox 2 uses a different directory structure stdin, stdout, stderr = ssh.exec_command( "cat /etc/pve/nodes/*/qemu-server/%d.conf" % vmid) lines = stdout.readlines() disks = {} lan_model = None name = 'unknown' for line in lines: line = line.strip() if line.startswith('#') or ':' not in line: continue key, value = line.split(':', 1) if key.startswith('vlan'): lan_model, lan_mac = value.split('=', 1) elif key.startswith('net'): lan_model, lan_mac = value.split('=', 1) if ',' in lan_mac: lan_mac = lan_mac.split(',', 1)[0] elif key == 'name': name = value.strip() elif key == 'sockets': cpu_count = int(value.strip()) elif key.startswith('ide') or key.startswith('virtio'): disks[key] = value.strip() if lan_model is None: DiscoveryWarning(message="No LAN for virtual server %r." % vmid, plugin=__name__, device=parent, ip=hypervisor_ip).save() return None dev = Device.create(model_name='Proxmox qemu kvm', model_type=DeviceType.virtual_server, ethernets=[Eth(label=lan_model, mac=lan_mac, speed=0)], parent=parent, management=master, name=name) wwns = [] for slot, disk in disks.iteritems(): params = {} if ',' in disk: disk, rawparams = disk.split(',', 1) for kv in rawparams.split(','): if not kv.strip(): continue k, v = kv.split('=', 1) params[k] = v.strip() if ':' in disk: vg, lv = disk.split(':', 1) else: vg = '' lv = disk if vg == 'local': size = _get_local_disk_size(ssh, lv, parent, hypervisor_ip) if not size > 0: continue model, created = ComponentModel.create( ComponentType.disk, family='QEMU disk image', priority=SAVE_PRIORITY, ) # The model's size is deliberately 0 because it's a virtual # volume: there would be potentially as many models as volumes. storage, created = Storage.concurrent_get_or_create(device=dev, mount_point=lv) storage.size = size storage.model = model storage.label = slot storage.save() continue if vg in ('', 'local', 'pve-local'): continue vol = '%s:%s' % (vg, lv) try: wwn, size = storages[lv] except KeyError: logger.warning('Volume %r does not exist.' % lv) DiscoveryWarning( message="Volume %r does not exist." % lv, plugin=__name__, device=dev, ip=hypervisor_ip, ).save() continue try: share = DiskShare.objects.get(wwn=wwn) wwns.append(wwn) except DiskShare.DoesNotExist: logger.warning('A share with serial %r does not exist.' % wwn) DiscoveryWarning( message="A share with serial %r does not exist." % wwn, plugin=__name__, device=dev, ip=hypervisor_ip, ).save() continue mount, created = DiskShareMount.concurrent_get_or_create(share=share, device=dev) mount.is_virtual = True mount.server = parent mount.size = size mount.volume = vol mount.save() for ds in dev.disksharemount_set.filter(server=parent).exclude( share__wwn__in=wwns): ds.delete() for ds in dev.disksharemount_set.filter(is_virtual=True).exclude( share__wwn__in=wwns): ds.delete() cpu_model, cpu_model_created = ComponentModel.create( ComponentType.processor, family='QEMU Virtual', name='QEMU Virtual CPU version 0.12.4', # FIXME: why so specific? priority=SAVE_PRIORITY, ) for i in range(cpu_count): cpu, cpu_created = Processor.concurrent_get_or_create(device=dev, index=i + 1) if cpu_created: cpu.label = 'CPU {}'.format(i + 1) cpu.model = cpu_model cpu.family = 'QEMU Virtual' cpu.save() dev.save(update_last_seen=True, priority=SAVE_PRIORITY) return dev
def run_ssh_xen(ipaddr, parent): ssh = _connect_ssh(ipaddr.address) try: vms = get_running_vms(ssh) macs = get_macs(ssh) disks = get_disks(ssh) shares = hardware.get_disk_shares(ssh) finally: ssh.close() for dev in parent.child_set.exclude(sn__in=[ vm_uuid for (vm_name, vm_uuid, vm_cores, vm_memory) in vms ]): dev.deleted = True dev.save() for vm_name, vm_uuid, vm_cores, vm_memory in vms: ethernets = [ Eth('vif %d' % i, mac, 0) for i, mac in enumerate(macs.get(vm_name, [])) ] dev = Device.create(ethernets=ethernets, parent=parent, sn=vm_uuid, model_type=DeviceType.virtual_server, model_name='XEN Virtual Server', priority=SAVE_PRIORITY) dev.name = vm_name dev.save(priority=SAVE_PRIORITY) cpu_model, cpu_model_created = ComponentModel.concurrent_get_or_create( speed=0, type=ComponentType.processor.id, family='XEN Virtual', cores=0) if cpu_model_created: cpu_model.name = 'XEN Virtual CPU' cpu_model.save() for i in xrange(vm_cores): cpu, created = Processor.concurrent_get_or_create(device=dev, index=i + 1) if created: cpu.label = 'CPU %d' % i cpu.model = cpu_model cpu.family = 'XEN Virtual' cpu.save() for cpu in dev.processor_set.filter(index__gt=vm_cores + 1): cpu.delete() mem_model, mem_model_created = ComponentModel.concurrent_get_or_create( speed=0, type=ComponentType.memory.id, family='XEN Virtual', cores=0, size=0) if mem_model_created: mem_model.name = 'XEN Virtual Memory' mem_model.save() memory, created = Memory.concurrent_get_or_create(device=dev, index=1) memory.size = vm_memory memory.model = mem_model memory.label = 'XEN Memory' memory.save() for mem in dev.memory_set.filter(index__gt=1): mem.delete() disk_model, created = ComponentModel.concurrent_get_or_create( type=ComponentType.disk.id, family='XEN virtual disk') if created: disk_model.name = 'XEN virtual disk' disk_model.save() vm_disks = disks.get(vm_name, []) wwns = [] for uuid, sr_uuid, size, device in vm_disks: wwn, mount_size = shares.get('VHD-%s' % sr_uuid, (None, None)) if wwn: try: share = DiskShare.objects.get(wwn=wwn) wwns.append(wwn) except DiskShare.DoesNotExist: logger.warning('A share with serial %r does not exist.' % wwn) DiscoveryWarning( message="A share with serial %r does not exist." % wwn, plugin=__name__, device=dev, ip=ipaddr, ).save() continue mount, created = DiskShareMount.concurrent_get_or_create( share=share, device=dev) mount.is_virtual = True mount.server = parent mount.size = mount_size mount.volume = device mount.save() else: storage, created = Storage.concurrent_get_or_create( device=dev, mount_point=device, sn=uuid) storage.size = size storage.model = disk_model storage.label = device storage.save() for disk in dev.storage_set.exclude( sn__in={uuid for uuid, x, y, z in vm_disks}): disk.delete() for ds in dev.disksharemount_set.filter(server=parent).exclude( share__wwn__in=wwns): ds.delete() for ds in dev.disksharemount_set.filter(is_virtual=True).exclude( share__wwn__in=wwns): ds.delete() return ', '.join(vm_name for (vm_name, vm_uuid, vm_cores, vm_memory) in vms)
def _add_virtual_machine(ssh, vmid, parent, master, storages): stdin, stdout, stderr = ssh.exec_command("cat /etc/qemu-server/%d.conf" % vmid) lines = stdout.readlines() if not lines: # Proxmox 2 uses a different directory structure stdin, stdout, stderr = ssh.exec_command( "cat /etc/pve/nodes/*/qemu-server/%d.conf" % vmid) lines = stdout.readlines() disks = {} lan_model = None name = 'unknown' for line in lines: line = line.strip() key, value = line.split(':', 1) if key.startswith('vlan'): lan_model, lan_mac = value.split('=', 1) elif key.startswith('net'): lan_model, lan_mac = value.split('=', 1) if ',' in lan_mac: lan_mac = lan_mac.split(',', 1)[0] elif key == 'name': name = value.strip() elif key == 'sockets': cpu_count = int(value.strip()) elif key.startswith('ide') or key.startswith('virtio'): disks[key] = value.strip() if lan_model is None: return None dev = Device.create(model_name='Proxmox qemu kvm', model_type=DeviceType.virtual_server, ethernets=[Eth(label=lan_model, mac=lan_mac, speed=0)], parent=parent, management=master, name=name) wwns = [] for slot, disk in disks.iteritems(): params = {} if ',' in disk: disk, rawparams = disk.split(',', 1) for kv in rawparams.split(','): if not kv.strip(): continue k, v = kv.split('=', 1) params[k] = v.strip() if ':' in disk: vg, lv = disk.split(':', 1) else: vg = '' lv = disk if vg == 'local': model, created = ComponentModel.concurrent_get_or_create( type=ComponentType.disk.id, family='QEMU disk image') if created: model.save() storage, created = Storage.concurrent_get_or_create(device=dev, mount_point=lv) storage.size = _get_local_disk_size(ssh, lv) storage.model = model storage.label = slot storage.save() continue if vg in ('', 'local', 'pve-local'): continue vol = '%s:%s' % (vg, lv) try: wwn, size = storages[lv] except KeyError: logger.warning('Volume %r does not exist.' % lv) continue try: share = DiskShare.objects.get(wwn=wwn) wwns.append(wwn) except DiskShare.DoesNotExist: logger.warning('A share with WWN %r does not exist.' % wwn) continue mount, created = DiskShareMount.concurrent_get_or_create(share=share, device=dev) mount.is_virtual = True mount.server = parent mount.size = size mount.volume = vol mount.save() for ds in dev.disksharemount_set.filter(server=parent).exclude( share__wwn__in=wwns): ds.delete() for ds in dev.disksharemount_set.filter(is_virtual=True).exclude( share__wwn__in=wwns): ds.delete() cpu_model, cpu_model_created = ComponentModel.concurrent_get_or_create( speed=0, type=ComponentType.processor.id, family='QEMU Virtual', cores=0) if cpu_model_created: cpu_model.name = 'QEMU Virtual CPU version 0.12.4' cpu_model.save() for i in range(cpu_count): cpu, cpu_created = Processor.concurrent_get_or_create(device=dev, index=i + 1) if cpu_created: cpu.label = 'CPU {}'.format(i + 1) cpu.model = cpu_model cpu.family = 'QEMU Virtual' cpu.save() dev.save(update_last_seen=True) return dev
def _add_virtual_machine(ssh, vmid, parent, master, storage): stdin, stdout, stderr = ssh.exec_command("cat /etc/qemu-server/%d.conf" % vmid) disks = {} lan_model = None name = "unknown" for line in stdout: line = line.strip() key, value = line.split(":", 1) if key.startswith("vlan"): lan_model, lan_mac = value.split("=", 1) elif key == "name": name = value.strip() elif key == "sockets": cpu_count = int(value.strip()) elif key.startswith("ide") or key.startswith("virtio"): disks[key] = value.strip() if lan_model is None: return None dev = Device.create( model_name="Proxmox qemu kvm", model_type=DeviceType.virtual_server, ethernets=[Eth(label=lan_model, mac=lan_mac, speed=0)], parent=parent, management=master, name=name, ) wwns = [] for slot, disk in disks.iteritems(): params = {} if "," in disk: disk, rawparams = disk.split(",", 1) for kv in rawparams.split(","): if not kv.strip(): continue k, v = kv.split("=", 1) params[k] = v.strip() if ":" in disk: vg, lv = disk.split(":", 1) else: vg = "" lv = disk if vg == "local": model, created = ComponentModel.concurrent_get_or_create( type=ComponentType.disk.id, family="QEMU disk image" ) if created: model.save() storage, created = Storage.concurrent_get_or_create(device=dev, mount_point=lv) storage.size = _get_local_disk_size(ssh, lv) storage.model = model storage.label = slot storage.save() continue if vg in ("", "local", "pve-local"): continue vol = "%s:%s" % (vg, lv) try: wwn, size = storage[lv] except KeyError: logger.warning("Volume %r does not exist." % lv) continue try: share = DiskShare.objects.get(wwn=wwn) wwns.append(wwn) except DiskShare.DoesNotExist: logger.warning("A share with WWN %r does not exist." % wwn) continue mount, created = DiskShareMount.concurrent_get_or_create(share=share, device=dev) mount.is_virtual = True mount.server = parent mount.size = size mount.volume = vol mount.save() for ds in dev.disksharemount_set.filter(server=parent).exclude(share__wwn__in=wwns): ds.delete() for ds in dev.disksharemount_set.filter(is_virtual=True).exclude(share__wwn__in=wwns): ds.delete() cpu_model, cpu_model_created = ComponentModel.concurrent_get_or_create( speed=0, type=ComponentType.processor.id, family="QEMU Virtual", cores=0 ) if cpu_model_created: cpu_model.name = "QEMU Virtual CPU version 0.12.4" cpu_model.save() for i in range(cpu_count): cpu, cpu_created = Processor.concurrent_get_or_create(device=dev, index=i + 1) if cpu_created: cpu.label = "CPU {}".format(i + 1) cpu.model = cpu_model cpu.family = "QEMU Virtual" cpu.save() dev.save(update_last_seen=True) return dev
def run_ssh_xen(ipaddr, parent): ssh = _connect_ssh(ipaddr.address) try: vms = get_running_vms(ssh) macs = get_macs(ssh) disks = get_disks(ssh) shares = hardware.get_disk_shares(ssh) finally: ssh.close() for dev in parent.child_set.exclude( sn__in=[vm_uuid for (vm_name, vm_uuid, vm_cores, vm_memory) in vms] ): dev.deleted = True dev.save() for vm_name, vm_uuid, vm_cores, vm_memory in vms: ethernets = [Eth('vif %d' % i, mac, 0) for i, mac in enumerate(macs.get(vm_name, []))] dev = Device.create(ethernets=ethernets, parent=parent, sn=vm_uuid, model_type=DeviceType.virtual_server, model_name='XEN Virtual Server', priority=SAVE_PRIORITY) dev.name = vm_name dev.save(priority=SAVE_PRIORITY) cpu_model, cpu_model_created = ComponentModel.concurrent_get_or_create( speed=0, type=ComponentType.processor.id, family='XEN Virtual', cores=0) if cpu_model_created: cpu_model.name = 'XEN Virtual CPU' cpu_model.save() for i in xrange(vm_cores): cpu, created = Processor.concurrent_get_or_create(device=dev, index=i + 1) if created: cpu.label = 'CPU %d' % i cpu.model = cpu_model cpu.family = 'XEN Virtual' cpu.save() for cpu in dev.processor_set.filter(index__gt=vm_cores+1): cpu.delete() mem_model, mem_model_created = ComponentModel.concurrent_get_or_create( speed=0, type=ComponentType.memory.id, family='XEN Virtual', cores=0, size=0) if mem_model_created: mem_model.name = 'XEN Virtual Memory' mem_model.save() memory, created = Memory.concurrent_get_or_create(device=dev, index=1) memory.size = vm_memory memory.model = mem_model memory.label = 'XEN Memory' memory.save() for mem in dev.memory_set.filter(index__gt=1): mem.delete() disk_model, created = ComponentModel.concurrent_get_or_create( type=ComponentType.disk.id, family='XEN virtual disk') if created: disk_model.name = 'XEN virtual disk' disk_model.save() vm_disks = disks.get(vm_name, []) wwns = [] for uuid, sr_uuid, size, device in vm_disks: wwn, mount_size = shares.get('VHD-%s' % sr_uuid, (None, None)) if wwn: try: share = DiskShare.objects.get(wwn=wwn) wwns.append(wwn) except DiskShare.DoesNotExist: logger.warning('A share with serial %r does not exist.' % wwn) DiscoveryWarning( message="A share with serial %r does not exist." % wwn, plugin=__name__, device=dev, ip=ipaddr, ).save() continue mount, created = DiskShareMount.concurrent_get_or_create( share=share, device=dev) mount.is_virtual = True mount.server = parent mount.size = mount_size mount.volume = device mount.save() else: storage, created = Storage.concurrent_get_or_create( device=dev, mount_point=device, sn=uuid) storage.size = size storage.model = disk_model storage.label = device storage.save() for disk in dev.storage_set.exclude(sn__in={ uuid for uuid, x , y , z in vm_disks }): disk.delete() for ds in dev.disksharemount_set.filter( server=parent).exclude(share__wwn__in=wwns): ds.delete() for ds in dev.disksharemount_set.filter( is_virtual=True).exclude(share__wwn__in=wwns): ds.delete() return ', '.join(vm_name for (vm_name, vm_uuid, vm_cores, vm_memory) in vms)
def _add_virtual_machine(ssh, vmid, parent, master, storages, hypervisor_ip): stdin, stdout, stderr = ssh.exec_command( "cat /etc/qemu-server/%d.conf" % vmid) lines = stdout.readlines() if not lines: # Proxmox 2 uses a different directory structure stdin, stdout, stderr = ssh.exec_command( "cat /etc/pve/nodes/*/qemu-server/%d.conf" % vmid) lines = stdout.readlines() disks = {} lan_model = None name = 'unknown' for line in lines: line = line.strip() if line.startswith('#') or ':' not in line: continue key, value = line.split(':', 1) if key.startswith('vlan'): lan_model, lan_mac = value.split('=', 1) elif key.startswith('net'): lan_model, lan_mac = value.split('=', 1) if ',' in lan_mac: lan_mac = lan_mac.split(',', 1)[0] elif key == 'name': name = value.strip() elif key == 'sockets': cpu_count = int(value.strip()) elif key.startswith('ide') or key.startswith('virtio'): disks[key] = value.strip() if lan_model is None: DiscoveryWarning( message="No LAN for virtual server %r." % vmid, plugin=__name__, device=parent, ip=hypervisor_ip ).save() return None dev = Device.create( model_name='Proxmox qemu kvm', model_type=DeviceType.virtual_server, ethernets=[Eth(label=lan_model, mac=lan_mac, speed=0)], parent=parent, management=master, name=name ) wwns = [] for slot, disk in disks.iteritems(): params = {} if ',' in disk: disk, rawparams = disk.split(',', 1) for kv in rawparams.split(','): if not kv.strip(): continue k, v = kv.split('=', 1) params[k] = v.strip() if ':' in disk: vg, lv = disk.split(':', 1) else: vg = '' lv = disk if vg == 'local': size = _get_local_disk_size(ssh, lv, parent, hypervisor_ip) if not size > 0: continue model, created = ComponentModel.create( ComponentType.disk, family='QEMU disk image', priority=SAVE_PRIORITY, ) # The model's size is deliberately 0 because it's a virtual # volume: there would be potentially as many models as volumes. storage, created = Storage.concurrent_get_or_create( device=dev, mount_point=lv) storage.size = size storage.model = model storage.label = slot storage.save() continue if vg in ('', 'local', 'pve-local'): continue vol = '%s:%s' % (vg, lv) try: wwn, size = storages[lv] except KeyError: logger.warning('Volume %r does not exist.' % lv) DiscoveryWarning( message="Volume %r does not exist." % lv, plugin=__name__, device=dev, ip=hypervisor_ip, ).save() continue try: share = DiskShare.objects.get(wwn=wwn) wwns.append(wwn) except DiskShare.DoesNotExist: logger.warning('A share with serial %r does not exist.' % wwn) DiscoveryWarning( message="A share with serial %r does not exist." % wwn, plugin=__name__, device=dev, ip=hypervisor_ip, ).save() continue mount, created = DiskShareMount.concurrent_get_or_create( share=share, device=dev) mount.is_virtual = True mount.server = parent mount.size = size mount.volume = vol mount.save() for ds in dev.disksharemount_set.filter( server=parent).exclude(share__wwn__in=wwns): ds.delete() for ds in dev.disksharemount_set.filter( is_virtual=True).exclude(share__wwn__in=wwns): ds.delete() cpu_model, cpu_model_created = ComponentModel.create( ComponentType.processor, family='QEMU Virtual', name='QEMU Virtual CPU version 0.12.4', # FIXME: why so specific? priority=SAVE_PRIORITY, ) for i in range(cpu_count): cpu, cpu_created = Processor.concurrent_get_or_create(device=dev, index=i + 1) if cpu_created: cpu.label = 'CPU {}'.format(i + 1) cpu.model = cpu_model cpu.family = 'QEMU Virtual' cpu.save() dev.save(update_last_seen=True, priority=SAVE_PRIORITY) return dev
def handle_lshw_storage(dev, lshw, is_virtual=False, priority=0): storages = [] for storage in jpath.get_all("..disk", lshw): if not storage: continue if isinstance(storage, list): storages.extend(storage) else: storages.append(storage) storages.sort(key=get_logical_name) mount_points = set() for stor in storages: if "logicalname" not in stor: continue ln = stor["logicalname"] if isinstance(ln, list): mount_points.update(ln) else: mount_points.add(ln) dev.storage_set.filter(mount_point__in=mount_points).delete() for storage in storages: if "size" in storage: size = storage["size"] elif "capacity" in storage: size = storage["capacity"] else: # empty slot continue sn = unicode(storage.get("serial") or "") or None if ( not sn or sn.startswith("QM000") or storage.get("vendor", "").strip().lower() in DISK_VENDOR_BLACKLIST or storage.get("product", "").strip().lower() in DISK_PRODUCT_BLACKLIST ): continue if sn: stor, created = Storage.concurrent_get_or_create(sn=sn, device=dev) stor.mount_point = storage.get("logicalname", None) else: stor, created = Storage.concurrent_get_or_create( sn=None, device=dev, mount_point=storage.get("logicalname", None) ) stor.size = int(size["value"]) stor.size /= units.size_divisor[size["units"]] stor.size = int(stor.size) stor.speed = 0 if storage.get("vendor", "").strip(): stor.label = storage["vendor"].strip() + " " else: stor.label = "" if storage.get("product", "").strip(): stor.label += storage["product"].strip() elif storage.get("description", "").strip(): stor.label += storage["description"].strip() else: stor.label += "Generic disk" caps = storage["capabilities"] extra = "\n".join([": ".join((unicode(key), unicode(caps[key]) or "")) for key in sorted(caps.keys())]) stor.model, c = ComponentModel.concurrent_get_or_create( size=stor.size, speed=stor.speed, type=ComponentType.disk.id, family="", extra_hash=hashlib.md5(extra).hexdigest(), extra=extra, ) stor.model.name = "{} {}MiB".format(stor.label, stor.size) stor.model.save(priority=priority) stor.save(priority=priority)
def _add_virtual_machine(ssh, vmid, parent, master, storages): stdin, stdout, stderr = ssh.exec_command( "cat /etc/qemu-server/%d.conf" % vmid) lines = stdout.readlines() if not lines: # Proxmox 2 uses a different directory structure stdin, stdout, stderr = ssh.exec_command( "cat /etc/pve/nodes/*/qemu-server/%d.conf" % vmid) lines = stdout.readlines() disks = {} lan_model = None name = 'unknown' for line in lines: line = line.strip() key, value = line.split(':', 1) if key.startswith('vlan'): lan_model, lan_mac = value.split('=', 1) elif key.startswith('net'): lan_model, lan_mac = value.split('=', 1) if ',' in lan_mac: lan_mac = lan_mac.split(',', 1)[0] elif key == 'name': name = value.strip() elif key == 'sockets': cpu_count = int(value.strip()) elif key.startswith('ide') or key.startswith('virtio'): disks[key] = value.strip() if lan_model is None: return None dev = Device.create( model_name='Proxmox qemu kvm', model_type=DeviceType.virtual_server, ethernets=[Eth(label=lan_model, mac=lan_mac, speed=0)], parent=parent, management=master, name=name ) wwns = [] for slot, disk in disks.iteritems(): params = {} if ',' in disk: disk, rawparams = disk.split(',', 1) for kv in rawparams.split(','): if not kv.strip(): continue k, v = kv.split('=', 1) params[k] = v.strip() if ':' in disk: vg, lv = disk.split(':', 1) else: vg = '' lv = disk if vg == 'local': model, created = ComponentModel.concurrent_get_or_create( type=ComponentType.disk.id, family='QEMU disk image') if created: model.save() storage, created = Storage.concurrent_get_or_create( device=dev, mount_point=lv) storage.size = _get_local_disk_size(ssh, lv) storage.model = model storage.label = slot storage.save() continue if vg in ('', 'local', 'pve-local'): continue vol = '%s:%s' % (vg, lv) try: wwn, size = storages[lv] except KeyError: logger.warning('Volume %r does not exist.' % lv) continue try: share = DiskShare.objects.get(wwn=wwn) wwns.append(wwn) except DiskShare.DoesNotExist: logger.warning('A share with WWN %r does not exist.' % wwn) continue mount, created = DiskShareMount.concurrent_get_or_create( share=share, device=dev) mount.is_virtual = True mount.server = parent mount.size = size mount.volume = vol mount.save() for ds in dev.disksharemount_set.filter( server=parent).exclude(share__wwn__in=wwns): ds.delete() for ds in dev.disksharemount_set.filter( is_virtual=True).exclude(share__wwn__in=wwns): ds.delete() cpu_model, cpu_model_created = ComponentModel.concurrent_get_or_create( speed=0, type=ComponentType.processor.id, family='QEMU Virtual', cores=0) if cpu_model_created: cpu_model.name = 'QEMU Virtual CPU version 0.12.4' cpu_model.save() for i in range(cpu_count): cpu, cpu_created = Processor.concurrent_get_or_create(device=dev, index=i+1) if cpu_created: cpu.label = 'CPU {}'.format(i + 1) cpu.model = cpu_model cpu.family = 'QEMU Virtual' cpu.save() dev.save(update_last_seen=True) return dev
def run_ssh_aix(ip): ssh = _connect_ssh(ip) try: ethernets = [] for model_line in _ssh_lines(ssh, 'lsattr -El sys0 | grep ^modelname'): machine_model = model_line.split(None, 2)[1] break for mac_line in _ssh_lines(ssh, 'netstat -ia | grep link'): interface, mtu, net, mac, rest = mac_line.split(None, 4) if '.' not in mac: continue octets = mac.split('.') mac = ''.join('%02x' % int(o, 16) for o in octets).upper() ethernets.append(Eth(label=interface, mac=mac, speed=0)) disks = {} os_storage_size = 0 for disk_line in _ssh_lines(ssh, 'lsdev -c disk'): disk, rest = disk_line.split(None, 1) wwn = None model = None for line in _ssh_lines(ssh, 'lscfg -vl %s' % disk): if 'hdisk' in line: match = re.search(r'\(([0-9]+) MB\)', line) if match: os_storage_size += int(match.group(1)) elif 'Serial Number...' in line: label, sn = line.split('.', 1) sn = sn.strip('. \n') elif 'Machine Type and Model.' in line: label, model = line.split('.', 1) model = model.strip('. \n') disks[disk] = (model, sn) os_version = '' for line in _ssh_lines(ssh, 'oslevel'): os_version = line.strip() break os_memory = 0 for line in _ssh_lines(ssh, 'lsattr -El sys0 | grep ^realmem'): match = re.search(r'[0-9]+', line) if match: os_memory = int(int(match.group(0)) / 1024) break os_corescount = 0 for line in _ssh_lines(ssh, 'lparstat -i|grep ^Active\ Phys'): match = re.search(r'[0-9]+', line) if match: os_corescount += int(match.group(0)) finally: ssh.close() dev = Device.create(ethernets=ethernets, model_type=DeviceType.rack_server, model_name='%s AIX' % MODELS.get(machine_model, machine_model)) ipaddr = IPAddress.objects.get(address=ip) ipaddr.device = dev ipaddr.save() wwns = [] sns = [] stors = [] for disk, (model_name, sn) in disks.iteritems(): if not sn: continue if model_name == 'VV': wwns.append(sn) else: stors.append((disk, model_name, sn)) sns.append(sn) for mount in dev.disksharemount_set.exclude(share__wwn__in=wwns): mount.delete() for stor in dev.storage_set.exclude(sn__in=sns): stor.delete() for wwn in wwns: try: share = DiskShare.objects.get(wwn=wwn) except DiskShare.DoesNotExist: continue wwn = normalize_wwn(sn[-4:] + sn[:-4]) mount, created = DiskShareMount.concurrent_get_or_create( share=share, device=dev, is_virtual=False) mount.volume = disk mount.save() for disk, model_name, sn in stors: model, mcreated = ComponentModel.concurrent_get_or_create( type=ComponentType.disk.id, family=model_name, extra_hash='') model.name = model_name model.save() stor, created = Storage.concurrent_get_or_create(device=dev, sn=sn) stor.model = model stor.label = disk stor.save() mem, created = Memory.concurrent_get_or_create(device=dev, index=0) mem.label = 'Memory' mem.model, c = ComponentModel.concurrent_get_or_create( size=0, speed=0, type=ComponentType.memory.id, family='pSeries', extra_hash='') mem.model.name = 'pSeries Memory' mem.model.save() mem.save() cpu, created = Processor.concurrent_get_or_create(device=dev, index=0) cpu.label = 'CPU' cpu.model, c = ComponentModel.concurrent_get_or_create( speed=0, cores=0, type=ComponentType.processor.id, extra_hash='', family='pSeries CPU') cpu.model.name = 'pSeries CPU' cpu.model.save() cpu.save() os = OperatingSystem.create(dev=dev, os_name='AIX', version=os_version, family='AIX') os.memory = os_memory if os_memory else None os.cores_count = os_corescount if os_corescount else None os.storage = os_storage_size if os_storage_size else None os.save() return machine_model
def run_ssh_aix(ip): ssh = _connect_ssh(ip) try: ethernets = [] for model_line in _ssh_lines(ssh, "lsattr -El sys0 | grep ^modelname"): machine_model = model_line.split(None, 2)[1] break for mac_line in _ssh_lines(ssh, "netstat -ia | grep link"): interface, mtu, net, mac, rest = mac_line.split(None, 4) if "." not in mac: continue octets = mac.split(".") mac = "".join("%02x" % int(o, 16) for o in octets).upper() ethernets.append(Eth(label=interface, mac=mac, speed=0)) disks = {} for disk_line in _ssh_lines(ssh, "lsdev -c disk"): disk, rest = disk_line.split(None, 1) wwn = None model = None for line in _ssh_lines(ssh, "lscfg -vl %s" % disk): if "Serial Number..." in line: label, sn = line.split(".", 1) sn = sn.strip(". \n") elif "Machine Type and Model." in line: label, model = line.split(".", 1) model = model.strip(". \n") disks[disk] = (model, sn) finally: ssh.close() dev = Device.create( ethernets=ethernets, model_type=DeviceType.rack_server, model_name="%s AIX" % MODELS.get(machine_model, machine_model), ) ipaddr = IPAddress.objects.get(address=ip) ipaddr.device = dev ipaddr.save() wwns = [] sns = [] stors = [] for disk, (model_name, sn) in disks.iteritems(): if not sn: continue if model_name == "VV": wwns.append(sn) else: stors.append((disk, model_name, sn)) sns.append(sn) for mount in dev.disksharemount_set.exclude(share__wwn__in=wwns): mount.delete() for stor in dev.storage_set.exclude(sn__in=sns): stor.delete() for wwn in wwns: try: share = DiskShare.objects.get(wwn=wwn) except DiskShare.DoesNotExist: continue wwn = network.normalize_wwn(sn[-4:] + sn[:-4]) mount, created = DiskShareMount.concurrent_get_or_create(share=share, device=dev, is_virtual=False) mount.volume = disk mount.save() for disk, model_name, sn in stors: model, mcreated = ComponentModel.concurrent_get_or_create( type=ComponentType.disk.id, family=model_name, extra_hash="" ) model.name = model_name model.save() stor, created = Storage.concurrent_get_or_create(device=dev, sn=sn) stor.model = model stor.label = disk stor.save() mem, created = Memory.concurrent_get_or_create(device=dev, index=0) mem.label = "Memory" mem.model, c = ComponentModel.concurrent_get_or_create( size=0, speed=0, type=ComponentType.memory.id, family="pSeries", extra_hash="" ) mem.model.name = "pSeries Memory" mem.model.save() mem.save() cpu, created = Processor.concurrent_get_or_create(device=dev, index=0) cpu.label = "CPU" cpu.model, c = ComponentModel.concurrent_get_or_create( speed=0, cores=0, type=ComponentType.processor.id, extra_hash="", family="pSeries CPU" ) cpu.model.name = "pSeries CPU" cpu.model.save() cpu.save() return machine_model
def _prepare_storage_special_cases(self): self.special_dev = Device.create(sn='sn_123_321_123_321', model_name='SomeDeviceModelName', model_type=DeviceType.unknown) self.temp_dev = Device.create(sn='sn_999_888_777', model_name='SomeDeviceModelName', model_type=DeviceType.unknown) model_name = 'TestStorage 40960MiB' model, _ = ComponentModel.create( type=ComponentType.disk, priority=0, size=40960, family=model_name, ) storage, _ = Storage.concurrent_get_or_create( device=self.special_dev, mount_point='C:', defaults={ 'label': 'TestStorage', 'model': model, 'size': 40960, }, ) storage, _ = Storage.concurrent_get_or_create( device=self.special_dev, mount_point='D:', defaults={ 'label': 'TestStorage', 'model': model, 'size': 40960, 'sn': 'stor_sn_123_321_2', }, ) storage, _ = Storage.concurrent_get_or_create( device=self.special_dev, mount_point='E:', defaults={ 'label': 'TestStorage', 'model': model, 'size': 40960, 'sn': 'stor_sn_123_321_3', }, ) storage, _ = Storage.concurrent_get_or_create( device=self.temp_dev, mount_point='G:', defaults={ 'label': 'TestStorage', 'model': model, 'size': 40960, 'sn': 'stor_sn_123_321_5', }, ) storage, _ = Storage.concurrent_get_or_create( device=self.special_dev, mount_point='H:', defaults={ 'label': 'TestStorage', 'model': model, 'size': 40960, 'sn': 'stor_sn_123_321_6', }, ) storage, _ = Storage.concurrent_get_or_create( device=self.special_dev, mount_point='X:', defaults={ 'label': 'TestStorage', 'model': model, 'size': 40960, 'sn': 'stor_sn_123_321_7', }, ) # FIXME: this assigns a 40GB model to a 80GB device. How to handles # cases like this? storage, _ = Storage.concurrent_get_or_create( device=self.special_dev, mount_point='I:', defaults={ 'label': 'TestStorage', 'model': model, 'size': 81920, 'sn': 'stor_sn_123_321_8', }, ) storage, _ = Storage.concurrent_get_or_create( device=self.special_dev, mount_point='Y:', defaults={ 'label': 'TestStorage', 'model': model, 'size': 40960, 'sn': 'stor_sn_123_321_9', }, ) storage, _ = Storage.concurrent_get_or_create( sn='stor_sn_123_321_10', defaults={ 'device': self.special_dev, 'label': 'TestStorage', 'model': model, 'size': 81920, }, ) save_storage([{ 'sn': 'stor_sn_123_321_1', 'mountpoint': 'C:', 'label': 'TestStorage', 'size': 40960, }, { 'sn': 'stor_sn_123_321_2', 'mountpoint': 'D:', 'label': 'TestStorage', 'size': 40960, }, { 'sn': 'stor_sn_123_321_4', 'mountpoint': 'F:', 'label': 'TestStorage', 'size': 40960 }, { 'sn': 'stor_sn_123_321_5', 'mountpoint': 'G:', 'label': 'TestStorage', 'size': 40960 }, { 'sn': 'stor_sn_123_321_7', 'mountpoint': 'H:', 'label': 'TestStorage', 'size': 40960 }, { 'sn': 'stor_sn_123_321_9', 'mountpoint': 'I:', 'label': 'TestStorage', 'size': 81920 }, { 'sn': 'stor_sn_123_321_10', 'mountpoint': 'J:', 'label': 'TestStorage', 'size': 40960 }], self.special_dev)
def _prepare_storage_special_cases(self): self.special_dev = Device.create( sn='sn_123_321_123_321', model_name='SomeDeviceModelName', model_type=DeviceType.unknown ) self.temp_dev = Device.create( sn='sn_999_888_777', model_name='SomeDeviceModelName', model_type=DeviceType.unknown ) model_name = 'TestStorage 40960MiB' model, _ = ComponentModel.create( type=ComponentType.disk, priority=0, size=40960, family=model_name, ) storage, _ = Storage.concurrent_get_or_create( device=self.special_dev, mount_point='C:', defaults={ 'label': 'TestStorage', 'model': model, 'size': 40960, }, ) storage, _ = Storage.concurrent_get_or_create( device=self.special_dev, mount_point='D:', defaults={ 'label': 'TestStorage', 'model': model, 'size': 40960, 'sn': 'stor_sn_123_321_2', }, ) storage, _ = Storage.concurrent_get_or_create( device=self.special_dev, mount_point='E:', defaults={ 'label': 'TestStorage', 'model': model, 'size': 40960, 'sn': 'stor_sn_123_321_3', }, ) storage, _ = Storage.concurrent_get_or_create( device=self.temp_dev, mount_point='G:', defaults={ 'label': 'TestStorage', 'model': model, 'size': 40960, 'sn': 'stor_sn_123_321_5', }, ) storage, _ = Storage.concurrent_get_or_create( device=self.special_dev, mount_point='H:', defaults={ 'label': 'TestStorage', 'model': model, 'size': 40960, 'sn': 'stor_sn_123_321_6', }, ) storage, _ = Storage.concurrent_get_or_create( device=self.special_dev, mount_point='X:', defaults={ 'label': 'TestStorage', 'model': model, 'size': 40960, 'sn': 'stor_sn_123_321_7', }, ) # FIXME: this assigns a 40GB model to a 80GB device. How to handles # cases like this? storage, _ = Storage.concurrent_get_or_create( device=self.special_dev, mount_point='I:', defaults={ 'label': 'TestStorage', 'model': model, 'size': 81920, 'sn': 'stor_sn_123_321_8', }, ) storage, _ = Storage.concurrent_get_or_create( device=self.special_dev, mount_point='Y:', defaults={ 'label': 'TestStorage', 'model': model, 'size': 40960, 'sn': 'stor_sn_123_321_9', }, ) storage, _ = Storage.concurrent_get_or_create( sn='stor_sn_123_321_10', defaults={ 'device': self.special_dev, 'label': 'TestStorage', 'model': model, 'size': 81920, }, ) save_storage( [ { 'sn': 'stor_sn_123_321_1', 'mountpoint': 'C:', 'label': 'TestStorage', 'size': 40960, }, { 'sn': 'stor_sn_123_321_2', 'mountpoint': 'D:', 'label': 'TestStorage', 'size': 40960, }, { 'sn': 'stor_sn_123_321_4', 'mountpoint': 'F:', 'label': 'TestStorage', 'size': 40960 }, { 'sn': 'stor_sn_123_321_5', 'mountpoint': 'G:', 'label': 'TestStorage', 'size': 40960 }, { 'sn': 'stor_sn_123_321_7', 'mountpoint': 'H:', 'label': 'TestStorage', 'size': 40960 }, { 'sn': 'stor_sn_123_321_9', 'mountpoint': 'I:', 'label': 'TestStorage', 'size': 81920 }, { 'sn': 'stor_sn_123_321_10', 'mountpoint': 'J:', 'label': 'TestStorage', 'size': 40960 } ], self.special_dev )
def run_ssh_aix(ip): ssh = _connect_ssh(ip) try: ethernets = [] for model_line in _ssh_lines(ssh, 'lsattr -El sys0 | grep ^modelname'): machine_model = model_line.split(None, 2)[1] break for mac_line in _ssh_lines(ssh, 'netstat -ia | grep link'): interface, mtu, net, mac, rest = mac_line.split(None, 4) if '.' not in mac: continue octets = mac.split('.') mac = ''.join('%02x' % int(o, 16) for o in octets).upper() ethernets.append(Eth(label=interface, mac=mac, speed=0)) disks = {} os_storage_size = 0 for disk_line in _ssh_lines(ssh, 'lsdev -c disk'): disk, rest = disk_line.split(None, 1) wwn = None model = None for line in _ssh_lines(ssh, 'lscfg -vl %s' % disk): if 'hdisk' in line: match = re.search(r'\(([0-9]+) MB\)', line) if match: os_storage_size += int(match.group(1)) elif 'Serial Number...' in line: label, sn = line.split('.', 1) sn = sn.strip('. \n') elif 'Machine Type and Model.' in line: label, model = line.split('.', 1) model = model.strip('. \n') disks[disk] = (model, sn) os_version = '' for line in _ssh_lines(ssh, 'oslevel'): os_version = line.strip() break os_memory = 0 for line in _ssh_lines(ssh, 'lsattr -El sys0 | grep ^realmem'): match = re.search(r'[0-9]+', line) if match: os_memory = int(int(match.group(0)) / 1024) break os_corescount = 0 for line in _ssh_lines(ssh, 'lparstat -i|grep ^Active\ Phys'): match = re.search(r'[0-9]+', line) if match: os_corescount += int(match.group(0)) finally: ssh.close() dev = Device.create( ethernets=ethernets, model_type=DeviceType.rack_server, model_name='%s AIX' % MODELS.get(machine_model, machine_model)) ipaddr = IPAddress.objects.get(address=ip) ipaddr.device = dev ipaddr.save() wwns = [] sns = [] stors = [] for disk, (model_name, sn) in disks.iteritems(): if not sn: continue if model_name == 'VV': wwns.append(sn) else: stors.append((disk, model_name, sn)) sns.append(sn) for mount in dev.disksharemount_set.exclude(share__wwn__in=wwns): mount.delete() for stor in dev.storage_set.exclude(sn__in=sns): stor.delete() for wwn in wwns: try: share = DiskShare.objects.get(wwn=wwn) except DiskShare.DoesNotExist: continue wwn = normalize_wwn(sn[-4:] + sn[:-4]) mount, created = DiskShareMount.concurrent_get_or_create( share=share, device=dev, defaults={'is_virtual':False}) mount.volume = disk mount.save(priority=SAVE_PRIORITY) for disk, model_name, sn in stors: # FIXME: storage with no size model, c = ComponentModel.create( ComponentType.disk, family=model_name, priority=SAVE_PRIORITY, ) stor, created = Storage.concurrent_get_or_create( device=dev, sn=sn, mount_point=None, ) stor.model = model stor.label = disk stor.save(priority=SAVE_PRIORITY) # FIXME: memory with no size mem, created = Memory.concurrent_get_or_create(device=dev, index=0) mem.label = 'Memory' mem.model, c = ComponentModel.create( ComponentType.memory, family='pSeries', priority=SAVE_PRIORITY, ) mem.save(priority=SAVE_PRIORITY) # FIXME: CPUs without info cpu, created = Processor.concurrent_get_or_create(device=dev, index=0) cpu.label = 'CPU' cpu.model, c = ComponentModel.create( ComponentType.processor, family='pSeries', name='pSeries CPU', priority=SAVE_PRIORITY, ) cpu.save(priority=SAVE_PRIORITY) OperatingSystem.create(dev=dev, os_name='AIX', version=os_version, family='AIX', memory=os_memory or None, cores_count=os_corescount or None, storage=os_storage_size or None, priority=SAVE_PRIORITY ) return machine_model
def handle_lshw_storage(dev, lshw, is_virtual=False, priority=0): storages = [] for storage in jpath.get_all('..disk', lshw): if not storage: continue if isinstance(storage, list): storages.extend(storage) else: storages.append(storage) storages.sort(key=get_logical_name) mount_points = set() for stor in storages: if 'logicalname' not in stor: continue ln = stor['logicalname'] if isinstance(ln, list): mount_points.update(ln) else: mount_points.add(ln) dev.storage_set.filter(mount_point__in=mount_points).delete() for storage in storages: if 'size' in storage: size = storage['size'] elif 'capacity' in storage: size = storage['capacity'] else: # empty slot continue sn = unicode(storage.get('serial') or '') or None if not sn or sn.startswith('QM000') or \ storage.get('vendor', '').strip().lower() in DISK_VENDOR_BLACKLIST or \ storage.get('product', '').strip().lower() in DISK_PRODUCT_BLACKLIST: continue if sn: stor, created = Storage.concurrent_get_or_create(sn=sn, device=dev) stor.mount_point = storage.get('logicalname', None) else: stor, created = Storage.concurrent_get_or_create(sn=None, device=dev, mount_point=storage.get('logicalname', None)) stor.size = int(size['value']) stor.size /= units.size_divisor[size['units']] stor.size = int(stor.size) stor.speed = 0 if storage.get('vendor', '').strip(): stor.label = storage['vendor'].strip() + ' ' else: stor.label = '' if storage.get('product', '').strip(): stor.label += storage['product'].strip() elif storage.get('description', '').strip(): stor.label += storage['description'].strip() else: stor.label += 'Generic disk' caps = storage['capabilities'] extra = "\n".join([": ".join((unicode(key), unicode(caps[key]) or '')) for key in sorted(caps.keys())]) stor.model, c = ComponentModel.concurrent_get_or_create( size=stor.size, speed=stor.speed, type=ComponentType.disk.id, family='', extra_hash=hashlib.md5(extra).hexdigest(), extra=extra) stor.model.name = '{} {}MiB'.format(stor.label, stor.size) stor.model.save(priority=priority) stor.save(priority=priority)