OSDN Git Service

Change disk layout display
authorkeisuke fukawa <keisuke@karesansui-project.info>
Thu, 1 Jul 2010 08:48:06 +0000 (17:48 +0900)
committerkeisuke fukawa <keisuke@karesansui-project.info>
Thu, 1 Jul 2010 08:48:06 +0000 (17:48 +0900)
karesansui/gadget/guest.py
karesansui/gadget/guestby1device.py
karesansui/lib/virt/virt.py
karesansui/static/css/device.css
karesansui/static/css/guest.css
karesansui/templates/default/guest/guest.input
karesansui/templates/default/guestby1device/guestby1device.input

index c9c92ed..5310cf7 100644 (file)
@@ -170,14 +170,16 @@ def validates_guest_add(obj):
                 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
@@ -424,31 +426,53 @@ class Guest(Rest):
             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
@@ -586,7 +610,7 @@ class Guest(Rest):
                     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
@@ -604,6 +628,8 @@ class Guest(Rest):
 
         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"]
@@ -624,8 +650,8 @@ class Guest(Rest):
                 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
@@ -668,23 +694,21 @@ class Guest(Rest):
             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:
index 5604807..bb9d51a 100644 (file)
@@ -56,7 +56,7 @@ class GuestBy1Device(Rest):
 
         bridge_prefix = {
                           "XEN":"xenbr",
-                          "KVM":"eth",
+                          "KVM":"eth|bondbr",
                         }
 
         model = findbyguest1(self.orm, guest_id)
@@ -64,96 +64,101 @@ class GuestBy1Device(Rest):
         # 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()
@@ -209,8 +214,9 @@ class GuestBy1Device(Rest):
 
                 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,
@@ -224,13 +230,12 @@ class GuestBy1Device(Rest):
                                                            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."))
 
index 383976c..22f6f87 100644 (file)
@@ -2892,6 +2892,46 @@ class KaresansuiVirtConnection:
                         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:
 
index d1e516e..88eff37 100644 (file)
     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;
+}
index 0df2a35..19dc6b8 100644 (file)
     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;
+}
index fe516dd..78f556e 100644 (file)
@@ -187,21 +187,23 @@ function show_element(id,flag) {
 }
 
 $(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));
@@ -210,6 +212,10 @@ $(document).ready(function(){
             $("#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():
@@ -227,16 +233,13 @@ $(document).ready(function(){
             $("#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({
@@ -265,34 +268,21 @@ $(document).ready(function(){
         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:
@@ -385,40 +375,40 @@ qcow2: Qemu is the most common image formats supported.
         "${_('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.')}");
 });
 // -->
@@ -431,7 +421,7 @@ qcow2: Qemu is the most common image formats supported.
         </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">
@@ -473,43 +463,8 @@ qcow2: Qemu is the most common image formats supported.
 
         <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")}&nbsp;:&nbsp;
             <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()):
@@ -526,17 +481,18 @@ TODO: iscsiのストレージプールを表示させない。dir, fsのみ表
 %         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>
@@ -582,6 +538,16 @@ TODO: iscsiのストレージプールを表示させない。dir, fsのみ表
                             </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>
@@ -592,17 +558,17 @@ TODO: iscsiのストレージプールを表示させない。dir, fsのみ表
 % 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
@@ -654,7 +620,7 @@ TODO: iscsiのストレージプールを表示させない。dir, fsのみ表
                 ${_('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>
@@ -746,5 +712,5 @@ TODO: iscsiのストレージプールを表示させない。dir, fsのみ表
         </div>
         <br style="clear: both;"/>
     </div>
-</div> 
+</div>
 
index 58d5914..ce98c91 100644 (file)
 
 <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.')}");
@@ -121,24 +152,6 @@ $(document).ready(function(){
             "${_('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>
 
@@ -200,103 +213,103 @@ if("${VMType}" == "KVM") {
             <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")}&nbsp;:&nbsp;
+                    <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}&nbsp;:&nbsp;${iscsi['iqn'] | h}&nbsp;&nbsp;&nbsp;</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>