[PATCH] Fix Bug: Template Tab Broken in Chrome due to Code Error
by Hongliang Wang
String.prototype.startsWith is a Firefox-specified API and Chrome doesn't
support it. Replace it with a generic method.
Signed-off-by: Hongliang Wang <hlwang(a)linux.vnet.ibm.com>
---
ui/js/src/kimchi.template_main.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/js/src/kimchi.template_main.js b/ui/js/src/kimchi.template_main.js
index eaa5247..48354c9 100644
--- a/ui/js/src/kimchi.template_main.js
+++ b/ui/js/src/kimchi.template_main.js
@@ -22,7 +22,7 @@ kimchi.doListTemplates = function() {
var listHtml = '';
var templateHtml = $('#templateTmpl').html();
$.each(result, function(index, value) {
- var isLocal = value.cdrom.startsWith("/");
+ var isLocal = /^\//.test(value['cdrom']);
if(isLocal){
value.location = "images/theme-default/icon-local.png";
}else{
--
1.8.1.4
10 years, 6 months
[PATCH] Put focus on form's first field
by Crístian Viana
A good usability practice is to leave the focus on the first editable
field on a form. That way, the user can start typing immediately what
they want without having to use the mouse to click on the
input element.
Explicitely request focus to every form's first field. Some input
elements did not have an ID; in those cases, the IDs were also added
to the HTML code.
Signed-off-by: Crístian Viana <vianac(a)linux.vnet.ibm.com>
---
ui/js/src/kimchi.guest_add_main.js | 1 +
ui/js/src/kimchi.guest_edit_main.js | 1 +
ui/js/src/kimchi.report_add_main.js | 1 +
ui/js/src/kimchi.repository_add_main.js | 1 +
ui/js/src/kimchi.repository_edit_main.js | 1 +
ui/js/src/kimchi.storagepool_add_main.js | 1 +
ui/js/src/kimchi.template_edit_main.js | 2 ++
ui/pages/guest-add.html.tmpl | 2 +-
ui/pages/repository-add.html.tmpl | 2 +-
9 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/ui/js/src/kimchi.guest_add_main.js b/ui/js/src/kimchi.guest_add_main.js
index 2113099..0a4f5e6 100644
--- a/ui/js/src/kimchi.guest_add_main.js
+++ b/ui/js/src/kimchi.guest_add_main.js
@@ -77,6 +77,7 @@ kimchi.guest_add_main = function() {
$('#form-vm-add').on('submit', addGuest);
$('#vm-doAdd').on('click', addGuest);
+ $('#guest-add-id-textbox').focus();
showTemplates();
};
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js
index 0236e2d..3588dcc 100644
--- a/ui/js/src/kimchi.guest_edit_main.js
+++ b/ui/js/src/kimchi.guest_edit_main.js
@@ -225,4 +225,5 @@ kimchi.guest_edit_main = function() {
$(guestEditForm).on('submit', submitForm);
$(saveButton).on('click', submitForm);
+ $('#guest-edit-id-textbox').focus();
};
diff --git a/ui/js/src/kimchi.report_add_main.js b/ui/js/src/kimchi.report_add_main.js
index 8759c2b..f7f1b4b 100644
--- a/ui/js/src/kimchi.report_add_main.js
+++ b/ui/js/src/kimchi.report_add_main.js
@@ -43,4 +43,5 @@ kimchi.report_add_main = function() {
addReportForm.on('submit', submitForm);
submitButton.on('click', submitForm);
+ nameTextbox.focus();
};
diff --git a/ui/js/src/kimchi.repository_add_main.js b/ui/js/src/kimchi.repository_add_main.js
index 5dc84e5..4ee7a62 100644
--- a/ui/js/src/kimchi.repository_add_main.js
+++ b/ui/js/src/kimchi.repository_add_main.js
@@ -97,4 +97,5 @@ kimchi.repository_add_main = function() {
};
$(addForm).on('submit', addRepository);
+ $('#repo_id').focus();
};
diff --git a/ui/js/src/kimchi.repository_edit_main.js b/ui/js/src/kimchi.repository_edit_main.js
index 26d6c66..0b562ee 100644
--- a/ui/js/src/kimchi.repository_edit_main.js
+++ b/ui/js/src/kimchi.repository_edit_main.js
@@ -72,4 +72,5 @@ kimchi.repository_edit_main = function() {
$(editForm).on('submit', editRepository);
$(saveButton).on('click', editRepository);
+ $('#repository-edit-name-textbox').focus();
};
diff --git a/ui/js/src/kimchi.storagepool_add_main.js b/ui/js/src/kimchi.storagepool_add_main.js
index 86dbe7f..d37a37d 100644
--- a/ui/js/src/kimchi.storagepool_add_main.js
+++ b/ui/js/src/kimchi.storagepool_add_main.js
@@ -20,6 +20,7 @@ kimchi.storagepool_add_main = function() {
kimchi.initStorageAddPage();
$('#form-pool-add').on('submit', kimchi.addPool);
$('#pool-doAdd').on('click', kimchi.addPool);
+ $('#poolId').focus();
};
kimchi.initStorageAddPage = function() {
diff --git a/ui/js/src/kimchi.template_edit_main.js b/ui/js/src/kimchi.template_edit_main.js
index f0f4718..a0e9e28 100644
--- a/ui/js/src/kimchi.template_edit_main.js
+++ b/ui/js/src/kimchi.template_edit_main.js
@@ -177,4 +177,6 @@ kimchi.template_edit_main = function() {
kimchi.message.error(err.responseJSON.reason);
});
});
+
+ $('#template-edit-id-textbox').focus();
};
diff --git a/ui/pages/guest-add.html.tmpl b/ui/pages/guest-add.html.tmpl
index 84a1994..e478b2e 100644
--- a/ui/pages/guest-add.html.tmpl
+++ b/ui/pages/guest-add.html.tmpl
@@ -37,7 +37,7 @@
<p class="text-help">
$_("The name used to identify the virtual machine. If omitted, a name will be chosen based on the template used.")
</p>
- <input type="text" class="text" style="width: 300px" name="name">
+ <input type="text" class="text" style="width: 300px" name="name" id="guest-add-id-textbox">
</div>
</section>
<section class="form-section">
diff --git a/ui/pages/repository-add.html.tmpl b/ui/pages/repository-add.html.tmpl
index 05b4de9..9a8a037 100644
--- a/ui/pages/repository-add.html.tmpl
+++ b/ui/pages/repository-add.html.tmpl
@@ -39,7 +39,7 @@
$_("Single word, unique identifier for the repository.")
</p>
<div class="textbox-wrapper">
- <input type="text" class="text" name="repo_id" />
+ <input type="text" class="text" name="repo_id" id="repo_id" />
</div>
</div>
</div>
--
1.9.0
10 years, 6 months
[PATCH] Add Ubuntu as modern distro to Power guests.
by Paulo Vital
Set Ubuntu 14.04 as base for modern Power guests.
Signed-off-by: Paulo Vital <pvital(a)linux.vnet.ibm.com>
---
src/kimchi/osinfo.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/kimchi/osinfo.py b/src/kimchi/osinfo.py
index cfe9972..0f11f7a 100644
--- a/src/kimchi/osinfo.py
+++ b/src/kimchi/osinfo.py
@@ -59,7 +59,8 @@ template_specs = {'x86': {'old': dict(common_spec, disk_bus='ide',
modern_version_bases = {'x86': {'debian': '6.0', 'ubuntu': '7.10',
'opensuse': '10.3', 'centos': '5.3',
'rhel': '6.0', 'fedora': '16', 'gentoo': '0'},
- 'power': {'rhel': '7.0', 'fedora': '19'}}
+ 'power': {'rhel': '7.0', 'fedora': '19',
+ 'ubuntu': '10.04'}}
icon_available_distros = [icon[5:-4] for icon in glob.glob1('%s/images/'
% paths.ui_dir, 'icon-*.png')]
--
1.8.3.1
10 years, 6 months
[PATCH V5 0/7] Issue #342: load i18n.html of the plugin
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
V4 -> V5:
let autoconf generate sample.conf
V3 -> V4:
rebase
V2 -> V3:
change "enable-plugins" to "enable-sample"
remove nls
improve the Portuguese translation.
V1 -> V2:
The improvement concept here is to directly generate JSON on the server
and assign it to the i18n variable, rather than inserting nodes into the DOM.
Plugins would use a plugin1.i18n= structure to keep plugin strings from
colliding with each other, or with the kimchi variables.
ShaoHe Feng (6):
Update root.py to make Cheetah render the JSON template.
Update the i18n tmpl to produce JSON
Add JS API for fetching i18n JSON
Issue #342: load i18n.html of the plugin
add an optional to toggle the sample plugin
generate the translation files for plugins/sample
Zhou Zheng Sheng (1):
Add Minimal UI Page for the Sample Plugin
configure.ac | 18 ++++
plugins/sample/Makefile.am | 11 +-
plugins/sample/__init__.py | 3 +-
plugins/sample/config.status | 1 +
plugins/sample/po/LINGUAS | 1 +
plugins/sample/po/Makefile.in.in | 1 +
plugins/sample/po/Makevars | 1 +
plugins/sample/po/POTFILES.in | 2 +
plugins/sample/po/en_US.po | 21 ++++
plugins/sample/po/gen-pot | 1 +
plugins/sample/po/pt_BR.po | 24 +++++
plugins/sample/po/zh_CN.po | 24 +++++
plugins/sample/sample.conf | 7 --
plugins/sample/sample.conf.in | 12 +++
plugins/sample/ui/config/tab-ext.xml | 8 +-
plugins/sample/ui/pages/i18n.json.tmpl | 9 ++
plugins/sample/ui/pages/tab.html.tmpl | 6 ++
src/kimchi/root.py | 5 +
src/kimchi/template.py | 34 ++++---
ui/js/src/kimchi.api.js | 18 +++-
ui/js/src/kimchi.main.js | 24 ++++-
ui/pages/i18n.html.tmpl | 178 ---------------------------------
ui/pages/i18n.json.tmpl | 165 ++++++++++++++++++++++++++++++
23 files changed, 361 insertions(+), 213 deletions(-)
create mode 120000 plugins/sample/config.status
create mode 120000 plugins/sample/po/LINGUAS
create mode 120000 plugins/sample/po/Makefile.in.in
create mode 120000 plugins/sample/po/Makevars
create mode 100644 plugins/sample/po/POTFILES.in
create mode 100644 plugins/sample/po/en_US.po
create mode 120000 plugins/sample/po/gen-pot
create mode 100644 plugins/sample/po/pt_BR.po
create mode 100644 plugins/sample/po/zh_CN.po
delete mode 100644 plugins/sample/sample.conf
create mode 100644 plugins/sample/sample.conf.in
create mode 100644 plugins/sample/ui/pages/i18n.json.tmpl
create mode 100644 plugins/sample/ui/pages/tab.html.tmpl
delete mode 100644 ui/pages/i18n.html.tmpl
create mode 100644 ui/pages/i18n.json.tmpl
--
1.9.3
10 years, 6 months
[PATCHv2] Issue#348: Add loading icon when nfs mount is in progress
by lvroyce@linux.vnet.ibm.com
From: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
v1>v2, Improve feedback msg according to Hongliang's comments.
Add loading icon to indicate nfs mount in progress,
when error or normal response returns,
close create window.
Signed-off-by: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
---
ui/js/src/kimchi.storagepool_add_main.js | 2 ++
ui/pages/storagepool-add.html.tmpl | 6 ++++++
2 files changed, 8 insertions(+)
diff --git a/ui/js/src/kimchi.storagepool_add_main.js b/ui/js/src/kimchi.storagepool_add_main.js
index 86dbe7f..6b77bd8 100644
--- a/ui/js/src/kimchi.storagepool_add_main.js
+++ b/ui/js/src/kimchi.storagepool_add_main.js
@@ -198,6 +198,7 @@ kimchi.validateNfsForm = function () {
kimchi.message.error.code('KCHPOOL6005E');
return false;
}
+ $('#nfs-mount-loading').removeClass('hidden');
return true;
};
@@ -295,6 +296,7 @@ kimchi.addPool = function(event) {
kimchi.window.close();
}, function(err) {
kimchi.message.error(err.responseJSON.reason);
+ kimchi.window.close();
});
}
}
diff --git a/ui/pages/storagepool-add.html.tmpl b/ui/pages/storagepool-add.html.tmpl
index 977db66..b033b36 100644
--- a/ui/pages/storagepool-add.html.tmpl
+++ b/ui/pages/storagepool-add.html.tmpl
@@ -91,6 +91,12 @@
</ul>
</div>
</div>
+ <div class="hidden" id="nfs-mount-loading">
+ <p class="text-help">
+ $_("Trying to mount NFS export path. It may take several seconds.")
+ <img src = "../images/theme-default/loading.gif" />
+ </p>
+ </div>
</div>
</section>
</div>
--
1.8.3.2
10 years, 6 months
[PATCH V4] Issue#305: Redesign bridged network UI section
by Wen Wang
Finished align vlan fields. Redesigned the pattern of the label positions
V3 -> V4:
Address to Hongliang Wang: Assigned "for" attribute for label to associate it with text box accordingly
V2 -> V3:
Address to Hongliang Wang: Have the additional margin place removed.
v1 -> v2:
Address to Hongliang Wang: Have the unrelated lines removed & Have the display format changed from table to div.
Address to Yuxin Huo: Have the unused IDs removed.
Signed-off-by: Wen Wang <wenwang(a)linux.vnet.ibm.com>
---
ui/css/theme-default/network.css | 21 ++++++++++++++++-----
ui/js/src/kimchi.network.js | 8 ++++----
ui/pages/tabs/network.html.tmpl | 34 +++++++++++++++++++++-------------
3 files changed, 41 insertions(+), 22 deletions(-)
diff --git a/ui/css/theme-default/network.css b/ui/css/theme-default/network.css
index 67f2aa2..176b277 100644
--- a/ui/css/theme-default/network.css
+++ b/ui/css/theme-default/network.css
@@ -209,19 +209,30 @@
vertical-align: top;
}
-.network-config .destination {
- margin-left: 28px;
+.bridge-option-column {
+ display: inline-block;
+ margin-left: 56px;
+ vertical-align: middle;
+}
+
+.bridge-option-column > div {
+ height: 25px;
+ line-height: 25px;
}
-.network-config .VLAN {
- margin-left: 28px;
+.bridge-option-column select {
+ height: 26px;
}
-.network-config .VLAN input[type="text"] {
+.bridge-option-column input[type="text"] {
height: 25px;
width: 60px;
}
+#labelNetworkVlanID {
+ margin-left: 26px;
+}
+
.network-config .input-hint-icon {
margin: -1px 1px 0 0;
display: inline-block;
diff --git a/ui/js/src/kimchi.network.js b/ui/js/src/kimchi.network.js
index 7a331be..ca6d29b 100644
--- a/ui/js/src/kimchi.network.js
+++ b/ui/js/src/kimchi.network.js
@@ -275,13 +275,14 @@ kimchi.enableBridgeOptions = function(enable) {
$("#networkVlanID").prop("disabled", true);
$("#networkVlanID").val("");
$("#networkInterface").val("");
- $("#bridge-options").slideUp(100);
+ $("#bridgeOptions").slideUp(100);
} else if (!$("#networkInterface").val()){
$("#networkInterface").prop("selectedIndex", 0);
- $("#bridge-options").slideDown(100);
+ $("#bridgeOptions").slideDown(100);
}
};
+
kimchi.setDefaultNetworkType = function(isInterfaceAvail) {
$("#networkTypeBri").prop("checked", isInterfaceAvail);
$("#networkTypeBri").prop("disabled", !isInterfaceAvail);
@@ -289,7 +290,7 @@ kimchi.setDefaultNetworkType = function(isInterfaceAvail) {
if (!isInterfaceAvail) {
kimchi.enableBridgeOptions(false);
} else {
- $("#bridge-options").slideDown(100);
+ $("#bridgeOptions").slideDown(100);
}
};
@@ -318,7 +319,6 @@ kimchi.cleanNetworkDialog = function() {
$("#networkVlanID").prop("disabled", true);
$("#enableVlan").prop("checked", false);
};
-
kimchi.setupNetworkFormEvent = function() {
$("#networkName").on("keyup", function(event) {
$("#networkName").toggleClass("invalid-field", !$("#networkName").val().match(/^[a-zA-Z0-9_]+$/));
diff --git a/ui/pages/tabs/network.html.tmpl b/ui/pages/tabs/network.html.tmpl
index e49b257..aedf7e8 100644
--- a/ui/pages/tabs/network.html.tmpl
+++ b/ui/pages/tabs/network.html.tmpl
@@ -46,7 +46,7 @@
<div class="section-container">
<div class="section-header">1. $_("Network Name")</div>
<div class="section-content">
- <input type="text" id="networkName">
+ <input type="text" id="networkName" />
<div class="input-hint">
<span class="ui-icon ui-icon-info input-hint-icon"></span>
<span class="input-hint-text">$_("Alphanumeric and '_' characters only.")</span>
@@ -57,27 +57,35 @@
<div class="section-header">2. $_("Network Type")</div>
<div class="section-content">
<div class="input-container">
- <input type="radio" id="networkTypeIso" name="networkType" value="isolated">
+ <input type="radio" id="networkTypeIso" name="networkType" value="isolated" />
<label for="networkTypeIso">$_("Isolated: no physical network connection")</label>
</div>
<div class="input-container">
- <input type="radio" id="networkTypeNat" name="networkType" value="nat">
+ <input type="radio" id="networkTypeNat" name="networkType" value="nat" />
<label for="networkTypeNat">$_("NAT: outbound physical network connection only")</label>
</div>
<div class="input-container">
- <input type="radio" id="networkTypeBri" name="networkType" value="bridged">
+ <input type="radio" id="networkTypeBri" name="networkType" value="bridged" />
<label for="networkTypeBri">$_("Bridged: Virtual machines are connected to physical network directly")</label>
</div>
- <div id="bridge-options">
- <div class="destination">
- <label for="networkInterface">$_("Destination"): </label>
- <select id="networkInterface"></select>
+ <div id="bridgeOptions">
+ <div class="bridge-option-column">
+ <div>
+ <label for="networkInterface">$_("Destination"): </label>
+ </div>
+ <div>
+ <select id="networkInterface"></select>
+ </div>
</div>
- <div class="VLAN">
- <label for="enableVlan">$_("Enable VLAN"): </label>
- <input id="enableVlan" type="checkbox" value=""/>
- <label for="networkVlanID">$_("VLAN ID"): </label>
- <input type="text" id="networkVlanID" disabled>
+ <div class="bridge-option-column">
+ <div>
+ <input id="enableVlan" type="checkbox" value="" />
+ <label for="enableVlan">$_("Enable VLAN"): </label>
+ </div>
+ <div>
+ <label for="networkVlanID" id="labelNetworkVlanID">$_("VLAN ID"): </label>
+ <input type="text" id="networkVlanID" disabled />
+ </div>
</div>
</div>
</div>
--
1.9.1
10 years, 6 months
Kimchi feedback
by Paul Clarke
(Fairly new user of Kimchi, with first impressions)
Is there a good location for documentation?
It seems difficult to make a new ISO available, or I chose a poor way.
- I downloaded from an FTP site requiring non-anonymous authentication
- I scp'd it to root@host
- I tried to use it from there, but I got permission denied
"KCHISO0008E: The hypervisor doesn't have permission to use this ISO
/root/..."
- the message above recommends copying the file to /var/lib/libvirt, but
I think you actually have to copy it to /var/lib/libvirt/images
- you also need to "chown qemu" the ISO image
After the above steps, it finally became visible and usable.
Further feedback:
- The above error message appears as a bright pop-over with a nice 'X'
for dismissing, but it automatically disappears so quickly, it's
impossible to read the entire message
- in the "Edit Template" dialog, what is "CPU Number"? I presume that
is "number of (virtual) processors"?
- in the "Edit Template" dialog, what are the units for "Memory"? It is
apparently megabytes, but that should be noted
Regards,
Paul Clarke, IBM
10 years, 6 months
[PATCH] Prevent ascii error when volume name has unsupported characters
by Rodrigo Trujillo
During ISO search (Template creation window), kimchi search volumes in
storagepools and it encodes every file name found. If some file has
unsupported characters, an error is raised and none ISO is presented to
user.
This patch fixes this error.
Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo(a)linux.vnet.ibm.com>
---
src/kimchi/model/storagevolumes.py | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/kimchi/model/storagevolumes.py b/src/kimchi/model/storagevolumes.py
index d58fd0b..ab8e2fa 100644
--- a/src/kimchi/model/storagevolumes.py
+++ b/src/kimchi/model/storagevolumes.py
@@ -114,6 +114,10 @@ class StorageVolumeModel(object):
raise InvalidOperation("KCHVOL0006E", {'name': pool})
try:
return pool.storageVolLookupByName(name.encode("utf-8"))
+ except UnicodeDecodeError as e:
+ msg = 'Unable to encode file name "%s" from pool "%s":\n %s'
+ kimchi_log.warn(msg %(name, poolname, str(e)))
+ return None
except libvirt.libvirtError as e:
if e.get_error_code() == libvirt.VIR_ERR_NO_STORAGE_VOL:
raise NotFoundError("KCHVOL0002E", {'name': name,
@@ -151,6 +155,8 @@ class StorageVolumeModel(object):
def lookup(self, pool, name):
vol = self._get_storagevolume(pool, name)
+ if not vol:
+ return None
path = vol.path()
info = vol.info()
xml = vol.XMLDesc(0)
@@ -240,6 +246,8 @@ class IsoVolumesModel(object):
for volume in volumes:
res = self.storagevolume.lookup(pool_name, volume)
+ if res is None:
+ continue
if res['format'] == 'iso':
res['name'] = '%s' % volume
iso_volumes.append(res)
--
1.9.0
10 years, 6 months