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.
20 from karesansui.lib.rest import Rest, auth
22 from karesansui.lib.virt.virt import KaresansuiVirtException, \
23 KaresansuiVirtConnection
24 from karesansui.lib.merge import MergeGuest
25 from karesansui.lib.utils import get_ifconfig_info, generate_mac_address, is_param, \
26 generate_uuid, string_from_uuid
28 from karesansui.gadget.guestby1disk import create_disk_job, validates_disk, \
29 create_storage_volume_dir, exec_disk_job
31 from karesansui.gadget.guestby1nic import create_nic_job, validates_nic
33 from karesansui.gadget.hostby1networkstorage import get_iscsi_cmd
35 from karesansui.db.access.machine import findbyguest1
36 from karesansui.db.access._2pysilhouette import save_job_collaboration
37 from karesansui.db.access.machine2jobgroup import new as m2j_new
38 from karesansui.db.model._2pysilhouette import JobGroup, Job
40 from pysilhouette.command import dict2command
42 from karesansui.lib.const import DISK_QEMU_FORMAT, DISK_NON_QEMU_FORMAT, \
43 STORAGE_VOLUME_PWD, DISK_USES, \
44 VIRT_COMMAND_DELETE_STORAGE_VOLUME, VIRT_COMMAND_CREATE_STORAGE_VOLUME
46 from karesansui.lib.checker import Checker, \
47 CHECK_EMPTY, CHECK_VALID, CHECK_LENGTH, \
48 CHECK_STARTROOT, CHECK_EXIST, CHECK_ISDIR
50 class GuestBy1Device(Rest):
53 def _GET(self, *param, **params):
54 (host_id, guest_id) = self.chk_guestby1(param)
55 if guest_id is None: return web.notfound()
62 model = findbyguest1(self.orm, guest_id)
65 self.kvc = KaresansuiVirtConnection()
68 active_pool = self.kvc.list_active_storage_pool()
69 pools = inactive_pool + active_pool
73 return web.badrequest('One can not start a storage pool.')
75 self.view.pools = pools
77 domname = self.kvc.uuid_to_domname(model.uniq_key)
78 if not domname: return web.notfound()
80 virt = self.kvc.search_kvg_guests(domname)[0]
82 guest = MergeGuest(model, virt)
85 VMType = guest.info["virt"].get_info()["VMType"].upper()
90 phydev_regex = re.compile(r"%s" % bridge_prefix[VMType])
92 for dev,dev_info in get_ifconfig_info().iteritems():
94 if phydev_regex.match(dev):
99 phydev.append("%s0" % bridge_prefix[VMType])
102 self.view.phydev = phydev # Physical device
103 self.view.virnet = sorted(self.kvc.list_active_network()) # Virtual device
104 self.view.mac_address = generate_mac_address() # new mac address
105 self.view.ifinfo = virt.get_interface_info() # interface info
106 self.view.guest = guest # virt obj off
107 self.view.VMType = VMType
109 self.view.DISK_FORMATS = DISK_QEMU_FORMAT
111 self.view.DISK_FORMATS = DISK_NON_QEMU_FORMAT
113 self.view.bus_types = self.kvc.bus_types
115 # iscsi block device list
116 network_storages = get_iscsi_cmd(self, host_id)
117 if network_storages is False:
118 self.logger.debug("Get iSCSI command failed. Return to timeout")
119 return web.internalerror('Internal Server Error. (Timeout)')
121 self.view.network_storages = network_storages
125 # pool_obj = self.kvc.search_kvn_storage_pools(pool)[0]
126 # pool_info = pool_obj.get_info()
127 # if pool_obj.is_active() is True and pool_info['type'] == 'iscsi':
128 # vols_obj = pool_obj.search_kvn_storage_volumes(self.kvc)
130 # for vol_obj in vols_obj:
131 # vols_info.append(vol_obj.get_info())
133 # iscsi_pools[pool] = {"info" : pool_obj.get_info(),
134 # "vols" : vols_info,
136 #self.view.iscsi_pools = iscsi_pools
139 os_pool = self.kvc.get_storage_pool_name_bydomain(domname, "os")
141 return web.badrequest(_("Was found that the guest are using storage pools."))
142 self.view.os_pool = os_pool[0]
144 #self.view.pool_info = self.kvc.search_kvn_storage_pools(os_pool[0])[0].get_info()
146 for pool in self.kvc.search_kvn_storage_pools():
147 pools_info.append(pool.get_info())
148 self.view.pools_info = pools_info
151 self.view.disk_info = virt.get_disk_info() # Disk info
153 #from karesansui.lib.utils import preprint_r
154 #preprint_r(self.view.pools_info)
155 #preprint_r(self.view.pools_vols_info)
156 #import pdb; pdb.set_trace()
164 def _POST(self, *param, **params):
165 (host_id, guest_id) = self.chk_guestby1(param)
166 if guest_id is None: return web.notfound()
168 model = findbyguest1(self.orm, guest_id)
171 kvc = KaresansuiVirtConnection()
173 domname = kvc.uuid_to_domname(model.uniq_key)
174 if not domname: return web.conflict(web.ctx.path)
175 virt = kvc.search_kvg_guests(domname)[0]
176 nic_info = virt.get_interface_info()
179 if self.input.device_type == "nic":
180 if not validates_nic(self):
181 return web.badrequest(self.view.alert)
185 if x['mac']['address'] == self.input.mac_address:
189 return web.badrequest(_('Specified MAC address is already defined.'))
191 mac = self.input.mac_address
194 if self.input.nic_type == "phydev":
195 bridge = self.input.phydev
196 elif self.input.nic_type == "virnet":
197 network = self.input.virnet
199 self.logger.debug('spinning off create_nic_job dom=%s, mac=%s, bridge=%s, network=%s' \
200 % (domname, mac, bridge, network))
202 create_nic_job(self,model,domname,mac,bridge,network)
203 return web.accepted()
206 elif self.input.device_type == "disk":
207 if not validates_disk(self):
208 return web.badrequest(self.view.alert)
212 if self.input.disk_layout == "create": # create(dir)
214 volume_name = string_from_uuid(generate_uuid())
215 volume_job = create_storage_volume_dir(self,
220 self.input.disk_format,
221 self.input.disk_size,
222 self.input.disk_size,
227 pool_name = self.input.pool_dir
228 elif self.input.disk_layout == "iscsi": # create(iscsi block)
230 pool_name = self.input.pool_dir
231 target_storage = kvc.get_storage_volume_iscsi_bysymlink(self.input.iscsi_block)
232 pool_name = target_storage['pool']
233 volume_name = target_storage['volume']
235 return badrequest(_("No storage type specified."))
238 disk_job = create_disk_job(self,
243 bus=self.input.bus_type,
244 format=self.input.disk_format,
249 if exec_disk_job(obj=self,
252 volume_job=volume_job,
255 return web.accepted()
265 '/host/(\d+)/guest/(\d+)/device/?(\.part|\.html)?$', GuestBy1Device,