[PATCH] [Wok] Issue #79: All error messages should keep on UI until user dismiss it
by sguimaraes943@gmail.com
From: Samuel Guimarães <sguimaraes943(a)gmail.com>
This commit makes all messages closeable by default, removing the fade animation after 10 seconds.
A parameter to allow a custom ID for each alert was also added to wok.message function.
Samuel Guimarães (1):
Issue #79: All error messages should keep on UI until user dismiss it
ui/js/src/wok.message.js | 53 +++++++++++++++++++++++++-----------------------
1 file changed, 28 insertions(+), 25 deletions(-)
--
1.8.3.1
8 years, 5 months
[PATCH V2] [Kimchi 0/2] Updates to support Fedora 24
by pvital@linux.vnet.ibm.com
From: Paulo Vital <pvital(a)linux.vnet.ibm.com>
V1 -> V2:
- Fix missing ","
V1:
This patch-set adds support to recognize Fedora 24 ISO images and add new
optins for remote Fedora images.
Paulo Vital (2):
Issue #965: Recognize Fedora 24 ISO image.
Update Fedora remote images.
distros.d/fedora.json | 32 +++++++++++++++++++++++---------
isoinfo.py | 1 +
2 files changed, 24 insertions(+), 9 deletions(-)
--
2.5.5
8 years, 5 months
[PATCH] [Kimchi 0/2] Updates to support Fedora 24
by pvital@linux.vnet.ibm.com
From: Paulo Vital <pvital(a)linux.vnet.ibm.com>
This patch-set adds support to recognize Fedora 24 ISO images and add new
optins for remote Fedora images.
Paulo Vital (2):
Issue #965: Recognize Fedora 24 ISO image.
Update Fedora remote images.
distros.d/fedora.json | 32 +++++++++++++++++++++++---------
isoinfo.py | 1 +
2 files changed, 24 insertions(+), 9 deletions(-)
--
2.5.5
8 years, 5 months
[RFC] Replace jQuery Bootgrid with Datatables.net
by Samuel Henrique De Oliveira Guimaraes
Hi team,
As part of the redesign process of some Ginger and Gingerbase panels, one of the main issues is that the jQuery Bootgrid tables are not exactly fitting with the Design Spec. If you compare System Modules and System Services tables with Kimchi they look and feel like part of the same application but if you navigate through Ginger Network and Storage tabs, there are some alignment and spacing issues. Most of these UI glitches could be fixed with plain CSS and / or editing jQuery Bootgrid "formatters" but we already faced some issues with the Software Updates and Network Configuration that required some workarounds that were not documented by jQuery Bootgrid authors.
Based on that, I suggested to Aline and Daniel if we could redesign these panels using Datatables.net instead of just shaping Bootgrid with CSS changes that may require rework once or if we update Bootgrid library due security or any other reason. I've mentioned before that we would probably have to update to this library if we decided to use Bootstrap 4 in the future but it seems that we may need to change the library and rewrite some panels a little bit earlier.
For the UI development it makes sense to use this library instead of adding "native" sort, filters and paging to wok.datagrid component because it has a larger community, a support board and tons of documented examples. Plus, it already has accessibility improvements that we would have to manually implement to our panels. In the future we could even drop wok.datagrid entirely and port everything that doesn't have a Gallery / List view design pattern to Datatables.net.
Here's the plan:
1- jQuery Bootgrid and Datatables.net will coexist within Wok and we will update Ginger panel by panel until there isn't a trace of jQuery Bootgrid.
2- Update Software Updates to Datatables.net
3- Update User Logs to Datatables.net
4- Remove jQuery Bootgrid from Wok
5- Update Kimchi Storage to Datatables.net (at least the main table can be replaced, the Storage Volumes view would have to keep the old wok.datagrid because of the Gallery/List switch)
6- Update Kimchi Network to Datatables.net
7- Rename or rewrite wok.datagrid to something else like wok.gallery-view for Kimchi Guests, Templates and Storage Volumes
About Datatables.net:
1- License: https://datatables.net/faqs/index#Licensing<https://datatables.net/faqs/index%23Licensing>
2- Support: Although the license is MIT, they offer a paid and the community support - https://datatables.net/support/index
3- API Examples: https://datatables.net/examples/index
4- Manual: https://datatables.net/manual/index
5- Styling (spoiler alert: they support almost every CSS library): https://datatables.net/examples/styling/bootstrap.html
Let me know your opinions.
Regards,
Samuel
8 years, 5 months
[PATCH V2] [Kimchi] Handle URLError exception when creating Template.
by pvital@linux.vnet.ibm.com
From: Paulo Vital <pvital(a)linux.vnet.ibm.com>
urllib2 raised URLError when could not access a remote file due to unauthorized
access, for example. This patch gives to IsoImage the ability to handle this
exception and raises a relevant error message to user.
This patch fixes Issue #959
Signed-off-by: Paulo Vital <pvital(a)linux.vnet.ibm.com>
---
i18n.py | 1 +
isoinfo.py | 15 +++++++++------
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/i18n.py b/i18n.py
index 2d8390f..b33c6ec 100644
--- a/i18n.py
+++ b/i18n.py
@@ -52,6 +52,7 @@ messages = {
"to file access control lists for '%(user)s' user if possible, or add the "
"'%(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x 'path_to_iso'."
"Details: %(err)s" ),
+ "KCHISO0009E": _("Unable to access remote ISO. Details: %(err)s"),
"KCHIMG0001E": _("An error occurred when probing image OS information."),
"KCHIMG0003E": _("Unable to read image file %(filename)s"),
diff --git a/isoinfo.py b/isoinfo.py
index 4cb0209..7c000b7 100644
--- a/isoinfo.py
+++ b/isoinfo.py
@@ -28,7 +28,7 @@ import sys
import urllib2
-from wok.exception import IsoFormatError
+from wok.exception import IsoFormatError, OperationFailed
from wok.plugins.kimchi.utils import check_url_path
from wok.utils import wok_log
@@ -419,11 +419,14 @@ lang=en#!/wiki/W51a7ffcf4dfd_4b40_9d82_446ebc23c550/page/PowerLinux\
def _get_iso_data(self, offset, size):
if self.remote:
- request = urllib2.Request(self.path)
- range_header = "bytes=%d-%d" % (offset, offset + size - 1)
- request.add_header("range", range_header)
- with contextlib.closing(urllib2.urlopen(request)) as response:
- data = response.read()
+ try:
+ request = urllib2.Request(self.path)
+ range_header = "bytes=%d-%d" % (offset, offset + size - 1)
+ request.add_header("range", range_header)
+ with contextlib.closing(urllib2.urlopen(request)) as response:
+ data = response.read()
+ except urllib2.URLError as e:
+ raise OperationFailed("KCHISO0009E", {'err': e})
else:
with open(self.path) as fd:
fd.seek(offset)
--
2.5.5
8 years, 5 months
[PATCH] [WoK] Github #138: fix loadash Makefile.am
by dhbarboza82@gmail.com
From: Daniel Henrique Barboza <danielhb(a)linux.vnet.ibm.com>
Co-authored-by: Aline Manera <alinefm(a)linux.vnet.ibm.com>
The path to lodashdir was wrong and was breaking
WoK startup when executing into RPM.
Signed-off-by: Daniel Henrique Barboza <danielhb(a)linux.vnet.ibm.com>
---
ui/libs/lodash/Makefile.am | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/libs/lodash/Makefile.am b/ui/libs/lodash/Makefile.am
index 25c9cb1..f534901 100644
--- a/ui/libs/lodash/Makefile.am
+++ b/ui/libs/lodash/Makefile.am
@@ -16,6 +16,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-lodashdir = $(datadir)/wok/ui/libs/lodash.js
+lodashdir = $(datadir)/wok/ui/libs/lodash
dist_lodash_DATA = $(wildcard *.js) $(NULL)
--
2.5.5
8 years, 5 months
[PATCH][Wok] UI: Create notification-container and make notifications persistent
by Rodrigo Trujillo
There is an issue in frontend that does not allow notification messages
to be showed more than once if the problem happens again.
Also, when notifications are created, they are showed in different parts
of the UI, for each plugin or plugin tab (usually in the alert-container).
If some window does not have alert-container, the notification is not
showed.
This patch creates a notificatoin-container 'on-the-fly' in the windows
that Wok is displaying and shows the notification.
Notification is check by its message content, instead of the code ID,
allowing multiple similar notifications but with different subjects
(like different VM names).
Notifications are showed again if message was closed but backend returns
the same notification massage. Before, messages were nevermore display.
Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo(a)linux.vnet.ibm.com>
---
ui/css/src/wok.scss | 4 ++++
ui/css/wok.css | 4 ++++
ui/js/src/wok.main.js | 1 -
ui/js/src/wok.utils.js | 13 ++++++++-----
4 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/ui/css/src/wok.scss b/ui/css/src/wok.scss
index c4a81d4..0672cdb 100755
--- a/ui/css/src/wok.scss
+++ b/ui/css/src/wok.scss
@@ -142,6 +142,10 @@ body {
}
}
+#notification-container .alert {
+ margin: 10px;
+}
+
// Login
@import "modules/login";
// Topbar and navigation
diff --git a/ui/css/wok.css b/ui/css/wok.css
index 96b9e6e..6da0aa8 100644
--- a/ui/css/wok.css
+++ b/ui/css/wok.css
@@ -133,6 +133,10 @@ body {
cursor: not-allowed !important;
}
+#notification-container .alert {
+ margin: 10px;
+}
+
.login .content .container {
width: 100% !important;
padding-left: 0 !important;
diff --git a/ui/js/src/wok.main.js b/ui/js/src/wok.main.js
index 55b8d0d..1d49c9e 100644
--- a/ui/js/src/wok.main.js
+++ b/ui/js/src/wok.main.js
@@ -19,7 +19,6 @@
*/
wok.NOTIFICATION_INTERVAL = 2000
-wok.postedNotifications = []
wok.tabMode = {};
wok.config = undefined;
diff --git a/ui/js/src/wok.utils.js b/ui/js/src/wok.utils.js
index 236bf0a..54f8cf0 100644
--- a/ui/js/src/wok.utils.js
+++ b/ui/js/src/wok.utils.js
@@ -214,12 +214,15 @@ wok.notificationsLoop = function notificationsLoop() {
function(notifications){
if(notifications && notifications.length > 0) {
$.each(notifications, function(i, notif) {
- if (wok.postedNotifications.indexOf(notif.message) == -1) {
- wok.message.notify(notif, '#message-container-area');
- wok.postedNotifications.push(notif.message);
+ // Check if notification is being displayed
+ if (!$("#notification-container").length) {
+ $('.navbar.toolbar').next().prepend('<div id="notification-container"></div>');
}
- })
- };
+ if (($("#notification-container").find("div:contains('" + notif.message + "')").length) == 0) {
+ wok.message.notify(notif, '#notification-container');
+ }
+ });
+ }
setTimeout(notificationsLoop, wok.NOTIFICATION_INTERVAL);
},
function(data){
--
2.1.0
8 years, 5 months
[PATCH] [Kimchi] Add UI netboot support for adding templates
by Socorro Stoppler
This patch adds UI support for netboot template. Due to this, the radio
buttons have been reintroduced in add template to choose between current
choice (image, iso - local and remote which has been combined into one
panel) and netboot template.
Signed-off-by: Socorro Stoppler <socorro(a)linux.vnet.ibm.com>
---
ui/js/src/kimchi.template_add_main.js | 73 ++++++++++++++++++++++++++++++++---
ui/pages/template-add.html.tmpl | 27 +++++++++----
2 files changed, 87 insertions(+), 13 deletions(-)
diff --git a/ui/js/src/kimchi.template_add_main.js b/ui/js/src/kimchi.template_add_main.js
index 948f710..ed020d3 100644
--- a/ui/js/src/kimchi.template_add_main.js
+++ b/ui/js/src/kimchi.template_add_main.js
@@ -17,6 +17,7 @@
*/
kimchi.template_add_main = function() {
"use strict";
+ var currentPage = 'iso-local-box';
$('#loading-isos').removeClass('hidden');
kimchi.deepScanHandler = null;
var isos = [];
@@ -53,6 +54,7 @@ kimchi.template_add_main = function() {
$('#local-iso-field').hide();
$('#select-all-local-iso').prop('checked', false);
$('#btn-template-local-iso-create').attr('disabled', 'disabled');
+ $('#btn-template-netboot-create').attr('disabled', 'disabled');
$('#iso-search').hide();
$('#iso-more').hide();
$('#iso-search-loading').hide();
@@ -64,6 +66,7 @@ kimchi.template_add_main = function() {
$('#iso-url').val(''); // 4 - Remote folder path text
$('#btn-template-file-create').attr('disabled', 'disabled').css('display', 'inline-block'); // 1 - Folder path
$('#btn-template-local-iso-create').attr('disabled', 'disabled').css('display', 'none'); // 2 - Selected ISOs
+ $('#btn-template-netboot-create').attr('disabled', 'disabled').css('display', 'none'); // 3 - Netboot
$('#select-all-local-iso, #select-all-remote-iso').prop('checked', false); // False to all select-all checkboxes
$('#list-local-iso [type="checkbox"], #list-remote-iso [type="checkbox"]').prop('checked', false); // False to all list checkboxes
};
@@ -98,6 +101,7 @@ kimchi.template_add_main = function() {
$('#iso-url').val('');
$('#btn-template-file-create').attr('disabled', 'disabled').css('display', 'inline-block');
$('#btn-template-local-iso-create').attr('disabled', 'disabled').css('display', 'none'); // 2 - Selected ISOs
+ $('#btn-template-netboot-create').attr('disabled', 'disabled').css('display', 'none'); // 3 - Netboot
$('#select-all-local-iso, #select-all-remote-iso').prop('checked', false); // False to all select-all checkboxes
$('#list-local-iso [type="checkbox"], #list-remote-iso [type="checkbox"]').prop('checked', false); // False to all list checkboxes
};
@@ -116,6 +120,7 @@ kimchi.template_add_main = function() {
} else {
$('#btn-template-file-create').attr('disabled', 'disabled');
}
+ $('#btn-template-netboot-create').attr('disabled', 'disabled').css('display', 'none'); // 3 - Netboot
});
initLocalIsoField();
@@ -222,12 +227,11 @@ kimchi.template_add_main = function() {
$('#iso-file').parent().removeClass('has-error');
$('#btn-template-file-create').attr('disabled', 'disabled').css('display', 'none'); // 1 - Folder path
-
$('#btn-template-local-iso-create').removeAttr('disabled').css('display', 'inline-block'); // 2 - Selected ISOs
-
} else {
$('#btn-template-local-iso-create').attr('disabled', 'disabled');
}
+ $('#btn-template-netboot-create').attr('disabled', 'disabled').css('display', 'none'); // 3 - Netboot
});
$('#list-local-iso').on('click', '[type="checkbox"]', function() {
@@ -238,6 +242,7 @@ kimchi.template_add_main = function() {
$('#btn-template-file-create').attr('disabled', 'disabled').css('display', 'none'); // 1 - Folder path
$('#btn-template-local-iso-create').attr('disabled', 'disabled').css('display', 'inline-block'); // 2 - Selected ISOs
+ $('#btn-template-netboot-create').attr('disabled', 'disabled').css('display', 'none'); // 3 - Netboot
if (checkedLength) {
$('#btn-template-local-iso-create').removeAttr('disabled');
@@ -250,6 +255,16 @@ kimchi.template_add_main = function() {
}
});
+ $('#btn-template-netboot-create').click(function() {
+ var data = {
+ "source_media": {"type": "netboot"}
+ };
+ addTemplate(data, function() {
+ $('#btn-template-netboot-create').text(i18n['KCHAPI6005M']);
+ $('#btn-template-netboot-create').prop('disabled', false);
+ });
+ });
+
$('#btn-template-local-iso-create').click(function() {
$('input', '#iso-file-box').prop('disabled', true);
$('#btn-template-local-iso-create').text(i18n['KCHAPI6008M']);
@@ -299,11 +314,9 @@ kimchi.template_add_main = function() {
$('#iso-url').val('');
$('#btn-template-file-create').attr('disabled', 'disabled').css('display', 'none'); // 1 - Folder path
-
$('#btn-template-local-iso-create').attr('disabled', 'disabled').css('display', 'none'); // 2 - Selected ISOs
-
+ $('#btn-template-netboot-create').attr('disabled', 'disabled').css('display', 'none'); // 3 - Netboot
$('#select-all-local-iso, #select-all-remote-iso').prop('checked', false); // False to all select-all checkboxes
-
$('#list-local-iso [type="checkbox"], #list-remote-iso [type="checkbox"]').prop('checked', false); // False to all list checkboxes
};
@@ -340,6 +353,56 @@ kimchi.template_add_main = function() {
$('input#iso-url').parent().toggleClass('has-error', !isValid);
}, 0);
});
+
+ $('#image-src').change(function() {
+ if (this.checked) {
+ if (currentPage === 'netboot-path') {
+ kimchi.switchPage(currentPage, 'iso-local-box', 'right');
+ }
+ currentPage = 'iso-local-box';
+ $('#template-add-window .modal-body .template-pager').animate({
+ height: "635px"
+ }, 400);
+ initLocalIsoField();
+ initIsoFileField();
+ $('#loading-isos').removeClass('hidden');
+ kimchi.listIsos(function(local_isos) { //local ISOs
+ kimchi.listDistros(function(remote_isos) { //remote ISOs
+ isos = local_isos.concat(remote_isos); //all isos
+ if (isos && isos.length) {
+ showLocalIsoField(isos);
+ $('#iso-more').show();
+ } else {
+ $('#iso-search').show();
+ }
+ $('#loading-isos').fadeOut(100, function() {});
+ });
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason, '#local-iso-error-container');
+ $('#loading-isos').fadeOut(300, function() {
+ $('#loading-isos').addClass('hidden');
+ });
+ });
+ setupFilters();
+ enabledRemoteIso();
+ }
+ });
+
+ $('#netboot-src').change(function() {
+ if (this.checked) {
+ if (currentPage === 'iso-local-box') {
+ kimchi.switchPage(currentPage, 'netboot-path', 'left');
+ }
+ currentPage = 'netboot-path';
+ $('#template-add-window .modal-body .template-pager').animate({
+ height: "300px"
+ }, 400);
+ $('#btn-template-file-create').attr('disabled', 'disabled').css('display', 'none'); // 1 - Folder path
+ $('#btn-template-local-iso-create').attr('disabled', 'disabled').css('display', 'none'); // 2 - Selected ISOs
+ $('#btn-template-netboot-create').removeAttr('disabled').css('display', 'inline-block'); // 3 - Netboot
+ }
+ });
+
//do create
var addTemplate = function(data, callback) {
kimchi.createTemplate(data, function() {
diff --git a/ui/pages/template-add.html.tmpl b/ui/pages/template-add.html.tmpl
index 4226a8f..e5c7aa5 100644
--- a/ui/pages/template-add.html.tmpl
+++ b/ui/pages/template-add.html.tmpl
@@ -30,6 +30,13 @@
<div class="modal-body">
<div class="template-modal-container">
<div id="alert-modal-container"></div>
+ <div>
+ <h5>$_("Where is the source media for this template? ")</h5>
+ <input type="radio" checked="checked" name="iso-source" id="image-src" value="image-src" class="wok-radio">
+ <label for="image-src">$_("Image Template")</label>
+ <input type="radio" name="iso-source" id="netboot-src" value="netboot-src" class="wok-radio">
+ <label for="netboot-src">$_("Netboot Template")</label>
+ </div>
</div>
<div class="template-pager">
<div class="page-list">
@@ -103,16 +110,20 @@
</div>
</div>
</div>
- </div>
- </div>
- <div class="modal-footer">
- <button class="btn btn-default" id="btn-template-file-create" disabled="disabled">$_("Create")</button>
- <button class="btn btn-default" id="btn-template-local-iso-create" disabled="disabled">$_("Create")</button>
- <button class="btn btn-default" data-dismiss="modal" type="button">$_("Cancel")</button>
- </div>
-</div>
+ <div class="page" id="netboot-path">
+ </div>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button class="btn btn-default" id="btn-template-file-create" disabled="disabled">$_("Create")</button>
+ <button class="btn btn-default" id="btn-template-local-iso-create" disabled="disabled">$_("Create")</button>
+ <button class="btn btn-default" id="btn-template-netboot-create" disabled="disabled">$_("Create")</button>
+ <button class="btn btn-default" data-dismiss="modal" type="button">$_("Cancel")</button>
+ </div>
+ </div>
<script>
kimchi.template_add_main();
</script>
+</div>
</body>
</html>
--
2.5.0
8 years, 5 months
[PATCH][Kimchi] Recognize different interfaces type when cloning vm
by Ramon Medeiros
When cloning a VM, it's needed to add a new mac address. model/vms.py
was selection <interface type=network /> only. Using correct xpath
framework, now all <interface> tag with type as attribute and <mac
address> as a subelement, is selected. After all, they will received new
mac address. This way, it's not needed to check if the interfaces has it
own mac address.
Signed-off-by: Ramon Medeiros <ramonn(a)linux.vnet.ibm.com>
---
model/vms.py | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/model/vms.py b/model/vms.py
index f069c4e..9753a10 100644
--- a/model/vms.py
+++ b/model/vms.py
@@ -83,12 +83,10 @@ VM_ONLINE_UPDATE_PARAMS = ['graphics', 'groups', 'memory', 'users']
VM_OFFLINE_UPDATE_PARAMS = ['cpu_info', 'graphics', 'groups', 'memory',
'name', 'users']
+XPATH_DOMAIN_CHANGE_MAC = "./devices/interface[@type='%s']/mac[@address='%s']"
XPATH_DOMAIN_DISK = "/domain/devices/disk[@device='disk']/source/@file"
XPATH_DOMAIN_DISK_BY_FILE = "./devices/disk[@device='disk']/source[@file='%s']"
XPATH_DOMAIN_NAME = '/domain/name'
-XPATH_DOMAIN_MAC = "/domain/devices/interface[@type='network']/mac/@address"
-XPATH_DOMAIN_MAC_BY_ADDRESS = "./devices/interface[@type='network']/"\
- "mac[@address='%s']"
XPATH_DOMAIN_MEMORY = '/domain/memory'
XPATH_DOMAIN_MEMORY_UNIT = '/domain/memory/@unit'
XPATH_DOMAIN_UUID = '/domain/uuid'
@@ -97,6 +95,7 @@ XPATH_DOMAIN_DEV_CPU_ID = '/domain/devices/spapr-cpu-socket/@id'
XPATH_CPU = './cpu'
XPATH_NAME = './name'
XPATH_NUMA_CELL = './cpu/numa/cell'
+XPATH_MAC = "./devices/interface[@type]/mac/[@address]"
XPATH_TOPOLOGY = './cpu/topology'
XPATH_VCPU = './vcpu'
XPATH_MAX_MEMORY = './maxMemory'
@@ -417,19 +416,25 @@ class VMModel(object):
The XML descriptor <xml> with the new MAC addresses instead of the
old ones.
"""
- old_macs = xpath_get_text(xml, XPATH_DOMAIN_MAC)
- new_macs = []
+ # get dict with macs and interfaces
+ old_macs_int = {}
+ for node in ET.fromstring(xml).findall(XPATH_MAC):
+ old_macs_int[node.get("address")] = node.getparent().get("type")
- for mac in old_macs:
+ # update mac address
+ new_macs = []
+ for mac_addr in old_macs_int:
while True:
new_mac = model.vmifaces.VMIfacesModel.random_mac()
# make sure the new MAC doesn't conflict with the original VM
# and with the new values on the new VM.
- if new_mac not in (old_macs + new_macs):
+ if new_mac not in (old_macs_int.keys() + new_macs):
new_macs.append(new_mac)
break
- xml = xml_item_update(xml, XPATH_DOMAIN_MAC_BY_ADDRESS % mac,
+ dev_type = old_macs_int[mac_addr]
+ xml = xml_item_update(xml, XPATH_DOMAIN_CHANGE_MAC % (dev_type,
+ mac_addr),
new_mac, 'address')
return xml
--
2.5.5
8 years, 5 months