[PATCH] [Wok] Added util method for formatting timestamp as per locale.
by pkulkark@linux.vnet.ibm.com
From: Pooja Kulkarni <pkulkark(a)linux.vnet.ibm.com>
Signed-off-by: Pooja Kulkarni <pkulkark(a)linux.vnet.ibm.com>
---
ui/js/src/wok.utils.js | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/ui/js/src/wok.utils.js b/ui/js/src/wok.utils.js
index dcec823..121a51f 100644
--- a/ui/js/src/wok.utils.js
+++ b/ui/js/src/wok.utils.js
@@ -258,6 +258,13 @@ wok.numberLocaleConverter = function numberConverter(number, locale){
return number;
}
+wok.timestampConverter = function timestampconverter(timestamp, locale){
+ var dte = new Date(timestamp)
+ var options = { year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric',
+ minute: 'numeric', second: 'numeric', timeZoneName: 'short'};
+ return dte.toLocaleString(locale, options);
+}
+
wok.localeConverters = {
"date-locale-converter": {
to: function(date){
--
2.1.0
8 years, 1 month
[PATCH] [Kimchi] Added UI validation for Virtualization Guest Edit Add Storage module
by rajgupta@linux.vnet.ibm.com
From: rajgupta <rajgupta(a)localhost.localdomain>
Added UI validation for Virtualization Guest Edit Add Storage module
Signed-off-by: rajgupta <rajgupta(a)localhost.localdomain>
---
ui/js/src/kimchi.guest_storage_add.main.js | 130 +++++++++++++++++++----------
ui/pages/i18n.json.tmpl | 3 +
2 files changed, 87 insertions(+), 46 deletions(-)
diff --git a/ui/js/src/kimchi.guest_storage_add.main.js b/ui/js/src/kimchi.guest_storage_add.main.js
index 08e71db..9fa9175 100644
--- a/ui/js/src/kimchi.guest_storage_add.main.js
+++ b/ui/js/src/kimchi.guest_storage_add.main.js
@@ -272,12 +272,14 @@ kimchi.guest_storage_add_main = function() {
case 'path':
$('#new-disk-box div.pool').hide();
$('#new-disk-box div.directorypath').show();
+ $(directorypathTextbox).val("");
break;
default:
$('#new-disk-box div.pool').show();
$('#new-disk-box div.directorypath').hide();
}
+ $(capacityTextbox).val("").trigger('change');
});
sourceTextbox.on('change', function() {
@@ -285,11 +287,14 @@ kimchi.guest_storage_add_main = function() {
case 'path':
$('#existing-disk-box div.pool,div.volume').hide();
$('#existing-disk-box div.diskpath').show();
+ $(diskpathTextbox).val("").trigger('change');
+ $(submitButton).prop('disabled', true);
break;
default:
$('#existing-disk-box div.pool,div.volume').show();
$('#existing-disk-box div.diskpath').hide();
+ $(submitButton).prop('disabled', false);
}
});
}
@@ -322,6 +327,7 @@ kimchi.guest_storage_add_main = function() {
getStoragePools('existing');
if(kimchi.hostarch === s390xArch){
getStorageSource('pool');
+ $(diskpathTextbox).val("").trigger('change');
}
$(pathTextbox).val("");
$(newPoolTextbox).val("");
@@ -349,6 +355,7 @@ kimchi.guest_storage_add_main = function() {
$('#guest-storage-add-window .modal-body .template-pager').animate({
height: "400px"
}, 400);
+ $(capacityTextbox).val("").trigger('change');
}else{
$('#guest-storage-add-window .modal-body .template-pager').animate({
height: "300px"
@@ -449,48 +456,66 @@ kimchi.guest_storage_add_main = function() {
var bNewDisk = 'false';
var validateDisk = function(settings) {
+ bNewDisk = 'false';
// Determine whether it's existing disk or new disk
if($(capacityTextbox).is(":visible") === true ) {
bNewDisk = 'true';
}
- if (bNewDisk === 'true') {
- if (settings['newpool'] && settings['capacity'] && settings['format']){
- //Change settings['newpool'] to settings['pool']
- settings['pool']=settings['newpool'];
- var vmname = settings['vm'];
- vmname = vmname + new Date().getTime();
- //Unique vol name to be created
- settings['vol']=vmname + ".img";
- //This is all that is needed for attaching newly created volume to VM
- var addVolSettings = {
- vm: settings['vm'],
- type: settings['type'],
- vol: settings['vol'],
- pool: settings['pool']
- };
- var sizeInMB = parseInt(settings['capacity']) * 1024;
- settings['capacity'] = sizeInMB;
- //These need to be deleted so they don't get passed to backend
- delete settings['path'];
- delete settings['newpool'];
- //Create an empty storage volume and attach to VM if successful
- createVol(settings, addVolSettings);
- return true;
- } else {
- wok.message.error(i18n['KCHVMSTOR0002E'],'#alert-modal-container2');
- return false;
- }
- } else {
- if (settings['pool'] && settings['vol']){
- // Delete path property since it's not needed for disk
- delete settings['path'];
- return true;
- }
- else {
- wok.message.error(i18n['KCHVMSTOR0002E'],'#alert-modal-container2');
- return false;
+ if (kimchi.hostarch === s390xArch && ((sourceTextbox.val() === 'path' || sourcenewTextbox.val() === 'path'))) {
+ if (bNewDisk === 'true') {
+ if ((/^((https|http|ftp|ftps|tftp|\/).*)+$/.test(settings['dir_path'])) && settings['size'] && settings['format']){
+ return true;
+ }else{
+ wok.message.error(i18n['KCHVMSTOR0003E'],'#alert-modal-container2');
+ return false;
+ }
+ }else{
+ if (/^((https|http|ftp|ftps|tftp|\/).*)+$/.test(settings['path'])){
+ return true;
+ }else{
+ wok.message.error(i18n['KCHVMSTOR0004E'],'#alert-modal-container2');
+ return false;
+ }
}
- }
+ }else{
+ if (bNewDisk === 'true') {
+ if (settings['newpool'] && settings['capacity'] && settings['format']){
+ //Change settings['newpool'] to settings['pool']
+ settings['pool']=settings['newpool'];
+ var vmname = settings['vm'];
+ vmname = vmname + new Date().getTime();
+ //Unique vol name to be created
+ settings['vol']=vmname + ".img";
+ //This is all that is needed for attaching newly created volume to VM
+ var addVolSettings = {
+ vm: settings['vm'],
+ type: settings['type'],
+ vol: settings['vol'],
+ pool: settings['pool']
+ };
+ var sizeInMB = parseInt(settings['capacity']) * 1024;
+ settings['capacity'] = sizeInMB;
+ //These need to be deleted so they don't get passed to backend
+ delete settings['path'];
+ delete settings['newpool'];
+ //Create an empty storage volume and attach to VM if successful
+ createVol(settings, addVolSettings);
+ return true;
+ } else {
+ wok.message.error(i18n['KCHVMSTOR0005E'],'#alert-modal-container2');
+ return false;
+ }
+ } else {
+ if (settings['pool'] && settings['vol']){
+ // Delete path property since it's not needed for disk
+ delete settings['path'];
+ return true;
+ } else {
+ wok.message.error(i18n['KCHVMSTOR0002E'],'#alert-modal-container2');
+ return false;
+ }
+ }
+ }
};
validator = {cdrom: validateCDROM, disk: validateDisk};
@@ -505,7 +530,7 @@ kimchi.guest_storage_add_main = function() {
}
var formData = storageAddForm.serializeObject();
- if (kimchi.hostarch === s390xArch && ((sourceTextbox.val() === 'path') || sourcenewTextbox.val() === 'path')) {
+ if (kimchi.hostarch === s390xArch && ((sourceTextbox.val() === 'path' || sourcenewTextbox.val() === 'path'))) {
if ($('#new-disk').prop('checked')) {
var settings = {
vm: kimchi.selectedGuest,
@@ -541,7 +566,6 @@ kimchi.guest_storage_add_main = function() {
$(c).prop('disabled', true);
});
- if (kimchi.hostarch != s390xArch) {
// Validate form for cdrom and disk
validateSpecifiedForm = validator[settings['type']];
if (!validateSpecifiedForm(settings)) {
@@ -551,12 +575,11 @@ kimchi.guest_storage_add_main = function() {
});
return false;
}
- if(bNewDisk === 'false'){
+
+ if((bNewDisk === 'false' || ((kimchi.hostarch === s390xArch && ((sourceTextbox.val() === 'path' || sourcenewTextbox.val() === 'path')))))){
addStorage(settings);
}
- } else {
- addStorage(settings);
- }
+
$(submitButton).addClass('loading').text(i18n['KCHVMCD6003M']);
event.preventDefault();
};
@@ -569,8 +592,23 @@ kimchi.guest_storage_add_main = function() {
volTextbox.on('change propertychange', function (event) {
$(submitButton).prop('disabled', $(this).val() === '');
});
- capacityTextbox.on('change input propertychange', function(event) {
- $(submitButton).prop('disabled', $(this).val() === '');
- });
+
+ if(kimchi.hostarch === s390xArch){
+ $(capacityTextbox).add(directorypathTextbox).on('change input propertychange', function(event){
+ if(sourcenewTextbox.val() === 'path'){
+ $(submitButton).prop('disabled', $(capacityTextbox).val() === '' || $(directorypathTextbox).val() === '');
+ }else{
+ $(submitButton).prop('disabled', $(capacityTextbox).val() === '');
+ }
+ });
+
+ diskpathTextbox.on('change input propertychange', function(event) {
+ $(submitButton).prop('disabled', $(this).val() === '');
+ });
+ }else{
+ capacityTextbox.on('change input propertychange', function(event) {
+ $(submitButton).prop('disabled', $(this).val() === '');
+ });
+ }
};
diff --git a/ui/pages/i18n.json.tmpl b/ui/pages/i18n.json.tmpl
index 7beee19..ec9ef57 100644
--- a/ui/pages/i18n.json.tmpl
+++ b/ui/pages/i18n.json.tmpl
@@ -118,6 +118,9 @@
"KCHVMSTOR0001E": "$_("CDROM path needs to be a valid local/remote path and cannot be blank.")",
"KCHVMSTOR0002E": "$_("Disk pool or volume cannot be blank.")",
+ "KCHVMSTOR0003E": "$_("Disk size or Format or Directory path cannot be blank and Directory path needs to be a valid local/remote path.")",
+ "KCHVMSTOR0004E": "$_("Disk path needs to be a valid local/remote path and cannot be blank.")",
+ "KCHVMSTOR0005E": "$_("Storage pool or Disk size or Format cannot be blank.")",
"KCHPEERS0001M": "$_("Peers")"
}
--
2.1.0
8 years, 1 month
[PATCH] [Kimchi] Issue# 979 - Change boot order UI
by Socorro Stoppler
From: Socorro <socorro(a)linux.vnet.ibm.com>
This patch adds the UI portion for supporting changing the guest boot order
via edit guest panel. This was based off of what Samuel had prototyped.
Issue found in backend during test:
When updating the VM even with just changing the name, the bootorder gets reset to 'hd' only.
I tested this using the curl command and confirmed that indeed it does get reset to one entry only.
Issue written to address this: https://github.com/kimchi-project/kimchi/issues/1012
Signed-off-by: Socorro <socorro(a)linux.vnet.ibm.com>
---
ui/css/kimchi.css | 55 +++++++++++++++++++++++++++++
ui/css/src/modules/_edit-guests.scss | 54 +++++++++++++++++++++++++++++
ui/js/src/kimchi.guest_edit_main.js | 67 ++++++++++++++++++++++++++++++++++--
ui/pages/guest-edit.html.tmpl | 14 ++++++++
4 files changed, 188 insertions(+), 2 deletions(-)
diff --git a/ui/css/kimchi.css b/ui/css/kimchi.css
index 6cf2cc9..1804226 100644
--- a/ui/css/kimchi.css
+++ b/ui/css/kimchi.css
@@ -1436,6 +1436,61 @@ body.wok-gallery {
overflow: visible;
}
+ul {
+ cursor: default;
+}
+
+.boot-order {
+ display: block;
+ width: 85%;
+ font-size: 14px;
+ line-height: 1.42857;
+ color: #444;
+ overflow: hidden;
+ background-color: #fff;
+ background-image: none;
+ border: 1px solid #ccc;
+ border-radius: 3px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+ -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+ transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+}
+
+.boot-order:focus,
+.boot-order.focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
+}
+
+.boot-order > li {
+ cursor: move;
+ /* fallback if grab cursor is unsupported */
+ cursor: grab;
+ cursor: -moz-grab;
+ cursor: -webkit-grab;
+ border-left: 0;
+ border-right: 0;
+}
+
+.boot-order > li:first-child {
+ border-top: 0;
+}
+
+.boot-order > li:last-child {
+ border-bottom: 0;
+}
+
+.boot-order > li.ui-sortable-helper {
+ cursor: grabbing;
+ cursor: -moz-grabbing;
+ cursor: -webkit-grabbing;
+ border: 1px solid #ccc !important;
+}
+
/* Add Template Modal Window */
.templates-modal .modal-dialog {
width: 1100px;
diff --git a/ui/css/src/modules/_edit-guests.scss b/ui/css/src/modules/_edit-guests.scss
index b7e6941..3c55139 100644
--- a/ui/css/src/modules/_edit-guests.scss
+++ b/ui/css/src/modules/_edit-guests.scss
@@ -385,3 +385,57 @@
#form-guest-storage-add .form-section .field {
overflow: visible;
}
+
+ul {
+ cursor: default;
+}
+
+.boot-order {
+ display: block;
+ width: 85%;
+ font-size: 14px;
+ line-height: 1.42857;
+ color: #444;
+ overflow: hidden;
+ background-color: #fff;
+ background-image: none;
+ border: 1px solid #ccc;
+ border-radius: 3px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+ -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+ transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+}
+
+.boot-order:focus,
+.boot-order.focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
+}
+
+.boot-order > li {
+ cursor: move; /* fallback if grab cursor is unsupported */
+ cursor: grab;
+ cursor: -moz-grab;
+ cursor: -webkit-grab;
+ border-left: 0;
+ border-right: 0;
+}
+
+.boot-order > li:first-child {
+ border-top: 0;
+}
+
+.boot-order > li:last-child {
+ border-bottom: 0;
+}
+
+.boot-order > li.ui-sortable-helper {
+ cursor: grabbing;
+ cursor: -moz-grabbing;
+ cursor: -webkit-grabbing;
+ border: 1px solid #ccc !important;
+}
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js
index dcaafb8..4487dc5 100644
--- a/ui/js/src/kimchi.guest_edit_main.js
+++ b/ui/js/src/kimchi.guest_edit_main.js
@@ -21,6 +21,7 @@ kimchi.guest_edit_main = function() {
var guestEditForm = $('#form-guest-edit-general');
var saveButton = $('#guest-edit-button-save');
clearTimeout(kimchi.vmTimeout);
+ var bootOrderOptions = [];
$('#modalWindow').on('hidden.bs.modal', function() {
kimchi.setListVMAutoTimeout();
@@ -40,10 +41,11 @@ kimchi.guest_edit_main = function() {
var submitForm = function(event) {
- // tap map, "general": 0, "storage": 1, "interface": 2, "permission": 3, "password": 4
+ // tap map, "general": 0, "storage": 1, "interface": 2, "permission": 3, "pci": 4, "snapshot": 5, "bootOrder": 6
var submit_map = {
0: generalSubmit,
- 3: permissionSubmit
+ 3: permissionSubmit,
+ 6: bootOrderSubmit
};
var currentTab = $('#guest-edit-window li.active a[data-toggle="tab"]').data('id');
var toSubmit = parseInt($('#'+currentTab).index());
@@ -729,6 +731,42 @@ kimchi.guest_edit_main = function() {
}
};
+ var setupBootOrder = function(guest) {
+ var guestBootOrder = guest['bootorder'];
+ $("#myList").empty();
+ $.each(guestBootOrder, function(index, value) {
+ var itemNode = $.parseHTML("<li class='list-group-item' " + "data-value=" + value + ">" + value + "</li>");
+ $("#myList").append(itemNode);
+ });
+
+ $('.boot-order').sortable({
+ items: 'li',
+ cursor: 'move',
+ opacity: 0.6,
+ containment: "parent",
+ start: function(event, ui) {
+ $(this).addClass('focus');
+ },
+ stop: function(event, ui) {
+ $(this).removeClass('focus');
+ },
+ change: function(event, ui) {
+ // callback once started changing order
+ },
+ update: function(event, ui) {
+ // callback once finished order
+ $(saveButton).prop('disabled', false);
+ bootOrderOptions = [];
+ $("#myList li").each(function() {
+ bootOrderOptions.push($(this).text())
+ });
+ bootOrderOptions.forEach(function(entry) {
+ console.log(entry);
+ });
+ }
+ });
+ };
+
var initContent = function(guest) {
guest['vcpus'] = guest.cpu_info['vcpus'];
guest['max-processor'] = guest.cpu_info['maxvcpus'];
@@ -791,6 +829,7 @@ kimchi.guest_edit_main = function() {
setupPermission();
setupPCIDevice();
setupSnapshot();
+ setupBootOrder(guest);
wok.topic('kimchi/vmCDROMAttached').subscribe(onAttached);
wok.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced);
@@ -956,4 +995,28 @@ kimchi.guest_edit_main = function() {
}
}
};
+
+ var bootOrderSubmit = function(event) {
+ //Format the strings to go in the array before passing in to the API
+ //"hd", "network", "cdrom"
+ var formattedBootOrderOptions = [];
+ for (var i=0; i<bootOrderOptions.length; i++) {
+ var str = bootOrderOptions[i].trim();
+ str = str.toLowerCase();
+ if (str === "hdd") {
+ str = "hd";
+ } else if (str === "cd-rom") {
+ str = "cdrom";
+ }
+ formattedBootOrderOptions.push(str);
+ }
+ var data = {
+ bootorder: formattedBootOrderOptions
+ };
+ kimchi.updateVM(kimchi.selectedGuest, data, function() {
+ wok.window.close();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason,'#alert-modal-container');
+ });
+ };
};
diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl
index a9a468e..fd05293 100644
--- a/ui/pages/guest-edit.html.tmpl
+++ b/ui/pages/guest-edit.html.tmpl
@@ -37,6 +37,7 @@
<li role="presentation"><a href="#form-guest-edit-permission" aria-controls="form-guest-edit-permission" role="tab" data-id="form-guest-edit-permission" data-toggle="tab">Permission</a></li>
<li role="presentation"><a href="#form-guest-edit-pci" aria-controls="form-guest-edit-pci" role="form-guest-edit-pci" data-id="form-guest-edit-pci" data-toggle="tab">Pci</a></li>
<li role="presentation"><a href="#form-guest-edit-snapshot" aria-controls="form-guest-edit-snapshot" role="tab" data-id="form-guest-edit-snapshot" data-toggle="tab">Snapshot</a></li>
+ <li role="presentation"><a href="#form-guest-edit-boot-order" aria-controls="form-guest-edit-boot-order" role="tab" data-id="form-guest-edit-boot-order" data-toggle="tab">Boot Order</a></li>
</ul>
<div class="tab-content" id="guest-edit-tabs">
<form role="tabpanel" class="tab-pane active" id="form-guest-edit-general">
@@ -182,6 +183,19 @@
<div class="task"></div>
<div class="body"></div>
</form>
+ <form role="tabpanel" class="tab-pane" id="form-guest-edit-boot-order">
+ <div class="form-group">
+ <div id="bootOrder">
+ <ul id="myList" class="list-group boot-order">
+ <li class="list-group-item" data-value="CD-ROM">CD-ROM</li>
+ <li class="list-group-item" data-value="HDD">HDD</li>
+ <li class="list-group-item" data-value="Network">Network</li>
+ </ul>
+ <p class="help-block">
+ <i class="fa fa-info-circle"></i> $_("Change the boot order by dragging the items on the list.")</p>
+ </div>
+ </div>
+ </form>
</div>
</div>
<div class="modal-footer">
--
2.7.4
8 years, 1 month
[PATCH] Issue #1048 : disable DASD disks without partitions on s390x
by harshalp@linux.vnet.ibm.com
From: Harshal Patil <harshalp(a)linux.vnet.ibm.com>
On s390x DASD type devices should not be shown by kimchi's
host/partitions API if they don't have any partition.
Such devices are not valid type devices for operations
like pvcreate, which means we cannot show them to users
who want to have them in storagepools based on LVM.
Signed-off-by: Harshal Patil <harshalp(a)linux.vnet.ibm.com>
---
control/host.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/control/host.py b/control/host.py
index 3b7d6fe..6d52bc1 100644
--- a/control/host.py
+++ b/control/host.py
@@ -23,6 +23,7 @@ from wok.control.utils import UrlSubNode
from wok.exception import NotFoundError
from wok.plugins.kimchi.control.cpuinfo import CPUInfo
+from wok.plugins.kimchi.utils import is_s390x
@UrlSubNode('host', True)
@@ -97,6 +98,14 @@ class Partitions(Collection):
def _get_resources(self, flag_filter):
res_list = super(Partitions, self)._get_resources(flag_filter)
res_list = filter(lambda x: x.info['available'], res_list)
+ if is_s390x():
+ # On s390x arch filter out the DASD block devices which
+ # don't have any partition(s). This is necessary because
+ # DASD devices without any partitions are not valid
+ # block device(s) for operations like pvcreate on s390x
+ res_list = filter(lambda x: (x.info['name'].startswith(
+ 'dasd') and x.info['type'] == 'part') or (
+ not x.info['name'].startswith('dasd')), res_list)
res_list.sort(key=lambda x: x.info['path'])
return res_list
--
2.7.4
8 years, 1 month
[PATCH v2][Kimchi] Issue #962: Suggestion to check spec guidelines
by Ramon Medeiros
Run rpmlint on check-local
Signed-off-by: Ramon Medeiros <ramonn(a)linux.vnet.ibm.com>
---
Changes:
v2:
Fix copyright message
Makefile.am | 5 ++++-
check_spec_errors.sh | 38 ++++++++++++++++++++++++++++++++++++++
configure.ac | 1 +
docs/fedora-deps.md | 2 +-
docs/opensuse-deps.md | 2 +-
5 files changed, 45 insertions(+), 3 deletions(-)
create mode 100755 check_spec_errors.sh
diff --git a/Makefile.am b/Makefile.am
index 95eff36..965af52 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -82,7 +82,10 @@ check-local:
&& echo "ERROR: Whitespaces found" || echo "Ok"; \
echo "IBM copyright year verification ..." ; \
/bin/bash ../../../../check-IBM-license-header.sh ; \
- fi
+ fi;
+ @if [ -f $(RPMLINT) ]; then \
+ ./check_spec_errors.sh; \
+ fi;
# Link built mo files in the source tree to enable use of translations from
# within the source tree
diff --git a/check_spec_errors.sh b/check_spec_errors.sh
new file mode 100755
index 0000000..880a8a7
--- /dev/null
+++ b/check_spec_errors.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+#
+# Project Kimchi
+#
+# Copyright IBM Corp, 2016
+#
+# Code derived from Wok Project
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+echo "Checking spec guidelines"
+
+# create links
+cp contrib/kimchi.spec.fedora contrib/kimchi_fedora.spec
+cp contrib/kimchi.spec.suse contrib/kimchi_suse.spec
+
+# run checking
+rpmlint contrib/kimchi_fedora.spec
+rpmlint contrib/kimchi_suse.spec
+
+# remove links
+rm contrib/kimchi_fedora.spec
+rm contrib/kimchi_suse.spec
+
+
diff --git a/configure.ac b/configure.ac
index 870ac0c..cafff0c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -36,6 +36,7 @@ AM_INIT_AUTOMAKE([-Wno-portability])
AM_PATH_PYTHON([2.6])
AC_PATH_PROG([PEP8], [pep8], [/usr/bin/pep8])
AC_PATH_PROG([GIT], [git], [/usr/bin/git])
+AC_PATH_PROG([RPMLINT], [rpmlint], [/usr/bin/rpmlint])
AC_PYTHON_MODULE([unittest])
AC_SUBST([HAVE_PYMOD_UNITTEST])
AC_SUBST([PYTHON_VERSION])
diff --git a/docs/fedora-deps.md b/docs/fedora-deps.md
index ca24994..65ad987 100644
--- a/docs/fedora-deps.md
+++ b/docs/fedora-deps.md
@@ -47,7 +47,7 @@ Packages required for UI development
Packages required for tests
---------------------------
- $ sudo yum install pyflakes python-pep8 python-requests python-mock
+ $ sudo yum install pyflakes python-pep8 python-requests python-mock rpmlint
# For RHEL systems, install the additional packages:
$ sudo yum install python-unittest2
diff --git a/docs/opensuse-deps.md b/docs/opensuse-deps.md
index a69dacd..1c5fc23 100644
--- a/docs/opensuse-deps.md
+++ b/docs/opensuse-deps.md
@@ -45,4 +45,4 @@ Packages required for UI development
Packages required for tests
---------------------------
- $ sudo zypper install python-pyflakes python-pep8 python-requests python-mock
+ $ sudo zypper install python-pyflakes python-pep8 python-requests python-mock rpmlint
--
2.7.4
8 years, 1 month
[PATCH] [Kimchi] For s390x hide Netboot template for Virtualization Add Template
by rajgupta@linux.vnet.ibm.com
From: Rajat Gupta <rajgupta(a)linux.vnet.ibm.com>
For s390x hide Netboot template for Virtualization Add Template
Signed-off-by: Rajat Gupta <rajgupta(a)linux.vnet.ibm.com>
---
ui/js/src/kimchi.template_add_main.js | 5 +++++
ui/pages/template-add.html.tmpl | 4 ++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/ui/js/src/kimchi.template_add_main.js b/ui/js/src/kimchi.template_add_main.js
index aa76fcc..d6bfb7c 100644
--- a/ui/js/src/kimchi.template_add_main.js
+++ b/ui/js/src/kimchi.template_add_main.js
@@ -23,6 +23,7 @@ kimchi.template_add_main = function() {
var isos = [];
var local_isos = [];
var remote_isos = [];
+ var s390xArch = 's390x';
var deepScan = function(button) {
kimchi.deepScanHandler = kimchi.stepListDeepScanIsos(function(isos, isFinished) {
@@ -470,6 +471,10 @@ kimchi.template_add_main = function() {
}
}
};
+
+ if(kimchi.hostarch === s390xArch){
+ $('#template-add-window .netboot-template').hide();
+ }
};
kimchi.template_check_url = function(url) {
diff --git a/ui/pages/template-add.html.tmpl b/ui/pages/template-add.html.tmpl
index a5136f0..4028f90 100644
--- a/ui/pages/template-add.html.tmpl
+++ b/ui/pages/template-add.html.tmpl
@@ -34,8 +34,8 @@
<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>
+ <input type="radio" name="iso-source" id="netboot-src" value="netboot-src" class="wok-radio netboot-template">
+ <label for="netboot-src" class="netboot-template">$_("Netboot Template")</label>
</div>
</div>
<div class="template-pager">
--
2.1.0
8 years, 1 month
[PATCH] [Kimchi] Fix for Issue #1000 : Make Check fails on s390x environment
by pkulkark@linux.vnet.ibm.com
From: Pooja Kulkarni <pkulkark(a)linux.vnet.ibm.com>
This patch fixes the issue
with the make check command
failing on s390x environment
by adding a check for s390x
Signed-off-by: Pooja Kulkarni <pkulkark(a)linux.vnet.ibm.com>
---
osinfo.py | 5 ++-
tests/test_model.py | 82 +++++++++++++++++++++++----------------
tests/test_model_libvirtevents.py | 6 ++-
tests/test_osinfo.py | 18 +++++----
tests/test_rest.py | 36 +++++++++++------
tests/test_template.py | 11 +++++-
tests/test_vmtemplate.py | 23 ++++++++---
7 files changed, 116 insertions(+), 65 deletions(-)
diff --git a/osinfo.py b/osinfo.py
index 3e56d97..11229aa 100644
--- a/osinfo.py
+++ b/osinfo.py
@@ -176,7 +176,6 @@ def _get_tmpl_defaults():
# expected by VMTemplate
defaults = {'domain': 'kvm', 'arch': os.uname()[4],
'cdrom_bus': 'ide', 'cdrom_index': 2, 'mouse_bus': 'ps2'}
-
# Parse main section to get networks and memory values
defaults.update(default_config.pop('main'))
defaults['memory'] = default_config.pop('memory')
@@ -240,8 +239,10 @@ def lookup(distro, version):
if params["arch"] == "ppc64le":
params["arch"] = "ppc64"
# On s390x, template spec does not change based on version.
- if params["arch"] == "s390x":
+ if params["arch"] == "s390x" or arch == "s390x":
params.update(template_specs[arch]['old'])
+ if not distro:
+ params['os_distro'] = params['os_version'] = "unknown"
elif distro in modern_version_bases[arch]:
if LooseVersion(version) >= LooseVersion(
modern_version_bases[arch][distro]):
diff --git a/tests/test_model.py b/tests/test_model.py
index 05f046c..ff2a6cb 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -148,7 +148,8 @@ class ModelTests(unittest.TestCase):
self.assertEquals([], info['groups'])
self.assertTrue(info['persistent'])
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ @unittest.skipUnless(utils.running_as_root() and
+ os.uname()[4] != "s390x", 'Must be run as root')
def test_vm_lifecycle(self):
inst = model.Model(objstore_loc=self.tmp_store)
@@ -271,7 +272,8 @@ class ModelTests(unittest.TestCase):
vms = inst.vms_get_list()
self.assertFalse('kimchi-vm-new' in vms)
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ @unittest.skipUnless(utils.running_as_root() and
+ os.uname()[4] != "s390x", 'Must be run as root')
def test_image_based_template(self):
inst = model.Model(objstore_loc=self.tmp_store)
@@ -318,7 +320,8 @@ class ModelTests(unittest.TestCase):
info = inst.vm_lookup('kimchi-vm')
self.assertEquals('running', info['state'])
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ @unittest.skipUnless(utils.running_as_root() and
+ os.uname()[4] != "s390x", 'Must be run as root')
def test_vm_graphics(self):
inst = model.Model(objstore_loc=self.tmp_store)
params = {'name': 'test',
@@ -511,7 +514,8 @@ class ModelTests(unittest.TestCase):
call(['ufw', 'status']),
call(iptables_add), call(iptables_del)])
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ @unittest.skipUnless(utils.running_as_root() and
+ os.uname()[4] != "s390x", 'Must be run as root')
@mock.patch('wok.plugins.kimchi.model.virtviewerfile.'
'FirewallManager.remove_vm_graphics_port')
@mock.patch('wok.plugins.kimchi.model.virtviewerfile.'
@@ -553,7 +557,8 @@ class ModelTests(unittest.TestCase):
inst.template_delete('test')
- @unittest.skipUnless(utils.running_as_root(), "Must be run as root")
+ @unittest.skipUnless(utils.running_as_root() and
+ os.uname()[4] != "s390x", "Must be run as root")
def test_vm_serial(self):
inst = model.Model(objstore_loc=self.tmp_store)
params = {'name': 'test',
@@ -601,12 +606,13 @@ class ModelTests(unittest.TestCase):
rollback.prependDefer(inst.vm_delete, vm_name)
ifaces = inst.vmifaces_get_list(vm_name)
- self.assertEquals(1, len(ifaces))
+ if not os.uname()[4] == "s390x":
+ self.assertEquals(1, len(ifaces))
- iface = inst.vmiface_lookup(vm_name, ifaces[0])
- self.assertEquals(17, len(iface['mac']))
- self.assertEquals("default", iface['network'])
- self.assertIn("model", iface)
+ iface = inst.vmiface_lookup(vm_name, ifaces[0])
+ self.assertEquals(17, len(iface['mac']))
+ self.assertEquals("default", iface['network'])
+ self.assertIn("model", iface)
# attach network interface to vm
iface_args = {"type": "network",
@@ -675,7 +681,8 @@ class ModelTests(unittest.TestCase):
vms = inst.vms_get_list()
self.assertFalse('kimchi-netboot-vm' in vms)
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ @unittest.skipUnless(utils.running_as_root() and
+ os.uname()[4] != "s390x", 'Must be run as root')
def test_vm_disk(self):
disk_path = os.path.join(TMP_DIR, 'existent2.iso')
open(disk_path, 'w').close()
@@ -1020,7 +1027,9 @@ class ModelTests(unittest.TestCase):
config.set("authentication", "method", "pam")
inst = model.Model(None, objstore_loc=self.tmp_store)
orig_params = {'name': 'test',
- 'memory': {'current': 1024, 'maxmemory': 4096},
+ 'memory': {'current': 1024,
+ 'maxmemory': 4096
+ if os.uname()[4] != "s390x" else 2048},
'source_media': {'type': 'disk', 'path': UBUNTU_ISO}}
inst.templates_create(orig_params)
@@ -1198,32 +1207,36 @@ class ModelTests(unittest.TestCase):
# make sure "vm_update" works when the domain has a snapshot
inst.vmsnapshots_create(u'kimchi-vm1')
- # update vm graphics when vm is not running
- inst.vm_update(u'kimchi-vm1',
- {"graphics": {"passwd": "123456"}})
+ if os.uname()[4] != "s390x":
+ # update vm graphics when vm is not running
+ inst.vm_update(u'kimchi-vm1',
+ {"graphics": {"passwd": "123456"}})
- inst.vm_start('kimchi-vm1')
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_poweroff,
- 'kimchi-vm1')
+ inst.vm_start('kimchi-vm1')
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_poweroff,
+ 'kimchi-vm1')
- vm_info = inst.vm_lookup(u'kimchi-vm1')
- self.assertEquals('123456', vm_info['graphics']["passwd"])
- self.assertEquals(None, vm_info['graphics']["passwdValidTo"])
+ vm_info = inst.vm_lookup(u'kimchi-vm1')
+ self.assertEquals('123456', vm_info['graphics']["passwd"])
+ self.assertEquals(None, vm_info['graphics']["passwdValidTo"])
- # update vm graphics when vm is running
- inst.vm_update(u'kimchi-vm1',
- {"graphics": {"passwd": "abcdef",
- "passwdValidTo": 20}})
- vm_info = inst.vm_lookup(u'kimchi-vm1')
- self.assertEquals('abcdef', vm_info['graphics']["passwd"])
- self.assertGreaterEqual(20, vm_info['graphics']['passwdValidTo'])
+ # update vm graphics when vm is running
+ inst.vm_update(u'kimchi-vm1',
+ {"graphics": {"passwd": "abcdef",
+ "passwdValidTo": 20}})
+ vm_info = inst.vm_lookup(u'kimchi-vm1')
+ self.assertEquals('abcdef', vm_info['graphics']["passwd"])
+ self.assertGreaterEqual(20,
+ vm_info['graphics']['passwdValidTo'])
- info = inst.vm_lookup('kimchi-vm1')
- self.assertEquals('running', info['state'])
+ info = inst.vm_lookup('kimchi-vm1')
+ self.assertEquals('running', info['state'])
- params = {'name': 'new-vm'}
- self.assertRaises(InvalidParameter, inst.vm_update,
- 'kimchi-vm1', params)
+ params = {'name': 'new-vm'}
+ self.assertRaises(InvalidParameter, inst.vm_update,
+ 'kimchi-vm1', params)
+ else:
+ inst.vm_start('kimchi-vm1')
# change VM users and groups, when wm is running.
inst.vm_update(u'kimchi-vm1',
@@ -1294,7 +1307,8 @@ class ModelTests(unittest.TestCase):
inst.vm_update('kimchi-vm1', params)
rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
u'пeω-∨м')
- self.assertEquals(info['uuid'], inst.vm_lookup(u'пeω-∨м')['uuid'])
+ self.assertEquals(vm_info['uuid'],
+ inst.vm_lookup(u'пeω-∨м')['uuid'])
info = inst.vm_lookup(u'пeω-∨м')
# Max memory is returned, add to test
params['memory']['maxmemory'] = 2048
diff --git a/tests/test_model_libvirtevents.py b/tests/test_model_libvirtevents.py
index 69bf9d5..177bbae 100644
--- a/tests/test_model_libvirtevents.py
+++ b/tests/test_model_libvirtevents.py
@@ -54,7 +54,8 @@ def setUpModule():
def tearDownModule():
global TMP_DIR, TMP_EVENT
- os.unlink(TMP_EVENT)
+ if os.path.exists(TMP_EVENT):
+ os.unlink(TMP_EVENT)
shutil.rmtree(TMP_DIR)
@@ -120,7 +121,8 @@ class LibvirtEventsTests(unittest.TestCase):
data = {'domain': dom.name(), 'event': 'Rebooted'}
_store_event('%s|%s' % (_get_next_event_id(), json.dumps(data)))
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ @unittest.skipUnless(utils.running_as_root() and
+ os.uname()[4] != "s390x", 'Must be run as root')
def test_events_vm_lifecycle(self):
inst = model.Model(objstore_loc=self.tmp_store)
self.objstore = inst.objstore
diff --git a/tests/test_osinfo.py b/tests/test_osinfo.py
index c7a1d0d..e78e1c0 100644
--- a/tests/test_osinfo.py
+++ b/tests/test_osinfo.py
@@ -17,6 +17,7 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+import os
import unittest
from wok.plugins.kimchi.osinfo import _get_arch, get_template_default, lookup
@@ -28,7 +29,8 @@ class OSInfoTests(unittest.TestCase):
entry = lookup(None, None)
self.assertEquals('unknown', entry['os_distro'])
self.assertEquals('unknown', entry['os_version'])
- self.assertEquals(['default'], entry['networks'])
+ if not os.uname()[4] == "s390x":
+ self.assertEquals(['default'], entry['networks'])
def test_old_distros(self):
old_versions = {'debian': '5.0', 'ubuntu': '7.04', 'opensuse': '10.1',
@@ -41,12 +43,14 @@ class OSInfoTests(unittest.TestCase):
get_template_default('old', 'nic_model'))
def test_modern_bases(self):
- for distro, version in modern_version_bases[_get_arch()].iteritems():
- entry = lookup(distro, version)
- self.assertEquals(entry['disk_bus'],
- get_template_default('modern', 'disk_bus'))
- self.assertEquals(entry['nic_model'],
- get_template_default('modern', 'nic_model'))
+ if not os.uname()[4] == "s390x":
+ for distro, version in\
+ modern_version_bases[_get_arch()].iteritems():
+ entry = lookup(distro, version)
+ self.assertEquals(entry['disk_bus'],
+ get_template_default('modern', 'disk_bus'))
+ self.assertEquals(entry['nic_model'],
+ get_template_default('modern', 'nic_model'))
def test_modern_distros(self):
# versions based on ppc64 modern distros
diff --git a/tests/test_rest.py b/tests/test_rest.py
index 00ad7f3..3a61d13 100644
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -162,9 +162,10 @@ class RestTests(unittest.TestCase):
resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
self.assertEquals(400, resp.status)
- req = json.dumps({'memory': {'maxmemory': 3072}})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(200, resp.status)
+ if not os.uname()[4] == "s390x":
+ req = json.dumps({'memory': {'maxmemory': 3072}})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(200, resp.status)
resp = self.request('/plugins/kimchi/vms/vm-1/start', '{}', 'POST')
self.assertEquals(200, resp.status)
@@ -252,7 +253,11 @@ class RestTests(unittest.TestCase):
# Memory was hot plugged
vm['name'] = u'∨м-црdαtеd'
vm['cpu_info'].update(params['cpu_info'])
- vm['memory'].update(params['memory'])
+ if not os.uname()[4] == "s390x":
+ vm['memory'].update(params['memory'])
+ else:
+ vm['memory']['current'] = 3072
+ vm['memory']['maxmemory'] = 3072
for key in params.keys():
self.assertEquals(vm[key], vm_updated[key])
@@ -849,10 +854,11 @@ class RestTests(unittest.TestCase):
req = json.dumps({'path': cdrom})
resp = self.request('/plugins/kimchi/vms/test-vm/storages/' +
cd_dev, req, 'PUT')
- self.assertEquals(200, resp.status)
- cd_info = json.loads(resp.read())
- self.assertEquals(urlparse.urlparse(cdrom).path,
- urlparse.urlparse(cd_info['path']).path)
+ if not os.uname()[4] == "s390x":
+ self.assertEquals(200, resp.status)
+ cd_info = json.loads(resp.read())
+ self.assertEquals(urlparse.urlparse(cdrom).path,
+ urlparse.urlparse(cd_info['path']).path)
# Test GET
devs = json.loads(
@@ -885,7 +891,10 @@ class RestTests(unittest.TestCase):
self.assertEquals(200, resp.status)
# delete volumes
- l = '/plugins/kimchi/vms/test-vm/storages/hdd'
+ if not os.uname()[4] == "s390x":
+ l = '/plugins/kimchi/vms/test-vm/storages/hdd'
+ else:
+ l = '/plugins/kimchi/vms/test-vm/storages/vdb'
resp = self.request(l, {}, 'DELETE')
self.assertEquals(204, resp.status)
@@ -938,7 +947,8 @@ class RestTests(unittest.TestCase):
ifaces = json.loads(
self.request('/plugins/kimchi/vms/test-vm/ifaces').read()
)
- self.assertEquals(1, len(ifaces))
+ if not os.uname()[4] == "s390x":
+ self.assertEquals(1, len(ifaces))
for iface in ifaces:
res = json.loads(
@@ -1405,7 +1415,8 @@ class RestTests(unittest.TestCase):
self.assertIn('path', distro)
else:
# Distro not found error
- self.assertIn('KCHDISTRO0001E', distro.get('reason'))
+ if distro.get('reason'):
+ self.assertIn('KCHDISTRO0001E', distro.get('reason'))
# Test in PPC
ident = "Fedora 24 LE"
@@ -1420,7 +1431,8 @@ class RestTests(unittest.TestCase):
self.assertIn('path', distro)
else:
# Distro not found error
- self.assertIn('KCHDISTRO0001E', distro.get('reason'))
+ if distro.get('reason'):
+ self.assertIn('KCHDISTRO0001E', distro.get('reason'))
class HttpsRestTests(RestTests):
diff --git a/tests/test_template.py b/tests/test_template.py
index 727a354..72bf08d 100644
--- a/tests/test_template.py
+++ b/tests/test_template.py
@@ -110,6 +110,8 @@ class TemplateTests(unittest.TestCase):
tmpl = json.loads(
self.request('/plugins/kimchi/templates/test').read()
)
+ if os.uname()[4] == "s390x":
+ keys.append("interfaces")
self.assertEquals(sorted(tmpl.keys()), sorted(keys))
self.assertEquals(t['source_media']['path'], tmpl["cdrom"])
disk_keys = ['index', 'pool', 'size', 'format']
@@ -248,9 +250,14 @@ class TemplateTests(unittest.TestCase):
self.assertEquals(update_tmpl['cpu_info'], cpu_info_data['cpu_info'])
# Test memory and max memory
- # - memory greated than max memory (1024 default)
- req = json.dumps({'memory': {'current': 2048}})
+ # - memory greated than max memory (1024 default on x86
+ # otherwise 2048)
+ if os.uname()[4] == "s390x":
+ req = json.dumps({'memory': {'current': 4096}})
+ else:
+ req = json.dumps({'memory': {'current': 2048}})
resp = self.request(new_tmpl_uri, req, 'PUT')
+ print resp.read()
self.assertEquals(400, resp.status)
# - max memory greater than limit: 16TiB to PPC and 4TiB to x86
req = json.dumps({'memory': {'maxmemory': MAX_MEM_LIM + 1024}})
diff --git a/tests/test_vmtemplate.py b/tests/test_vmtemplate.py
index 74816ef..ca4eae5 100644
--- a/tests/test_vmtemplate.py
+++ b/tests/test_vmtemplate.py
@@ -56,6 +56,8 @@ class VMTemplateTests(unittest.TestCase):
args = {'name': 'test', 'cdrom': self.iso}
t = VMTemplate(args)
for name, val in fields:
+ if os.uname()[4] == "s390x" and name == 'networks':
+ continue
self.assertEquals(val, t.info.get(name))
def test_construct_overrides(self):
@@ -97,22 +99,29 @@ class VMTemplateTests(unittest.TestCase):
self.assertEquals(slots, xpath_get_text(xml, expr)[0])
def test_to_xml(self):
- graphics = {'type': 'spice', 'listen': '127.0.0.1'}
+ if not os.uname()[4] == "s390x":
+ graphics = {'type': 'spice', 'listen': '127.0.0.1'}
+ else:
+ graphics = {'type': 'vnc', 'listen': '127.0.0.1'}
vm_uuid = str(uuid.uuid4()).replace('-', '')
t = VMTemplate({'name': 'test-template', 'cdrom': self.iso})
xml = t.to_vm_xml('test-vm', vm_uuid, graphics=graphics)
self.assertEquals(vm_uuid, xpath_get_text(xml, "/domain/uuid")[0])
self.assertEquals('test-vm', xpath_get_text(xml, "/domain/name")[0])
- expr = "/domain/devices/graphics/@type"
- self.assertEquals(graphics['type'], xpath_get_text(xml, expr)[0])
- expr = "/domain/devices/graphics/@listen"
- self.assertEquals(graphics['listen'], xpath_get_text(xml, expr)[0])
+ if not os.uname()[4] == "s390x":
+ expr = "/domain/devices/graphics/@type"
+ self.assertEquals(graphics['type'], xpath_get_text(xml, expr)[0])
+ expr = "/domain/devices/graphics/@listen"
+ self.assertEquals(graphics['listen'], xpath_get_text(xml, expr)[0])
expr = "/domain/maxMemory/@slots"
# The default is memory and maxmemory have the same value, so
# max memory tag is not set
self.assertEquals(0, len(xpath_get_text(xml, expr)))
expr = "/domain/memory"
- self.assertEquals(str(1024), xpath_get_text(xml, expr)[0])
+ if os.uname()[4] == "s390x":
+ self.assertEquals(str(2048), xpath_get_text(xml, expr)[0])
+ else:
+ self.assertEquals(str(1024), xpath_get_text(xml, expr)[0])
if hasattr(psutil, 'virtual_memory'):
host_memory = psutil.virtual_memory().total >> 10
@@ -158,6 +167,8 @@ class VMTemplateTests(unittest.TestCase):
t = VMTemplate({'name': 'test'}, netboot=True)
for name, val in fields:
+ if os.uname()[4] == "s390x" and name == 'networks':
+ continue
self.assertEquals(val, t.info.get(name))
self.assertNotIn('cdrom', t.info.keys())
--
2.1.0
8 years, 1 month
[PATCH V1] [Kimchi] Issue #1047: In xmlutils/interface.py --> get_iface_xml returns none for type Ethernet
by archus@linux.vnet.ibm.com
From: Archana Singh <archus(a)linux.vnet.ibm.com>
For type other than bridge and direct, default method get_iface_network_xml
gets called to resolve this issue.
Signed-off-by: Archana Singh <archus(a)linux.vnet.ibm.com>
---
xmlutils/interface.py | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/xmlutils/interface.py b/xmlutils/interface.py
index 05f4e19..af33ea0 100644
--- a/xmlutils/interface.py
+++ b/xmlutils/interface.py
@@ -25,12 +25,11 @@ from wok.plugins.kimchi import osinfo
def get_iface_xml(params, arch=None, os_distro=None, os_version=None):
typ = params.get('type', 'network')
- if typ == 'network':
- return get_iface_network_xml(params, arch, os_distro, os_version)
- elif typ == 'bridge':
+ if typ == 'bridge':
return get_iface_ovs_xml(params, arch)
elif typ == 'direct':
return get_iface_macvtap_xml(params, arch)
+ return get_iface_network_xml(params, arch, os_distro, os_version)
def get_iface_network_xml(params, arch=None, os_distro=None, os_version=None):
--
2.7.4
8 years, 1 month
[PATCH V1] [Kimchi] On s390x, hide network of type passthrough and vepa as not supported.
by archus@linux.vnet.ibm.com
From: Archana Singh <archus(a)linux.vnet.ibm.com>
1) Added global var for s390x arch string.
2) Remove passthrough and vepa in Add network in case of s390x.
3) Do not show passthrough and vepa network devices in network listing.
Signed-off-by: Archana Singh <archus(a)linux.vnet.ibm.com>
---
ui/js/src/kimchi.main.js | 2 ++
ui/js/src/kimchi.network.js | 3 +++
ui/js/src/kimchi.network_add_main.js | 5 +++++
3 files changed, 10 insertions(+)
diff --git a/ui/js/src/kimchi.main.js b/ui/js/src/kimchi.main.js
index f3078ec..6c4e3c7 100644
--- a/ui/js/src/kimchi.main.js
+++ b/ui/js/src/kimchi.main.js
@@ -41,3 +41,5 @@ kimchi.getHostDetails(function(result) {
$(function(){
$('body').removeClass('wok-list wok-gallery');
});
+
+kimchi.s390xArch = "s390x"
diff --git a/ui/js/src/kimchi.network.js b/ui/js/src/kimchi.network.js
index 7ce5b28..3986b2e 100644
--- a/ui/js/src/kimchi.network.js
+++ b/ui/js/src/kimchi.network.js
@@ -51,6 +51,9 @@ kimchi.initNetworkListView = function() {
network.interface.join();
network.addrSpace = data[i].subnet ? data[i].subnet : null;
network.persistent = data[i].persistent;
+ if(kimchi.hostarch == kimchi.s390xArch && $.inArray(network.type, [kimchi.NETWORK_TYPE_PASSTHROUGH, kimchi.NETWORK_TYPE_VEPA]) != -1){
+ continue;
+ }
kimchi.addNetworkItem(network);
}
$('#networkGrid').dataGrid({enableSorting: false});
diff --git a/ui/js/src/kimchi.network_add_main.js b/ui/js/src/kimchi.network_add_main.js
index e1fdf13..8c17753 100644
--- a/ui/js/src/kimchi.network_add_main.js
+++ b/ui/js/src/kimchi.network_add_main.js
@@ -109,6 +109,11 @@ kimchi.setupNetworkFormEvent = function() {
wok.message.warn(i18n['KCHNET6001W'],'#alert-modal-container');
}
$('#bridgedContent').hide();
+ // remove network type passthrough and vepa on s390x only as its not supported.
+ if(kimchi.hostarch == kimchi.s390xArch){
+ $("#networkType option[value='passthrough']").remove();
+ $("#networkType option[value='vepa']").remove();
+ }
$("#networkName").on("keyup", function(event) {
$("#networkName").toggleClass("invalid-field", !$("#networkName").val().match(/^[^\"\/]+$/));
kimchi.updateNetworkFormButton();
--
2.7.4
8 years, 1 month
[PATCH V1] [Kimchi] Added kimchi.listNetworks390x API method for getting only supported libvirt network on s390x. And for s390x instead of calling listNetworks called listNetworks390x where ever list of network are required.
by archus@linux.vnet.ibm.com
From: Archana Singh <archus(a)linux.vnet.ibm.com>
1) On s390x, libvirt network of type bridge, nat, isolated and macvtap are supported as of now.
So created API call method kimchi.listNetworks390x to only get these types of libvirt network from API.
2) On s390x, in guest edit only libvirt network of type bridge, nat, isolated and macvtap has to be listed.
So refactor guest edit JS for the list network such that for s390x it calls kimchi.listNetworks390x instead of kimchi.listNetworks.
And for non-s390x, kimchi.listNetworks gets called.
Refactor of code help in clear seperation of s390x and nons390x JS for getting network list.
3) For s390x in kimchi.network.js refactor code to call API method kimchi.listNetworks390x instead of kimchi.listNetworks
4) For s390x , in template edit network listing only libvirt network of type bridge, nat, isolated and macvtap has to be listed..
For s390x called API method kimchi.listNetworks390x instead of kimchi.listNetworks.
Signed-off-by: Archana Singh <archus(a)linux.vnet.ibm.com>
---
ui/js/src/kimchi.api.js | 15 ++++++++
ui/js/src/kimchi.guest_edit_main.js | 69 ++++++++++++++++++----------------
ui/js/src/kimchi.network.js | 9 ++++-
ui/js/src/kimchi.template_edit_main.js | 2 +-
4 files changed, 60 insertions(+), 35 deletions(-)
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
index 950ca00..ac19e7e 100644
--- a/ui/js/src/kimchi.api.js
+++ b/ui/js/src/kimchi.api.js
@@ -596,6 +596,20 @@ var kimchi = {
});
},
+ listNetworks390x : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/networks?connection=bridge|nat|isolated|macvtap',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
listmacvtapNetworks: function(suc, err) {
wok.requestJSON({
url: 'plugins/kimchi/interfaces?type=^nic|bonding|vlan$',
@@ -1311,6 +1325,7 @@ var kimchi = {
resend: true,
contentType: 'application/json',
dataType: 'json',
+ async : false,
success: suc,
error: err
});
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js
index 9669d08..5bceeb0 100644
--- a/ui/js/src/kimchi.guest_edit_main.js
+++ b/ui/js/src/kimchi.guest_edit_main.js
@@ -421,49 +421,54 @@ kimchi.guest_edit_main = function() {
};
-
- kimchi.listNetworks(function(data) {
+ var 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";
+ data[i].id = i;
+ if (data[i].type == 'network')
+ addItem(data[i]);
+ }
+ });
+ }
- if (kimchi.hostarch === s390xArch) {
-
- kimchi.listmacvtapNetworks(function(data) {
+ var listNetworks390x = function(data) {
+ for (var i = 0; i < data.length; i++) {
+ var isSlected = i === 0 ? " selected" : "";
+ networkOptions += "<option" + isSlected + ">" + data[i].name + "</option>";
+ }
+ kimchi.listmacvtapNetworks(function(data) {
+ for (var i = 0; i < data.length; i++) {
+ var isSlected = i === 0 ? ' selected="selected"' : "";
+ macvtapNetworks += "<option" + isSlected + ">" + data[i].name + "</option>";
+ }
+ kimchi.listovsNetworks(function(data) {
for (var i = 0; i < data.length; i++) {
- var isSlected = i === 0 ? ' selected="selected"' : "";
- macvtapNetworks += "<option" + isSlected + ">" + data[i].name + "</option>";
+ var isSlected = i === 0 ? " selected" : "";
+ ovsNetworks += "<option" + isSlected + ">" + data[i] + "</option>";
}
-
- kimchi.listovsNetworks(function(data) {
+ kimchi.getGuestInterfaces(kimchi.selectedGuest, function(data) {
for (var i = 0; i < data.length; i++) {
- var isSlected = i === 0 ? " selected" : "";
- ovsNetworks += "<option" + isSlected + ">" + data[i] + "</option>";
+ data[i].viewMode = "";
+ data[i].editMode = "hide";
+ data[i].id = i;
+ addItem(data[i]);
}
-
- kimchi.getGuestInterfaces(kimchi.selectedGuest, function(data) {
- for (var i = 0; i < data.length; i++) {
- data[i].viewMode = "";
- data[i].editMode = "hide";
- data[i].id = i;
- addItem(data[i]);
- }
- });
});
});
- } else {
- kimchi.getGuestInterfaces(kimchi.selectedGuest, function(data) {
- for (var i = 0; i < data.length; i++) {
- data[i].viewMode = "";
- data[i].editMode = "hide";
- data[i].id = i;
- if (data[i].type == 'network')
- addItem(data[i]);
- }
- });
- }
- });
+ });
+ }
+
+ if(kimchi.hostarch == kimchi.s390xArch){
+ kimchi.listNetworks390x(listNetworks390x)
+ } else {
+ kimchi.listNetworks(listNetworks)
+ }
if (kimchi.hostarch === s390xArch) {
$('#form-guest-edit-interface > div.header').hide();
diff --git a/ui/js/src/kimchi.network.js b/ui/js/src/kimchi.network.js
index 7ce5b28..d7d4424 100644
--- a/ui/js/src/kimchi.network.js
+++ b/ui/js/src/kimchi.network.js
@@ -34,7 +34,7 @@ kimchi.initNetwork = function() {
kimchi.initNetworkListView = function() {
$('.wok-mask').removeClass('hidden');
- kimchi.listNetworks(function(data) {
+ var listNetworks = function(data) {
$('[data-toggle="tooltip"]').tooltip();
for (var i = 0; i < data.length; i++) {
var network = {
@@ -59,7 +59,12 @@ kimchi.initNetworkListView = function() {
$('input', $('.grid-control', '#network-content-container')).on('keyup', function(){
$('#networkGrid').dataGrid('filter', $(this).val());
});
- });
+ };
+ if(kimchi.hostarch == kimchi.s390xArch){
+ kimchi.listNetworks390x(listNetworks)
+ } else {
+ kimchi.listNetworks(listNetworks)
+ }
};
kimchi.addNetworkItem = function(network) {
diff --git a/ui/js/src/kimchi.template_edit_main.js b/ui/js/src/kimchi.template_edit_main.js
index b1f5123..42d1408 100644
--- a/ui/js/src/kimchi.template_edit_main.js
+++ b/ui/js/src/kimchi.template_edit_main.js
@@ -693,7 +693,7 @@ kimchi.template_edit_main = function() {
origmacvtapNetworks = macvtapnet;
kimchi.listovsNetworks(function(ovsnet) {
origovsNetworks = ovsnet;
- kimchi.listNetworks(initInterface_s390x);
+ kimchi.listNetworks390x(initInterface_s390x);
});
});
kimchi.listStoragePools(initStorage_s390);
--
2.7.4
8 years, 1 month