[PATCH] [Wok 1/2] Issue #101: In runcommand, enabling UTF-8 characters support in command output.
by archus@linux.vnet.ibm.com
From: Archana Singh <archus(a)linux.vnet.ibm.com>
Command output needs to be english for programmatically parsing of output.
"LC_ALL = C" set the all LC_* to en_US and charset to ASCII.
Replaced C with "en_US.UTF-8" enable charset to UTF-8.
Signed-off-by: Archana Singh <archus(a)linux.vnet.ibm.com>
---
src/wok/utils.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/wok/utils.py b/src/wok/utils.py
index b37518f..3783685 100644
--- a/src/wok/utils.py
+++ b/src/wok/utils.py
@@ -226,9 +226,9 @@ def run_command(cmd, timeout=None, silent=False, tee=None,
if env_vars is None:
env_vars = os.environ.copy()
- env_vars['LC_ALL'] = 'C'
+ env_vars['LC_ALL'] = 'en_US.UTF-8'
elif env_vars.get('LC_ALL') is None:
- env_vars['LC_ALL'] = 'C'
+ env_vars['LC_ALL'] = 'en_US.UTF-8'
try:
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
--
1.8.3.1
8 years, 7 months
[PATCH] [Wok 0/2] Fix for Issues #101 and #115
by archus@linux.vnet.ibm.com
From: Archana Singh <archus(a)linux.vnet.ibm.com>
1) Enabling UTF-8 characters support in command output.
2) Fix for _get_resources wok_log.error result into unicode error.
Archana Singh (2):
Issue #101: In runcommand, enabling UTF-8 characters support in
command output.
Issue #115: _get_resources wok_log.error result into unicode error
src/wok/control/base.py | 8 ++++++--
src/wok/utils.py | 4 ++--
2 files changed, 8 insertions(+), 4 deletions(-)
--
1.8.3.1
8 years, 7 months
[PATCHv2] [Kimchi] Edit Virtual Network with passthrough support
by Socorro Stoppler
v2:
- Fixed bugs encountered while testing
- Added support for macvtap passthrough
- Addressed feedback from Lucio
- UI issues below are still unresolved
- Due to value from backend currently is not showing up when edit comes up and instead
'Nothing selected' is showing, this is being handled gracefully in that if user leaves
the Destination field as is, the value (from backend) is preserved.
v1:
- First attempt of Edit Virtual Network UI
- Known UI Issues:s
- after the update happens, the list of networks are not shown properly (i.e. rows are all
bunched up and actions buttons are diagonal, but fixes itself after you move off the tab
and come back to it
- when edit panel first opens up, the value for the Destination selector (if applicable) is
either showing 'Nothing selected' or it's showing the first item on the list rather than
the value that came from backend
- Bridged network has not been tested so there's bound to be issues there
Proposal:
Per discussion w/Lucio, with regards to vlan_id, I'd like to propose to have the backend show the vlan_id as a separate field.
This came about when I couldn't find that field and as it turns out, it was because it was appended to the interface names
Signed-off-by: Socorro Stoppler <socorro(a)linux.vnet.ibm.com>
---
ui/js/src/kimchi.api.js | 23 ++++
ui/js/src/kimchi.network.js | 14 +++
ui/js/src/kimchi.network_add_main.js | 20 ++--
ui/js/src/kimchi.network_edit_main.js | 198 ++++++++++++++++++++++++++++++++++
ui/pages/network-edit.html.tmpl | 78 ++++++++++++++
ui/pages/tabs/network.html.tmpl | 3 +-
6 files changed, 327 insertions(+), 9 deletions(-)
create mode 100644 ui/js/src/kimchi.network_edit_main.js
create mode 100644 ui/pages/network-edit.html.tmpl
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
index 83d1cc7..8c01646 100644
--- a/ui/js/src/kimchi.api.js
+++ b/ui/js/src/kimchi.api.js
@@ -648,6 +648,17 @@ var kimchi = {
});
},
+ retrieveNetwork : function(name, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/networks/' + encodeURIComponent(name),
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success: suc,
+ error: err
+ });
+ },
+
deleteNetwork : function(name, suc, err) {
wok.requestJSON({
url : 'plugins/kimchi/networks/' + encodeURIComponent(name),
@@ -661,6 +672,18 @@ var kimchi = {
});
},
+ updateNetwork : function(name, settings, suc, err) {
+ wok.requestJSON({
+ url : "plugins/kimchi/networks/" + encodeURIComponent(name),
+ type : 'PUT',
+ contentType : 'application/json',
+ data : JSON.stringify(settings),
+ dataType : 'json',
+ success: suc,
+ error: err
+ });
+ },
+
listHostPartitions : function(suc, err) {
wok.requestJSON({
url : 'plugins/kimchi/host/partitions',
diff --git a/ui/js/src/kimchi.network.js b/ui/js/src/kimchi.network.js
index c0100cf..381449d 100644
--- a/ui/js/src/kimchi.network.js
+++ b/ui/js/src/kimchi.network.js
@@ -91,6 +91,8 @@ kimchi.getNetworkItemHtml = function(network) {
startClass : network.state === "up" ? "wok-hide-action-item" : "",
stopClass : network.state === "down" ? "wok-hide-action-item" : disable_in_use,
stopDisabled : network.in_use ? "disabled" : "",
+ editClass : network.state === "up" || network.in_use ? "disabled" : "",
+ editDisabled : network.state === "up" || network.in_use ? "disabled" : "",
deleteClass : network.state === "up" || network.in_use ? "disabled" : "",
deleteDisabled: network.state === "up" || network.in_use ? "disabled" : ""
});
@@ -107,6 +109,8 @@ kimchi.stopNetwork = function(network,menu) {
if (!network.in_use) {
$("[nwAct='delete']", menu).removeClass("disabled");
$(":first-child", $("[nwAct='delete']", menu)).removeAttr("disabled");
+ $("[nwAct='edit']", menu).removeClass("disabled");
+ $(":first-child", $("[nwAct='edit']", menu)).removeAttr("disabled");
}
$(".network-state", $("#" + wok.escapeStr(network.name))).switchClass("loading", "down");
}, function(err) {
@@ -128,6 +132,8 @@ kimchi.addNetworkActions = function(network) {
$("[nwAct='start']", menu).addClass("disabled");
$("[nwAct='delete']", menu).addClass("disabled");
$(":first-child", $("[nwAct='delete']", menu)).attr("disabled", true);
+ $("[nwAct='edit']", menu).addClass("disabled");
+ $(":first-child", $("[nwAct='edit']", menu)).attr("disabled", true);
kimchi.toggleNetwork(network.name, true, function() {
$("[nwAct='start']", menu).addClass("wok-hide-action-item");
$("[nwAct='start']", menu).removeClass("disabled");
@@ -142,8 +148,10 @@ kimchi.addNetworkActions = function(network) {
$("[nwAct='start']", menu).removeClass("disabled");
if (!network.in_use) {
$("[nwAct='delete']", menu).removeClass("disabled");
+ $("[nwAct='edit']", menu).removeClass("disabled");
}
$(":first-child", $("[nwAct='delete']", menu)).removeAttr("disabled");
+ $(":first-child", $("[nwAct='edit']", menu)).removeAttr("disabled");
wok.message.error(err.responseJSON.reason);
});
} else if ($(evt.currentTarget).attr("nwAct") === "stop") {
@@ -180,6 +188,12 @@ kimchi.addNetworkActions = function(network) {
$('#networkGrid').dataGrid('deleteRow', $(evt.currentTarget).parents(".wok-datagrid-row"));
});
}, null);
+ } else if ($(evt.currentTarget).attr("nwAct") === "edit") {
+ if (network.state === "up" || network.in_use) {
+ return false;
+ }
+ kimchi.selectedNetwork = network.name;
+ wok.window.open('plugins/kimchi/network-edit.html');
}
});
diff --git a/ui/js/src/kimchi.network_add_main.js b/ui/js/src/kimchi.network_add_main.js
index 3090aeb..a500cf8 100644
--- a/ui/js/src/kimchi.network_add_main.js
+++ b/ui/js/src/kimchi.network_add_main.js
@@ -56,7 +56,7 @@ kimchi.startNetworkCreation = function() {
};
kimchi.openNetworkDialog = function(okCallback) {
- kimchi.loadInterfaces();
+ kimchi.loadInterfaces(undefined, false);
$("#networkFormOk").on("click", function() {
$("#networkFormOk").button("disable");
@@ -73,10 +73,12 @@ kimchi.openNetworkDialog = function(okCallback) {
});
};
-kimchi.setDefaultNetworkType = function(isInterfaceAvail) {
+kimchi.setDefaultNetworkType = function(isInterfaceAvail, bEdit) {
$("#networkType").selectpicker();
if (!isInterfaceAvail) {
- kimchi.enableBridgeOptions(false);
+ if (!bEdit) {
+ kimchi.enableBridgeOptions(false);
+ }
$("#networkBriDisabledLabel").removeClass('hidden');
} else {
$("#networkBriDisabledLabel").remove();
@@ -128,9 +130,9 @@ kimchi.setupNetworkFormEvent = function() {
}
}
$('#networkDestinationID').selectpicker('destroy');
- kimchi.loadInterfaces(new Array("nic", "bonding"));
+ kimchi.loadInterfaces(new Array("nic", "bonding"), false);
} else {
- kimchi.loadInterfaces();
+ kimchi.loadInterfaces(undefined, false);
}
});
@@ -175,7 +177,7 @@ kimchi.enableBridgeOptions = function(enable, networkType, networkDestinationTyp
};
};
-kimchi.loadInterfaces = function(interfaceFilterArray) {
+kimchi.loadInterfaces = function(interfaceFilterArray, bEdit) {
var loadInterfacesHTML = function(result) {
var options = [];
@@ -200,8 +202,10 @@ kimchi.loadInterfaces = function(interfaceFilterArray) {
}
$selectDestination.append(selectDestinationOptionHTML);
$('#networkDestinationID').selectpicker('refresh');
- kimchi.setDefaultNetworkType(result.length!==0);
- kimchi.changeNetworkDestination();
+ kimchi.setDefaultNetworkType(result.length!==0, bEdit);
+ if (!bEdit) {
+ kimchi.changeNetworkDestination();
+ }
};
var networkType = $("#networkType").val();
diff --git a/ui/js/src/kimchi.network_edit_main.js b/ui/js/src/kimchi.network_edit_main.js
new file mode 100644
index 0000000..761d2f4
--- /dev/null
+++ b/ui/js/src/kimchi.network_edit_main.js
@@ -0,0 +1,198 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM Corp, 2016
+ *
+ * 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.
+ */
+
+kimchi.network_edit_main = function() {
+ var initNetwork = function(network) {
+ var networkType = network['connection'];
+ $('#bridgedContent').hide();
+ $('#networkType').val(networkType);
+ $('#networkName').val(kimchi.selectedNetwork);
+
+ var subnetValue = network['subnet'];
+ if (subnetValue === "") {
+ $('#networkSubnetRange').val("unavailable");
+ } else {
+ $('#networkSubnetRange').val(subnetValue);
+ }
+
+ // Default to hide Subnet
+ $('#subnetRange').hide();
+
+ if(networkType === "nat" || networkType === "isolated") {
+ //Show subnet/dhcp range
+ $('#subnetRange').show();
+ }
+
+ if (networkType === kimchi.NETWORK_TYPE_MACVTAP ||
+ networkType === kimchi.NETWORK_TYPE_PASSTHROUGH ||
+ networkType === kimchi.NETWORK_TYPE_VEPA ||
+ networkType === kimchi.NETWORK_TYPE_BRIDGED) {
+ $('#bridgedContent').show();
+ $('#networkDestination').show();
+ $('#vlan').hide();
+ if (networkType === kimchi.NETWORK_TYPE_BRIDGED) {
+ //Now check if there's a vlan id and only show if one exists
+ var netInterface = network['interfaces'];
+ var netInterfaceParts = netInterface[0].split('-', 2);
+ var netvlanID = netInterfaceParts[1];
+ if (netvlanID !== undefined) {
+ //Show vlan ID field; do not show the checkbox
+ $('#vlan').show();
+ $('#vlan_chkbox').hide();
+ $('#vlan-enabled').show();
+ $('#networkVlanID').val(netvlanID);
+ }
+ }
+ }
+
+ kimchi.setupNetworkFormEventForEdit(network);
+
+ //TODO: Trial and error trying to get select box to show show the one that it's currently set to but it doesn't work
+ var netInterface = network['interfaces'];
+ $('#networkDestinationID').append('val', netInterface);
+ $('#networkDestinationID').val(netInterface);
+ $("#networkDestinationID option[value='+netInterface+']").prop('selected', true);
+ $('#networkDestinationID').selectpicker('refresh');
+ };
+
+ kimchi.retrieveNetwork(kimchi.selectedNetwork, initNetwork);
+
+ var generalSubmit = function(event) {
+ $('#networkFormOk').text(i18n['KCHAPI6010M']);
+ $('#networkFormOk').prop('disabled', true);
+
+ var data = $('#networkConfig').serializeObject();
+ kimchi.updateNetworkValues();
+ };
+
+ $('#networkConfig').on('submit', generalSubmit);
+ $('#networkFormOk').on('click', generalSubmit);
+};
+
+kimchi.setupNetworkFormEventForEdit = function(network) {
+ var selectedType = network['connection'];
+ if (selectedType === kimchi.NETWORK_TYPE_BRIDGED) {
+ if (kimchi.capabilities && kimchi.capabilities.nm_running) {
+ wok.message.warn(i18n['KCHNET6001W'],'#alert-modal-container');
+ }
+ }
+
+ // Network name validation
+ $("#networkName").on("keyup", function(event) {
+ $("#networkName").toggleClass("invalid-field", !$("#networkName").val().match(/^[^\"\/]+$/));
+ kimchi.updateNetworkFormButtonForEdit();
+ });
+
+ var selectedType = network['connection'];
+ if(selectedType === kimchi.NETWORK_TYPE_MACVTAP ||
+ selectedType === kimchi.NETWORK_TYPE_PASSTHROUGH ||
+ selectedType === kimchi.NETWORK_TYPE_VEPA) {
+ if (selectedType === kimchi.NETWORK_TYPE_MACVTAP) {
+ $('#networkDestinationID').attr('multiple', false).data('liveSearch',false);
+ } else {
+ $('#networkDestinationID').attr('multiple', true);
+ if($('#networkDestinationID option').length > 10 ) {
+ $('#networkDestinationID').data('liveSearch',true);
+ }
+ }
+ $('#networkDestinationID').selectpicker('destroy');
+
+ kimchi.loadInterfaces(new Array("nic", "bonding"), true);
+ } else {
+ kimchi.loadInterfaces(undefined, true);
+ }
+ //TODO: Need to confirm if this is still needed
+ var netInterface = network['interfaces'];
+ $('#networkDestinationID').append('val', netInterface);
+ $('#networkDestinationID').val(netInterface);
+ $("#networkDestinationID option[value='+netInterface+']").prop('selected', true);
+ $('#networkDestinationID').selectpicker('refresh');
+};
+
+kimchi.updateNetworkFormButtonForEdit = function() {
+ if ($("#networkName").hasClass("invalid-field")) {
+ $('#networkFormOk').prop('disabled', true);
+ } else{
+ $('#networkFormOk').prop('disabled', false);
+ }
+};
+
+kimchi.getNetworkDialogValuesForEdit = function() {
+ var network = {
+ name : $("#networkName").val(),
+ type : $("#networkType").val(),
+ subnetRange: $("#networkSubnetRange").val(),
+ interface: $("#networkDestinationID").val(),
+ vlan_id: $("#networkVlanID").val()
+ };
+ if (network.type === kimchi.NETWORK_TYPE_BRIDGED) {
+ if (network.vlan_id !== "") {
+ network.vlan_id = parseInt($("#networkVlanID").val());
+ }
+ }
+ return network;
+};
+
+kimchi.updateNetworkValues = function() {
+ kimchi.retrieveNetwork(kimchi.selectedNetwork, function(settings) {
+ var network = kimchi.getNetworkDialogValuesForEdit();
+ var data = {
+ name : network.name,
+ subnet: network.subnetRange,
+ interfaces: [ network.interface ],
+ vlan_id: network.vlan_id
+ };
+ var originalDest = settings.interfaces;
+ var updatedDest = $('#networkDestinationID').val();
+ if (originalDest === updatedDest || updatedDest === null) {
+ delete data['interfaces'];
+ }
+ if (network.type !== "nat" && network.type !== "isolated") {
+ delete data['subnet'];
+ } else { // either nat or isolated
+ delete data['interfaces'];
+ delete data['vlan_id'];
+ }
+ if (network.type === kimchi.NETWORK_TYPE_BRIDGED) {
+ if (data.vlan_id === "") {
+ delete data['vlan_id'];
+ } else {
+ data.vlan_id = parseInt($("#networkVlanID").val());
+ }
+ } else {
+ delete data['vlan_id'];
+ }
+
+ // Just like in Add Network, VEPA connection - network.interface - is already an array
+ if (network.type === kimchi.NETWORK_TYPE_VEPA || network.type === kimchi.NETWORK_TYPE_PASSTHROUGH) {
+ if (network.interface !== null) {
+ data.interfaces = network.interface;
+ }
+ }
+
+ kimchi.updateNetwork(kimchi.selectedNetwork, data, function() {
+ $("#networkBody").empty();
+ kimchi.initNetworkListView();
+ wok.window.close();
+ }, function(settings) {
+ wok.message.error(settings.responseJSON.reason,'#alert-modal-container');
+ $('#networkFormOk').text(i18n['KCHAPI6007M']);
+ $('#networkFormOk').prop('disabled', false);
+ });
+ });
+};
diff --git a/ui/pages/network-edit.html.tmpl b/ui/pages/network-edit.html.tmpl
new file mode 100644
index 0000000..4cc7232
--- /dev/null
+++ b/ui/pages/network-edit.html.tmpl
@@ -0,0 +1,78 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM Corp, 2016
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<html>
+<body>
+<div id="edit-network-window" class="window modal-content">
+ <div class="modal-header">
+ <h4 class="modal-title" id="networkModalLabel">$_("Edit Network")</h4>
+ </div>
+ <div id="networkConfig" class="modal-body">
+ <span id="alert-modal-container"></span>
+ <div class="form-group">
+ <label for="networkType">$_("Network Type")</label>
+ <input type="text" class="form-control" id="networkType" disabled="disabled" />
+ </div>
+ <div class="form-group">
+ <label for="networkName">$_("Network Name")</label>
+ <input type="text" class="form-control" name="netName" id="networkName" />
+ <p class="help-block">
+ <i class="fa fa-info-circle"></i> $_("Name should not contain '/' and '\"'.")</p>
+ </div>
+ <div id="subnetRange" class="form-group" "col-md-3">
+ <div class="form-group">
+ <label for="networkSubnetRange">$_("Address Space")</label>
+ <input type="text" class="form-control" id="networkSubnetRange" />
+ </div>
+ </div>
+ <div id="networkBriDisabledLabel" class="form-group hidden">
+ <p>$_("(No interfaces found)")</p>
+ </div>
+ <div id="bridgedContent">
+ <div id="networkDestination" class="form-group">
+ <label for="networkDestinationID">$_("Destination")</label>
+ <select id="networkDestinationID" data-size="5" class="selectpicker col-md-12 col-lg-12 form-control">
+ </select>
+ </div>
+ <div class="form-group" id="vlan">
+ <div id="vlan_chkbox">
+ <input id="enableVlan" class="wok-checkbox" type="checkbox" value="" />
+ <label for="enableVlan" id="labelEnableVlan">$_("Enable VLAN") </label>
+ </div>
+ <div id="vlan-enabled">
+ <label for="networkVlanID" id="labelNetworkVlanID">$_("VLAN ID"): </label>
+ <input type="text" id="networkVlanID" class="form-control" />
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button type="submit" id="networkFormOk" class="btn btn-default">$_("Save")</button>
+ <button type="button" id="networkFormCancel" data-dismiss="modal" class="btn btn-default">$_("Cancel")</button>
+ </div>
+</div>
+<script type="text/javascript">
+kimchi.network_edit_main();
+</script>
+</body>
+</html>
diff --git a/ui/pages/tabs/network.html.tmpl b/ui/pages/tabs/network.html.tmpl
index d8660d3..6ddabaa 100644
--- a/ui/pages/tabs/network.html.tmpl
+++ b/ui/pages/tabs/network.html.tmpl
@@ -99,6 +99,7 @@
<ul class="dropdown-menu" role="menu">
<li role="presentation" nwAct="start" class='{startClass}'><a><i class="fa fa-undo"></i>$_("Start")</a></li>
<li role="presentation" nwAct="stop" class='{stopClass}'><a {stopDisabled}><i class="fa fa-ban"></i>$_("Stop")</a></li>
+ <li role="presentation" nwAct="edit" class='{editClass}'><a {editDisabled}><i class="fa fa-pencil"></i>$_("Edit")</a></li>
<li role="presentation" nwAct="delete" class='critical {deleteClass}'><a {deleteDisabled}><i class="fa fa-minus-circle"></i>$_("Delete")</a></li>
</ul>
</div>
@@ -110,4 +111,4 @@
kimchi.initNetwork();
</script>
</body>
-</html>
\ No newline at end of file
+</html>
--
2.5.0
8 years, 7 months
[PATCH V2] [Kimchi] UI fixes for edit virtual network
by Aline Manera
This patch solves the issues pointed by Socorro:
- after the update happens, the list of networks are not shown
properly (i.e. rows are all bunched up and actions buttons are diagonal, but fixes itself
after you move off the tab and come back to it
- when edit panel first opens up, the value for the Destination selector (if applicable) is
either showing 'Nothing selected' or it's showing the first item on the list rather than
the value that came from backend
Signed-off-by: Aline Manera <alinefm(a)linux.vnet.ibm.com>
---
ui/js/src/kimchi.api.js | 12 ++++++++
ui/js/src/kimchi.network_add_main.js | 48 ++++++++++++++++---------------
ui/js/src/kimchi.network_edit_main.js | 53 +++++++++++++++++++++++------------
ui/pages/network-edit.html.tmpl | 3 --
4 files changed, 73 insertions(+), 43 deletions(-)
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
index 8c01646..1ef3649 100644
--- a/ui/js/src/kimchi.api.js
+++ b/ui/js/src/kimchi.api.js
@@ -634,6 +634,18 @@ var kimchi = {
});
},
+ getInterface : function(iface, suc, err, sync) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/interfaces/' + encodeURIComponent(iface),
+ type : 'GET',
+ contentType : 'application/json',
+ async : !sync,
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
getVEPAInterfaces : function(suc, err) {
wok.requestJSON({
url : 'plugins/kimchi/interfaces?module=^(?!mlx5_core|mlx5-core).*$',
diff --git a/ui/js/src/kimchi.network_add_main.js b/ui/js/src/kimchi.network_add_main.js
index a500cf8..85df203 100644
--- a/ui/js/src/kimchi.network_add_main.js
+++ b/ui/js/src/kimchi.network_add_main.js
@@ -177,31 +177,35 @@ kimchi.enableBridgeOptions = function(enable, networkType, networkDestinationTyp
};
};
-kimchi.loadInterfaces = function(interfaceFilterArray, bEdit) {
-
- var loadInterfacesHTML = function(result) {
- var options = [];
- $selectDestination = $('#networkDestinationID');
- var nics = {};
- $('#networkDestinationID').find('option').remove();
- var selectDestinationOptionHTML = '';
- for (var i = 0; i < result.length; i++) {
- if (typeof interfaceFilterArray === 'undefined') {
- options.push({label:result[i].name,value:result[i].name});
- nics[result[i].name] = result[i];
- selectDestinationOptionHTML += '<option data-type="'+ result[i].type +'" value="'+ result[i].name + '">' + result[i].name + '</option>';
- } else {
- for (var k = 0; k < interfaceFilterArray.length; k++) {
- if (result[i].type == interfaceFilterArray[k]) {
- options.push({label:result[i].name,value:result[i].name});
- nics[result[i].name] = result[i];
- selectDestinationOptionHTML += '<option data-type="'+ result[i].type +'" value="'+ result[i].name + '">' + result[i].name + '</option>';
- }
+kimchi.createInterfacesOpts = function(ifaces, interfaceFilterArray) {
+ var options = [];
+ $selectDestination = $('#networkDestinationID');
+ var nics = {};
+ $('#networkDestinationID').find('option').remove();
+ var selectDestinationOptionHTML = '';
+ for (var i = 0; i < ifaces.length; i++) {
+ if (typeof interfaceFilterArray === 'undefined') {
+ options.push({label:ifaces[i].name,value:ifaces[i].name});
+ nics[ifaces[i].name] = ifaces[i];
+ selectDestinationOptionHTML += '<option data-type="' + ifaces[i].type + '" value="'+ ifaces[i].name + '">' + ifaces[i].name + '</option>';
+ } else {
+ for (var k = 0; k < interfaceFilterArray.length; k++) {
+ if (ifaces[i].type == interfaceFilterArray[k]) {
+ options.push({label:ifaces[i].name,value:ifaces[i].name});
+ nics[ifaces[i].name] = ifaces[i];
+ selectDestinationOptionHTML += '<option data-type="'+ ifaces[i].type +'" value="'+ ifaces[i].name + '">' + ifaces[i].name + '</option>';
}
}
}
- $selectDestination.append(selectDestinationOptionHTML);
- $('#networkDestinationID').selectpicker('refresh');
+ }
+ $selectDestination.append(selectDestinationOptionHTML);
+ $('#networkDestinationID').selectpicker('refresh');
+};
+
+kimchi.loadInterfaces = function(interfaceFilterArray, bEdit) {
+
+ var loadInterfacesHTML = function(result) {
+ kimchi.createInterfacesOpts(result, interfaceFilterArray);
kimchi.setDefaultNetworkType(result.length!==0, bEdit);
if (!bEdit) {
kimchi.changeNetworkDestination();
diff --git a/ui/js/src/kimchi.network_edit_main.js b/ui/js/src/kimchi.network_edit_main.js
index 761d2f4..4dd830a 100644
--- a/ui/js/src/kimchi.network_edit_main.js
+++ b/ui/js/src/kimchi.network_edit_main.js
@@ -61,13 +61,6 @@ kimchi.network_edit_main = function() {
}
kimchi.setupNetworkFormEventForEdit(network);
-
- //TODO: Trial and error trying to get select box to show show the one that it's currently set to but it doesn't work
- var netInterface = network['interfaces'];
- $('#networkDestinationID').append('val', netInterface);
- $('#networkDestinationID').val(netInterface);
- $("#networkDestinationID option[value='+netInterface+']").prop('selected', true);
- $('#networkDestinationID').selectpicker('refresh');
};
kimchi.retrieveNetwork(kimchi.selectedNetwork, initNetwork);
@@ -98,6 +91,30 @@ kimchi.setupNetworkFormEventForEdit = function(network) {
kimchi.updateNetworkFormButtonForEdit();
});
+ var loadIfaces = function(interfaceFilterArray){
+ var buildInterfaceOpts = function(result) {
+ var currentIfaces = network['interfaces'];
+ for (var i = 0; i < currentIfaces.length; i++) {
+ kimchi.getInterface(currentIfaces[i], function(iface) {
+ result.push(iface);
+ } , null, true);
+ }
+ kimchi.createInterfacesOpts(result, interfaceFilterArray);
+
+ for (var i = 0; i < currentIfaces.length; i++) {
+ $("#networkDestinationID option[value='" + currentIfaces[i] + "']").attr('selected','selected');
+ }
+ $('#networkDestinationID').selectpicker('refresh');
+ };
+
+ var networkType = $("#networkType").val();
+ if (networkType === kimchi.NETWORK_TYPE_VEPA) {
+ kimchi.getVEPAInterfaces(buildInterfaceOpts);
+ } else {
+ kimchi.getInterfaces(buildInterfaceOpts);
+ }
+ }
+
var selectedType = network['connection'];
if(selectedType === kimchi.NETWORK_TYPE_MACVTAP ||
selectedType === kimchi.NETWORK_TYPE_PASSTHROUGH ||
@@ -112,16 +129,10 @@ kimchi.setupNetworkFormEventForEdit = function(network) {
}
$('#networkDestinationID').selectpicker('destroy');
- kimchi.loadInterfaces(new Array("nic", "bonding"), true);
+ loadIfaces(new Array("nic", "bonding"));
} else {
- kimchi.loadInterfaces(undefined, true);
+ loadIfaces(undefined);
}
- //TODO: Need to confirm if this is still needed
- var netInterface = network['interfaces'];
- $('#networkDestinationID').append('val', netInterface);
- $('#networkDestinationID').val(netInterface);
- $("#networkDestinationID option[value='+netInterface+']").prop('selected', true);
- $('#networkDestinationID').selectpicker('refresh');
};
kimchi.updateNetworkFormButtonForEdit = function() {
@@ -185,9 +196,15 @@ kimchi.updateNetworkValues = function() {
}
}
- kimchi.updateNetwork(kimchi.selectedNetwork, data, function() {
- $("#networkBody").empty();
- kimchi.initNetworkListView();
+ kimchi.updateNetwork(kimchi.selectedNetwork, data, function(result) {
+ $('#' + kimchi.selectedNetwork).remove();
+ network = result;
+ network.type = result.connection;
+ network.state = result.state === "active" ? "up" : "down";
+ network.interface = result.interfaces ? result.interfaces[0] : i18n["KCHNET6001M"];
+ network.addrSpace = result.subnet ? result.subnet : i18n["KCHNET6001M"];
+ network.persistent = result.persistent;
+ $('#networkGrid').dataGrid('addRow', kimchi.addNetworkItem(network));
wok.window.close();
}, function(settings) {
wok.message.error(settings.responseJSON.reason,'#alert-modal-container');
diff --git a/ui/pages/network-edit.html.tmpl b/ui/pages/network-edit.html.tmpl
index 4cc7232..3f2f3fe 100644
--- a/ui/pages/network-edit.html.tmpl
+++ b/ui/pages/network-edit.html.tmpl
@@ -45,9 +45,6 @@
<input type="text" class="form-control" id="networkSubnetRange" />
</div>
</div>
- <div id="networkBriDisabledLabel" class="form-group hidden">
- <p>$_("(No interfaces found)")</p>
- </div>
<div id="bridgedContent">
<div id="networkDestination" class="form-group">
<label for="networkDestinationID">$_("Destination")</label>
--
2.5.5
8 years, 7 months
[PATCH] [Wok] Fix advanced log search by time
by Jose Ricardo Ziviani
- Backend does not allow log search by time, giving an error
WOKLOG0001E. This commit fixes this issue by including the
time field in the list of FILTER_FIELDS.
Signed-off-by: Jose Ricardo Ziviani <joserz(a)linux.vnet.ibm.com>
---
src/wok/reqlogger.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/wok/reqlogger.py b/src/wok/reqlogger.py
index 1145dbd..b309d8f 100644
--- a/src/wok/reqlogger.py
+++ b/src/wok/reqlogger.py
@@ -33,7 +33,7 @@ from wok.utils import ascii_dict, remove_old_files
# Log search setup
-FILTER_FIELDS = ['app', 'date', 'download', 'req', 'user']
+FILTER_FIELDS = ['app', 'date', 'download', 'req', 'user', 'time']
LOG_DOWNLOAD_URI = "/data/logs/%s"
LOG_DOWNLOAD_TIMEOUT = 6
LOG_FORMAT = "[%(date)s %(time)s] %(req)-6s %(app)-11s %(user)s: %(message)s\n"
--
2.7.4
8 years, 7 months
[PATCH v2] [Kimchi] [RFC] Storage Volume management UI
by sguimaraes943@gmail.com
From: Samuel Guimarães <sguimaraes943(a)gmail.com>
This patch adds the UI for Storage Volume management action button, filter input, gallery view and gallery / list view toggle-switch button with multi-selection enabled.
v1:
- HTML and CSS
v2:
- Delete and Wipe with multi-selection
- Confirm messages with list of selected volumes when wiping or deleting volumes (requires SCSS/CSS patch sent to Wok)
- Filter working
- Removed "Add Volume" link from Storage Pool action button
- Added "Add Volume" to Volume box action button
To do:
- Clone function
- Fix progress bar (gallery view) and spinner (list view) when adding and cloning a new volume
- Add a temporary volume when cloning process is still in progress
Known issues:
- List doesn't refresh when the only volume available is deleted from Storage Pool.
Please let me know if you find any bug or if you have any suggestion.
Samuel Guimarães (1):
Storage Volume management UI
ui/css/kimchi.css | 273 +++++++++++++++----
ui/css/src/modules/_storage.scss | 295 +++++++++++++++++----
ui/js/src/kimchi.api.js | 50 ++++
ui/js/src/kimchi.storage_main.js | 256 ++++++++++++++----
ui/js/src/kimchi.storagepool_add_volume_main.js | 2 +-
ui/js/src/kimchi.storagepool_resize_volume_main.js | 58 ++++
ui/pages/i18n.json.tmpl | 5 +
ui/pages/storagepool-resize-volume.html.tmpl | 51 ++++
ui/pages/tabs/storage.html.tmpl | 120 ++++++---
9 files changed, 925 insertions(+), 185 deletions(-)
create mode 100644 ui/js/src/kimchi.storagepool_resize_volume_main.js
create mode 100644 ui/pages/storagepool-resize-volume.html.tmpl
--
1.9.3
8 years, 7 months
[PATCH] [Kimchi] UI fixes for edit virtual network
by Aline Manera
This patch solves the issues pointed by Socorro:
- after the update happens, the list of networks are not shown
properly (i.e. rows are all bunched up and actions buttons are diagonal, but fixes itself
after you move off the tab and come back to it
- when edit panel first opens up, the value for the Destination selector (if applicable) is
either showing 'Nothing selected' or it's showing the first item on the list rather than
the value that came from backend
---
ui/js/src/kimchi.api.js | 12 +++++++++
ui/js/src/kimchi.network_add_main.js | 48 +++++++++++++++++++----------------
ui/js/src/kimchi.network_edit_main.js | 48 ++++++++++++++++++++++-------------
ui/pages/network-edit.html.tmpl | 3 ---
4 files changed, 68 insertions(+), 43 deletions(-)
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
index 8c01646..1ef3649 100644
--- a/ui/js/src/kimchi.api.js
+++ b/ui/js/src/kimchi.api.js
@@ -634,6 +634,18 @@ var kimchi = {
});
},
+ getInterface : function(iface, suc, err, sync) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/interfaces/' + encodeURIComponent(iface),
+ type : 'GET',
+ contentType : 'application/json',
+ async : !sync,
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
getVEPAInterfaces : function(suc, err) {
wok.requestJSON({
url : 'plugins/kimchi/interfaces?module=^(?!mlx5_core|mlx5-core).*$',
diff --git a/ui/js/src/kimchi.network_add_main.js b/ui/js/src/kimchi.network_add_main.js
index a500cf8..85df203 100644
--- a/ui/js/src/kimchi.network_add_main.js
+++ b/ui/js/src/kimchi.network_add_main.js
@@ -177,31 +177,35 @@ kimchi.enableBridgeOptions = function(enable, networkType, networkDestinationTyp
};
};
-kimchi.loadInterfaces = function(interfaceFilterArray, bEdit) {
-
- var loadInterfacesHTML = function(result) {
- var options = [];
- $selectDestination = $('#networkDestinationID');
- var nics = {};
- $('#networkDestinationID').find('option').remove();
- var selectDestinationOptionHTML = '';
- for (var i = 0; i < result.length; i++) {
- if (typeof interfaceFilterArray === 'undefined') {
- options.push({label:result[i].name,value:result[i].name});
- nics[result[i].name] = result[i];
- selectDestinationOptionHTML += '<option data-type="'+ result[i].type +'" value="'+ result[i].name + '">' + result[i].name + '</option>';
- } else {
- for (var k = 0; k < interfaceFilterArray.length; k++) {
- if (result[i].type == interfaceFilterArray[k]) {
- options.push({label:result[i].name,value:result[i].name});
- nics[result[i].name] = result[i];
- selectDestinationOptionHTML += '<option data-type="'+ result[i].type +'" value="'+ result[i].name + '">' + result[i].name + '</option>';
- }
+kimchi.createInterfacesOpts = function(ifaces, interfaceFilterArray) {
+ var options = [];
+ $selectDestination = $('#networkDestinationID');
+ var nics = {};
+ $('#networkDestinationID').find('option').remove();
+ var selectDestinationOptionHTML = '';
+ for (var i = 0; i < ifaces.length; i++) {
+ if (typeof interfaceFilterArray === 'undefined') {
+ options.push({label:ifaces[i].name,value:ifaces[i].name});
+ nics[ifaces[i].name] = ifaces[i];
+ selectDestinationOptionHTML += '<option data-type="' + ifaces[i].type + '" value="'+ ifaces[i].name + '">' + ifaces[i].name + '</option>';
+ } else {
+ for (var k = 0; k < interfaceFilterArray.length; k++) {
+ if (ifaces[i].type == interfaceFilterArray[k]) {
+ options.push({label:ifaces[i].name,value:ifaces[i].name});
+ nics[ifaces[i].name] = ifaces[i];
+ selectDestinationOptionHTML += '<option data-type="'+ ifaces[i].type +'" value="'+ ifaces[i].name + '">' + ifaces[i].name + '</option>';
}
}
}
- $selectDestination.append(selectDestinationOptionHTML);
- $('#networkDestinationID').selectpicker('refresh');
+ }
+ $selectDestination.append(selectDestinationOptionHTML);
+ $('#networkDestinationID').selectpicker('refresh');
+};
+
+kimchi.loadInterfaces = function(interfaceFilterArray, bEdit) {
+
+ var loadInterfacesHTML = function(result) {
+ kimchi.createInterfacesOpts(result, interfaceFilterArray);
kimchi.setDefaultNetworkType(result.length!==0, bEdit);
if (!bEdit) {
kimchi.changeNetworkDestination();
diff --git a/ui/js/src/kimchi.network_edit_main.js b/ui/js/src/kimchi.network_edit_main.js
index 761d2f4..4b813c9 100644
--- a/ui/js/src/kimchi.network_edit_main.js
+++ b/ui/js/src/kimchi.network_edit_main.js
@@ -61,13 +61,6 @@ kimchi.network_edit_main = function() {
}
kimchi.setupNetworkFormEventForEdit(network);
-
- //TODO: Trial and error trying to get select box to show show the one that it's currently set to but it doesn't work
- var netInterface = network['interfaces'];
- $('#networkDestinationID').append('val', netInterface);
- $('#networkDestinationID').val(netInterface);
- $("#networkDestinationID option[value='+netInterface+']").prop('selected', true);
- $('#networkDestinationID').selectpicker('refresh');
};
kimchi.retrieveNetwork(kimchi.selectedNetwork, initNetwork);
@@ -98,6 +91,25 @@ kimchi.setupNetworkFormEventForEdit = function(network) {
kimchi.updateNetworkFormButtonForEdit();
});
+ var loadIfaces = function(interfaceFilterArray){
+ var buildInterfaceOpts = function(result) {
+ var currentIfaces = network['interfaces'];
+ for (var i = 0; i < currentIfaces.length; i++) {
+ kimchi.getInterface(currentIfaces[i], function(iface) {
+ result.push(iface);
+ } , null, true);
+ }
+ kimchi.createInterfacesOpts(result, interfaceFilterArray);
+ };
+
+ var networkType = $("#networkType").val();
+ if (networkType === kimchi.NETWORK_TYPE_VEPA) {
+ kimchi.getVEPAInterfaces(buildInterfaceOpts);
+ } else {
+ kimchi.getInterfaces(buildInterfaceOpts);
+ }
+ }
+
var selectedType = network['connection'];
if(selectedType === kimchi.NETWORK_TYPE_MACVTAP ||
selectedType === kimchi.NETWORK_TYPE_PASSTHROUGH ||
@@ -112,16 +124,10 @@ kimchi.setupNetworkFormEventForEdit = function(network) {
}
$('#networkDestinationID').selectpicker('destroy');
- kimchi.loadInterfaces(new Array("nic", "bonding"), true);
+ loadIfaces(new Array("nic", "bonding"));
} else {
- kimchi.loadInterfaces(undefined, true);
+ loadIfaces(undefined);
}
- //TODO: Need to confirm if this is still needed
- var netInterface = network['interfaces'];
- $('#networkDestinationID').append('val', netInterface);
- $('#networkDestinationID').val(netInterface);
- $("#networkDestinationID option[value='+netInterface+']").prop('selected', true);
- $('#networkDestinationID').selectpicker('refresh');
};
kimchi.updateNetworkFormButtonForEdit = function() {
@@ -185,9 +191,15 @@ kimchi.updateNetworkValues = function() {
}
}
- kimchi.updateNetwork(kimchi.selectedNetwork, data, function() {
- $("#networkBody").empty();
- kimchi.initNetworkListView();
+ kimchi.updateNetwork(kimchi.selectedNetwork, data, function(result) {
+ $('#' + kimchi.selectedNetwork).remove();
+ network = result;
+ network.type = result.connection;
+ network.state = result.state === "active" ? "up" : "down";
+ network.interface = result.interfaces ? result.interfaces[0] : i18n["KCHNET6001M"];
+ network.addrSpace = result.subnet ? result.subnet : i18n["KCHNET6001M"];
+ network.persistent = result.persistent;
+ $('#networkGrid').dataGrid('addRow', kimchi.addNetworkItem(network));
wok.window.close();
}, function(settings) {
wok.message.error(settings.responseJSON.reason,'#alert-modal-container');
diff --git a/ui/pages/network-edit.html.tmpl b/ui/pages/network-edit.html.tmpl
index 4cc7232..3f2f3fe 100644
--- a/ui/pages/network-edit.html.tmpl
+++ b/ui/pages/network-edit.html.tmpl
@@ -45,9 +45,6 @@
<input type="text" class="form-control" id="networkSubnetRange" />
</div>
</div>
- <div id="networkBriDisabledLabel" class="form-group hidden">
- <p>$_("(No interfaces found)")</p>
- </div>
<div id="bridgedContent">
<div id="networkDestination" class="form-group">
<label for="networkDestinationID">$_("Destination")</label>
--
2.5.5
8 years, 7 months
[PATCH] [Wok] Fixed minor CSS issues and wok-confirm content when displaying lists
by sguimaraes943@gmail.com
From: Samuel Guimarães <sguimaraes943(a)gmail.com>
This patch adds some new styles for lists inside wok.confirm dialogs and fixes a minor issue with grouped Bootstrap selectors badly compiled by old version of python-libsass.
This is required for new Storage Volume management options.
Samuel Guimarães (1):
Fixed minor CSS issues and wok-confirm content when displaying lists
ui/css/bootstrap.custom.css | 6 +++---
ui/css/src/modules/_wok-confirm.scss | 11 +++++++++++
ui/css/wok.css | 11 +++++++++++
3 files changed, 25 insertions(+), 3 deletions(-)
--
1.9.3
8 years, 7 months
[PATCH] [Wok] Moved i18n variable from htmlStr
by pkulkark@linux.vnet.ibm.com
From: Pooja Kulkarni <pkulkark(a)linux.vnet.ibm.com>
This patch fixes the issue with
the i18n variable breaking wok
by moving it from htmlStr.
Signed-off-by: Pooja Kulkarni <pkulkark(a)linux.vnet.ibm.com>
---
ui/js/src/wok.list.js | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/ui/js/src/wok.list.js b/ui/js/src/wok.list.js
index d17a3e7..1d4e526 100644
--- a/ui/js/src/wok.list.js
+++ b/ui/js/src/wok.list.js
@@ -43,7 +43,7 @@ wok.widget.List.prototype = (function() {
'<div id="{id}-action-group" class="wok-list-action-button-container">',
'<div class="dropdown mobile-action">',
'<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false">',
- '<span class="mobile-action-label">'+i18n['WOKSETT0012M']+'</span>',
+ '<span class="mobile-action-label">{actions}</span>',
'</button>',
'<ul class="dropdown-menu" role="menu">',
'</ul>',
@@ -246,7 +246,8 @@ wok.widget.List.prototype = (function() {
loading: i18n.WOKGRD6001M,
message: i18n.WOKGRD6002M,
buttonLabel: i18n.WOKGRD6003M,
- detailedLabel: i18n.WOKGRD6004M
+ detailedLabel: i18n.WOKGRD6004M,
+ actions: i18n.WOKSETT0012M
})).appendTo(container);
this.domNode = domNode;
--
2.1.0
8 years, 7 months
Re: [Kimchi-devel] [PATCH] [Kimchi] Isolate unit tests execution.
by Aline Manera
On 05/20/2016 08:27 AM, Paulo Ricardo Paz Vital wrote:
> On May 18 06:24PM, Aline Manera wrote:
>>
>> On 05/16/2016 11:16 PM, pvital(a)linux.vnet.ibm.com wrote:
>>> From: Paulo Vital <pvital(a)linux.vnet.ibm.com>
>>>
>>> This patch isolates each unit test execution reducing the occurrences of tests
>>> using data from previous unit tests and making results not reliable.
>>>
>>> In addition, it also simplifies the output of tests execution, printing the tags
>>> PASSED and FAILED and the error/failed banners only when necessary.
>>>
>>> Signed-off-by: Paulo Vital <pvital(a)linux.vnet.ibm.com>
>>> ---
>>> tests/run_tests.sh.in | 53 +++++++++++++++++++++++++++++++++++++++------------
>>> 1 file changed, 41 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/tests/run_tests.sh.in b/tests/run_tests.sh.in
>>> index 68dfa2e..d9c2661 100644
>>> --- a/tests/run_tests.sh.in
>>> +++ b/tests/run_tests.sh.in
>>> @@ -21,6 +21,10 @@
>>> HAVE_UNITTEST=@HAVE_PYMOD_UNITTEST@
>>> PYTHON_VER=@PYTHON_VERSION@
>>>
>>> +RED='\033[0;31m'
>>> +GREEN='\033[0;32m'
>>> +NC='\033[0m' # No Color
>>> +
>>> if [ "$1" = "-v" ]; then
>>> OPTS="-v"
>>> shift
>>> @@ -40,19 +44,44 @@ else
>>> CMD="python -m unittest"
>>> fi
>>>
>>> -LIST=($ARGS)
>>> -MODEL_LIST=()
>>> -MOCK_LIST=()
>>> -for ((i=0;i<${#LIST[@]};i++)); do
>>> -
>>> - if [[ ${LIST[$i]} == test_model* ]]; then
>>> - MODEL_LIST+=(${LIST[$i]})
>>> +NUM_TESTS=0
>>> +TIME=0
>>> +declare -A FAILED_UT # dict to store failed unit tests and its OUTPUT_FILE
>>> +for UT in $ARGS; do
>>> + OUTPUT_FILE=$(mktemp)
>>> + echo -n "***** Running unit test: $UT... "
>>> + # ../../../../../ refers to the project root
>>> + # ../../../../ refers to wok directory
>>> + # ../../../ refers to plugins directory
>>> + PYTHONPATH=../../../../../:../../../../:../../../ \
>>> + PYTHONWARNINGS="ignore:Unverified HTTPS request" \
>>> + $CMD $OPTS $UT &> $OUTPUT_FILE
>> You can do:
>>
>> output=$($CMD $OPTS $UT)
>>
>> to get the test output. That way we don't need to create multiple temporary
>> files.
>>
> Yeap, I can do this. However, the idea to have a temporary file is keep the full
> output of the test case execution for future analysis, instead of check only the
> console history.
>
> This patch, when an error or failure happens, prints only the 'banner' with the
> test case error on user console. With the output stored in a file (temporary
> because I delete the files which finishes with no errors) I can see it later to
> fix the error.
>
My point is: you don't need to have multiple files.
Store the error output in a variable and if it is not empty in the end
of the process, write it into a file and print the output to user as you
already do.
>>> + RES=$?
>>> + if [ $RES -ne 0 ]; then
>>> + # unit test has failed, so keep the OUTPUT_FILE and print the results
>>> + echo -e "\t ${RED}FAILED${NC}"
>>> + ERROR_LOG_BEGIN=$(grep -n "^\==*" $OUTPUT_FILE | head -n1 | cut -d":" -f1)
>>> + ERROR_LOG_END=$(cat $OUTPUT_FILE | wc -l)
>>> + tail -n $((${ERROR_LOG_END}-${ERROR_LOG_BEGIN}+1)) $OUTPUT_FILE
>>> + FAILED_UT+=([$UT]=$OUTPUT_FILE)
>>> + OUTPUT=$(grep "Ran" $OUTPUT_FILE)
>> Following my suggestion to do not use temporary files, all the above block
>> will be replace by:
>>
>> FAILED_UT+=$output
>>
> With this changes the full output of test execution will be printed in the
> console. As I told above, this patch's idea is 'clean' the output printed in the
> console by showing only the error/failure 'banner' and keeping the full
> execution stack on a file.
>
>>> else
>>> - MOCK_LIST+=(${LIST[$i]})
>>> + # unit test has passed, so print the results and delete the OUTPUT_FILE
>>> + OUTPUT=$(grep "Ran" $OUTPUT_FILE)
>>> + echo -e "\t ${GREEN}PASSED${NC} - $OUTPUT"
>>> + rm -rf $OUTPUT_FILE
>>> fi
>>> + TES=$(echo $OUTPUT | cut -d" " -f2)
>>> + NUM_TESTS=$(echo "$NUM_TESTS + $TES" | bc)
>>> + TES=$(echo $OUTPUT | cut -d" " -f5)
>>> + TIME=$(echo "$TIME + ${TES:0:-1}" | bc)
>>> done
>>>
>>> -# ../../../../../ refers to the project root
>>> -# ../../../../ refers to wok directory
>>> -# ../../../ refers to plugins directory
>>> -PYTHONPATH=../../../../../:../../../../:../../../ PYTHONWARNINGS="ignore:Unverified HTTPS request" $CMD $OPTS ${MODEL_LIST[@]} ${MOCK_LIST[@]}
>>> +# Print summary results
>>> +echo -e "======================================================================"
>>> +echo -e "===================== Kimchi Unit Tests Summary ======================"
>>> +echo -e "Ran $NUM_TESTS tests in $TIME seconds."
>>> +for i in "${!FAILED_UT[@]}"; do
>>> + FAIL_STATS=$(grep FAILED ${FAILED_UT[$i]} | cut -d" " -f2-4)
>>> + echo -e "$i FAILED: $FAIL_STATS - log available at ${FAILED_UT[$i]}"
>>> +done
>>> --
>>> 2.5.5
> --
> Paulo Ricardo Paz Vital
> Linux Technology Center, IBM Systems
> http://www.ibm.com/linux/ltc/
8 years, 7 months