[PATCH] User action menu overflows when actions with names longer than a few chars are included
by Adam King
Update the CSS so the user action menu will expand to accomodate longer action names
Signed-off-by: Adam King <rak(a)linux.vnet.ibm.com>
---
ui/css/theme-default/topbar.css | 1 +
1 file changed, 1 insertion(+)
diff --git a/ui/css/theme-default/topbar.css b/ui/css/theme-default/topbar.css
index 7180cd5..b6f2fef 100644
--- a/ui/css/theme-default/topbar.css
+++ b/ui/css/theme-default/topbar.css
@@ -155,6 +155,7 @@
color: black;
padding: 12px 18px;
white-space: nowrap;
+ width: inherit;
}
.user-menu-item {
--
1.9.0
10 years, 8 months
[V3] UI: Edit Guest Network Interface
by huoyuxin@linux.vnet.ibm.com
From: Yu Xin Huo <huoyuxin(a)linux.vnet.ibm.com>
Signed-off-by: Yu Xin Huo <huoyuxin(a)linux.vnet.ibm.com>
---
ui/css/theme-default/guest-edit.css | 43 ++++++++++++++++
ui/js/src/kimchi.api.js | 55 +++++++++++++++++++++
ui/js/src/kimchi.guest_edit_main.js | 91 +++++++++++++++++++++++++++++++++++
ui/pages/guest-edit.html.tmpl | 28 +++++++++++
4 files changed, 217 insertions(+), 0 deletions(-)
diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css
index b4d2105..36f7f75 100644
--- a/ui/css/theme-default/guest-edit.css
+++ b/ui/css/theme-default/guest-edit.css
@@ -156,3 +156,46 @@
.guest-edit-cdrom-button.detach[disabled] {
background-position: -54px -108px;
}
+
+.guest-edit-interface .header {
+ margin-bottom: 8px;
+ padding-bottom: 2px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+ overflow: hidden;
+}
+
+.guest-edit-interface .body .item {
+ margin: 5px 0;
+}
+
+.guest-edit-interface .cell {
+ display: inline-block;
+ width: 250px;
+}
+
+.guest-edit-interface .body select {
+ width: 180px;
+ padding: 0px;
+}
+
+.guest-edit-interface .action-area {
+ float: right;
+}
+
+.guest-edit-interface button {
+ width: 20px;
+ height: 20px;
+}
+
+.guest-edit-interface .header button {
+ margin-bottom: 1px;
+}
+
+.guest-edit-interface .body button:not(:last-child) {
+ margin-right: 2px;
+}
+
+.guest-edit-interface .hide {
+ display: none;
+}
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
index 29a5770..3c6765c 100644
--- a/ui/js/src/kimchi.api.js
+++ b/ui/js/src/kimchi.api.js
@@ -970,5 +970,60 @@ var kimchi = {
kimchi.message.error(data.responseJSON.reason);
}
});
+ },
+
+ getGuestInterfaces: function(name, suc, err) {
+ var url = kimchi.url+'vms/'+encodeURIComponent(name)+'/ifaces';
+ kimchi.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err || function(data) {
+ kimchi.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ createGuestInterface : function(name, interface, suc, err) {
+ kimchi.requestJSON({
+ url : kimchi.url+'vms/'+encodeURIComponent(name)+'/ifaces',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ data : JSON.stringify(interface),
+ success : suc,
+ error : err || function(data) {
+ kimchi.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ deleteGuestInterface : function(vm, mac, suc, err) {
+ kimchi.requestJSON({
+ url : kimchi.url+'vms/'+encodeURIComponent(vm)+'/ifaces/'+encodeURIComponent(mac),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ kimchi.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ updateGuestInterface : function(vm, mac, interface, suc, err) {
+ $.ajax({
+ url : kimchi.url+'vms/'+encodeURIComponent(vm)+'/ifaces/'+encodeURIComponent(mac),
+ type : 'PUT',
+ contentType : 'application/json',
+ data : JSON.stringify(interface),
+ dataType : 'json',
+ success: suc,
+ error: err ? err : function(data) {
+ kimchi.message.error(data.responseJSON.reason);
+ }
+ });
}
};
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js
index 8a44b54..2ba6b79 100644
--- a/ui/js/src/kimchi.guest_edit_main.js
+++ b/ui/js/src/kimchi.guest_edit_main.js
@@ -78,6 +78,95 @@ kimchi.guest_edit_main = function() {
});
};
+ var setupInterface = function() {
+ $(".add", "#form-guest-edit-interface").button({
+ icons: { primary: "ui-icon-plusthick" },
+ text: false
+ }).click(function(){
+ addItem({
+ mac: "",
+ network: "",
+ type: "network",
+ viewMode: "hide",
+ editMode: ""
+ });
+ });
+ var toggleEdit = function(item, on){
+ $("label", item).toggleClass("hide", on);
+ $("select", item).toggleClass("hide", !on);
+ $(".action-area", item).toggleClass("hide");
+ };
+ var addItem = function(data) {
+ var itemNode = $.parseHTML(kimchi.template($('#interface-tmpl').html(),data));
+ $(".body", "#form-guest-edit-interface").append(itemNode);
+ $("select", itemNode).append(networkOptions);
+ if(data.network!==""){
+ $("select", itemNode).val(data.network);
+ }
+ $(".edit", itemNode).button({
+ disabled: true,
+ icons: { primary: "ui-icon-pencil" },
+ text: false
+ }).click(function(){
+ toggleEdit($(this).parent().parent(), true);
+ });
+ $(".delete", itemNode).button({
+ icons: { primary: "ui-icon-trash" },
+ text: false
+ }).click(function(){
+ var item = $(this).parent().parent();
+ kimchi.deleteGuestInterface(kimchi.selectedGuest, item.prop("id"), function(){
+ item.remove();
+ });
+ });
+ $(".save", itemNode).button({
+ icons: { primary: "ui-icon-disk" },
+ text: false
+ }).click(function(){
+ var item = $(this).parent().parent();
+ var interface = {
+ network: $("select", item).val(),
+ type: "network"
+ };
+ var postUpdate = function(){
+ $("label", item).text(interface.network);
+ toggleEdit(item, false);
+ };
+ if(item.prop("id")==""){
+ kimchi.createGuestInterface(kimchi.selectedGuest, interface, function(data){
+ item.prop("id", data.mac);
+ postUpdate();
+ });
+ }else{
+ kimchi.updateGuestInterface(kimchi.selectedGuest, item.prop("id"), interface, function(){
+ postUpdate();
+ });
+ }
+ });
+ $(".cancel", itemNode).button({
+ icons: { primary: "ui-icon-arrowreturnthick-1-w" },
+ text: false
+ }).click(function(){
+ var item = $(this).parent().parent();
+ $("label", item).text()==="" ? item.remove() : toggleEdit(item, false);
+ });
+ };
+ var networkOptions = "";
+ kimchi.listNetworks(function(data){
+ for(var i=0;i<data.length;i++){
+ var isSlected = i==0 ? " selected" : "";
+ networkOptions += "<option"+isSlected+">"+data[i].name+"</option>";
+ }
+ kimchi.getGuestInterfaces(kimchi.selectedGuest, function(data){
+ for(var i=0;i<data.length;i++){
+ data[i].viewMode = "";
+ data[i].editMode = "hide";
+ addItem(data[i]);
+ }
+ });
+ });
+ };
+
var initContent = function(guest) {
guest['icon'] = guest['icon'] || 'images/icon-vm.png';
$('#form-guest-edit-general').fillWithObject(guest);
@@ -99,6 +188,8 @@ kimchi.guest_edit_main = function() {
refreshCDROMs();
};
+ setupInterface();
+
kimchi.topic('kimchi/vmCDROMAttached').subscribe(onAttached);
kimchi.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced);
kimchi.topic('kimchi/vmCDROMDetached').subscribe(onDetached);
diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl
index aae9694..552b4c8 100644
--- a/ui/pages/guest-edit.html.tmpl
+++ b/ui/pages/guest-edit.html.tmpl
@@ -35,6 +35,9 @@
<li>
<a href="#form-guest-edit-storage">$_("Storage")</a>
</li>
+ <li>
+ <a href="#form-guest-edit-interface">$_("Interface")</a>
+ </li>
</ul>
<form id="form-guest-edit-general">
<fieldset class="guest-edit-fieldset">
@@ -101,6 +104,14 @@
</div>
</fieldset>
</form>
+ <form id="form-guest-edit-interface" class="guest-edit-interface">
+ <div class="header">
+ <span class="cell">$_("Network")</span>
+ <span class="cell">$_("Type")</span>
+ <button class="add action-area"></button>
+ </div>
+ <div class="body"></div>
+ </form>
</div>
</div>
<footer>
@@ -131,6 +142,23 @@
</div>
</div>
</script>
+<script id="interface-tmpl" type="text/html">
+ <div class="item" id="{mac}">
+ <span class="cell">
+ <label class="{viewMode}">{network}</label>
+ <select class="{editMode}"></select>
+ </span>
+ <span class="cell">
+ <span>{type}</span>
+ </span>
+ <span class="action-area {editMode}">
+ <button class="save"></button><button class="cancel"></button>
+ </span>
+ <span class="action-area {viewMode}">
+ <button class="edit"></button><button class="delete"></button>
+ </span>
+ <div>
+</script>
<script type="text/javascript">
kimchi.guest_edit_main();
--
1.7.1
10 years, 8 months
[PATCH v3 0/2] Patch set to correct missed tranlsations
by Adam King
This set updates the input to the po build process, then regenerates the PO files.
Adam King (2):
Update po/POTFILES.in
Regenerate PO files
po/POTFILES.in | 21 +-
po/en_US.po | 1040 ++++++---------------------------------
po/kimchi.pot | 962 ++++--------------------------------
po/pt_BR.po | 1475 ++++++++++++++++++++++++++------------------------------
po/zh_CN.po | 1301 +++++++++++++++++++++++--------------------------
5 files changed, 1541 insertions(+), 3258 deletions(-)
--
1.9.0
10 years, 8 months
[PATCH V7 0/5] bug fix: get user and group when VM is running
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
V6 -> V7:
After V6 rebase, still find one error code "KCHVM0029E" does not change.
V5 -> V6:
rebase
V4 -> V5:
it is wrong to call dom.isPersistent in V4, fix it.
V3 -> V4:
work around if libvirt do not support metadata API well.
V2 -> V3:
move the virDomain.metadata and virDomain.setMetadata to model/utils.py
add testcase
V1 -> V2:
libvirt also support virDomain.metadata and virDomain.setMetadata two api.
use virDomain.metadata to get the user and group.
use virDomain.setMetadata to set the user and group.
ShaoHe Feng (5):
Add two function to set and get domain xml metadata
bug fix: get user and group when vm is living.
update test case to set/get user and group when VM is running
write the template OS info to vm metadata
manually manage the metadata element
src/kimchi/i18n.py | 1 +
src/kimchi/model/utils.py | 73 +++++++++++++++++++++++++++++++++
src/kimchi/model/vms.py | 102 ++++++++++++++++++++++++++++------------------
tests/test_model.py | 13 ++++++
4 files changed, 150 insertions(+), 39 deletions(-)
--
1.9.0
10 years, 8 months
[PATCH V5 0/5] bug fix: get user and group when VM is running
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
V4 -> V5:
it is wrong to call dom.isPersistent in V4, fix it.
V3 -> V4:
work around if libvirt do not support metadata API well.
V2 -> V3:
move the virDomain.metadata and virDomain.setMetadata to model/utils.py
add testcase
V1 -> V2:
libvirt also support virDomain.metadata and virDomain.setMetadata two api.
use virDomain.metadata to get the user and group.
use virDomain.setMetadata to set the user and group.
ShaoHe Feng (5):
Add two function to set and get domain xml metadata
bug fix: get user and group when vm is living.
update test case to set/get user and group when VM is running
write the template OS info to vm metadata
manually manage the metadata element
src/kimchi/i18n.py | 1 +
src/kimchi/model/utils.py | 73 ++++++++++++++++++++++++++++++++++++++++
src/kimchi/model/vms.py | 86 +++++++++++++++++++++++++++--------------------
tests/test_model.py | 13 +++++++
4 files changed, 137 insertions(+), 36 deletions(-)
--
1.9.0
10 years, 8 months
[PATCH v6 0/4] Github #329: Kimchi must not run as root
by Daniel Barboza
From: Daniel Henrique Barboza <danielhb(a)linux.vnet.ibm.com>
New in v6:
- Moved the SSL logic from server.py to proxy.py
- server.py is now responsible to launch the proxy
- removed references of 'ssl_port'
New in v5:
- fixes to VNC connection
- fixes to unit tests
- obscuring kimchid port by making it localhost only
- launhing nginx proxy in unit tests
New in v4:
- added a new module with all nginx-related methods
- added DEBIAN entries
- other fixes proposed by Aline
After reading the comments from Zhou Zheng Sheng, I simplified
the work I did in version 2 to run only one cherrypy process
instead of two processes, one for frontend and another for the
backend. Nginx is still being used as a reverse proxy to allow
kimchid to run as root, but not being exposed to the outside.
As Zhou mentioned, it is to little avail to run frontend and
backend separately if the exposed port is running by the
reverse proxy anyway. He mentioned the RPC approach as a best
long-term approach, which I agree. We can solve this issue right
now and the work in a more suitable solution, such as RPC, and
then ditch nginx.
Daniel Henrique Barboza (4):
Github #329: Proxy module and template file
Github #329: Kimchid, config.py.in and server.py changes
Github #329: changes in mockmodel, model/config and tests
Github #329: .gitignore, spec, control.in and readme
.gitignore | 1 +
Makefile.am | 2 +
contrib/DEBIAN/control.in | 3 +-
contrib/kimchi.spec.fedora.in | 2 +
contrib/kimchi.spec.suse.in | 2 +
docs/README.md | 4 +-
src/Makefile.am | 3 +-
src/kimchi/config.py.in | 5 +-
src/kimchi/mockmodel.py | 2 +-
src/kimchi/model/config.py | 2 +-
src/kimchi/proxy.py | 107 ++++++++++++++++++++++++++++++++++++++++++
src/kimchi/server.py | 44 +++++------------
src/kimchid.in | 44 ++++++++++++-----
src/nginx.conf.in | 55 ++++++++++++++++++++++
tests/test_rest.py | 8 ++--
tests/utils.py | 10 +++-
16 files changed, 238 insertions(+), 56 deletions(-)
create mode 100644 src/kimchi/proxy.py
create mode 100644 src/nginx.conf.in
--
1.8.3.1
10 years, 8 months
[PATCH v2 0/2] Patch set to correct missed tranlsations
by Adam King
This set updates the input to the po build process, then regenerates the PO files.
Adam King (2):
Update po/POTFILES.in
Regenerate PO files
po/POTFILES.in | 22 +-
po/en_US.po | 1123 +++++++++--------------------------------
po/kimchi.pot | 962 ++++-------------------------------
po/pt_BR.po | 1533 ++++++++++++++++++++++++++++----------------------------
po/zh_CN.po | 1354 ++++++++++++++++++++++++-------------------------
5 files changed, 1792 insertions(+), 3202 deletions(-)
--
1.9.0
10 years, 8 months
[PATCH V3 0/3] VM shutdown support in backend
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
V2 -> V3
rebase
V1 -> V2
update a new domain state pmsuspended
ShaoHe Feng (3):
VM shutdown support in backend
VM shutdown support in UI
New domain state pmsuspended
docs/API.md | 3 +++
src/kimchi/control/vms.py | 1 +
src/kimchi/i18n.py | 1 +
src/kimchi/mockmodel.py | 3 +++
src/kimchi/model/vms.py | 11 ++++++++++-
ui/js/src/kimchi.api.js | 11 +++++++++++
ui/js/src/kimchi.guest_main.js | 23 +++++++++++++++++++++++
ui/pages/guest.html.tmpl | 1 +
ui/pages/i18n.html.tmpl | 2 ++
9 files changed, 55 insertions(+), 1 deletion(-)
--
1.9.0
10 years, 8 months
[PATCH 0/2] Patch set to correct missed tranlsations
by Adam King
This set updates the input to the po build process, then regenerates the PO files.
Adam King (2):
Update po/POTFILES.in
Regenerate PO files
po/POTFILES.in | 7 ++-
po/en_US.po | 139 ++++++++++++++++++++++++++++++++++-----------
po/kimchi.pot | 122 +++++++++++++++++++++++++++++++---------
po/pt_BR.po | 175 +++++++++++++++++++++++++++++++++++++++++++--------------
po/zh_CN.po | 163 +++++++++++++++++++++++++++++++++++++++++------------
5 files changed, 465 insertions(+), 141 deletions(-)
--
1.9.0
10 years, 8 months
[PATCH] Fix error storage pool lookup usage in deep scan
by lvroyce@linux.vnet.ibm.com
From: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
Wrong usage of storage pool lookup will result in
deep scan ignore list appending failure,
correct it so that deep scan ignore pool path will work.
Signed-off-by: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
---
src/kimchi/model/storagepools.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/kimchi/model/storagepools.py b/src/kimchi/model/storagepools.py
index ba24538..69cf6fc 100644
--- a/src/kimchi/model/storagepools.py
+++ b/src/kimchi/model/storagepools.py
@@ -155,7 +155,7 @@ class StoragePoolsModel(object):
for pool in self.get_list():
try:
- res = self.storagepool_lookup(pool)
+ res = StoragePoolModel(conn=self.conn, objstore=self.objstore).lookup(pool)
if res['state'] == 'active':
scan_params['ignore_list'].append(res['path'])
except Exception, e:
--
1.8.3.2
10 years, 8 months