2016-05-26 3 views
1

У меня есть этот простой скрипт для проверки использования памяти виртуальными машинами, управляемыми libvirt.libvirt: от целого целого до строки?

Как преобразовать целое число для state из dom.info() в удобочитаемую строку?

import libvirt 
import re 

import sys 


def mem_total_kb(): 
    meminfo = open('/proc/meminfo').read() 
    matched = re.search(r'^MemTotal:\s+(\d+)', meminfo) 
    return int(matched.groups()[0]) 


def main(): 
    conn = libvirt.openReadOnly(None) 

    if conn == None: 
     print 'Failed to open connection to the hypervisor' 
     sys.exit(1) 
    used_mem_sum = 0 
    for domain_id in conn.listDomainsID(): 
     dom = conn.lookupByID(domain_id) 
     state, max_mem, used_mem, vcpus, cpu_time_used = dom.info() 
     print(
     'name=%s state=%s max_mem=%s used_mem=%s vcpus=%s cpu_time_used=%s' % (dom.name(), state, max_mem, used_mem, vcpus, cpu_time_used)) 
     used_mem_sum += used_mem 
    print('Sum of used mem: %s KiB' % used_mem_sum) 
    mem_total = mem_total_kb() 
    print('Sum of physical mem: %s KiB' % mem_total) 
    if used_mem_sum > mem_total: 
     print('########## VMs use more RAM than available!') 
     return 
    mem_left=mem_total - used_mem_sum 
    print('Memory left: %s KiB' % (mem_left)) 
    mem_left_should=4000000 
    if mem_left<mem_left_should: 
     print('less than mem_left_should=%sKiB left!' % mem_left_should) 


if __name__ == '__main__': 
    main() 

Docs: https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainInfo

состояние: состояние движения, один из virDomainState

enum virDomainState { 

VIR_DOMAIN_NOSTATE = 0 
no state 
VIR_DOMAIN_RUNNING = 1 
the domain is running 
VIR_DOMAIN_BLOCKED = 2 
the domain is blocked on resource 
VIR_DOMAIN_PAUSED = 3 
the domain is paused by user 
VIR_DOMAIN_SHUTDOWN = 4 
the domain is being shut down 
VIR_DOMAIN_SHUTOFF = 5 
the domain is shut off 
VIR_DOMAIN_CRASHED = 6 
the domain is crashed 
VIR_DOMAIN_PMSUSPENDED = 7 
the domain is suspended by guest power management 
VIR_DOMAIN_LAST = 8 
NB: this enum value will increase over time as new events are added to the libvirt API. It reflects the last state supported by this version of the libvirt API. 

} 
+0

Можете ли вы привести пример того, что вы имеете в виду, например. '1 -> Один'? – jcfollower

+0

@jcfollower Я обновил вопрос. – guettli

+0

Поскольку он маленький, вы можете просто создать свой собственный словарь ... 'state_descr = {0: 'No State', 1: 'Домен запущен', ...}' – jcfollower

ответ

2

Похоже, что имена констант перечислены в модуле libvirt. Следующие работы для меня ...

import libvirt 
import pprint 
import re 

d = {} 
for k, v in libvirt.__dict__.iteritems(): 
    if re.match('VIR_DOMAIN_[A-Z]+$', k): 
     d[v] = k 

pprint.pprint(d) 

... и печатает ...

{0: 'VIR_DOMAIN_NOSTATE', 
1: 'VIR_DOMAIN_RUNNING', 
2: 'VIR_DOMAIN_BLOCKED', 
3: 'VIR_DOMAIN_PAUSED', 
4: 'VIR_DOMAIN_SHUTDOWN', 
5: 'VIR_DOMAIN_SHUTOFF', 
6: 'VIR_DOMAIN_CRASHED', 
7: 'VIR_DOMAIN_PMSUSPENDED'} 

Описания, которые, вероятно, просто комментарии в оригинальном исходном коде, которые, вероятно, не подвергаются. Одним из примеров определяет свой собственный словарь на line 106 ...

state_names = { libvirt.VIR_DOMAIN_RUNNING : "running", 
       libvirt.VIR_DOMAIN_BLOCKED : "idle", 
       libvirt.VIR_DOMAIN_PAUSED : "paused", 
       libvirt.VIR_DOMAIN_SHUTDOWN : "in shutdown", 
       libvirt.VIR_DOMAIN_SHUTOFF : "shut off", 
       libvirt.VIR_DOMAIN_CRASHED : "crashed", 
       libvirt.VIR_DOMAIN_NOSTATE : "no state" } 

... так что вы можете просто взять его оттуда, хотя это, кажется неполным.

+0

Отображение от целых чисел до имен VIR_DOMAIN_ * - это все, что мне нужно. Большое спасибо. – guettli

0

Этот Баш скрипт будет получать список virDomainState значений (за исключением VIR_DOMAIN_LAST) и их описания в формате JSON:

#!/bin/bash 

HEADER=include/libvirt/libvirt-domain.h 

get_header_file() 
{ 
    curl -s https://raw.githubusercontent.com/libvirt/libvirt/master/"$HEADER" 
} 

select_virDomainState_block() 
{ 
    sed -n '/virDomainState:/,/^\} virDomainState;/ p' 
} 

join_multiline_comments() 
{ 
    sed -n '\%/\*[^*]*$% N; \%/\*.*\*/$% { s/\s*\n\s*/ /; p; }' 
} 

enum_values_to_json_map() 
{ 
    echo '{' 
    sed "s/\s*VIR_DOMAIN\S\+\s*=\s*//; s^,\s*/\*\s*^ : '^; s^\s*\*/^',^;" 
    echo '}' 
} 

get_header_file     \ 
| select_virDomainState_block \ 
| join_multiline_comments  \ 
| grep 'VIR_DOMAIN\S\+\s*='  \ 
| enum_values_to_json_map 

Пример использования:

$ ./get_libvirt_domain_states 
{ 
0 : 'no state', 
1 : 'the domain is running', 
2 : 'the domain is blocked on resource', 
3 : 'the domain is paused by user', 
4 : 'the domain is being shut down', 
5 : 'the domain is shut off', 
6 : 'the domain is crashed', 
7 : 'the domain is suspended by guest power management', 
} 

Обратите внимание, что скрипт загружает файл ~ 150kb из хранилища Libvirt зеркала на GitHub. Он предназначен для облегчения обновления с кодом libvirt. Конечно, вы можете назвать это из своего кода на Python, но лично я бы этого не сделал.

+0

Хм это зависит от интернет-соединения .... нет способа получить от целого до строки через libvirt? – guettli

+1

libvirt, похоже, не предоставляет такую ​​функциональность. По крайней мере, я не мог найти его. Вы должны сохранить свой собственный словарь в коде (как предлагалось @jcfollower). Я просто упрощаю вам поддерживать этот словарь в синхронизации с кодом libvirt. – Leon