c789121f84
This is core part of migration. Things not migrated yet: - DispVM (qubes_restore needs to be almost rewritten) - VM xen config files should be fixed (use "script:" prefix in block device description, perhaps generate this files on VM start) Huge, slow xend not needed any more, now it conflicts with libxl
207 lines
7.2 KiB
Python
Executable File
207 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
|
|
|
|
|
|
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 "WARNING: VM '{0}' has corrupted files!".format(vm.name)
|
|
|
|
main()
|