Skip to content

Commit 2bf2cb1

Browse files
Adding dmidecode support in server-info for better view of memory subsystem (#178)
* Added(server-info): reminder about installation pcituils and dmidecode. * Added(server-info): using dmidecode memory data file (type, speed and size). for -show and -rate * Added(test-data): server-info archive from cheapest vscale CentOS 7 * Added(assessor): Grade by known values * Fixed(test-data): server-info show expected output changed * Refactoring(dmi): parser complexity fighting * Refactoring(parsers): provide optional simplier way of initialisation for any Parser-based class * Incremented version #37
1 parent 81d35b8 commit 2bf2cb1

File tree

31 files changed

+321
-28
lines changed

31 files changed

+321
-28
lines changed

netutils_linux_hardware/assessor.py

+23-2
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,33 @@ def assess_cpu(self):
3939
'Vendor ID': Grade.str(cpuinfo.get('Vendor ID'), good=['GenuineIntel']),
4040
}
4141

42+
def assess_memory_device(self, device):
43+
return {
44+
'size': Grade.int(device.get('size', 0), 512, 8196),
45+
'type': Grade.known_values(device.get('type', 'RAM'), {
46+
'DDR1': 2,
47+
'DDR2': 3,
48+
'DDR3': 6,
49+
'DDR4': 10,
50+
}),
51+
'speed': Grade.int(device.get('speed', 0), 200, 4000),
52+
}
53+
54+
def assess_memory_devices(self, devices):
55+
return dict((handle, self.assess_memory_device(device)) for handle, device in devices.items())
56+
57+
def assess_memory_size(self, size):
58+
return {
59+
'MemTotal': Grade.int(size.get('MemTotal'), 2 * (1024 ** 2), 16 * (1024 ** 2)),
60+
'SwapTotal': Grade.int(size.get('SwapTotal'), 512 * 1024, 4 * (1024 ** 2)),
61+
}
62+
4263
def assess_memory(self):
4364
meminfo = self.data.get('memory')
4465
if meminfo:
4566
return {
46-
'MemTotal': Grade.int(meminfo.get('MemTotal'), 2 * (1024 ** 2), 16 * (1024 ** 2)),
47-
'SwapTotal': Grade.int(meminfo.get('SwapTotal'), 512 * 1024, 4 * (1024 ** 2)),
67+
'devices': self.assess_memory_devices(meminfo.get('devices')),
68+
'size': self.assess_memory_size(meminfo.get('size')),
4869
}
4970

5071
def assess_system(self):

netutils_linux_hardware/grade.py

+4
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,7 @@ def str(value, good=None, bad=None):
1818
@staticmethod
1919
def fact(value, mode=False):
2020
return 10 if (value is None) != mode else 1
21+
22+
@staticmethod
23+
def known_values(value, _dict):
24+
return _dict.get(value, 1)

netutils_linux_hardware/parsers.py

+45-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88

99

1010
class Parser(object):
11-
@staticmethod
11+
def __init__(self, filepath=None):
12+
self.result = self.parse_file_safe(filepath) if filepath else None
13+
1214
def parse(text, **kwargs):
1315
raise NotImplementedError
1416

@@ -122,6 +124,48 @@ def parse(self, text):
122124
return dict((k, int(v.replace(' kB', ''))) for k, v in iteritems(yaml.load(text)) if k in self.keys_required)
123125

124126

127+
class MemInfoDMIDevice(object):
128+
def __init__(self, text):
129+
self.data = {
130+
'speed': 0,
131+
'type': 'RAM',
132+
'size': 0,
133+
}
134+
self.type = 'RAM'
135+
self.handle = None
136+
self.size = 0
137+
self.parse_text(text)
138+
139+
def parse_text(self, text):
140+
""" Разбор описания плашки памяти от dmidecode """
141+
for line in map(str.strip, text.split('\n')):
142+
self.parse_line(line)
143+
144+
def parse_line(self, line):
145+
for key in ('Speed', 'Type', 'Size'):
146+
if line.startswith(key + ':'):
147+
self.data[key.lower()] = line.split()[1]
148+
break
149+
if line.startswith('Handle'):
150+
self.handle = line.split(' ')[1].strip(',')
151+
152+
153+
class MemInfoDMI(Parser):
154+
@staticmethod
155+
def parse(text):
156+
""" Разбор всего вывода dmidecode --type memory """
157+
return MemInfoDMI.__parse(text.split('\n\n')) if text else None
158+
159+
@staticmethod
160+
def __parse(devices):
161+
output = dict()
162+
for device in devices:
163+
if 'Memory Device' in device:
164+
mem_dev = MemInfoDMIDevice(device)
165+
output[mem_dev.handle] = mem_dev
166+
return output
167+
168+
125169
class CPULayout(Parser):
126170
@staticmethod
127171
def parse(text):

netutils_linux_hardware/reader.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
# pylint: disable=C0111, C0103
33

44
import os
5+
56
import yaml
6-
from netutils_linux_hardware.parsers import YAMLLike, CPULayout, DiskInfo, MemInfo
7+
78
from netutils_linux_hardware.netdev import ReaderNet
9+
from netutils_linux_hardware.parsers import YAMLLike, CPULayout, DiskInfo, MemInfo, MemInfoDMI
810

911

1012
class Reader(object):
11-
1213
info = None
1314

1415
def __init__(self, datadir):
@@ -25,12 +26,15 @@ def gather_info(self):
2526

2627
self.info = {
2728
'cpu': {
28-
'info': YAMLLike().parse_file_safe(self.path('lscpu_info')),
29-
'layout': CPULayout().parse_file_safe(self.path('lscpu_layout')),
29+
'info': YAMLLike(self.path('lscpu_info')).result,
30+
'layout': CPULayout(self.path('lscpu_layout')).result,
3031
},
3132
'net': ReaderNet(self.datadir, self.path).netdevs,
3233
'disk': DiskInfo().parse(self.path('disks_types'), self.path('lsblk_sizes'), self.path('lsblk_models')),
33-
'memory': MemInfo().parse_file_safe(self.path('meminfo')),
34+
'memory': {
35+
'size': MemInfo(self.path('meminfo')).result,
36+
'devices': MemInfoDMI(self.path('dmidecode')).result,
37+
},
3438
}
3539
for key in ('CPU MHz', 'BogoMIPS'):
3640
if self.info.get('cpu', {}).get('info', {}).get(key):

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def read(*paths):
1616

1717
setuptools.setup(
1818
name='netutils-linux',
19-
version='2.5.2',
19+
version='2.6.1',
2020
author='Oleg Strizhechenko',
2121
author_email='[email protected]',
2222
license='MIT',

tests/server-info-show.tests/1xE3-1271.I217_and_X710.L2_mixed.masterconf/expected_output

+6-4
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@ disk:
3333
size: 120034123776
3434
type: SSD
3535
memory:
36-
MemFree: 14142256
37-
MemTotal: 16290904
38-
SwapFree: 8216572
39-
SwapTotal: 8216572
36+
devices: null
37+
size:
38+
MemFree: 14142256
39+
MemTotal: 16290904
40+
SwapFree: 8216572
41+
SwapTotal: 8216572
4042
net:
4143
eth0:
4244
buffers:

tests/server-info-show.tests/1xE31240.2x82576.L2.manual/expected_output

+3-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ cpu:
3131
'6': '0'
3232
'7': '0'
3333
disk: null
34-
memory: null
34+
memory:
35+
devices: null
36+
size: null
3537
net:
3638
eth0:
3739
buffers:

tests/server-info-show.tests/1xE5200.82571EB_and_AR8121.L2.manual/expected_output

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ cpu:
2424
'0': '0'
2525
'1': '0'
2626
disk: null
27-
memory: null
27+
memory:
28+
devices: null
29+
size: null
2830
net:
2931
eth1:
3032
buffers:

tests/server-info-show.tests/1xi3.single_i350.l2_mixed.manual/expected_output

+3-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ cpu:
2828
'2': '0'
2929
'3': '0'
3030
disk: null
31-
memory: null
31+
memory:
32+
devices: null
33+
size: null
3234
net:
3335
eth6:
3436
buffers:

tests/server-info-show.tests/1xi7-4770K.1x82541PI.L2.manual/expected_output

+3-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ cpu:
3232
'6': '0'
3333
'7': '0'
3434
disk: null
35-
memory: null
35+
memory:
36+
devices: null
37+
size: null
3638
net:
3739
eth0:
3840
buffers:

tests/server-info-show.tests/2xE5-2640.i350_and_82599ES.l2_mixed.masterconf/expected_output

+6-4
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,12 @@ disk:
6565
size: 1000204886016
6666
type: HDD
6767
memory:
68-
MemFree: 432940
69-
MemTotal: 32843852
70-
SwapFree: 16490492
71-
SwapTotal: 16490492
68+
devices: null
69+
size:
70+
MemFree: 432940
71+
MemTotal: 32843852
72+
SwapFree: 16490492
73+
SwapTotal: 16490492
7274
net:
7375
eth1:
7476
buffers:

tests/server-info-show.tests/2xE5530.82576_and_82574L.l2_mixed.manual/expected_output

+3-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ cpu:
3939
'8': '0'
4040
'9': '1'
4141
disk: null
42-
memory: null
42+
memory:
43+
devices: null
44+
size: null
4345
net:
4446
eth1:
4547
buffers:

tests/server-info-show.tests/2xL5520.1x82576.L2_mixed.manual/expected_output

+3-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ cpu:
4040
'8': '0'
4141
'9': '0'
4242
disk: null
43-
memory: null
43+
memory:
44+
devices: null
45+
size: null
4446
net:
4547
em2:
4648
buffers:

tests/server-info-show.tests/2xX5650.BCM5709_and_MT27520.L2.manual/expected_output

+3-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ cpu:
3636
'8': '0'
3737
'9': '1'
3838
disk: null
39-
memory: null
39+
memory:
40+
devices: null
41+
size: null
4042
net:
4143
eth1:
4244
buffers:

tests/server-info-show.tests/kvm.l3.masterconf/expected_output

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ cpu:
2626
'0': '0'
2727
'1': '1'
2828
disk: null
29-
memory: null
29+
memory:
30+
devices: null
31+
size: null
3032
net:
3133
eth1:
3234
buffers:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
processor : 0
2+
vendor_id : GenuineIntel
3+
cpu family : 6
4+
model : 79
5+
model name : Intel(R) Xeon(R) CPU E5-2630 v4 @ 2.20GHz
6+
stepping : 1
7+
microcode : 0x1
8+
cpu MHz : 2199.986
9+
cache size : 25600 KB
10+
physical id : 0
11+
siblings : 1
12+
core id : 0
13+
cpu cores : 1
14+
apicid : 0
15+
initial apicid : 0
16+
fpu : yes
17+
fpu_exception : yes
18+
cpuid level : 13
19+
wp : yes
20+
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl eagerfpu pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap xsaveopt arat
21+
bogomips : 4399.97
22+
clflush size : 64
23+
cache_alignment : 64
24+
address sizes : 40 bits physical, 48 bits virtual
25+
power management:
26+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/sys/block/vda/queue/rotational:1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# dmidecode 3.0
2+
Getting SMBIOS data from sysfs.
3+
SMBIOS 2.4 present.
4+
5+
Handle 0x1000, DMI type 16, 15 bytes
6+
Physical Memory Array
7+
Location: Other
8+
Use: System Memory
9+
Error Correction Type: Multi-bit ECC
10+
Maximum Capacity: 512 MB
11+
Error Information Handle: Not Provided
12+
Number Of Devices: 1
13+
14+
Handle 0x1100, DMI type 17, 21 bytes
15+
Memory Device
16+
Array Handle: 0x1000
17+
Error Information Handle: 0x0000
18+
Total Width: 64 bits
19+
Data Width: 64 bits
20+
Size: 512 MB
21+
Form Factor: DIMM
22+
Set: None
23+
Locator: DIMM 0
24+
Bank Locator: Not Specified
25+
Type: RAM
26+
Type Detail: None
27+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Ring parameters for eth0:
2+
Pre-set maximums:
3+
RX: 256
4+
RX Mini: 0
5+
RX Jumbo: 0
6+
TX: 256
7+
Current hardware settings:
8+
RX: 256
9+
RX Mini: 0
10+
RX Jumbo: 0
11+
TX: 256
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
driver: virtio_net
2+
version: 1.0.0
3+
firmware-version:
4+
expansion-rom-version:
5+
bus-info: 0000:00:03.0
6+
supports-statistics: no
7+
supports-test: no
8+
supports-eeprom-access: no
9+
supports-register-dump: no
10+
supports-priv-flags: no
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
CPU0
2+
0: 24 IO-APIC-edge timer
3+
1: 10 IO-APIC-edge i8042
4+
6: 3 IO-APIC-edge floppy
5+
8: 1 IO-APIC-edge rtc0
6+
9: 0 IO-APIC-fasteoi acpi
7+
10: 0 IO-APIC-fasteoi virtio2
8+
11: 0 IO-APIC-fasteoi uhci_hcd:usb1
9+
12: 15 IO-APIC-edge i8042
10+
14: 0 IO-APIC-edge ata_piix
11+
15: 0 IO-APIC-edge ata_piix
12+
24: 0 PCI-MSI-edge virtio1-config
13+
25: 607727 PCI-MSI-edge virtio1-req.0
14+
26: 0 PCI-MSI-edge virtio0-config
15+
27: 6070473 PCI-MSI-edge virtio0-input.0
16+
28: 17 PCI-MSI-edge virtio0-output.0
17+
NMI: 0 Non-maskable interrupts
18+
LOC: 45350286 Local timer interrupts
19+
SPU: 0 Spurious interrupts
20+
PMI: 0 Performance monitoring interrupts
21+
IWI: 4143286 IRQ work interrupts
22+
RTR: 0 APIC ICR read retries
23+
RES: 0 Rescheduling interrupts
24+
CAL: 0 Function call interrupts
25+
TLB: 0 TLB shootdowns
26+
TRM: 0 Thermal event interrupts
27+
THR: 0 Threshold APIC interrupts
28+
DFR: 0 Deferred Error APIC interrupts
29+
MCE: 0 Machine check exceptions
30+
MCP: 3760 Machine check polls
31+
ERR: 0
32+
MIS: 0
33+
PIN: 0 Posted-interrupt notification event
34+
PIW: 0 Posted-interrupt wakeup event
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
NAME MODEL
2+
vda
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
21474836480 vda
2+
21473771008 / vda1

0 commit comments

Comments
 (0)