None,
) and check
- if is_param(obj.input, 'vm_disk_size'):
- check = checker.check_number(
- _('Disk Size (MB)'),
- obj.input.vm_disk_size,
- CHECK_VALID | CHECK_MIN | CHECK_EMPTY,
- DISK_MIN_SIZE,
- None,
- ) and check
+ if is_param(obj.input, 'pool_type'):
+ if obj.input.pool_type != "block":
+ if is_param(obj.input, 'vm_disk_size'):
+ check = checker.check_number(
+ _('Disk Size (MB)'),
+ obj.input.vm_disk_size,
+ CHECK_VALID | CHECK_MIN | CHECK_EMPTY,
+ DISK_MIN_SIZE,
+ None,
+ ) and check
if not is_param(obj.input, 'boot_image'):
check = False
if not pools:
return web.badrequest('One can not start a storage pool.')
- self.view.pools = pools
- pools_info = {}
- pools_vols_info = {}
-
- for pool in pools:
- pool_obj = self.kvc.search_kvn_storage_pools(pool)[0]
- if pool_obj.is_active() is True:
- vols_obj = pool_obj.search_kvn_storage_volumes(self.kvc)
- vols_info = {}
- for vol_obj in vols_obj:
- vol_name = vol_obj.get_storage_volume_name()
- vols_info[vol_name] = vol_obj.get_info()
-
- pools_vols_info[pool] = vols_info
-
- pools_info[pool] = pool_obj.get_info()
-
- self.view.pools_info = pools_info
- self.view.pools_vols_info = pools_vols_info
-
# Output .input
if self.is_mode_input() is True:
+ self.view.pools = pools
+ pools_info = {}
+ pools_vols_info = {}
+ pools_iscsi_blocks = {}
+ already_vols = []
+ guests = []
+
+ guests += self.kvc.list_inactive_guest()
+ guests += self.kvc.list_active_guest()
+ for guest in guests:
+ already_vol = self.kvc.get_storage_volume_bydomain(domain=guest,
+ image_type=None,
+ attr='path')
+ if already_vol:
+ already_vols += already_vol.keys()
+
+ for pool in pools:
+ pool_obj = self.kvc.search_kvn_storage_pools(pool)[0]
+ if pool_obj.is_active() is True:
+ pools_info[pool] = pool_obj.get_info()
+
+ blocks = None
+ if pools_info[pool]['type'] == 'iscsi':
+ blocks = self.kvc.get_storage_volume_iscsi_block_bypool(pool)
+ if blocks:
+ pools_iscsi_blocks[pool] = []
+ vols_obj = pool_obj.search_kvn_storage_volumes(self.kvc)
+ vols_info = {}
+
+ for vol_obj in vols_obj:
+ vol_name = vol_obj.get_storage_volume_name()
+ vols_info[vol_name] = vol_obj.get_info()
+ if blocks:
+ if vol_name in blocks and vol_name not in already_vols:
+ pools_iscsi_blocks[pool].append(vol_obj.get_info())
+
+ pools_vols_info[pool] = vols_info
+
+ self.view.pools_info = pools_info
+ self.view.pools_vols_info = pools_vols_info
+ self.view.pools_iscsi_blocks = pools_iscsi_blocks
+
bridge_prefix = {
"XEN":"xenbr",
- "KVM":"(eth|bond)",
+ "KVM":"(eth|bondbr)",
}
self.view.host_id = host_id
self.view.DEFAULT_KEYMAP = DEFAULT_KEYMAP
guests_json = []
for x in guests:
guests_json.append(x.get_json(self.me.languages))
-
+
self.view.guests = json_dumps(guests_json)
else:
self.view.exports = exports
model = findbyhost1(self.orm, host_id)
+ import pdb; pdb.set_trace()
+
uris = available_virt_uris()
if model.attribute == 0 and model.hypervisor == 1:
uri = uris["XEN"]
used_mac_addrs = self.kvc.list_used_mac_addr()
mem_info = self.kvc.get_mem_info()
- if is_param(self.input, "disk_layout") and \
- self.input.disk_layout == "create" and \
+ if is_param(self.input, "pool_type") and \
+ self.input.pool_type != "block" and \
is_param(self.input, "pool_dir"):
target_path = self.kvc.get_storage_pool_targetpath(self.input.pool_dir)
if target_path: # disk
options['keymap'] = self.input.keymap
is_create = False
- if is_param(self.input, "disk_layout"):
+ if is_param(self.input, "pool_type"):
if is_param(self.input, "bus_type"):
options['bus'] = self.input.bus_type
- if self.input.disk_layout == "create": # create volume
+ if self.input.pool_type == "dir" or self.input.pool_type == "fs": # create volume
is_create = True
options['disk-format'] = self.input.disk_format
options["storage-pool"] = self.input.pool_dir
options["storage-volume"] = options['name'] # default domain name
options['disk-size'] = self.input.vm_disk_size
- elif self.input.disk_layout == "iscsi": # iscsi volume TODO
- if is_param(self.input, "iscsi_pool") and is_param(self.input, "iscsi_volume"):
- options["storage-pool"] = self.input.iscsi_pool
- options["storage-volume"] = self.input.iscsi_volume
- else:
- return web.badrequest()
+ elif self.input.pool_type == "block": # iscsi block device
+ (iscsi_pool, iscsi_volume) = self.input.pool_dir.split("/", 2)
+ options["storage-pool"] = iscsi_pool
+ options["storage-volume"] = iscsi_volume
else:
return web.badrequest()
else:
bridge_prefix = {
"XEN":"xenbr",
- "KVM":"eth",
+ "KVM":"eth|bondbr",
}
model = findbyguest1(self.orm, guest_id)
# virt
self.kvc = KaresansuiVirtConnection()
try:
- inactive_pool = []
- active_pool = self.kvc.list_active_storage_pool()
- pools = inactive_pool + active_pool
- pools.sort()
-
- if not pools:
- return web.badrequest('One can not start a storage pool.')
-
- self.view.pools = pools
-
domname = self.kvc.uuid_to_domname(model.uniq_key)
- if not domname: return web.notfound()
-
+ if not domname:
+ return web.notfound()
virt = self.kvc.search_kvg_guests(domname)[0]
-
guest = MergeGuest(model, virt)
+ self.view.guest = guest
- try:
- VMType = guest.info["virt"].get_info()["VMType"].upper()
- except:
- VMType = "KVM"
-
- phydev = []
- phydev_regex = re.compile(r"%s" % bridge_prefix[VMType])
-
- for dev,dev_info in get_ifconfig_info().iteritems():
+ # Output .input
+ if self.is_mode_input() is True:
try:
- if phydev_regex.match(dev):
- phydev.append(dev)
+ VMType = guest.info["virt"].get_info()["VMType"].upper()
except:
- pass
- if len(phydev) == 0:
- phydev.append("%s0" % bridge_prefix[VMType])
-
- phydev.sort()
- self.view.phydev = phydev # Physical device
- self.view.virnet = sorted(self.kvc.list_active_network()) # Virtual device
- self.view.mac_address = generate_mac_address() # new mac address
- self.view.ifinfo = virt.get_interface_info() # interface info
- self.view.guest = guest # virt obj off
- self.view.VMType = VMType
- if VMType == "KVM":
- self.view.DISK_FORMATS = DISK_QEMU_FORMAT
- else:
- self.view.DISK_FORMATS = DISK_NON_QEMU_FORMAT
-
- self.view.bus_types = self.kvc.bus_types
-
- # iscsi block device list
- network_storages = get_iscsi_cmd(self, host_id)
- if network_storages is False:
- self.logger.debug("Get iSCSI command failed. Return to timeout")
- return web.internalerror('Internal Server Error. (Timeout)')
-
- self.view.network_storages = network_storages
-
- #iscsi_pools = {}
- #for pool in pools:
- # pool_obj = self.kvc.search_kvn_storage_pools(pool)[0]
- # pool_info = pool_obj.get_info()
- # if pool_obj.is_active() is True and pool_info['type'] == 'iscsi':
- # vols_obj = pool_obj.search_kvn_storage_volumes(self.kvc)
- # vols_info = []
- # for vol_obj in vols_obj:
- # vols_info.append(vol_obj.get_info())
- #
- # iscsi_pools[pool] = {"info" : pool_obj.get_info(),
- # "vols" : vols_info,
- # }
- #self.view.iscsi_pools = iscsi_pools
-
- # os pool info
- os_pool = self.kvc.get_storage_pool_name_bydomain(domname, "os")
- if not os_pool:
- return web.badrequest(_("Was found that the guest are using storage pools."))
- self.view.os_pool = os_pool[0]
-
- #self.view.pool_info = self.kvc.search_kvn_storage_pools(os_pool[0])[0].get_info()
- pools_info = []
- for pool in self.kvc.search_kvn_storage_pools():
- pools_info.append(pool.get_info())
- self.view.pools_info = pools_info
-
- # disk
- self.view.disk_info = virt.get_disk_info() # Disk info
-
- #from karesansui.lib.utils import preprint_r
- #preprint_r(self.view.pools_info)
- #preprint_r(self.view.pools_vols_info)
- #import pdb; pdb.set_trace()
+ VMType = "KVM"
+
+ self.view.VMType = VMType
+
+ # Network
+ phydev = []
+ phydev_regex = re.compile(r"%s" % bridge_prefix[VMType])
+
+ for dev,dev_info in get_ifconfig_info().iteritems():
+ try:
+ if phydev_regex.match(dev):
+ phydev.append(dev)
+ except:
+ pass
+ if len(phydev) == 0:
+ phydev.append("%s0" % bridge_prefix[VMType])
+
+ phydev.sort()
+ self.view.phydev = phydev # Physical device
+ self.view.virnet = sorted(self.kvc.list_active_network()) # Virtual device
+ self.view.mac_address = generate_mac_address() # new mac address
+
+ # Disk
+ inactive_pool = []
+ active_pool = self.kvc.list_active_storage_pool()
+ pools = inactive_pool + active_pool
+ pools.sort()
+
+ if not pools:
+ return web.badrequest('One can not start a storage pool.')
+
+ pools_info = {}
+ pools_vols_info = {}
+ pools_iscsi_blocks = {}
+ already_vols = []
+ guests = []
+
+ guests += self.kvc.list_inactive_guest()
+ guests += self.kvc.list_active_guest()
+ for guest in guests:
+ already_vol = self.kvc.get_storage_volume_bydomain(domain=guest,
+ image_type=None,
+ attr='path')
+ if already_vol:
+ already_vols += already_vol.keys()
+
+ for pool in pools:
+ pool_obj = self.kvc.search_kvn_storage_pools(pool)[0]
+ if pool_obj.is_active() is True:
+ pools_info[pool] = pool_obj.get_info()
+
+ blocks = None
+ if pools_info[pool]['type'] == 'iscsi':
+ blocks = self.kvc.get_storage_volume_iscsi_block_bypool(pool)
+ if blocks:
+ pools_iscsi_blocks[pool] = []
+ vols_obj = pool_obj.search_kvn_storage_volumes(self.kvc)
+ vols_info = {}
+
+ for vol_obj in vols_obj:
+ vol_name = vol_obj.get_storage_volume_name()
+ vols_info[vol_name] = vol_obj.get_info()
+ if blocks:
+ if vol_name in blocks and vol_name not in already_vols:
+ pools_iscsi_blocks[pool].append(vol_obj.get_info())
+
+ pools_vols_info[pool] = vols_info
+
+ self.view.pools = pools
+ self.view.pools_info = pools_info
+ self.view.pools_vols_info = pools_vols_info
+ self.view.pools_iscsi_blocks = pools_iscsi_blocks
+
+ if VMType == "KVM":
+ self.view.DISK_FORMATS = DISK_QEMU_FORMAT
+ else:
+ self.view.DISK_FORMATS = DISK_NON_QEMU_FORMAT
+
+ self.view.bus_types = self.kvc.bus_types
+
+ else: # .part
+ self.view.ifinfo = virt.get_interface_info() # interface info
+ self.view.disk_info = virt.get_disk_info() # Disk info
finally:
self.kvc.close()
volume_job = None
order = 0
- if self.input.disk_layout == "create": # create(dir)
+ if self.input.pool_type == "dir" or self.input.pool_type == "fs": # create(dir)
disk_type = 'file'
+ pool_name = self.input.pool_dir
volume_name = string_from_uuid(generate_uuid())
volume_job = create_storage_volume_dir(self,
model,
order)
order += 1
- pool_name = self.input.pool_dir
- elif self.input.disk_layout == "iscsi": # create(iscsi block)
+ elif self.input.pool_type == "block": # create(iscsi block)
disk_type = 'iscsi'
- pool_name = self.input.pool_dir
- target_storage = kvc.get_storage_volume_iscsi_bysymlink(self.input.iscsi_block)
- pool_name = target_storage['pool']
- volume_name = target_storage['volume']
+ (iscsi_pool, iscsi_volume) = self.input.pool_dir.split("/", 2)
+ pool_name = iscsi_pool
+ volume_name = iscsi_volume
+
else:
return badrequest(_("No storage type specified."))
break
return ret
+ def get_storage_volume_iscsi_block_bypool(self, pool):
+ """<comment-ja>
+ ストレージプールの名前からiSCSIブロックデバイスのボリュームの一覧を取得する
+ @param pool: プール名
+ @return: ストレージボリューム名の配列
+ @rtype: dict
+ </comment-ja>
+ <comment-en>
+ TODO: English Comment
+ </comment-en>
+ """
+ retval = []
+
+ try:
+ inactive_pool = self.list_inactive_storage_pool()
+ active_pool = self.list_active_storage_pool()
+ pools = inactive_pool + active_pool
+
+ pool_obj = self.search_kvn_storage_pools(pool)[0]
+ if not pool_obj:
+ raise KaresansuiVirtException(_("No storage pool '%s' could be found.") % pool)
+
+ vols = pool_obj.vol_listVolumes()
+ for vol in vols:
+ vol_obj = pool_obj.vol_storageVolLookupByName(vol)
+ vol_key = vol_obj.key()
+ vol_key = vol_key.replace("%s/" % (ISCSI_DEVICE_DIR), "")
+ regex = re.compile(r"^%s" % (re.escape(vol_key)))
+ is_mount = False
+ for pool in pools:
+ if regex.match(pool):
+ is_mount = True
+
+ if is_mount is False:
+ retval.append(vol)
+ except:
+ pass
+
+ return retval
+
class KaresansuiVirtGuest:
background-color: #a9cf15;
}
+#input_device .grayout-detail {
+ border: 1px solid #BCBCBC;
+ width: 100%;
+ margin: 5px 0px;
+}
+#input_device .detail-contents {
+ width: 100%;
+}
+#input_device .detail-separator{
+ height:18px;
+ width:60px;
+}
+#input_device .detail-space {
+ background:transparent url(${ctx.homepath}/static/images/kugiri-a.gif) repeat scroll 0 0;
+ height:4px;
+ margin-bottom:8px;
+ margin-top:8px;
+ width:100%;
+}
+#input_device table.detail-contents>tbody>tr>th{
+ font-weight: bold;
+ background-color: #FFFFFF;
+ padding:0px 10px;
+ width:20%;
+ text-align: left;
+ white-space: nowrap;
+}
+#input_device table.detail-contents>tbody>tr>td{
+ background-color: #FFFFFF;
+}
margin-left:12px;
width:95%;
}
+
+#input_guest .grayout-detail {
+ border: 1px solid #BCBCBC;
+ width: 100%;
+ margin: 5px 0px;
+}
+#input_guest .detail-contents {
+ width: 100%;
+}
+#input_guest .detail-separator{
+ height:18px;
+ width:60px;
+}
+#input_guest .detail-space {
+ background:transparent url(${ctx.homepath}/static/images/kugiri-a.gif) repeat scroll 0 0;
+ height:4px;
+ margin-bottom:8px;
+ margin-top:8px;
+ width:100%;
+}
+#input_guest table.detail-contents>tbody>tr>th{
+ font-weight: bold;
+ background-color: #FFFFFF;
+ padding:0px 10px;
+ width:20%;
+ text-align: left;
+ white-space: nowrap;
+}
+#input_guest table.detail-contents>tbody>tr>td{
+ background-color: #FFFFFF;
+}
}
$(document).ready(function(){
- // TODO: ストレージプール毎に最大値等を設定する
set_simple_slider("#disk_slider", "#vm_disk_size", 0, ${int(pools_info['default']['available']) / (1024 * 1024)}, ${int(pools_info['default']['available']) / (1024 * 1024)});
$("#pool_dir").change(function(){
var pool_name = $('option:selected', this).val();
var disk_type = $('option:selected', this).parent('optgroup').attr('label');
+ $("#pool_type").val(disk_type);
if(disk_type == 'block'){
- var parts = pool_name.split("_");
+ var parts = pool_name.split("/");
var vol_name = parts[1];
var vols_info = new Array();
-% for pool_name in sorted(pools_vols_info.keys()):
-% for vol_name in sorted(pools_vols_info[pool_name].keys()):
+% for pool_name in pools_iscsi_blocks.keys():
+% for vol_info in pools_iscsi_blocks[pool_name]:
var vol_info = new Array();
- vol_info['capacity'] = "${pools_vols_info[pool_name][vol_name]['capacity']}";
- vols_info["${vol_name}"] = vol_info;
+ vol_info['capacity'] = "${vol_info['capacity']}";
+ vol_info['path'] = "${vol_info['target']['path']}";
+ vol_info['realpath'] = "${vol_info['real']['dir']}/${vol_info['real']['name']}";
+ vols_info["${vol_info['name']}"] = vol_info;
% endfor
% endfor
var disk_capacity = Math.floor(vols_info[vol_name]['capacity'] / (1024 * 1024));
$("#disk_available_box").hide();
$("#disk_capacity_value_box").html(disk_capacity);
$("#disk_format_box").hide();
+ $("#disk_path_value_box").html(vols_info[vol_name]['path']);
+ $("#disk_realpath_value_box").html(vols_info[vol_name]['realpath']);
+ $("#disk_path_box").show();
+ $("#disk_realpath_box").show();
} else { // type is 'dir' or 'fs'
var pools_info = new Array();
% for pool_name in pools_info.keys():
$("#disk_available_value_box").html(disk_available);
$("#disk_capacity_value_box").html(disk_capacity);
$("#disk_format_box").show();
- }
-
- });
-
- $("#pool_iscsi_list").tablesorter({
- widgets: ['zebra', 'select'],
- headers: {
- 0: {sorter:false}
+ $("#disk_path_box").hide();
+ $("#disk_realpath_box").hide();
}
+
});
+ $("#disk_path_box").hide();
+ $("#disk_realpath_box").hide();
setDefaultValue();
$("#mem_slider").slider({
validates_guest
);
-
- $("tr[id*='pool_iscsi_row_']").each(function(){
- $(this).one('click.once', function(){
- var selc = $(this).attr("id").replace("pool_iscsi_row_", "").split("_");
- var pool = selc[0];
- var volume = selc[1];
-
- $("#iscsi_pool").attr("value", pool);
- $("#iscsi_volume").attr("value", volume);
- //selected_row()
- });
- });
-
//help
- helptip("#guest_name_help",
- "${_('Guest Name')}",
+ helptip("#guest_name_help",
+ "${_('Guest Name')}",
"${_('Name of the guest. This will be used in Karesansui control panel. Any letters, including spaces and symbols are allowed.')}");
- helptip("#guest_domain_name_help",
- "${_('Domain Name')}",
+ helptip("#guest_domain_name_help",
+ "${_('Domain Name')}",
"${_(r'VM domain name of the guest. This will be used to distinguish each guests in VM, so it should be unique between all guests (This is NOT a DNS \"domain\"). Alphabets and some symbols are allowed.')}");
- helptip("#guest_icon_help",
- "${_('Guest Icon')}",
+ helptip("#guest_icon_help",
+ "${_('Guest Icon')}",
"${_('Icon image to be used in Karesansui control panel. Choose the file and click upload button.')}");
- helptip("#guest_memory_help",
- "${_('Memory Size')}",
+ helptip("#guest_memory_help",
+ "${_('Memory Size')}",
"${_('The amount of RAM for the guest to use (in mega-bytes).')}");
// TRANSLATORS:
"${_('VNC Keymap')}",
"${_('Keymap of the keyboard to use with VNC.')}");
- helptip("#guest_disk_help",
- "${_('Disk Size')}",
+ helptip("#guest_disk_help",
+ "${_('Disk Size')}",
"${_('Size of the disk of the guest (MB)')}");
- helptip("#guest_kernel_help",
- "${_('Kernel Image')}",
+ helptip("#guest_kernel_help",
+ "${_('Kernel Image')}",
"${_('Kernel image for the guest. Specify FTP/HTTP URL, or a valid absolute file path.')}");
-
- helptip("#guest_initrd_help",
- "${_('Initrd Image')}",
+
+ helptip("#guest_initrd_help",
+ "${_('Initrd Image')}",
"${_('The initrd (bootup RAM disk) image for the guest. Specify FTP/HTTP URL, or a valid absolute file path.')}");
- helptip("#guest_iso_help",
- "${_('ISO Image')}",
+ helptip("#guest_iso_help",
+ "${_('ISO Image')}",
"${_('The ISO 9660 CD-ROM/DVD-ROM image for the guest. Specify a valid absolute file path.')}");
- helptip("#guest_vnc_port_help",
- "${_('VNC Port Number')}",
+ helptip("#guest_vnc_port_help",
+ "${_('VNC Port Number')}",
"${_('(Auto-recommended value displayed below.) TCP port number to access the guest with VNC. Numbers greater than 5900 are allowed. Unique number between all guests are recommended.')}");
- helptip("#guest_interface_type_help",
- "${_('Interface Type')}",
+ helptip("#guest_interface_type_help",
+ "${_('Interface Type')}",
"${_(r'Type of the virtual network interface connection. Choose \"Physical Device\" to connect directly to the physical network, or \"Virtual Network\" to connect guest to the virtual network (which are in \"Network\" tab of the host). ')}");
- helptip("#guest_mac_address_help",
- "${_('MAC Address')}",
+ helptip("#guest_mac_address_help",
+ "${_('MAC Address')}",
"${_('(Auto-recommended value displayed below.) MAC address of the guest in xx:xx:xx:xx:xx:xx format. Specify an address not used in the network.')}");
- helptip("#guest_option_help",
- "${_('Extra Kernel Options')}",
+ helptip("#guest_option_help",
+ "${_('Extra Kernel Options')}",
"${_('Kernel parameters to pass to the guest kernel on guest installation.')}");
- helptip("#guest_tag_help",
- "${_('Tag')}",
+ helptip("#guest_tag_help",
+ "${_('Tag')}",
"${_(r'Tag to add to the guest to be used in Karesansui control panel. Can be used to search guests using tags in the \"Guests\" panel. Separate tags with commas to specify two or more tags. Any letters, including spaces and symbols are allowed.')}");
});
// -->
</span>
<br style="clear: both;"/>
</div>
-
+
<div class="grayout-contents">
<div class="grayout-param">${_('Guest Name')}<span id="guest_name_help"/></div>
<div class="grayout-value grayout-form">
<div class="grayout-param">${_('Storage Type')}<span id="disk_layout_help"/></div>
<div class="grayout-value grayout-form">
-<style type="text/css">
-.grayout-detail {
- border: 1px solid #BCBCBC;
- width: 100%;
- margin: 5px 0px;
-}
-.detail-contents {
- width: 100%;
-}
-.detail-separator{
- height:18px;
- width:60px;
-}
-.detail-space {
- background:transparent url(${ctx.homepath}/static/images/kugiri-a.gif) repeat scroll 0 0;
- height:4px;
- margin-bottom:8px;
- margin-top:8px;
- width:100%;
-}
-table.detail-contents>tbody>tr>th{
- font-weight: bold;
- background-color: #FFFFFF;
- padding:0px 10px;
- width:20%;
- text-align: left;
- white-space: nowrap;
-}
-table.detail-contents>tbody>tr>td{
- background-color: #FFFFFF;
-}
-</style>
${_("Storage Pool Name")} :
<select id="pool_dir" name="pool_dir">
-<!--
-TODO: iscsiのストレージプールを表示させない。dir, fsのみ表示させる。
--->
% for group_type in ['dir', 'fs', 'block']:
<optgroup label="${group_type}">
% for name in sorted(pools_info.keys()):
% endif
% if group_type == 'block' and pools_info[name]['type'] == 'iscsi':
-% for vol_name in sorted(pools_vols_info[name].keys()):
- <option value="${name}_${vol_name}">${name}/${vol_name}</option>
-% endfor
+% if name in pools_iscsi_blocks:
+% for vol_info in pools_iscsi_blocks[name]:
+ <option value="${name}/${vol_info['name']}">${name} - ${vol_info['name']}</option>
+% endfor
+% endif
% endif
% endfor
</optgroup>
% endfor
</select>
<div class="grayout-detail">
- <input type="hidden" id="iscsi_pool" name="iscsi_pool" value="" />
- <input type="hidden" id="iscsi_volume" name="iscsi_volume" value="" />
+ <input type="hidden" id="pool_type" name="pool_type" value="dir" />
<table class="detail-contents">
<tr id="disk_type_box">
<th>${_('Storage Pool Type')}</th>
</select>
</td>
</tr>
+ <tr id="disk_path_box">
+ <th>${_('Device Path')}</th>
+ <td class="detail-separator"><img src="${ctx.homepath}/static/images/table-space.gif" alt="" /></td>
+ <td id="disk_path_value_box"></td>
+ </tr>
+ <tr id="disk_realpath_box">
+ <th>${_('Device Real Path')}</th>
+ <td class="detail-separator"><img src="${ctx.homepath}/static/images/table-space.gif" alt="" /></td>
+ <td id="disk_realpath_value_box"></td>
+ </tr>
</table>
</div>
</div>
% if "KVM" in hypervisors.keys():
% for x in bus_types:
% if x == "virtio":
- <option value="${x}" selected>${x}</option>
+ <option value="${x}" selected>${_(x)}</option>
% else:
- <option value="${x}">${x}</option>
+ <option value="${x}">${_(x)}</option>
% endif
% endfor
% else:
% for x in bus_types:
% if x == "xen":
- <option value="${x}" selected>${x}</option>
+ <option value="${x}" selected>${_(x)}</option>
% else:
- <option value="${x}">${x}</option>
+ <option value="${x}">${_(x)}</option>
% endif
% endfor
% endif
${_('ISO Image')}<span id="guest_iso_help"/>
</div>
<td>
- <input type="text" id="vm_iso" name="vm_iso" value="/git/iso/CentOS-5.4-x86_64-bin-DVD.iso" size="60" /><span class="require-text" id="vm_iso_require_str">${_('Require')}</span>
+ <input type="text" id="vm_iso" name="vm_iso" value="" size="60" /><span class="require-text" id="vm_iso_require_str">${_('Require')}</span>
</td>
</tr>
</table>
</div>
<br style="clear: both;"/>
</div>
-</div>
+</div>
<script type="text/javascript">
<!--
-$(document).ready(function(){
- $("table[id^='iscsi_disks_']").tablesorter({
- widgets: ['zebra', 'select']
- });
-
-// $("tr[id*='iscsi_block_']").each(function(){
-// alert($(this).attr('id'))
-// $(this).one('click.once', function(){
-// alert(alert($(this).attr('id')))
-// });
-// });
-
- function switch_iscsi_section() {
- var target_val = $("#pool_target_iscsi option:selected").val();
- $("#pool-iscsi-section table[id^='iscsi_disks_']:visible").hide();
- $("#pool-iscsi-section table[id='iscsi_disks_" + target_val + "']").show();
+function switch_section_pool() {
+ var _checkedObj = $("input:radio[name='disk_layout']:checked");
+ if(_checkedObj.val() == "create") {
+ $("#disk_dir_section").show();
+ $("#pool-iscsi-section").hide();
+ } else if(_checkedObj.val() == "iscsi") {
+ $("#disk_dir_section").hide();
+ $("#pool-iscsi-section").show();
}
- $("#pool_target_iscsi").click(function(){
- switch_iscsi_section();
- });
- switch_iscsi_section();
+}
- function switch_section_pool() {
- var _checkedObj = $("input:radio[name='disk_layout']:checked");
- if(_checkedObj.val() == "create") {
- show_element("#disk_dir_section",true);
- show_element("#pool-iscsi-section",false);
- } else if(_checkedObj.val() == "iscsi") {
- show_element("#disk_dir_section",false);
- show_element("#pool-iscsi-section",true);
- }
+function switch_section() {
+ var _checkedObj = $("input:radio[name='device_type']:checked");
+ if(_checkedObj.val() == "nic") {
+ $("#nic-section").show();
+ $("#disk-section").hide();
+ } else if(_checkedObj.val() == "disk") {
+ $("#nic-section").hide();
+ $("#disk-section").show();
}
+}
- $("input:radio[name='disk_layout']").click(function(){
- switch_section_pool();
- });
- switch_section_pool();
+function validates_device(){
+ var check = true;
+ ERROR_MSG = "";
+ var _checkedObj = $("input:radio[name='device_type']:checked");
+ if(_checkedObj.val() == "nic"){
+ check = check_macaddr($("#mac_address"),
+ CHECK_EMPTY | CHECK_VALID,
+ "${_('MAC Address')}") && check;
- function switch_section() {
- var _checkedObj = $("input:radio[name='device_type']:checked");
- if(_checkedObj.val() == "nic") {
- show_element("#nic-section",true);
- show_element("#disk-section",false);
- } else if(_checkedObj.val() == "disk") {
- show_element("#nic-section",false);
- show_element("#disk-section",true);
- }
- }
- switch_section();
+ } else if (_checkedObj.val() == "disk"){
+ /**
+ check = check_number($("#disk_size"),
+ CHECK_EMPTY | CHECK_VALID | CHECK_MIN,
+ "${_('Disk Size (MB)')}",
+ DISK_MIN_SIZE) && check;
+ **/
- function validates_device(){
- var check = true;
- ERROR_MSG = "";
+ } else {
+ ERROR_MSG = "${_('Please select a target.')}";
+ check = false;
+ }
- var _checkedObj = $("input:radio[name='device_type']:checked");
- if(_checkedObj.val() == "nic"){
- check = check_macaddr($("#mac_address"),
- CHECK_EMPTY | CHECK_VALID,
- "${_('MAC Address')}") && check;
+ if(!check){
+ show_alert_msg(ERROR_MSG, "ERROR");
+ }
+ return check;
+}
- } else if (_checkedObj.val() == "disk"){
-/**
- check = check_number($("#disk_size"),
- CHECK_EMPTY | CHECK_VALID | CHECK_MIN,
- "${_('Disk Size (MB)')}",
- DISK_MIN_SIZE) && check;
-**/
+$(document).ready(function(){
+ $("input:radio[name='device_type']").click(function(){
+ switch_section();
+ });
+ switch_section();
- } else {
- ERROR_MSG = "${_('Please select a target.')}";
- check = false;
- }
+ set_simple_slider("#disk_slider", "#vm_disk_size", 0, ${int(pools_info['default']['available']) / (1024 * 1024)}, ${int(pools_info['default']['available']) / (1024 * 1024)});
+ $("#pool_dir").change(function(){
+ var pool_name = $('option:selected', this).val();
+ var disk_type = $('option:selected', this).parent('optgroup').attr('label');
+ $("#pool_type").val(disk_type);
+ if(disk_type == 'block'){
+ var parts = pool_name.split("/");
+ var vol_name = parts[1];
- if(!check){
- show_alert_msg(ERROR_MSG, "ERROR");
+ var vols_info = new Array();
+% for pool_name in pools_iscsi_blocks.keys():
+% for vol_info in pools_iscsi_blocks[pool_name]:
+ var vol_info = new Array();
+ vol_info['capacity'] = "${vol_info['capacity']}";
+ vol_info['path'] = "${vol_info['target']['path']}";
+ vol_info['realpath'] = "${vol_info['real']['dir']}/${vol_info['real']['name']}";
+ vols_info["${vol_info['name']}"] = vol_info;
+% endfor
+% endfor
+ var disk_capacity = Math.floor(vols_info[vol_name]['capacity'] / (1024 * 1024));
+ $("#disk_size_box").hide();
+ $("#disk_type_value_box").html(disk_type);
+ $("#disk_available_box").hide();
+ $("#disk_capacity_value_box").html(disk_capacity);
+ $("#disk_format_box").hide();
+ $("#disk_path_value_box").html(vols_info[vol_name]['path']);
+ $("#disk_realpath_value_box").html(vols_info[vol_name]['realpath']);
+ $("#disk_path_box").show();
+ $("#disk_realpath_box").show();
+ } else { // type is 'dir' or 'fs'
+ var pools_info = new Array();
+% for pool_name in pools_info.keys():
+ var pool_info = new Array();
+ pool_info['available'] = "${pools_info[pool_name]['available']}";
+ pool_info['capacity'] = "${pools_info[pool_name]['capacity']}";
+ pools_info["${pool_name}"] = pool_info
+% endfor
+ var disk_available = Math.floor(pools_info[pool_name]['available'] / (1024 * 1024));
+ var disk_capacity = Math.floor(pools_info[pool_name]['capacity'] / (1024 * 1024));
+ $("#disk_size_box").show();
+ set_simple_slider("#disk_slider", "#vm_disk_size", 0, disk_available, disk_available);
+ $("#disk_type_value_box").html(disk_type);
+ $("#disk_available_box").show();
+ $("#disk_available_value_box").html(disk_available);
+ $("#disk_capacity_value_box").html(disk_capacity);
+ $("#disk_format_box").show();
+ $("#disk_path_box").hide();
+ $("#disk_realpath_box").hide();
}
- return check;
- }
- $("tr[id*='iscsi_block_']").click(function(){
- $("#iscsi_block").val($(this).attr("id").replace("iscsi_block_", ""));
});
+ $("#disk_path_box").hide();
+ $("#disk_realpath_box").hide();
+
+ if("${VMType}" == "KVM") {
+ $("#bus_type_html").show();
+ alert_on(".caution-alt", "CAUTION", "${_('This will be enabled on next guest bootup')}");
+ } else {
+ $("#bus_type_html").hide();
+ alert_off(".caution-alt");
+ }
ajax_post_event("#add_device_button",
"${ctx.homepath}/host/${guest.info['model'].parent_id}/guest/${guest.info['model'].id}/device",
"#input_device :input",
validates_device);
- $("input:radio[name='device_type']").click(function(){
- switch_section();
- });
-
helptip("#device_dev_type_help",
"${_('Device Type')}",
"${_(r'Type of the device to add. Choose \"Network\" to add a new network interface to the guest, or \"Disk\" to add a new virtual hard disk device.')}");
"${_('Disk Device Type')}",
"${_('Type of disk device to emulate.')}");
});
-
-
-function show_element(id,flag) {
- if(flag) {
- $(id).show();
- } else {
- $(id).hide();
- }
-}
-
-
-if("${VMType}" == "KVM") {
- show_element("#bus_type_html",true);
- alert_on(".caution-alt", "CAUTION", "${_('This will be enabled on next guest bootup')}");
-} else {
- show_element("#bus_type_html",false);
- alert_off(".caution-alt");
-}
-->
</script>
<div id="disk-section">
<div class="grayout-param">${_('Storage Type')}<span id="disk_layout_help"/></div>
<div class="grayout-value grayout-form">
- <input type="radio" id="disk_layout_create" name="disk_layout" value="create" checked />${_("Create new disk image")}
- <input type="radio" id="disk_layout_iscsi" name="disk_layout" value="iscsi" /> ${_("Use iSCSI")}
- <!-- create -->
- <div id="disk_dir_section">
- <div class="grayout-value grayout-form">
- TODO : sparse
- <table><tr>
- <th>${_("Storage Name")}</th>
- <th>${_("Available")}</th>
- <th>${_("Capacity")}</th>
- <th>${_("Disk Size (MB)")}<span id="disk_size_help"/></th>
- <th>${_("Image Type")}<span id="device_disk_device_type_help" /></th>
- </tr><tr>
- <td><select id="pool_dir" name="pool_dir">
-% for pool in pools_info:
-% if pool['type'] != 'iscsi':
- <option value="${pool['name']}">${pool['name']}</option>
-% endif
+
+ ${_("Storage Pool Name")} :
+ <select id="pool_dir" name="pool_dir">
+% for group_type in ['dir', 'fs', 'block']:
+ <optgroup label="${group_type}">
+% for name in sorted(pools_info.keys()):
+% if group_type == 'dir' and pools_info[name]['type'] == 'dir':
+% if pools_info[name]['name'] == 'default':
+ <option value="${name}" selected>${name}</option>
+% else:
+ <option value="${name}">${name}</option>
+% endif
+% endif
+
+% if group_type == 'fs' and pools_info[name]['type'] == 'fs':
+ <option value="${name}">${name}</option>
+% endif
+
+% if group_type == 'block' and pools_info[name]['type'] == 'iscsi':
+% if name in pools_iscsi_blocks:
+% for vol_info in pools_iscsi_blocks[name]:
+ <option value="${name}/${vol_info['name']}">${name} - ${vol_info['name']}</option>
+% endfor
+% endif
+% endif
+% endfor
+ </optgroup>
% endfor
- </select></td>
- <td>TODO : ${view_autounit(pools_info[0]['available'])}</td>
- <td>TODO : ${view_autounit(pools_info[0]['capacity'])}</td>
- <td>
+ </select>
+ <div class="grayout-detail">
+ <input type="hidden" id="pool_type" name="pool_type" value="dir" />
+ <table class="detail-contents">
+ <tr id="disk_type_box">
+ <th>${_('Storage Pool Type')}</th>
+ <td class="detail-separator"><img src="${ctx.homepath}/static/images/table-space.gif" alt="" /></td>
+ <td id="disk_type_value_box">${pools_info['default']['type'] | h}</td>
+ </tr>
+ <tr id="disk_size_box">
+ <th>${_('Disk Size (MB)')}</th>
+ <td class="detail-separator"><img src="${ctx.homepath}/static/images/table-space.gif" alt="" /></td>
+ <td id="disk_size_value_box">
<div id="disk_slider"></div>
- <input type="text" id="disk_size" name="disk_size" value="4096" /><span class="require-text">${_('Require')}</span>
+ <input type="text" id="vm_disk_size" name="vm_disk_size" value="0" /><span class="require-text">${_('Require')}</span>
</td>
- <td>
+ </tr>
+ <tr id="disk_available_box">
+ <th>${_('Available (MB)')}</th>
+ <td class="detail-separator"><img src="${ctx.homepath}/static/images/table-space.gif" alt="" /></td>
+ <td id="disk_available_value_box">${int(pools_info['default']['available']) / (1024 * 1024)}</td>
+ </tr>
+ <tr id="disk_capacity_box">
+ <th>${_('Capacity (MB)')}</th>
+ <td class="detail-separator"><img src="${ctx.homepath}/static/images/table-space.gif" alt="" /></td>
+ <td id="disk_capacity_value_box">${int(pools_info['default']['capacity']) / (1024 * 1024)}</td>
+ </tr>
+ <tr id="disk_format_box">
+ <th>${_('OS Image Type')}</th>
+ <td class="detail-separator"><img src="${ctx.homepath}/static/images/table-space.gif" alt="" /></td>
+ <td id="disk_format_value_box">
<select id="select_disk_format" name="disk_format">
% for x in DISK_FORMATS.values():
-% if VMType == "KVM" and x == "qcow2":
- <option value="${x}" "selected">${x}</option>
-% else:
+% if x == "qcow2":
+ <option value="${x}" selected>${x}</option>
+% else:
<option value="${x}">${x}</option>
-% endif
+% endif
% endfor
</select>
</td>
- </tr></table>
- </div>
- </div>
-
- <div id="pool-iscsi-section">
- <div class="grayout-value grayout-form">
- <select id="pool_target_iscsi" name="pool_target_iscsi">
-% for iscsi in network_storages:
- % if iscsi['activity'] == 1:
- <option value="${iscsi['iqn'] | h}">${iscsi['hostname'] | h} : ${iscsi['iqn'] | h} </option>
- % endif
-% endfor
- </select>
-% for iscsi in network_storages:
- <table id="iscsi_disks_${iscsi['iqn']}" class="tablesorter">
- <thead>
- <tr>
- <!--
- TRANSLATORS:
- 接続されているiSCSIディスクの一覧の表です。
- 分かりづらいので、画面を見ると良いかもしれません。
- ストレージプール -> 追加 -> ストレージプールの種類でiscsiを選択
-
- 上から順に
- ・ディスクを一意に特定できる名前
- /dev/disk/by-path/以下に自動的に作られるシンボリックリンクの名前です。
- 例:ip-192.168.166.52:3260-iscsi-iqn.2010-01.jp.co.hde.prd:iscsi0-lun-1
- ・ディスクのデバイス名
- 上記のシンボリックリンクが指す実体です。/dev/sd*のうち、一番右の名前を取ってきています。
- 例:sda
- -->
- <th>${_('Name')}</th>
- <th>${_('Device Name')}</th>
- </tr>
- </thead>
- <tbody>
-% for disk in iscsi['disk_list']:
-% if disk['is_blockable'] is True:
- <tr id="iscsi_block_${disk['symlink_name']}">
- <td>${disk['symlink_name'] | h}</td>
- <td>${disk['realpath_list'][1] | h}</td>
- </tr>
-% endif
-% endfor
- </tbody>
- </table>
-% endfor
- </div>
+ </tr>
+ <tr id="disk_path_box">
+ <th>${_('Device Path')}</th>
+ <td class="detail-separator"><img src="${ctx.homepath}/static/images/table-space.gif" alt="" /></td>
+ <td id="disk_path_value_box"></td>
+ </tr>
+ <tr id="disk_realpath_box">
+ <th>${_('Device Real Path')}</th>
+ <td class="detail-separator"><img src="${ctx.homepath}/static/images/table-space.gif" alt="" /></td>
+ <td id="disk_realpath_value_box"></td>
+ </tr>
+ </table>
</div>
</div>
<div id="bus_type_html">
- <div class="grayout-param">${_('Disk Device Type')}<span id="device_disk_device_type_help" /></div>
- <div class="grayout-value grayout-form">
- <select name='bus_type'>
+ <div class="grayout-param">${_('Disk Device Type')}<span id="device_disk_device_type_help" /></div>
+ <div class="grayout-value grayout-form">
+ <select name='bus_type'>
% for x in bus_types:
- <option value="${x}">${_(x)}</option>
+% if x == "virtio":
+ <option value="${x}" selected>${_(x)}</option>
+% else:
+ <option value="${x}">${_(x)}</option>
+% endif
% endfor
- </select>
- </div>
+ </select>
+ </div>
</div>
</div>