Merge lp:~virtualbricks/virtualbrick/pre-devel-0.3 into lp:virtualbrick/0.x

Proposed by Daniele Lacamera
Status: Merged
Merged at revision: 41
Proposed branch: lp:~virtualbricks/virtualbrick/pre-devel-0.3
Merge into: lp:virtualbrick/0.x
Diff against target: 301 lines (+133/-18)
3 files modified
virtualbricks.glade (+43/-1)
virtualbricks_BrickFactory.py (+36/-12)
virtualbricks_GUI.py (+54/-5)
To merge this branch: bzr merge lp:~virtualbricks/virtualbrick/pre-devel-0.3
Reviewer Review Type Date Requested Status
Francesco Apollonio Approve
Review via email: mp+47924@code.launchpad.net

Description of the change

Support for Qemu monitor. Added savevm/loadvm functions. Ready for final development of the blueprint live-management. After 0.2 release this is the focus of development.

To post a comment you must log in.
Revision history for this message
Francesco Apollonio (lorddex) :
review: Approve
42. By Daniele Lacamera

Added qcow2 to image creation

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'virtualbricks.glade'
2--- virtualbricks.glade 2011-01-29 19:10:34 +0000
3+++ virtualbricks.glade 2011-01-30 10:15:09 +0000
4@@ -2171,7 +2171,7 @@
5 </packing>
6 </child>
7 <child>
8- <widget class="GtkEntry" id="cfg_Qemu_append_text">
9+ <widget class="GtkEntry" id="cfg_Qemu_kopt_text">
10 <property name="visible">True</property>
11 <property name="can_focus">True</property>
12 <property name="invisible_char">&#x25CF;</property>
13@@ -4927,6 +4927,7 @@
14 <property name="items" translatable="yes">Auto
15 raw
16 qcow
17+qcow2
18 cow
19 vmdk
20 cloop</property>
21@@ -5657,6 +5658,38 @@
22 </widget>
23 </child>
24 <child>
25+ <widget class="GtkMenuItem" id="vmsuspend">
26+ <property name="visible">True</property>
27+ <property name="sensitive">False</property>
28+ <property name="label" translatable="yes">Suspend Qemu</property>
29+ <property name="use_underline">True</property>
30+ <signal name="activate" handler="on_vm_suspend"/>
31+ </widget>
32+ </child>
33+ <child>
34+ <widget class="GtkMenuItem" id="vmpoweroff">
35+ <property name="visible">True</property>
36+ <property name="sensitive">False</property>
37+ <property name="label" translatable="yes">Send ACPI poweroff</property>
38+ <property name="use_underline">True</property>
39+ <signal name="activate" handler="on_vm_powerbutton"/>
40+ </widget>
41+ </child>
42+ <child>
43+ <widget class="GtkMenuItem" id="vmhardreset">
44+ <property name="visible">True</property>
45+ <property name="sensitive">False</property>
46+ <property name="label" translatable="yes">Send ACPI hard reset</property>
47+ <property name="use_underline">True</property>
48+ <signal name="activate" handler="on_vm_hardreset"/>
49+ </widget>
50+ </child>
51+ <child>
52+ <widget class="GtkSeparatorMenuItem" id="&lt;separator&gt;">
53+ <property name="visible">True</property>
54+ </widget>
55+ </child>
56+ <child>
57 <widget class="GtkImageMenuItem" id="item_reset_job">
58 <property name="label">reset job</property>
59 <property name="visible">True</property>
60@@ -6687,6 +6720,15 @@
61 </widget>
62 </child>
63 <child>
64+ <widget class="GtkMenuItem" id="vmresume">
65+ <property name="visible">True</property>
66+ <property name="sensitive">False</property>
67+ <property name="label" translatable="yes">Resume VM</property>
68+ <property name="use_underline">True</property>
69+ <signal name="activate" handler="on_vm_resume"/>
70+ </widget>
71+ </child>
72+ <child>
73 <widget class="GtkMenuItem" id="configure_brick_action">
74 <property name="visible">True</property>
75 <property name="label" translatable="yes">Configure</property>
76
77=== modified file 'virtualbricks_BrickFactory.py'
78--- virtualbricks_BrickFactory.py 2011-01-29 19:10:34 +0000
79+++ virtualbricks_BrickFactory.py 2011-01-30 10:15:09 +0000
80@@ -114,12 +114,23 @@
81 class BrickConfig():
82 def set(self,attr):
83 kv = attr.split("=")
84- if len(kv) != 2:
85+ if len(kv) < 2:
86 return False
87 else:
88- print "setting %s to '%s'" % (kv[0], kv[1])
89+ val = ''
90+ if (len(kv)) > 2:
91+ val='"'
92+ for c in kv[1:]:
93+ val+=c.lstrip('"').rstrip('"')
94+ val+="="
95+ val = val.rstrip('=') + '"'
96+
97+ else:
98+ val+=kv[1]
99+
100+ print "setting %s to '%s'" % (kv[0], val)
101 # pure magic. I love python.
102- self.__dict__[kv[0]] = kv[1]
103+ self.__dict__[kv[0]] = val
104
105
106
107@@ -313,18 +324,25 @@
108 if (self.proc == None):
109 return False
110 if self.pid > 0:
111+
112+
113 if (self.needsudo):
114 os.system(self.settings.get('sudo') + ' "kill '+ str(self.pid) + '"')
115+ elif self.internal_console is not None and self.get_type() != "Qemu":
116+ self.send('shutdown\n')
117+ print self.recv()
118 else:
119 try:
120 os.kill(self.proc.pid, 15)
121 except:
122 pass
123- self.proc.wait()
124+ if(self.proc.poll()==None):
125+ return
126 self.proc = None
127 self.need_restart_to_apply_changes = False
128 if self.close_internal_console and callable(self.close_internal_console):
129 self.close_internal_console()
130+ self.internal_console == None
131 self.post_poweroff()
132
133 def post_poweron(self):
134@@ -366,8 +384,11 @@
135 def send(self,msg):
136 if self.internal_console == None:
137 return
138- print "= sending " + msg
139- self.internal_console.send(msg)
140+ try:
141+ print "= sending " + msg
142+ self.internal_console.send(msg)
143+ except:
144+ print "send failed"
145
146 def recv(self):
147 if self.internal_console == None:
148@@ -825,7 +846,7 @@
149 self.cfg.initrd=""
150 self.cfg.gdb=""
151 self.cfg.gdbport=""
152- self.cfg.append=""
153+ self.cfg.kopt=""
154
155 self.command_builder = {
156 '#argv0':'argv0',
157@@ -878,7 +899,7 @@
158 ##acpitable not supported
159 ##smbios not supported
160 '-kernel':'kernel',
161- '#append':'append',
162+ '-append':'kopt',
163 '-initrd':'initrd',
164 #'-serial':'serial',
165 #'-parallel':'parallel',
166@@ -898,7 +919,7 @@
167 '#kvm':'kvm',
168 #'-no-reboot':'', ## not supported
169 #'-no-shutdown':'', ## not supported
170- #'-loadvm':'',
171+ '-loadvm':'loadvm',
172 #'-daemonize':'', ## not supported
173 #'-option-rom':'',
174 #'-clock':'',
175@@ -1008,9 +1029,12 @@
176 if (self.cfg.rtc== "*"):
177 res.append('-rtc')
178 res.append('base=localtime')
179-
180- if (self.cfg.append != ""):
181- res.append(self.cfg.append);
182+
183+ res.append("-mon")
184+ res.append("chardev=mon")
185+ res.append("-chardev")
186+ res.append('socket,id=mon,path='+Settings.MYPATH + '/' + self.name + '.mgmt,server')
187+ self.cfg.console=Settings.MYPATH + '/' + self.name + '.mgmt'
188 print res
189 return res
190
191
192=== modified file 'virtualbricks_GUI.py'
193--- virtualbricks_GUI.py 2011-01-29 19:10:34 +0000
194+++ virtualbricks_GUI.py 2011-01-30 10:15:09 +0000
195@@ -10,6 +10,7 @@
196 import gobject
197 import time
198 import pygraphviz as pgv
199+import subprocess
200
201
202
203@@ -734,6 +735,10 @@
204 self.Dragging = self.brickfactory.getbrickbyname(name)
205 if event.button == 3:
206 self.selected = self.brickfactory.getbrickbyname(name)
207+ if self.selected.get_type() == "Qemu":
208+ self.set_sensitivegroup(['vmresume'])
209+ else:
210+ self.set_nonsensitivegroup(['vmresume'])
211 if self.selected:
212 self.show_window('menu_brickactions')
213
214@@ -774,6 +779,8 @@
215 if b.proc is not None:
216 b.poweroff()
217 else:
218+ if b.get_type() == "Qemu":
219+ b.cfg.loadvm=''
220 try:
221 b.poweron()
222 except(BrickFactory.BadConfigException):
223@@ -808,6 +815,11 @@
224 name = self.get_treeselected_name(tree, store, pthinfo)
225 if event.button == 3:
226 self.joblist_selected = self.brickfactory.getbrickbyname(name)
227+ if self.joblist_selected.get_type()=="Qemu":
228+ self.set_sensitivegroup(['vmsuspend', 'vmpoweroff', 'vmhardreset'])
229+ else:
230+ self.set_nonsensitivegroup(['vmsuspend', 'vmpoweroff', 'vmhardreset'])
231+
232 if self.joblist_selected:
233 self.show_window('menu_popup_joblist')
234 pass
235@@ -1046,10 +1058,7 @@
236 pass
237
238 def on_item_jobmonoitor_activate(self, widget=None, data=""):
239- if self.joblist_selected.get_type() is "Qemu":
240- self.show_window('dialog_jobmonitor')
241- else:
242- self.joblist_selected.open_console()
243+ self.joblist_selected.open_console()
244 pass
245
246 def on_item_stop_job_activate(self, widget=None, data=""):
247@@ -1469,6 +1478,42 @@
248 self.gladefile.get_widget('tap_ipconfig').set_sensitive(True)
249 else:
250 self.gladefile.get_widget('tap_ipconfig').set_sensitive(False)
251+
252+ def on_vm_suspend(self, widget=None, event=None, data=""):
253+ hda = self.joblist_selected.cfg.get('basehda')
254+ if hda is None or 0 != subprocess.Popen(["qemu-img","snapshot","-c","virtualbricks",hda]).wait():
255+ self.error("Suspend/Resume not supported on this disk.")
256+ return
257+ self.joblist_selected.recv()
258+ self.joblist_selected.send("savevm virtualbricks\n")
259+ while(not self.joblist_selected.recv().startswith("(qemu")):
260+ print ".",
261+ time.sleep(1)
262+ print
263+ self.joblist_selected.poweroff()
264+
265+ def on_vm_resume(self, widget=None, event=None, data=""):
266+ hda = self.selected.cfg.get('basehda')
267+ print "resume"
268+ if os.system("qemu-img snapshot -l "+hda+" |grep virtualbricks") == 0:
269+ if self.selected.proc is not None:
270+ self.selected.send("loadvm virtualbricks\n")
271+ self.selected.recv()
272+ return
273+ else:
274+ self.selected.cfg.set("loadvm=virtualbricks")
275+ self.selected.poweron()
276+ else:
277+ self.error("Cannot find suspend point.")
278+
279+
280+ def on_vm_powerbutton(self, widget=None, event=None, data=""):
281+ self.joblist_selected.send("system_powerdown\n")
282+ self.joblist_selected.recv()
283+
284+ def on_vm_hardreset(self, widget=None, event=None, data=""):
285+ self.joblist_selected.send("system_reset\n")
286+ self.joblist_selected.recv()
287
288
289 def signals(self):
290@@ -1598,7 +1643,11 @@
291 "on_random_macaddr":self.on_random_macaddr,
292 "on_tap_config_manual":self.on_tap_config_manual,
293 "on_check_kvm_toggled":self.on_check_kvm_toggled,
294- "on_button_newimage_close_clicked": self.on_newimage_close_clicked
295+ "on_button_newimage_close_clicked": self.on_newimage_close_clicked,
296+ "on_vm_suspend":self.on_vm_suspend,
297+ "on_vm_powerbutton":self.on_vm_powerbutton,
298+ "on_vm_hardreset":self.on_vm_hardreset,
299+ "on_vm_resume":self.on_vm_resume,
300 }
301 self.gladefile.signal_autoconnect(self.signaldict)
302

Subscribers

People subscribed via source and target branches