208 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			208 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/python2.6
 | 
						|
#
 | 
						|
# The Qubes OS Project, http://www.qubes-os.org
 | 
						|
#
 | 
						|
# Copyright (C) 2010  Joanna Rutkowska <joanna@invisiblethingslab.com>
 | 
						|
#
 | 
						|
# This program is free software; you can redistribute it and/or
 | 
						|
# modify it under the terms of the GNU General Public License
 | 
						|
# as published by the Free Software Foundation; either version 2
 | 
						|
# of the License, or (at your option) any later version.
 | 
						|
#
 | 
						|
# This program is distributed in the hope that it will be useful,
 | 
						|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
# GNU General Public License for more details.
 | 
						|
#
 | 
						|
# You should have received a copy of the GNU General Public License
 | 
						|
# along with this program; if not, write to the Free Software
 | 
						|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 | 
						|
#
 | 
						|
#
 | 
						|
 | 
						|
from qubes.qubes import QubesVmCollection
 | 
						|
from qubes.qubes import QubesHost
 | 
						|
from qubes.qubes import QubesException
 | 
						|
from optparse import OptionParser
 | 
						|
import sys
 | 
						|
 | 
						|
 | 
						|
fields = {
 | 
						|
    "qid": {"func": "vm.qid"},
 | 
						|
 | 
						|
    "name": {"func": "('=>' if qvm_collection.get_default_template_vm() is not None\
 | 
						|
             and vm.qid == qvm_collection.get_default_template_vm().qid else '')\
 | 
						|
             + ('[' if vm.is_template() else '')\
 | 
						|
             + ('<' if vm.is_disposablevm() else '')\
 | 
						|
             + ('{' if vm.is_netvm() else '')\
 | 
						|
             + vm.name \
 | 
						|
             + (']' if vm.is_template() else '')\
 | 
						|
             + ('>' if vm.is_disposablevm() else '')\
 | 
						|
             + ('}' if vm.is_netvm() else '')"},
 | 
						|
 | 
						|
    "type": {"func": "'Tpl' if vm.is_template() else \
 | 
						|
             ('Proxy' if vm.is_proxyvm() else \
 | 
						|
             (' Net' if vm.is_netvm() else ''))"},
 | 
						|
 | 
						|
    "updbl" : {"func": "'Yes' if vm.is_updateable() else ''"},
 | 
						|
 | 
						|
    "template": {"func": "'n/a' if vm.is_template() else\
 | 
						|
                 ('None' if vm.template_vm is None else\
 | 
						|
                 qvm_collection[vm.template_vm.qid].name)"},
 | 
						|
 | 
						|
    "netvm": {"func": "'n/a' if vm.is_netvm() and not vm.is_proxyvm() else\
 | 
						|
              ('*' if vm.uses_default_netvm else '') +\
 | 
						|
              qvm_collection[vm.netvm_vm.qid].name\
 | 
						|
                     if vm.netvm_vm is not None else '-'"},
 | 
						|
 | 
						|
    "ip" : {"func": "vm.ip"},
 | 
						|
    "netmask" : {"func": "vm.netmask"},
 | 
						|
    "gateway" : {"func": "vm.gateway"},
 | 
						|
 | 
						|
    "xid" : {"func" : "vm.get_xid() if vm.is_running() else '-'"},
 | 
						|
 | 
						|
    "mem" : {"func" : "(str(vm.get_mem()/1024) + ' MB') if vm.is_running() else '-'"},
 | 
						|
    "cpu" : {"func" : "round (cpu_usages[vm.get_xid()]['cpu_usage'], 1) if vm.is_running() else '-'"},
 | 
						|
    "disk": {"func" : "str(vm.get_disk_utilization()/(1024*1024)) + ' MB'"}, 
 | 
						|
    "state": {"func" : "vm.get_power_state()"},
 | 
						|
 | 
						|
    "priv-curr": {"func" : "str(vm.get_disk_utilization_private_img()/(1024*1024)) + ' MB'"},
 | 
						|
    "priv-max": {"func" : "str(vm.get_private_img_sz()/(1024*1024)) + ' MB'"},
 | 
						|
    "priv-util": {"func" : "str(vm.get_disk_utilization_private_img()*100/vm.get_private_img_sz()) + '%' if vm.get_private_img_sz() != 0 else '-'"},
 | 
						|
 | 
						|
    "root-curr": {"func" : "str(vm.get_disk_utilization_root_img()/(1024*1024)) + ' MB'"},
 | 
						|
    "root-max": {"func" : "str(vm.get_root_img_sz()/(1024*1024)) + ' MB'"},
 | 
						|
    "root-util": {"func" : "str(vm.get_disk_utilization_root_img()*100/vm.get_root_img_sz()) + '%' if vm.get_root_img_sz() != 0 else '-'"},
 | 
						|
 | 
						|
    "label" : {"func" : "vm.label.name"},
 | 
						|
 | 
						|
    "on" : {"func" : "'*' if vm.is_running() else ''"}
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
def main():
 | 
						|
    usage = "usage: %prog [options] <vm-name>"
 | 
						|
    parser = OptionParser (usage)
 | 
						|
 | 
						|
    parser.add_option ("-n", "--network", dest="network",
 | 
						|
                       action="store_true", default=False,
 | 
						|
                       help="Show network addresses assigned to VMs")
 | 
						|
 | 
						|
    parser.add_option ("-c", "--cpu", dest="cpu",
 | 
						|
                       action="store_true", default=False,
 | 
						|
                       help="Show CPU load")
 | 
						|
 | 
						|
    parser.add_option ("-m", "--mem", dest="mem",
 | 
						|
                       action="store_true", default=False,
 | 
						|
                       help="Show memory usage")
 | 
						|
 | 
						|
    parser.add_option ("-d", "--disk", dest="disk",
 | 
						|
                       action="store_true", default=False,
 | 
						|
                       help="Show VM disk utilization statistics")
 | 
						|
 | 
						|
    parser.add_option ("-i", "--ids", dest="ids",
 | 
						|
                       action="store_true", default=False,
 | 
						|
                       help="Show Qubes and Xen id#s")
 | 
						|
 | 
						|
 | 
						|
    (options, args) = parser.parse_args ()
 | 
						|
 | 
						|
    qvm_collection = QubesVmCollection()
 | 
						|
    qvm_collection.lock_db_for_reading()
 | 
						|
    qvm_collection.load()
 | 
						|
    qvm_collection.unlock_db()
 | 
						|
 | 
						|
    fields_to_display = ["name", "on", "state", "updbl", "type", "template", "netvm", "label" ]
 | 
						|
 | 
						|
    cpu_usages = None
 | 
						|
 | 
						|
    if (options.ids):
 | 
						|
        fields_to_display += ["qid", "xid"]
 | 
						|
 | 
						|
    if (options.cpu):
 | 
						|
        qhost = QubesHost()
 | 
						|
        (measure_time, cpu_usages) = qhost.measure_cpu_usage()
 | 
						|
        fields_to_display += ["cpu"]
 | 
						|
 | 
						|
    if (options.mem):
 | 
						|
        fields_to_display += ["mem"]
 | 
						|
 | 
						|
    if (options.network):
 | 
						|
        fields_to_display.remove ("template")
 | 
						|
        fields_to_display += ["ip", "netmask", "gateway"]
 | 
						|
 | 
						|
    if (options.disk):
 | 
						|
        fields_to_display.remove ("template")
 | 
						|
        fields_to_display.remove ("netvm")
 | 
						|
        fields_to_display += ["priv-curr", "priv-max", "root-curr", "root-max", "disk" ]
 | 
						|
 | 
						|
    
 | 
						|
    vms_list = [vm for vm in qvm_collection.values()]
 | 
						|
    no_vms = len (vms_list)
 | 
						|
    vms_to_display = []
 | 
						|
    # Frist, the NetVMs...
 | 
						|
    for netvm in vms_list:
 | 
						|
        if netvm.is_netvm():
 | 
						|
            vms_to_display.append (netvm)
 | 
						|
 | 
						|
    # Now, the AppVMs without template...
 | 
						|
    for appvm in vms_list:
 | 
						|
        if appvm.is_appvm() and appvm.template_vm is None:
 | 
						|
            vms_to_display.append (appvm)
 | 
						|
 | 
						|
    # Now, the template, and all its AppVMs...
 | 
						|
    for tvm in vms_list:
 | 
						|
        if tvm.is_template():
 | 
						|
            vms_to_display.append (tvm)
 | 
						|
            for vm in vms_list:
 | 
						|
                if (vm.is_appvm() or vm.is_disposablevm()) and \
 | 
						|
		    vm.template_vm and vm.template_vm.qid == tvm.qid:
 | 
						|
                    vms_to_display.append(vm)
 | 
						|
 | 
						|
    assert len(vms_to_display) == no_vms
 | 
						|
 | 
						|
    # First calculate the maximum width of each field we want to display
 | 
						|
    total_width = 0;
 | 
						|
    for f in fields_to_display:
 | 
						|
        fields[f]["max_width"] = len(f)
 | 
						|
        for vm in vms_to_display:
 | 
						|
            l = len(str(eval(fields[f]["func"])))
 | 
						|
            if l > fields[f]["max_width"]:
 | 
						|
                fields[f]["max_width"] = l
 | 
						|
        total_width += fields[f]["max_width"]
 | 
						|
 | 
						|
 | 
						|
    # Display the header
 | 
						|
    s = ""
 | 
						|
    for f in fields_to_display:
 | 
						|
        fmt="{{0:-^{0}}}-+".format(fields[f]["max_width"] + 1)
 | 
						|
        s += fmt.format('-')
 | 
						|
    print s
 | 
						|
    s = ""
 | 
						|
    for f in fields_to_display:
 | 
						|
        fmt="{{0:>{0}}} |".format(fields[f]["max_width"] + 1)
 | 
						|
        s += fmt.format(f) 
 | 
						|
    print s
 | 
						|
    s = ""
 | 
						|
    for f in fields_to_display:
 | 
						|
        fmt="{{0:-^{0}}}-+".format(fields[f]["max_width"] + 1)
 | 
						|
        s += fmt.format('-')
 | 
						|
    print s
 | 
						|
 | 
						|
    # ... and the actual data
 | 
						|
    for vm in vms_to_display:
 | 
						|
        s = ""
 | 
						|
        for f in fields_to_display:
 | 
						|
            fmt="{{0:>{0}}} |".format(fields[f]["max_width"] + 1)
 | 
						|
            s += fmt.format(eval(fields[f]["func"])) 
 | 
						|
        print s
 | 
						|
 | 
						|
        try:
 | 
						|
            vm.verify_files()
 | 
						|
        except QubesException as err:
 | 
						|
            print >> sys.stderr, "WARNING: VM '{0}' has corrupted files!".format(vm.name)
 | 
						|
 | 
						|
main()
 |