7 from qubes.qubes import QubesVmCollection
8 from qubes.qubes import QubesDispVmLabels
9 from qubes.qubes import QubesException
10 from qubes.qubes import QubesVmLabels
11 from qubes.qmemman_client import QMemmanClient
12 from qubes.qubesutils import block_list,block_attach,block_detach,block_detach_all,block_check_attached
13 from qubes.qubesutils import kbytes_to_kmg, bytes_to_kmg
17 current_savefile = '/var/run/qubes/current_savefile'
18 current_dvm_conf = '/var/run/qubes/current_dvm.conf'
19 avir_appvm_template = 'avir-template'
20 avir_dvm_template = 'avir-template-dvm'
22 def get_vm_collection():
23 vm_collection = QubesVmCollection()
24 vm_collection.lock_db_for_reading()
26 vm_collection.unlock_db()
29 def get_vm_by_name(vmname):
30 return get_vm_collection().get_vm_by_name(vmname)
32 def gen_scanner_name():
33 vm_collection = get_vm_collection()
34 vms = [vm for vm in vm_collection.values()]
37 if vm.is_appvm() and vm.template.name == avir_appvm_template:
38 vm_names.append (vm.name)
43 if "scanner"+str(id) not in vm_names:
44 return "scanner"+str(id)
45 print >> sys.stderr, "Unable to generate new scanner vm name"
50 self.tray_notify(str="Initialized")
52 def tray_notify(self, str, timeout = 3000):
53 notify_object.Notify("Qubes", 0, "red", "Qubes", str, [], [], timeout, dbus_interface="org.freedesktop.Notifications")
55 def tray_notify_error(self, str, timeout = 3000):
56 notify_object.Notify("Qubes", 0, "dialog-error", "Qubes", str, [], [], timeout, dbus_interface="org.freedesktop.Notifications")
58 def create_appvm(self):
59 #generate new avir-scanner name
60 scanner_vmname = gen_scanner_name()
61 print "Generating new scanner vm %s " % scanner_vmname
63 #create new vscanner virtual machine from template "avir-template"
64 qvm_collection = QubesVmCollection()
65 qvm_collection.lock_db_for_writing()
67 avir_template = qvm_collection.get_vm_by_name(avir_appvm_template)
68 if not avir_template.is_template():
69 print >> sys.stderr, "VM '{0}' is not a TemplateVM".format(avir_template)
74 scanner_vm = qvm_collection.add_new_vm(vmtype, name=scanner_vmname, template=avir_template, label = QubesVmLabels["orange"])
75 except QubesException as err:
76 print >> sys.stderr, "ERROR: {0}".format(err)
79 scanner_vm.memory = 512
82 scanner_vm.create_on_disk(verbose=True, source_template=avir_template)
84 # os.unlink(vm.root_img)
85 # os.rename(options.root, vm.root_img)
86 except (IOError, OSError) as err:
87 print >> sys.stderr, "ERROR: {0}".format(err)
91 qvm_collection.unlock_db()
94 def start_vm(self, vmname):
95 vm = get_vm_by_name(vmname)
96 if vm is None or vm.qid not in get_vm_collection():
97 print >> sys.stderr, "A VM with the name '{0}' does not exist in the system.".format(vmname)
101 xid = vm.start(verbose=True, preparing_dvm=False, start_guid=True, notify_function=None)
102 except (IOError, OSError, QubesException, MemoryError) as err:
104 # tray_notify_error(str(err))
106 print >> sys.stderr, "ERROR: {0}".format(err)
109 def create_dvm(self):
110 qmemman_client = QMemmanClient()
111 if not qmemman_client.request_memory(400*1024*1024):
112 qmemman_client.close()
113 errmsg = 'Not enough memory to create DVM. '
114 errmsg +='Terminate some appVM and retry.'
115 if os.path.exists('/usr/bin/kdialog'):
116 subprocess.call(['/usr/bin/kdialog', '--sorry', errmsg])
118 subprocess.call(['/usr/bin/zenity', '--warning', errmsg])
120 self.tray_notify("Starting new DispVM...")
122 qvm_collection = QubesVmCollection()
123 qvm_collection.lock_db_for_writing()
124 qvm_collection.load()
125 avir_template = qvm_collection.get_vm_by_name(avir_dvm_template)
126 if avir_template is None:
127 sys.stderr.write( 'Domain ' + avir_dvm_template + ' does not exist ?')
128 qvm_collection.unlock_db()
129 qmemman_client.close()
131 label = avir_template.label
132 retcode = subprocess.call(['/usr/lib/qubes/qubes_restore',
135 '-u', str(avir_template.default_user),
137 '-i', label.icon_path,
138 '-l', str(label.index)])
139 qmemman_client.close()
141 if os.path.exists('/usr/bin/kdialog'):
142 subprocess.call(['/usr/bin/kdialog', '--sorry', 'DisposableVM creation failed, see qubes_restore.log'])
144 subprocess.call(['/usr/bin/zenity', '--warning', 'DisposableVM creation failed, see qubes_restore.log'])
145 qvm_collection.unlock_db()
148 f = open('/var/run/qubes/dispVM_xid', 'r');
149 disp_xid = f.readline().rstrip('\n')
150 disp_name = f.readline().rstrip('\n')
151 disptempl = f.readline().rstrip('\n')
154 print >>sys.stderr, "getting vm %s" % disptempl
155 avir_disptempl = qvm_collection.get_vm_by_name(disptempl);
156 if avir_disptempl is None:
157 sys.stderr.write( 'Domain ' + disptempl + ' does not exist ?')
158 qvm_collection.unlock_db()
161 dispid = int(disp_name[4:])
162 dispvm = qvm_collection.add_new_disposablevm(disp_name, avir_disptempl.template, label=label, dispid=dispid, netvm=avir_disptempl.netvm)
163 print >> sys.stderr, "Waiting for the VM %s to startup...", dispvm.name
165 startup_counter_max = 60
166 while startup_counter < startup_counter_max:
167 if dispvm.is_running():
169 shutdown_counter += 1
172 qvm_collection.save()
173 qvm_collection.unlock_db()
176 def stop_vm(self, vmname):
177 vm = get_vm_by_name(vmname)
178 if vm is None or vm.qid not in get_vm_collection():
179 print >> sys.stderr, "A VM with the name '{0}' does not exist in the system.".format(vmname)
181 vm.shutdown(force=True)
182 print >> sys.stderr, "Waiting for the VM %s to shutdown...", vmname
184 shutdown_counter_max = 60
185 while shutdown_counter < shutdown_counter_max:
186 if not vm.is_running():
188 shutdown_counter += 1
191 def remove_vm(self, vmname):
192 qvm_collection = QubesVmCollection()
193 qvm_collection.lock_db_for_writing()
194 qvm_collection.load()
195 vm = qvm_collection.get_vm_by_name(vmname)
197 if vm is None or vm.qid not in qvm_collection:
198 print >> sys.stderr, "A VM with the name '{0}' does not exist in the system.".format(vmname)
202 print >> sys.stderr, "Cannot remove a running VM, stop it first"
206 dependent_vms = qvm_collection.get_vms_based_on(vm.qid)
207 if len(dependent_vms) > 0:
208 print >> sys.stderr, "The following AppVMs use '{0}' as a template:".format(vmname)
209 for vm in dependent_vms:
210 print >> sys.stderr, "{name:<12} (qid={qid})".format(qid=vm.qid, name=vm.name)
211 print >> sys.stderr, "Please remove those VMs first."
213 if qvm_collection.default_template_qid == vm.qid:
214 qvm_collection.default_template_qid = None
217 vm.remove_from_disk()
218 except (IOError, OSError) as err:
219 print >> sys.stderr, "Warning: {0}".format(err)
221 # Do not exit, perhaps the VM files were somehow removed
222 # so just remove it from Qubes DB
223 qvm_collection.pop(vm.qid)
224 qvm_collection.save()
225 qvm_collection.unlock_db()
227 def attach_dev(self, vmname, devname):
228 vm = get_vm_by_name(vmname)
229 if vm is None or vm.qid not in get_vm_collection():
230 print >> sys.stderr, "A VM with the name '{0}' does not exist in the system.".format(vmname)
232 print "Attaching %s to vm - %s" % (devname, vm.name)
234 kwargs['auto_detach'] = True
236 backend_vm = get_vm_by_name("dom0")
237 block_attach(vm, backend_vm, devname, **kwargs)
238 except QubesException as e:
239 print >> sys.stderr, "ERROR: %s" % str(e)
242 def detach_dev(self, vmname, devname):
243 vm = get_vm_by_name(vmname)
244 if vm is None or vm.qid not in get_vm_collection():
245 print >> sys.stderr, "A VM with the name '{0}' does not exist in the system.".format(vmname)
247 print "Detaching %s from vm - %s" % (devname, vmname)
249 #kwargs['frontend'] = "to_scan"
251 block_detach(vm, **kwargs)
252 except QubesException as e:
253 print >> sys.stderr, "ERROR: %s" % str(e)
256 def scan(self, vmname):
257 vm = get_vm_by_name(vmname)
258 if vm is None or vm.qid not in get_vm_collection():
259 print >> sys.stderr, "A VM with the name '{0}' does not exist in the system.".format(vmname)
261 subprocess.call(['/usr/lib/qubes/qrexec_client', '-d', vmname, 'root:mount /dev/xvdi /mnt/removable'])
262 #subprocess.call(['/usr/lib/qubes/qrexec_client', '-d', vmname, 'root:clamscan /mnt/removable'])
263 subprocess.call(['/usr/lib/qubes/qrexec_client', '-d', vmname, 'root:umount /mnt/removable'])
268 print >>sys.stderr, "time=%s, qfile-daemon-dvm init" % (str(time.time()))
269 notify_object = dbus.SessionBus().get_object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
270 vm_factory = VMFactory()
271 #vmname = vm_factory.create_dvm()
272 vmname = vm_factory.create_appvm()
273 vm_factory.start_vm(vmname)
274 vm_factory.attach_dev(vmname, "sdb")
275 vm_factory.scan(vmname)
276 vm_factory.detach_dev(vmname, "sdb")
277 #vm_factory.stop_vm(vmname)
278 #vm_factory.remove_vm(vmname)