1 # -*- coding: utf-8 -*-
3 # This file is part of Karesansui.
5 # Copyright (C) 2009-2010 HDE, Inc.
7 # This program is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU General Public License
9 # as published by the Free Software Foundation; either version 2
10 # of the License, or (at your option) any later version.
16 from web.utils import Storage
19 from karesansui.lib.rest import Rest, auth
21 from karesansui.lib.utils import \
22 comma_split, uniq_sort, is_param, json_dumps
24 from karesansui.lib.checker import Checker, \
25 CHECK_EMPTY, CHECK_LENGTH, CHECK_ONLYSPACE
27 from karesansui.lib.const import \
28 NOTE_TITLE_MIN_LENGTH, NOTE_TITLE_MAX_LENGTH, \
29 MACHINE_NAME_MIN_LENGTH, MACHINE_NAME_MAX_LENGTH, \
30 TAG_MIN_LENGTH, TAG_MAX_LENGTH, \
31 VIRT_COMMAND_DELETE_GUEST, VIRT_COMMAND_DELETE_STORAGE_VOLUME, \
34 from karesansui.lib.virt.virt import KaresansuiVirtConnection
35 from karesansui.lib.merge import MergeGuest
37 from karesansui.db.access.machine import \
38 findbyguest1, findby1name, logical_delete, \
39 update as m_update, delete as m_delete
41 from karesansui.db.access.machine2jobgroup import new as m2j_new
42 from karesansui.db.access._2pysilhouette import save_job_collaboration
43 from karesansui.db.access.tag import \
44 new as t_new, samecount as t_count, findby1name as t_name
46 from karesansui.db.model._2pysilhouette import Job, JobGroup
48 from karesansui.gadget.guestby1diskby1 import delete_storage_volume, delete_disk_job
49 from pysilhouette.command import dict2command
51 def validates_guest_edit(obj):
58 if not is_param(obj.input, 'm_name'):
60 checker.add_error(_('Parameter m_name does not exist.'))
62 check = checker.check_string(
65 CHECK_EMPTY | CHECK_LENGTH | CHECK_ONLYSPACE,
67 min = MACHINE_NAME_MIN_LENGTH,
68 max = MACHINE_NAME_MAX_LENGTH,
71 if is_param(obj.input, 'note_title'):
72 check = checker.check_string(
75 CHECK_LENGTH | CHECK_ONLYSPACE,
77 min = NOTE_TITLE_MIN_LENGTH,
78 max = NOTE_TITLE_MAX_LENGTH,
81 if is_param(obj.input, 'note_value'):
82 check = checker.check_string(
92 if is_param(obj.input, 'tags'):
93 for tag in comma_split(obj.input.tags):
94 check = checker.check_string(
97 CHECK_LENGTH | CHECK_ONLYSPACE,
100 max = TAG_MAX_LENGTH,
103 obj.view.alert = checker.errors
106 class GuestBy1(Rest):
109 ret = Rest._post(self, f)
110 if hasattr(self, "kvc") is True:
115 def _GET(self, *param, **params):
116 (host_id, guest_id) = self.chk_guestby1(param)
118 return web.notfound()
120 model = findbyguest1(self.orm, guest_id)
122 self.kvc = KaresansuiVirtConnection()
123 if self.is_mode_input() is True:
125 domname = self.kvc.uuid_to_domname(model.uniq_key)
127 return web.notfound()
129 virt = self.kvc.search_kvg_guests(domname)[0]
130 guest = MergeGuest(model, virt)
131 self.view.model = guest.info["model"]
138 domname = self.kvc.uuid_to_domname(model.uniq_key)
140 return web.notfound()
142 virt = self.kvc.search_kvg_guests(domname)[0]
144 guest = MergeGuest(model, virt)
146 guest_info = guest.info["virt"].get_info()
148 info['memory'] = guest_info["memory"]
149 info['cpu'] = guest_info["cpuTime"]
150 info['os'] = guest_info["OSType"]
151 info['hypervisor'] = guest_info["hypervisor"]
152 info['type'] = guest_info["VMType"]
153 info['hv_version'] = guest_info["hv_version"]
155 guest_diskinfo = guest.info["virt"].get_disk_info()
157 for disk in guest_diskinfo:
158 disks.append("%s(%sMB)" % (disk['target']['dev'],disk['source']['size']))
164 guest_interfaceinfo = guest.info["virt"].get_interface_info()
165 for inter in guest_interfaceinfo:
166 inters.append(inter["type"])
168 nics.append(inter["source"]["bridge"])
171 interfaceinfo = inters
174 guest_netinfo = guest.info["virt"].get_netinfo()
175 for nic in guest_netinfo.keys():
179 #pool_name = self.kvc.get_storage_pool_name_bydomain(domname)[0]
180 #pool = self.kvc.search_kvn_storage_pools(pool_name)[0]
181 #poolinfo = pool.get_info()
184 if self.__template__["media"] == 'json':
185 json_guest = guest.get_json(self.me.languages)
186 self.view.data = json_dumps(
188 "model": json_guest["model"],
189 "virt": json_guest["virt"],
190 "autostart": guest.info["virt"].autostart(),
192 "diskinfo": diskinfo,
194 "interfaceinfo": interfaceinfo,
199 self.view.model = guest.info["model"]
200 self.view.virt = guest.info["virt"]
201 self.view.autostart = guest.info["virt"].autostart()
202 self.view.info = info
203 self.view.diskinfo = diskinfo
204 self.view.netinfo = netinfo
205 self.view.interfaceinfo = interfaceinfo
206 self.view.poolinfo = poolinfo
214 def _PUT(self, *param, **params):
216 (host_id, guest_id) = self.chk_guestby1(param)
218 return web.notfound()
220 if not validates_guest_edit(self):
221 self.logger.debug("Update Guest OS is failed, Invalid input value.")
222 return web.badrequest(self.view.alert)
224 guest = findbyguest1(self.orm, guest_id)
227 if is_param(self.input, "note_title"):
228 guest.notebook.title = self.input.note_title
229 if is_param(self.input, "note_value"):
230 guest.notebook.value = self.input.note_value
232 if is_param(self.input, "m_name"):
233 guest.name = self.input.m_name
237 if is_param(self.input, "icon_filename", empty=True):
238 guest.icon = self.input.icon_filename
241 if is_param(self.input, "tags"):
243 tag_array = comma_split(self.input.tags)
244 tag_array = uniq_sort(tag_array)
246 if t_count(self.orm, x) == 0:
247 _tags.append(t_new(x))
249 _tags.append(t_name(self.orm, x))
252 guest.modified_user = self.me
254 m_update(self.orm, guest)
255 return web.seeother(web.ctx.path)
259 def _DELETE(self, *param, **params):
260 (host_id, guest_id) = self.chk_guestby1(param)
262 return web.notfound()
264 model = findbyguest1(self.orm, guest_id)
266 self.kvc = KaresansuiVirtConnection()
268 domname = self.kvc.uuid_to_domname(model.uniq_key)
270 self.logger.info("Did not exist in libvirt. - guestid=%s" % model.id)
271 logical_delete(self.orm, model)
272 # TODO ファイルシステムにゴミが残るので、delete_guest.pyを実行する必要がある。
274 return web.nocontent()
276 kvg_guest = self.kvc.search_kvg_guests(domname)
278 return web.badrequest(_("Guest OS not found. - name=%s") % domname)
280 kvg_guest = kvg_guest[0]
282 if kvg_guest.is_active():
285 return web.badrequest(_("Can not delete a running guest OS. - name=%s") % domname)
292 for disk in kvg_guest.get_disk_info():
293 if disk['type'] == 'file': # type="dir"
294 # delete_storage_volume
295 pool = self.kvc.get_storage_pool_name_byimage(disk['source']['file'])
297 return web.badrequest(_("Can not find the storage pool is not running. - target=%s") % (disk['source']['file']))
301 disk_volumes = self.kvc.get_storage_volume_bydomain(domname, 'disk', 'key')
303 for key in disk_volumes.keys():
304 if disk['source']['file'] == os.path.realpath(disk_volumes[key]):
305 volume = key # disk image
307 use = DISK_USES['DISK']
308 if volume is None: # os image
309 os_volume = self.kvc.get_storage_volume_bydomain(domname, 'os', 'key')
311 return web.badrequest(_("Guest OS disk could not be found."))
313 if disk['source']['file'] == os.path.realpath(os_volume.values()[0]):
314 use = DISK_USES['IMAGES']
315 volume = os_volume.keys()[0]
316 os_storage["pool"] = pool
317 os_storage["volume"] = volume
318 continue # OS delete command to do "VIRT_COMMAND_DELETE_GUEST" image.
320 jobs.append(delete_storage_volume(self,
328 jobs.append(delete_disk_job(self,
330 disk["target"]["dev"],
334 elif disk['type'] == 'block': # type="iscsi"
336 pool = self.kvc.get_storage_pool_name_byimage(disk['source']['dev'])
338 return web.badrequest(_("Can not find the storage pool is not running."))
342 os_volume = self.kvc.get_storage_volume_bydomain(domname, 'os', 'key')
344 return web.badrequest(_("Storage volume could not be found."))
346 volume = os_volume.values()[0]
347 if disk['source']['dev'] == volume:
348 os_storage["pool"] = pool
349 os_storage["volume"] = volume
350 continue # OS delete command to do "VIRT_COMMAND_DELETE_GUEST" image.
353 jobs.append(delete_disk_job(self,
355 disk["target"]["dev"],
359 return web.internalerror(
360 _("Not expected storage type. type=%") % disk['type'])
364 cmdname = "Delete Guest"
365 _jobgroup = JobGroup(cmdname, karesansui.sheconf['env.uniqkey'])
366 _jobgroup.jobs = jobs # Set Disk
367 action_cmd = dict2command(
368 "%s/%s" % (karesansui.config['application.bin.dir'], VIRT_COMMAND_DELETE_GUEST),
370 "pool" : os_storage["pool"],
371 "volume" : os_storage["volume"],
375 _job = Job('%s command' % cmdname, order, action_cmd)
376 _jobgroup.jobs.append(_job)
378 logical_delete(self.orm, model)
380 _machine2jobgroup = m2j_new(machine=model,
382 uniq_key=karesansui.sheconf['env.uniqkey'],
383 created_user=self.me,
384 modified_user=self.me,
387 save_job_collaboration(self.orm,
388 self.pysilhouette.orm,
393 return web.accepted(url = web.ctx.path)
395 #self.kvc.close() GuestBy1#_post
399 '/host/(\d+)/guest/(\d+)/?(\.html|\.part|\.json)?$', GuestBy1,