1 # -*- coding: utf-8 -*-
3 # This file is part of Karesansui.
5 # Copyright (C) 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
20 from karesansui.lib.virt.virt import KaresansuiVirtConnection
21 from karesansui.lib.const import STORAGE_POOL_TYPE, \
22 VIRT_COMMAND_CREATE_STORAGE_POOL, STORAGE_VOLUME_FORMAT, \
23 VIRT_COMMAND_DELETE_STORAGE_POOL, STORAGE_POOL_PWD, \
24 ISCSI_DEVICE_DIR, ISCSI_COMMAND_READY_MOUNT, VENDOR_DATA_ISCSI_MOUNT_DIR
26 from karesansui.lib.utils import get_system_user_list
28 from karesansui.db.access.machine import findbyhost1
29 from karesansui.db.access._2pysilhouette import save_job_collaboration
30 from karesansui.db.access.machine2jobgroup import new as m2j_new
31 from karesansui.db.model._2pysilhouette import JobGroup, Job
33 from karesansui.gadget.hostby1networkstorage import get_iscsi_cmd
34 from pysilhouette.command import dict2command
36 from karesansui.lib.utils import is_param
37 from karesansui.lib.checker import Checker, CHECK_EMPTY, CHECK_ONLYSPACE, CHECK_STARTROOT, \
41 def validates_pool_dir(obj, now_pools):
48 if is_param(obj.input, 'pool_name'):
49 check = checker.check_string(_('Storagepool Name'),
51 CHECK_EMPTY | CHECK_ONLYSPACE,
54 if obj.input.pool_name in now_pools:
56 checker.add_error(_('%s "%s" is already exist.') % (_('Storagepool Name'), obj.input.pool_name))
59 checker.add_error(_('"%s" is required.') %_('Storagepool Name'))
62 if is_param(obj.input, 'pool_target_path'):
63 check = checker.check_directory(_('Storagepool Target Path'),
64 obj.input.pool_target_path,
65 CHECK_EMPTY | CHECK_STARTROOT | CHECK_NOTROOT
69 checker.add_error(_('"%s" is required.') %_('Storagepool Target Path'))
71 obj.view.alert = checker.errors
74 def validates_pool_iscsi(obj, now_pools):
81 if is_param(obj.input, 'pool_name'):
82 check = checker.check_string(_('Storagepool Name'),
84 CHECK_EMPTY | CHECK_ONLYSPACE,
87 if obj.input.pool_name in now_pools:
89 checker.add_error(_('%s "%s" is already exist.') % (_('Storagepool Name'), obj.input.pool_name))
92 checker.add_error(_('"%s" is required.') %_('Storagepool Name'))
95 if is_param(obj.input, 'pool_target_iscsi'):
96 check = checker.check_string(_('Storagepool Target iSCSI'),
97 obj.input.pool_target_iscsi,
98 CHECK_EMPTY | CHECK_ONLYSPACE,
103 checker.add_error(_('"%s" is required.') %_('Storagepool Target iSCSI'))
105 obj.view.alert = checker.errors
109 def create_pool_dir_job(obj, machine, name, type_, target_path, mkdir_force,
110 options={}, rollback_options={}):
111 cmdname = u"Create Storage Pool"
112 cmd = VIRT_COMMAND_CREATE_STORAGE_POOL
114 options['name'] = name
115 options["type"] = type_
116 options["target_path"] = target_path
117 options["mode"] = STORAGE_POOL_PWD["MODE"]
118 options["group"] = pwd.getpwnam(STORAGE_POOL_PWD["GROUP"])[2]
119 options["owner"] = pwd.getpwnam(STORAGE_POOL_PWD["OWNER"])[2]
121 if mkdir_force is True:
122 options["mkdir_force"] = None
125 "%s/%s" % (karesansui.config['application.bin.dir'], cmd), options)
128 rollback_options["name"] = name
129 if mkdir_force is True:
130 rollback_options["force"] = None
132 rollback_cmd = dict2command(
133 "%s/%s" % (karesansui.config['application.bin.dir'], VIRT_COMMAND_DELETE_STORAGE_POOL),
136 _jobgroup = JobGroup(cmdname, karesansui.sheconf['env.uniqkey'])
137 _job = Job('%s command' % cmdname, 0, _cmd)
139 _job.rollback_command = rollback_cmd
140 _jobgroup.jobs.append(_job)
142 _machine2jobgroup = m2j_new(machine=machine,
144 uniq_key=karesansui.sheconf['env.uniqkey'],
146 modified_user=obj.me,
149 save_job_collaboration(obj.orm,
150 obj.pysilhouette.orm,
157 def create_pool_iscsi_job(obj, machine, name, type_, host_name, device_path, automount_list,
158 options={}, rollback_options={}):
159 cmdname = u"Create Storage Pool"
160 cmd = VIRT_COMMAND_CREATE_STORAGE_POOL
162 options['name'] = name
163 options["type"] = type_
164 options["host_name"] = host_name
165 options["device_path"] = device_path
168 "%s/%s" % (karesansui.config['application.bin.dir'], cmd), options)
170 rollback_options["name"] = name
171 rollback_options["force"] = None
172 rollback_cmd = dict2command(
173 "%s/%s" % (karesansui.config['application.bin.dir'], VIRT_COMMAND_DELETE_STORAGE_POOL),
176 _jobgroup = JobGroup(cmdname, karesansui.sheconf['env.uniqkey'])
177 _job = Job('%s command' % cmdname, 0, _cmd)
178 _job.rollback_command = rollback_cmd
179 _jobgroup.jobs.append(_job)
181 _machine2jobgroup = m2j_new(machine=machine,
183 uniq_key=karesansui.sheconf['env.uniqkey'],
185 modified_user=obj.me,
188 save_job_collaboration(obj.orm,
189 obj.pysilhouette.orm,
194 automount_options = {}
195 automount_options["type"] = STORAGE_POOL_TYPE['TYPE_FS']
197 for disk in automount_list:
198 readymount_options = {}
199 readymount_options["dev"] = "%s/%s" % (ISCSI_DEVICE_DIR, disk['symlink_name'])
200 if "is_format" in disk:
201 readymount_options["format"] = None
203 automount_options["name"] = disk['symlink_name']
204 automount_options["device_path"] = "%s/%s" % (ISCSI_DEVICE_DIR, disk['symlink_name'])
205 automount_options["target_path"] = "%s/%s" % (VENDOR_DATA_ISCSI_MOUNT_DIR, disk['symlink_name'])
207 readymount_cmd = dict2command(
208 "%s/%s" % (karesansui.config['application.bin.dir'], ISCSI_COMMAND_READY_MOUNT), readymount_options)
209 readymount_job = Job('Check mount command', 0, readymount_cmd)
211 automount_cmd = dict2command(
212 "%s/%s" % (karesansui.config['application.bin.dir'], cmd), automount_options)
213 automount_job = Job('%s command' % cmdname, 1, automount_cmd)
215 jobgroup = JobGroup(cmdname, karesansui.sheconf['env.uniqkey'])
216 jobgroup.jobs.append(readymount_job)
217 jobgroup.jobs.append(automount_job)
219 machine2jobgroup = m2j_new(machine=machine,
221 uniq_key=karesansui.sheconf['env.uniqkey'],
223 modified_user=obj.me,
226 save_job_collaboration(obj.orm,
227 obj.pysilhouette.orm,
234 class HostBy1StoragePool(Rest):
237 def _GET(self, *param, **params):
238 host_id = self.chk_hostby1(param)
239 if host_id is None: return web.notfound()
241 self.view.host_id = host_id
245 kvc = KaresansuiVirtConnection()
246 inactive_pool = kvc.list_inactive_storage_pool()
247 active_pool = kvc.list_active_storage_pool()
248 pools = inactive_pool + active_pool
251 self.view.pools = pools
254 pool_obj = kvc.search_kvn_storage_pools(pool)[0]
255 pools_info.append(pool_obj.get_info())
256 if pool_obj.is_active() is True:
257 vols_obj = pool_obj.search_kvn_storage_volumes(kvc)
260 for vol_obj in vols_obj:
261 vols_info.append(vol_obj.get_info())
265 self.view.pools_info = pools_info
267 if self.is_mode_input() is True:
270 kvc = KaresansuiVirtConnection()
273 tmp_pool_obj = kvc.search_kvn_storage_pools(pool)[0]
274 tmp_pool_info = tmp_pool_obj.get_info()
275 if not tmp_pool_info['type'].lower() == "iscsi":
276 available_pools.append(pool)
278 available_pools.sort()
279 self.view.pools = available_pools
283 network_storages = get_iscsi_cmd(self, host_id)
284 if network_storages is False:
285 self.logger.debug("Get iSCSI command failed. Return to timeout")
286 return web.internalerror('Internal Server Error. (Timeout)')
288 self.view.network_storages = network_storages
289 self.view.pool_types = (STORAGE_POOL_TYPE["TYPE_DIR"],
290 STORAGE_POOL_TYPE["TYPE_ISCSI"])
292 self.view.volume_formats = (STORAGE_VOLUME_FORMAT["TYPE_QCOW2"],
293 STORAGE_VOLUME_FORMAT["TYPE_RAW"],
294 STORAGE_VOLUME_FORMAT["TYPE_QCOW"],
295 STORAGE_VOLUME_FORMAT["TYPE_COW"],
296 STORAGE_VOLUME_FORMAT["TYPE_VMDK"],
302 def _POST(self, *param, **params):
303 host_id = self.chk_hostby1(param)
304 if host_id is None: return web.notfound()
306 self.view.host_id = host_id
308 model = findbyhost1(self.orm, host_id)
311 kvc = KaresansuiVirtConnection()
313 inactive_pool = kvc.list_inactive_storage_pool()
314 active_pool = kvc.list_active_storage_pool()
318 now_pools = inactive_pool + active_pool
319 if self.input.pool_type == STORAGE_POOL_TYPE["TYPE_DIR"]:
320 if not validates_pool_dir(self, now_pools):
321 return web.badrequest(self.view.alert)
324 if is_param(self.input, 'pool_mkdir_force'):
328 if create_pool_dir_job(self,
330 self.input.pool_name,
331 self.input.pool_type,
332 self.input.pool_target_path,
335 return web.accepted()
338 elif self.input.pool_type == STORAGE_POOL_TYPE["TYPE_ISCSI"]:
339 if not validates_pool_iscsi(self, now_pools):
340 return web.badrequest(self.view.alert)
342 network_storages = get_iscsi_cmd(self, host_id)
343 if network_storages is False:
344 self.logger.debug("Get iSCSI command failed. Return to timeout")
345 return web.internalerror('Internal Server Error. (Timeout)')
347 pool_host_name = None
348 pool_device_path = None
349 for iscsi in network_storages:
350 if self.input.pool_target_iscsi == iscsi["iqn"]:
351 pool_host_name = iscsi["hostname"]
352 pool_device_path = iscsi["iqn"]
353 disk_list = iscsi["disk_list"]
356 if pool_host_name is None or pool_device_path is None:
357 return web.badrequest()
360 for disk in disk_list:
361 if is_param(self.input, "iscsi-disk-use-type-%s" % (disk['symlink_name'])):
362 if self.input["iscsi-disk-use-type-%s" % (disk['symlink_name'])] == "mount" and disk['is_partitionable'] is False:
363 if is_param(self.input, "iscsi-disk-format-%s" % (disk['symlink_name'])):
364 if self.input["iscsi-disk-format-%s" % (disk['symlink_name'])] == "true":
365 disk["is_format"] = True
366 automount_list.append(disk)
368 if create_pool_iscsi_job(self,
370 self.input.pool_name,
371 self.input.pool_type,
377 return web.accepted()
383 return web.badrequest("The type that does not exist. %s" % self.input.pool_type)
386 '/host/(\d+)/storagepool/?(\.part)$', HostBy1StoragePool,