[PATCH V8 0/2] Add spice UI support
by zhoumeina
v7-v8 Change session novnc to display.
v6-v7 Add commit message of the second patch
v5-v6 Add token in spice contructor to be consistent with
the current proxy mechanism.
modify the vnc_proxy_port to display_proxy_port so
that it can be used by spice too.
v4-v5 vm_graphics is not null and not running make it
disabled
v3-v4 restructure js code to drop redundance code.
replace tabs with 4 spaces
v2-v3 Add related make files
v1-v2 add spice.html.tmpl
This patch add the front end support of spice.
1 If there were a spice vm in host, show a "spice" button
but not "vnc" in guest page.
2 click "spice" we can show a screen just like the demo
http://www.spice-space.org/spice-html5/spice.html
zhoumeina (2):
Add the front end support for SPICE
Modify vnc_proxy_port to display_proxy_port
configure.ac | 1 +
contrib/kimchi.spec.fedora.in | 1 +
contrib/kimchi.spec.suse.in | 1 +
docs/API.md | 2 +-
src/kimchi.conf.in | 2 +-
src/kimchi/config.py.in | 4 +-
src/kimchi/control/config.py | 2 +-
src/kimchi/vnc.py | 2 +-
ui/css/spice/spice.css | 115 ++++
ui/js/Makefile.am | 2 +-
ui/js/spice/Makefile.am | 25 +
ui/js/spice/atKeynames.js | 183 ++++++
ui/js/spice/bitmap.js | 51 ++
ui/js/spice/cursor.js | 92 +++
ui/js/spice/display.js | 806 ++++++++++++++++++++++++
ui/js/spice/enums.js | 282 +++++++++
ui/js/spice/inputs.js | 251 ++++++++
ui/js/spice/jsbn.js | 589 ++++++++++++++++++
ui/js/spice/lz.js | 166 +++++
ui/js/spice/main.js | 176 ++++++
ui/js/spice/png.js | 256 ++++++++
ui/js/spice/prng4.js | 79 +++
ui/js/spice/quic.js | 1335 ++++++++++++++++++++++++++++++++++++++++
ui/js/spice/rng.js | 102 +++
ui/js/spice/rsa.js | 146 +++++
ui/js/spice/sha1.js | 346 +++++++++++
ui/js/spice/spiceconn.js | 447 ++++++++++++++
ui/js/spice/spicedataview.js | 96 +++
ui/js/spice/spicemsg.js | 883 ++++++++++++++++++++++++++
ui/js/spice/spicetype.js | 480 +++++++++++++++
ui/js/spice/ticket.js | 250 ++++++++
ui/js/spice/utils.js | 261 ++++++++
ui/js/spice/wire.js | 123 ++++
ui/js/src/kimchi.api.js | 25 +-
ui/js/src/kimchi.guest_main.js | 27 +-
ui/pages/guest.html.tmpl | 1 +
ui/pages/spice.html.tmpl | 139 +++++
37 files changed, 7737 insertions(+), 12 deletions(-)
create mode 100644 ui/css/spice/spice.css
create mode 100644 ui/js/spice/Makefile.am
create mode 100644 ui/js/spice/atKeynames.js
create mode 100644 ui/js/spice/bitmap.js
create mode 100644 ui/js/spice/cursor.js
create mode 100644 ui/js/spice/display.js
create mode 100644 ui/js/spice/enums.js
create mode 100644 ui/js/spice/inputs.js
create mode 100644 ui/js/spice/jsbn.js
create mode 100644 ui/js/spice/lz.js
create mode 100644 ui/js/spice/main.js
create mode 100644 ui/js/spice/png.js
create mode 100644 ui/js/spice/prng4.js
create mode 100644 ui/js/spice/quic.js
create mode 100644 ui/js/spice/rng.js
create mode 100644 ui/js/spice/rsa.js
create mode 100644 ui/js/spice/sha1.js
create mode 100644 ui/js/spice/spiceconn.js
create mode 100644 ui/js/spice/spicedataview.js
create mode 100644 ui/js/spice/spicemsg.js
create mode 100644 ui/js/spice/spicetype.js
create mode 100644 ui/js/spice/ticket.js
create mode 100644 ui/js/spice/utils.js
create mode 100644 ui/js/spice/wire.js
create mode 100644 ui/pages/spice.html.tmpl
10 years, 10 months
[PATCH] Issue #308: Use correct iSCSI package for openSUSE
by Crístian Viana
Kimchi depends on an iSCSI system package to validate the iSCSI devices
when creating a storage pool. Currently, the package "iscsi-initiator-utils"
is listed as a dependency, but it is not available on openSUSE. Therefore, the
Kimchi RPM file cannot be installed on that distro.
Update the iSCSI dependency package name for openSUSE to "open-iscsi".
Signed-off-by: Crístian Viana <vianac(a)linux.vnet.ibm.com>
---
contrib/kimchi.spec.suse.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contrib/kimchi.spec.suse.in b/contrib/kimchi.spec.suse.in
index d1aec7b..bacf8df 100644
--- a/contrib/kimchi.spec.suse.in
+++ b/contrib/kimchi.spec.suse.in
@@ -21,7 +21,7 @@ Requires: python-ethtool
Requires: python-ipaddr
Requires: python-lxml
Requires: nfs-client
-Requires: iscsi-initiator-utils
+Requires: open-iscsi
%if 0%{?sles_version} == 11
Requires: python-ordereddict
--
1.8.4.2
10 years, 10 months
[PATCH V9 0/1] Open 8000 and 8001 port by default for distro packages
by taget@linux.vnet.ibm.com
From: Eli Qiao <taget(a)linux.vnet.ibm.com>
I tested on Fedora and Ubuntu system.
V9 -V8 changes:
1. Fix rebase error.
2. Revert 2 in V8
3. Add set +e when checking firewalld service to avoid bad return status.
V8 -V7 changes:
1. Rebase to latest code.(DEBIAN/control.in)
2. Install kimchid.xml to system dir (shu ming)
3. Remove changes for open suse.(Aline)
V7 -V6 changes:
1. Remove firewalld message when install kimchi rpm on fedora/RHEL
2. Start firewalld service if not start
3. Ship kimchid.xml to ubuntu distro in Makefile.am
V6 -V5 changes:
1.Keep specific condition for RHEL6 when starting kimchid service
2.Remove full path of firewall-cmd in postrm
V5 - V4 changes:
1. Add cover-letter. (Aline)
2. Move clean up rules into if condition. (Aline)
3. Use with_systemd condition to check if use firewalld rules. (Aline)
4. Fix typo (Aline)
V4 - V3 changes:
1 Fix typo in firewalld.xml (Rodrigo)
V3 - V2 changes:
1.Rename kimchid.xml to firewalld.xml (Mark)
2.Remove firewalld from serivce require (Mark)
3.Fix typo
V2 - V1 changes:
1.Add firewalld sevice configure file kimchid.xml to help open iptables port (Mark)
2.Add Ubuntu iptables rule (Royce)
Eli Qiao (1):
spec: Open 8000 and 8001 port by default
Makefile.am | 2 ++
contrib/DEBIAN/control.in | 1 +
contrib/DEBIAN/postinst | 6 ++++++
contrib/DEBIAN/postrm | 2 ++
contrib/kimchi.spec.fedora.in | 26 ++++++++++++++++++++++++++
src/Makefile.am | 1 +
src/firewalld.xml | 7 +++++++
7 files changed, 45 insertions(+)
create mode 100644 src/firewalld.xml
--
1.8.3.1
10 years, 10 months
[PATCH V2] Add support to RHEL 7
by abotega@linux.vnet.ibm.com
From: Adriano Botega <abotega(a)linux.vnet.ibm.com>
V1 -> V2:
Addressed Mark's comment: Just add the hyphen to the matching characters set.
RHEL 7 is the next Red Hat Enterprise distro version and because of a difference in the distro name in Volume Descriptor Table on it's ISO file, Kimchi is not recognizing as a RHEL distro.
This patch adds the correct regex to add support to RHEL 7
Signed-off-by: Adriano Botega <abotega(a)linux.vnet.ibm.com>
---
src/kimchi/isoinfo.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/kimchi/isoinfo.py b/src/kimchi/isoinfo.py
index 7e6d733..62cce39 100644
--- a/src/kimchi/isoinfo.py
+++ b/src/kimchi/isoinfo.py
@@ -110,7 +110,7 @@ iso_dir = [
('opensuse', '12.2',
'openSUSE-DVD-i586-Build0167|openSUSE-DVD-x86_640167'),
('rhel', '4.8', 'RHEL/4-U8'),
- ('rhel', lambda m: m.group(1), 'RHEL[_/](\d+\.\d+)'),
+ ('rhel', lambda m: m.group(1), 'RHEL[_/-](\d+\.\d+)'),
('debian', lambda m: m.group(1), 'Debian (\d+\.\d+)'),
('ubuntu', lambda m: m.group(2), '[Uu]buntu(-Server)? (\d+\.\d+)'),
('fedora', lambda m: m.group(1), 'Fedora[ -](\d+)'),
--
1.8.4.2
10 years, 10 months
About the pre-integration test
by Shu Ming
Hi,
After running the full unit-test cases by "sudo ./run_test.sh", I found
the test cases were broken in all platforms including Fedora 20, Fedora
18, Ubuntu 12.04. I am not sure which patch broke it, but I think we
should make sure all the existing unit-test cases passed before
integration.
To the maintainer, please enforce it when merging the patches. To the
patch's submitter, please do a full unit test before submitting your
patches into the mailing lists. It is very common for a new patch to
trigger other test case's failure which seems non-related. Please make
your code clean by the unit test cases. The unit test cases may take one
minute, but it will save other's time in hours.
10 years, 10 months
[PATCH V5] Add nfs server and target UI in create storage pool
by zhoumeina
v4-v5 Change some html nits.
V3-V4 add value in jquery widget.
move all storage all page style to css files.
v2-v3 Make nfs server inputbox to combobox
Edit jquery widgets to fix some small nits in it.
change some parameter according to the changes from
back end.
v1-v2 Fix some bug in this patch, make it working and retest
This patch is working adding a select box in create nfs pool,
when user don't want to input the server ip or name, he can
simply select "used the server I have used before" and choose
a server in a select box, this is more convinent.
In order to show server target I did a select box in UI, but sometimes
maybe the export path number is large. So I made a filter-select
widget to make user easier to choose the export path he want.
This is the first jquery widget. And let us make all common widget to
jquery widget from now on.
Signed-off-by: zhoumeina <zhoumein(a)linux.vnet.ibm.com>
---
ui/css/theme-default/button.css | 21 +++--
ui/css/theme-default/form.css | 6 ++
ui/css/theme-default/popover.css | 1 +
ui/css/theme-default/storage.css | 29 ++++++-
ui/js/Makefile.am | 4 +-
ui/js/src/kimchi.api.js | 27 ++++++-
ui/js/src/kimchi.popable.js | 2 +-
ui/js/src/kimchi.storagepool_add_main.js | 72 ++++++++++++++--
ui/js/src/kimchi.utils.js | 11 +++
ui/js/widgets/combobox.js | 131 +++++++++++++++++++++++++++++
ui/js/widgets/filter-select.js | 135 ++++++++++++++++++++++++++++++
ui/js/widgets/select-menu.js | 83 ++++++++++++++++++
ui/pages/i18n.html.tmpl | 5 +-
ui/pages/storagepool-add.html.tmpl | 59 ++++++++------
14 files changed, 539 insertions(+), 47 deletions(-)
create mode 100644 ui/js/widgets/combobox.js
create mode 100644 ui/js/widgets/filter-select.js
create mode 100644 ui/js/widgets/select-menu.js
diff --git a/ui/css/theme-default/button.css b/ui/css/theme-default/button.css
index c7ed3f6..dcca6a9 100644
--- a/ui/css/theme-default/button.css
+++ b/ui/css/theme-default/button.css
@@ -247,30 +247,37 @@
.btn-select {
display: inline-block;
position: relative;
- height: 38px;
+ height: 30px;
padding-right: 20px;
margin: 5px;
vertical-align: top;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
- border-radius: 5px;
- background: #eee;
+ background: #fff;
box-shadow: -1px -1px 1px #666, 1px 1px 1px #fff, 2px 2px 2px rgba(0, 0, 0, .15) inset;
font-size: 13px;
- line-height: 38px;
+ line-height: 30px;
text-align: left;
cursor: pointer;
}
-.btn-select .text {
+.btn-select .input {
+ border: 0 solid #CCCCCC;
padding: 0 10px;
+ margin-right: 10px;
+ font-size: 16px;
+ height: 30px;
+ line-height: 30px;
+ width: 100%;
+ position: absolute;
+ background: transparent;
}
.btn-select .arrow {
position: absolute;
width: 15px;
- height: 38px;
- line-height: 38px;
+ height: 30px;
+ line-height: 30px;
top: 0;
right: 5px;
background: url(../images/theme-default/arrow-down-black.png) no-repeat center center;
diff --git a/ui/css/theme-default/form.css b/ui/css/theme-default/form.css
index 28e30a5..d1a3885 100644
--- a/ui/css/theme-default/form.css
+++ b/ui/css/theme-default/form.css
@@ -49,4 +49,10 @@
.form-section input.invalid-field[type="text"] {
border-color: #FF4444;
+}
+
+.text-help {
+ font-size: 12px;
+ color: #333;
+ margin: 0 0 5px 5px;
}
\ No newline at end of file
diff --git a/ui/css/theme-default/popover.css b/ui/css/theme-default/popover.css
index 95eb183..e91ccc0 100644
--- a/ui/css/theme-default/popover.css
+++ b/ui/css/theme-default/popover.css
@@ -31,6 +31,7 @@
left: 0;
display: none;
cursor: default;
+ width: 100%;
}
.popover:BEFORE {
diff --git a/ui/css/theme-default/storage.css b/ui/css/theme-default/storage.css
index d81dc75..62e1540 100644
--- a/ui/css/theme-default/storage.css
+++ b/ui/css/theme-default/storage.css
@@ -529,7 +529,7 @@
width: 300px;
display: inline-block;
vertical-align: top;
- padding: 5px 5px 5px 20px;
+ padding: 5px 5px 5px 22px;
}
.storage-type-wrapper-controls input[type="text"] {
@@ -548,11 +548,36 @@
.storage-type-wrapper-controls > .dropdown {
margin: 5px 0 0 1px;
- width: 250px;
+ width: 150px;
}
.storage-type-wrapper-controls input[type="text"][disabled] {
color: #bbb;
background-color: #fafafa;
cursor: not-allowed;
+}
+
+.storage-add-input-width {
+ width: 285px;
+}
+
+.form-section .storage-field {
+ overflow: visible;
+}
+
+.storage-base-input-width {
+ width: 300px;
+}
+
+.storage-window {
+ width: 600px;
+ height: 700px;
+}
+
+.storage-port-width {
+ width:40px;
+}
+
+.storage-auth-width {
+ width: 150px;
}
\ No newline at end of file
diff --git a/ui/js/Makefile.am b/ui/js/Makefile.am
index 6808226..65254da 100644
--- a/ui/js/Makefile.am
+++ b/ui/js/Makefile.am
@@ -20,7 +20,7 @@
SUBDIRS = novnc
-EXTRA_DIST = src
+EXTRA_DIST = src widgets
jsdir = $(datadir)/kimchi/ui/js
@@ -31,7 +31,7 @@ dist_js_DATA = \
modernizr.custom.2.6.2.min.js \
$(NULL)
-kimchi.min.js: src/*.js
+kimchi.min.js: widgets/*.js src/*.js
cat $(sort $^) > $@
CLEANFILES = kimchi.min.js
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
index a4608ff..8d006d2 100644
--- a/ui/js/src/kimchi.api.js
+++ b/ui/js/src/kimchi.api.js
@@ -683,5 +683,30 @@ var kimchi = {
success : suc,
error : err
});
+ },
+
+ getStorageServers: function(type, suc, err) {
+ var url = kimchi.url + 'storageservers?target_type=' + type;
+ kimchi.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ getStorageTargets: function(server,type, suc, err) {
+ var url = kimchi.url + 'storageservers/' + server + '/storagetargets?target_type=' + type;
+ kimchi.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ timeout: 2000,
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
}
-};
+};
\ No newline at end of file
diff --git a/ui/js/src/kimchi.popable.js b/ui/js/src/kimchi.popable.js
index 153d32c..2a843be 100644
--- a/ui/js/src/kimchi.popable.js
+++ b/ui/js/src/kimchi.popable.js
@@ -25,7 +25,7 @@ kimchi.popable = function() {
$(document).on("click", ".popable", function(e) {
var isOpen = $(this).hasClass('open');
$(".popable").removeClass('open');
- if (!isOpen) {
+ if (!isOpen && $(this).find('ul').html() !== '') {
$(this).addClass('open');
}
diff --git a/ui/js/src/kimchi.storagepool_add_main.js b/ui/js/src/kimchi.storagepool_add_main.js
index 24de979..85ac70f 100644
--- a/ui/js/src/kimchi.storagepool_add_main.js
+++ b/ui/js/src/kimchi.storagepool_add_main.js
@@ -29,6 +29,9 @@ kimchi.storagepool_add_main = function() {
};
kimchi.initStorageAddPage = function() {
+ $('#poolTypeId').selectMenu();
+ $('#serverComboboxId').combobox();
+ $('#targetFilterSelectId').filterselect();
var options = [ {
label : "DIR",
value : "dir"
@@ -54,8 +57,66 @@ kimchi.initStorageAddPage = function() {
});
$('.host-partition').html(listHtml);
}
- kimchi.select('storagePool-list', options);
- $('#poolType').change(function() {
+ $('#poolTypeId').selectMenu("setData", options);
+ kimchi.getStorageServers('netfs', function(data) {
+ var serverContent = [];
+ serverContent.push({
+ label : i18n['select_default'],
+ value : ''
+ });
+ if (data.length > 0) {
+ $.each(data, function(index, value) {
+ serverContent.push({
+ label : value.addr,
+ value : value.addr
+ });
+ });
+ }
+ $('#serverComboboxId').combobox("setData", serverContent);
+ $('input[name=nfsServerType]').change(function() {
+ if ($(this).val() === 'input') {
+ $('#nfsServerInputDiv').removeClass('tmpl-html');
+ $('#nfsServerChooseDiv').addClass('tmpl-html');
+ } else {
+ $('#nfsServerInputDiv').addClass('tmpl-html');
+ $('#nfsServerChooseDiv').removeClass('tmpl-html');
+ }
+ });
+ $('#nfsserverId').on("change",function() {
+ if ($(this).val() !== '' && kimchi.isServer($(this).val())) {
+ $('#nfspathId').prop('disabled',false);
+ } else {
+ $('#nfspathId').prop( "disabled",true);
+ }
+ $('#targetFilterSelectId').filterselect('clear');
+ });
+ $('#nfspathId').focus(function() {
+ var targetContent = [];
+ kimchi.getStorageTargets($('#nfsserverId').val(), 'netfs', function(data) {
+ if (data.length > 0) {
+ $.each(data, function(index, value) {
+ targetContent.push({
+ label : value.target,
+ value : value.target
+ });
+ });
+ } else {
+ targetContent.push({
+ label : i18n['msg.no.result'],
+ value : ''
+ });
+ }
+ $('#targetFilterSelectId').filterselect("setData", targetContent);
+ },function() {
+ targetContent.push({
+ label : i18n['msg.no.result'],
+ value : ''
+ });
+ $('#targetFilterSelectId').filterselect("setData", targetContent);
+ });
+ });
+ });
+ $('#poolTypeInputId').change(function() {
if ($(this).val() === 'dir') {
$('.path-section').removeClass('tmpl-html');
$('.logical-section').addClass('tmpl-html');
@@ -111,7 +172,6 @@ kimchi.validateForm = function() {
} else {
return kimchi.validateLogicalForm();
}
-
};
kimchi.validateDirForm = function () {
@@ -162,11 +222,7 @@ kimchi.validateServer = function(serverField) {
kimchi.message.error(i18n['msg.pool.edit.server.blank']);
return false;
}
- var domain = "([0-9a-z_!~*'()-]+\.)*([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\.[a-z]{2,6}"
- var ip = "(\\d{1,3}\.){3}\\d{1,3}"
- regex = new RegExp('^' + domain + '|' + ip + '$')
-
- if (!regex.test(serverField)) {
+ if(kimchi.isServer(nfsserver)) {
kimchi.message.error(i18n['msg.validate.pool.edit.server']);
return false;
}
diff --git a/ui/js/src/kimchi.utils.js b/ui/js/src/kimchi.utils.js
index a23bf51..3cf36b9 100644
--- a/ui/js/src/kimchi.utils.js
+++ b/ui/js/src/kimchi.utils.js
@@ -168,3 +168,14 @@ kimchi.isUnsignedNumeric = function(number) {
var reg = /^d+(.d+)?$/
return reg.test(number);
}
+
+kimchi.isServer = function(server) {
+ var domain = "([0-9a-z_!~*'()-]+\.)*([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\.[a-z]{2,6}";
+ var ip = "(\\d{1,3}\.){3}\\d{1,3}";
+ regex = new RegExp('^' + domain + '|' + ip + '$');
+ if (!regex.test(server)) {
+ return false;
+ } else {
+ return true;
+ }
+};
diff --git a/ui/js/widgets/combobox.js b/ui/js/widgets/combobox.js
new file mode 100644
index 0000000..aa948e6
--- /dev/null
+++ b/ui/js/widgets/combobox.js
@@ -0,0 +1,131 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013
+ *
+ * Authors:
+ * zhoumeina <zhoumein(a)linux.vnet.ibm.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+(function($) {
+ $.widget('kimchi.combobox', {
+ _create : function() {
+ this.selectDiv = this.element;
+ this.listControl = this.selectDiv.find('ul').first();
+ this.listControl.html('');
+ this.target = this.selectDiv.find('input').first();
+ this.selectDiv.addClass('btn-select dropdown popable');
+ this.target.addClass('input');
+ this.listControl.addClass('select-list');
+ this.listControl.parent().addClass('popover');
+ },
+
+ setData : function(options) {
+ this.listControl.html('');
+ var that = this;
+ var value = this.target.val();
+ var selectedClass = 'active';
+ var itemTag = 'li';
+
+ that.listControl.on('click', itemTag, function(e) {
+ that.listControl.children().removeClass(selectedClass);
+ that.listControl.addClass(selectedClass);
+ that.target.text($(this).text());
+ var oldValue = that.target.val();
+ var newValue = $(this).data('value');
+ that.target.val(newValue);
+ if (oldValue !== newValue) {
+ that.target.change();
+ }
+ });
+
+ that.selectDiv.click(function(e) {
+ that.listControl.html('');
+ var items = that._dataList(options);
+ $.each(items, function(index, item) {
+ that.listControl.append(item);
+ })
+ });
+
+ that.target.keyup(function(event) {
+ that.listControl.html('');
+ var items = that._dataList(options);
+ var temp = 0;
+ $.each(items, function(index, item) {
+ if (item.html().indexOf(that.target.val()) >= 0) {
+ that.listControl.append(item);
+ temp++;
+ }
+ });
+ if (that.listControl.html() === '') {
+ that.listControl.html(i18n['msg.no.mapping.result']);
+ }
+ if (temp > 0) {
+ that._open();
+ }
+ });
+ },
+
+ value : function(value) {
+ if (value === undefined) {
+ return this.target.val();
+ }
+ this.target.val(value);
+ },
+
+ _dataList : function(options) {
+ var item;
+ var itemTag = 'li';
+ var selectedClass = 'active';
+ var items = [];
+ var that = this;
+ $.each(options, function(index, option) {
+ item = $('<' + itemTag + '></' + itemTag + '>');
+ item.text(option.label);
+ item.data('value', option.value);
+ if (option.value === that.target.val()) {
+ item.addClass(selectedClass);
+ }
+ items.push(item);
+ });
+ return items;
+ },
+
+ clear : function() {
+ this.target.val("");
+ },
+
+ _open : function() {
+ var isOpen = this.selectDiv.hasClass('open');
+ if (!isOpen) {
+ this.selectDiv.addClass('open');
+ }
+ },
+
+ _close : function() {
+ var isOpen = this.selectDiv.hasClass('open');
+ if (isOpen) {
+ this.selectDiv.removeClass('open');
+ }
+ },
+
+ destroy : function() {
+ this.selectDiv.removeClass('btn-select dropdown popable');
+ this.target.removeClass('input');
+ this.listControl.removeClass('select-list');
+ this.listControl.parent().removeClass('popover');
+ $.Widget.prototype.destroy.call(this);
+ }
+ });
+}(jQuery));
\ No newline at end of file
diff --git a/ui/js/widgets/filter-select.js b/ui/js/widgets/filter-select.js
new file mode 100644
index 0000000..6eaaa94
--- /dev/null
+++ b/ui/js/widgets/filter-select.js
@@ -0,0 +1,135 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013
+ *
+ * Authors:
+ * zhoumeina <zhoumein(a)linux.vnet.ibm.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+(function($) {
+ $.widget('kimchi.filterselect', {
+ _create : function() {
+ this.selectDiv = this.element;
+ this.listControl = this.selectDiv.find('ul').first();
+ this.listControl.html('');
+ this.target = this.selectDiv.find('input').first();
+ this.selectDiv.addClass('btn-select dropdown popable');
+ this.target.addClass('input');
+ this.listControl.addClass('select-list');
+ this.listControl.parent().addClass('popover');
+ },
+
+ setData : function(options) {
+ this.listControl.html('');
+ var that = this;
+ var value = this.target.val();
+ var selectedClass = 'active';
+ var itemTag = 'li';
+
+ that.listControl.on('click', itemTag, function(e) {
+ that.listControl.children().removeClass(selectedClass);
+ that.listControl.addClass(selectedClass);
+ that.target.text($(this).text());
+ var oldValue = that.target.val();
+ var newValue = $(this).data('value');
+ that.target.val(newValue);
+ if (oldValue !== newValue) {
+ that.target.change();
+ }
+ });
+
+ that.selectDiv.click(function(e) {
+ that.listControl.html('');
+ var items = that._dataList(options);
+ if (items.length === 0) {
+ that.listControl.html(i18n['msg.no.mapping.result']);
+ } else {
+ $.each(items, function(index, item) {
+ that.listControl.append(item);
+ })
+ }
+ });
+
+ that.target.keyup(function(event) {
+ that.listControl.html('');
+ var items = that._dataList(options);
+ var temp = 0;
+ $.each(items, function(index, item) {
+ if (item.html().indexOf(that.target.val()) >= 0) {
+ that.listControl.append(item);
+ temp++;
+ }
+ });
+ if (that.listControl.html() === '') {
+ that.listControl.html(i18n['msg.no.mapping.result']);
+ }
+ if (temp > 0) {
+ that._open();
+ }
+ });
+ },
+
+ value : function(value) {
+ if (value === undefined) {
+ return this.target.val();
+ }
+ this.target.val(value);
+ },
+
+ _dataList : function(options) {
+ var item;
+ var itemTag = 'li';
+ var selectedClass = 'active';
+ var items = [];
+ var that = this;
+ $.each(options, function(index, option) {
+ item = $('<' + itemTag + '></' + itemTag + '>');
+ item.text(option.label);
+ item.data('value', option.value);
+ if (option.value === that.target.val()) {
+ item.addClass(selectedClass);
+ }
+ items.push(item);
+ });
+ return items;
+ },
+
+ clear : function() {
+ this.target.val("");
+ },
+
+ _open : function() {
+ var isOpen = this.selectDiv.hasClass('open');
+ if (!isOpen) {
+ this.selectDiv.addClass('open');
+ }
+ },
+
+ _close : function() {
+ var isOpen = this.selectDiv.hasClass('open');
+ if (isOpen) {
+ this.selectDiv.removeClass('open');
+ }
+ },
+
+ destroy : function() {
+ this.selectDiv.removeClass('btn-select dropdown popable');
+ this.target.removeClass('input');
+ this.listControl.removeClass('select-list');
+ this.listControl.parent().removeClass('popover')
+ $.Widget.prototype.destroy.call(this);
+ }
+ });
+}(jQuery));
\ No newline at end of file
diff --git a/ui/js/widgets/select-menu.js b/ui/js/widgets/select-menu.js
new file mode 100644
index 0000000..053eeba
--- /dev/null
+++ b/ui/js/widgets/select-menu.js
@@ -0,0 +1,83 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013
+ *
+ * Authors:
+ * zhoumeina <zhoumein(a)linux.vnet.ibm.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+(function($) {
+ $.widget('kimchi.selectMenu', {
+
+ _create : function() {
+ this.selectDiv = this.element;
+ this.listControl = this.selectDiv.find('ul').first();
+ this.listControl.html('');
+ this.target = this.selectDiv.find('input').first();
+ this.label = this.selectDiv.find('span').first();
+ this.selectDiv.addClass('btn-select dropdown popable');
+ this.target.addClass('input');
+ this.label.addClass('input');
+ this.listControl.addClass('select-list');
+ this.listControl.parent().addClass('popover');
+ },
+
+ setData : function (options) {
+ var that = this;
+ var value = this.target.val();
+ var selectedClass = 'active';
+ var itemTag = 'li';
+ $.each(options, function(index, option) {
+ item = $('<' + itemTag + '></' + itemTag + '>');
+ item.text(option.label);
+ item.data('value', option.value);
+ if(option.value === value) {
+ item.addClass(selectedClass);
+ that.label.text(option.label);
+ }
+ that.listControl.append(item);
+ });
+ that.listControl.on('click', itemTag, function() {
+ that.listControl.children().removeClass(selectedClass);
+ that.listControl.addClass(selectedClass);
+ that.label.text($(this).text());
+ var oldValue = that.target.val();
+ var newValue = $(this).data('value');
+ that.target.val(newValue);
+ if(oldValue !== newValue) {
+ that.target.change();
+ }
+ });
+
+ },
+
+ value : function(data) {
+ if (data === undefined) {
+ return this.target.val();
+ }
+ this.target.val(data.value);
+ this.label.val(data.label);
+ },
+
+ destroy : function() {
+ this.selectDiv.removeClass('btn-select dropdown popable');
+ this.target.removeClass('input');
+ this.label.removeClass('input');
+ this.listControl.removeClass('select-list');
+ this.listControl.parent().removeClass('popover');
+ $.Widget.prototype.destroy.call(this);
+ }
+ });
+}(jQuery));
\ No newline at end of file
diff --git a/ui/pages/i18n.html.tmpl b/ui/pages/i18n.html.tmpl
index 603f8d7..9727eba 100644
--- a/ui/pages/i18n.html.tmpl
+++ b/ui/pages/i18n.html.tmpl
@@ -122,7 +122,10 @@ var i18n = {
" there, are you sure to continue? ")",
'msg.pool.edit.iscsitarget.blank': "$_("The iSCSI target can not be blank.")",
'msg.pool.edit.server.blank':"$_("Server name can not be blank.")",
- 'msg.validate.pool.edit.server':"$_("This is not a valid Server Name or IP. please, modify it.")"
+ 'msg.validate.pool.edit.server':"$_("This is not a valid Server Name or IP. please, modify it.")",
+ 'select_default': "$_("Please choose")",
+ 'msg.no.mapping.result': "$_("No such data exsit.")",
+ 'msg.no.result' : "$_("No valid result")"
};
</script>
</body>
diff --git a/ui/pages/storagepool-add.html.tmpl b/ui/pages/storagepool-add.html.tmpl
index e8dac43..6518df0 100644
--- a/ui/pages/storagepool-add.html.tmpl
+++ b/ui/pages/storagepool-add.html.tmpl
@@ -27,7 +27,7 @@
<!DOCTYPE html>
<html>
<body>
- <div class="window" style="width: 600px; height: 700px;">
+ <div class="window storage-window">
<header>
<h1 class="title">$_("Define a New Storage Pool")</h1>
<div class="close">X</div>
@@ -40,18 +40,17 @@
<p class="text-help">
$_("The name used to identify the storage pools, and it should not be empty.")
</p>
- <input id="poolId" required="required" type="text" class="text" style="width: 300px"
- name="name">
+ <input id="poolId" required="required" type="text" class="text storage-base-input-width" name="name">
</div>
</section>
<section class="form-section">
<h2>2. $_("Storage Pool Type")</h2>
<div class="storage-type-wrapper-controls">
- <div class="btn dropdown popable">
- <input id="poolType" name="type" type="hidden" value="dir"/>
- <span class="text" id="pool-type-label"></span><span class="arrow"></span>
- <div class="popover" style="width: 100%">
- <ul class="select-list" id="storagePool-list" data-target="poolType" data-label="pool-type-label">
+ <div id="poolTypeId">
+ <input id="poolTypeInputId" name="type" type="hidden" value="dir"/>
+ <span id="pool-type-label"></span><span class="arrow"></span>
+ <div>
+ <ul id="storagePool-list">
</ul>
</div>
</div>
@@ -65,30 +64,40 @@
$_("The path of the Storage Pool. Each Storage Pool must have a unique path.")</p>
<p class="text-help">
$_("Kimchi will try to create the directory when it does not already exist in your system.")</p>
- <input id="pathId" type="text" class="text" required="required" style="width: 300px">
+ <input id="pathId" type="text" class="text storage-base-input-width" required="required">
</div>
<div class="clear"></div>
</section>
</div>
<div class="nfs-section tmpl-html">
<section class="form-section">
- <h2>3. $_("NFS server IP")</h2>
- <div class="field">
+ <h2>3. $_("NFS Server IP")</h2>
+ <div class="field storage-field">
<p class="text-help">
- $_("NFS server IP or hostname. It should not be empty.")</p>
- <input id="nfsserverId" required="required" type="text" class="text"
- style="width: 300px">
+ $_("NFS server IP or hostname. It can be input or chosen from history.")</p>
+ <div id="serverComboboxId" class="storage-add-input-width">
+ <input id="nfsserverId"/>
+ <span class="arrow"></span>
+ <div>
+ <ul id="nfs-server-used">
+ </ul>
+ </div>
+ </div>
</div>
</section>
<section class="form-section">
<h2>4. $_("NFS Path")</h2>
- <div class="field">
+ <div class="field storage-field">
<p class="text-help">$_("The nfs exported path on nfs server")</p>
- <input id="nfspathId" required="required" type="text" class="text"
- style="width: 300px">
- <input type="hidden" id="localpathId" class="text" value="none">
- </div>
- <div class="clear"></div>
+ <div id="targetFilterSelectId" class="storage-add-input-width">
+ <input id="nfspathId" class="input" disabled/>
+ <span class="arrow"></span>
+ <div>
+ <ul id="nfs-server-target">
+ </ul>
+ </div>
+ </div>
+ </div>
</section>
</div>
<div class="logical-section tmpl-html">
@@ -103,15 +112,15 @@
<div class="field">
<p class="text-help">
$_("iSCSI server IP or hostname. It should not be empty.")</p>
- <input id="iscsiserverId" placeholder="$_("Server")" type="text" class="text" style="width: 300px">
- <input id="iscsiportId" placeholder="$_("Port")" type="text" class="text" style="width:40px" maxlength='4'>
+ <input id="iscsiserverId" placeholder="$_("Server")" type="text" class="text storage-base-input-width">
+ <input id="iscsiportId" placeholder="$_("Port")" type="text" class="text storage-port-width" maxlength="4">
</div>
</section>
<section class="form-section">
<h2>4. $_("Target")</h2>
<div class="field">
<p class="text-help">$_("The iSCSI target on iSCSI server")</p>
- <input id="iscsiTargetId" type="text" class="text" style="width: 300px">
+ <input id="iscsiTargetId" type="text" class="text storage-base-input-width>
</div>
</section>
<section class="form-section">
@@ -123,8 +132,8 @@
<section class="authenticationfield form-section tmpl-html">
<h2>5. $_("iSCSI Authentication")</h2>
<div class="field">
- <input id="usernameId" placeholder="$_("User Name")" type="text" class="text" style="width: 150px">
- <input id="passwordId" placeholder="$_("Password")" type="text" class="text" style="width: 150px">
+ <input id="usernameId" placeholder="$_("User Name")" type="text" class="text storage-auth-width">
+ <input id="passwordId" placeholder="$_("Password")" type="text" class="text storage-auth-width">
</div>
</section>
</div>
--
1.7.1
10 years, 10 months
Re: [Kimchi-devel] [project-kimchi] [PATCH] Bug Fix: Get correct exception info when run unittest on Python2.6
by Sheldon
On 07/09/2013 02:51 AM, Adam Litke wrote:
> On Thu, Jul 04, 2013 at 05:50:06PM +0800, caobbu(a)linux.vnet.ibm.com wrote:
>> From: Bing Bu Cao <mars(a)linux.vnet.ibm.com>
>>
>> When running unittest on SLES(python2.6), found a problem:
>> If an exception occurs in body of 'with' statement, the 'exc_value' is a str
>> not a exception object, 'raise firstException' will raise a TypeError.
>> In this case, we will not get info of the first exception.
>>
>> This is a bug on Python 2.6:
>> http://bugs.python.org/issue7853
>>
>> Reference:
>> http://docs.python.org/2.7/library/stdtypes.html#context-manager-types
>>
>> Signed-off-by: Bing Bu Cao <mars(a)linux.vnet.ibm.com>
>> ---
>> tests/utils.py | 15 ++++-----------
>> 1 files changed, 4 insertions(+), 11 deletions(-)
>>
>> diff --git a/tests/utils.py b/tests/utils.py
>> index debccfb..11c8bf4 100644
>> --- a/tests/utils.py
>> +++ b/tests/utils.py
>> @@ -128,21 +128,14 @@ class RollbackContext(object):
>> return self
>>
>> def __exit__(self, exc_type, exc_value, traceback):
>> - firstException = exc_value
>> -
>> for undo, args, kwargs in self._finally:
>> try:
>> undo(*args, **kwargs)
>> except Exception as e:
>> - # keep the earliest exception info
>> - if not firstException:
>> - firstException = e
>> - # keep the original traceback info
>> - traceback = sys.exc_info()[2]
>> -
>> - # re-raise the earliest exception
>> - if firstException is not None:
>> - raise firstException, None, traceback
> I don't think the proper solution is to delete the ability to raise the
> previous exception. To workaround the python bug you could just check
> the type of exc_value and only raise if it's an Exception. If it's a
> string you can just log it.
not only string but also int.
should we still consider this patch.
or we will not give up to support RollbackContext on some distros?
$ ./run_tests.sh test_utils
FE
======================================================================
ERROR: test_path_permission (test_utils.searchPermissionTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/user/kimchi/tests/test_utils.py", line 145, in
test_path_permission
break
File "/home/user/kimchi/tests/utils.py", line 177, in __exit__
raise firstException, None, traceback
TypeError: exceptions must be old-style classes or derived from
BaseException, not int
>
>> + traceback = sys.exc_info()[2]
>> + raise e, None, traceback
>> +
>> + return False if exc_value is not None else True
>>
>> def defer(self, func, *args, **kwargs):
>> self._finally.append((func, args, kwargs))
>> --
>> 1.7.7.6
>>
>> --
>> project-kimchi mailing list <project-kimchi(a)googlegroups.com>
>> https://groups.google.com/forum/#!forum/project-kimchi
>> ---
>> You received this message because you are subscribed to the Google Groups "project-kimchi" group.
>> To unsubscribe from this group and stop receiving emails from it, send an email to project-kimchi+unsubscribe(a)googlegroups.com.
>> For more options, visit https://groups.google.com/groups/opt_out.
>>
>>
--
Thanks and best regards!
Sheldon Feng(冯少合)<shaohef(a)linux.vnet.ibm.com>
IBM Linux Technology Center
10 years, 10 months
[kimchi-devel RFC] REST API for Permission check and fixes
by Royce Lv
User scenarios:
Users may create template from ISOs from shallow/deep scan or from
a user specified local path. Because kimchid runs as root and have
access of most ISOs scanned. For qemu, however, the real user to start a
vm, does not always have access of the ISO to install a vm. Under this
circumstance, we need to denote that:
1. On scanning, indicate which ISOs may not be accessible by qemu user.
2. When create a template from an ISO which qemu does not have access ,
ask if user want to fix permission, if not, disable the template.
3. If user accept fix permission, change permission of template cdrom.
Rest API will look like:
1. scanning and report
GET /storagepools/pool-1/storagevolumes/iso-volume
{'type': 'raw', 'path': '/home/i-am-an-iso.iso', 'accessible': False}
2. Create template
POST /templates
{'name': 'template-1'
'cdrom': 'a-b-c'} "a-b-c.iso" not accessible by qemu
---->
{'name': 'template-1', 'status': 'disable'}
NOTE: template in 'disable' status may because of any of its
facility not active (storagepool, iso, network, etc)
3. Fix permission(Permission fix just open for template, we don't
support fix for single volume/path temporarily)
PUT /templates/t-1/cdrom {'accessible': True}
10 years, 10 months
[RFC]: Use lxml to generate and manipulate XML documents
by Sheldon
As we all know there is a issue about generate and manipulate XML documents
*https://github.com/kimchi-project/kimchi/issues/124*
IMO, lxml is a good choice.
you can see this patch:
$ git show 69edfe9
Mark use it to generate XML documents.
And for manipulate XML documents, here is a example.
/$ ipython -c 'from lxml import objectify
root = objectify.fromstring("<root><a
k=\"key\">24.12.2000<b>12.24.2000</b></a></root>")
print root.a
print root.a.b
print root.a.get("k")
' /
/re//sult//: //
//24.12.2000 //
//12.24.2000 //
//key /
more info: http://lxml.de/
--
Thanks and best regards!
Sheldon Feng(???)<shaohef(a)linux.vnet.ibm.com>
IBM Linux Technology Center
10 years, 10 months