On 01/07/2014 11:51 AM, Zhou Zheng Sheng wrote:
on 2014/01/03 17:29, zhoumeina wrote:
> This patch is working for add iscsi type in storage pool create
> page.
> 1.Add iscsi server to create storage pool page.
> 2.Add iscsi target to create storage pool page.
>
> Signed-off-by: zhoumeina <zhoumein(a)linux.vnet.ibm.com>
> ---
> ui/css/theme-default/form.css | 5 ++
> ui/js/src/kimchi.storagepool_add_main.js | 77 +++++++++++++++++++++++++----
> ui/js/src/kimchi.utils.js | 5 ++
> ui/pages/i18n.html.tmpl | 7 ++-
> ui/pages/storagepool-add.html.tmpl | 48 +++++++++++++++----
> 5 files changed, 119 insertions(+), 23 deletions(-)
>
> diff --git a/ui/css/theme-default/form.css b/ui/css/theme-default/form.css
> index c24b277..28e30a5 100644
> --- a/ui/css/theme-default/form.css
> +++ b/ui/css/theme-default/form.css
> @@ -45,3 +45,8 @@
> line-height: 30px;
> padding: 0 5px;
> }
> +
> +
> +.form-section input.invalid-field[type="text"] {
> + border-color: #FF4444;
> +}
> \ No newline at end of file
> diff --git a/ui/js/src/kimchi.storagepool_add_main.js
b/ui/js/src/kimchi.storagepool_add_main.js
> index a154933..a2e1f15 100644
> --- a/ui/js/src/kimchi.storagepool_add_main.js
> +++ b/ui/js/src/kimchi.storagepool_add_main.js
> @@ -35,6 +35,9 @@ kimchi.initStorageAddPage = function() {
> }, {
> label : "NFS",
> value : "netfs"
> + } ,{
> + label : "iSCSI",
> + value : "iscsi"
> } ];
> kimchi.listHostPartitions(function(data) {
> if (data.length > 0) {
> @@ -57,16 +60,34 @@ kimchi.initStorageAddPage = function() {
> $('.path-section').removeClass('tmpl-html');
> $('.logical-section').addClass('tmpl-html');
> $('.nfs-section').addClass('tmpl-html');
> + $('.iscsi-section').addClass('tmpl-html');
> } else if ($(this).val() === 'netfs') {
> $('.path-section').addClass('tmpl-html');
> $('.logical-section').addClass('tmpl-html');
> $('.nfs-section').removeClass('tmpl-html');
> + $('.iscsi-section').addClass('tmpl-html');
> + } else if ($(this).val() === 'iscsi') {
> + $('.path-section').addClass('tmpl-html');
> + $('.logical-section').addClass('tmpl-html');
> + $('.nfs-section').addClass('tmpl-html');
> + $('.iscsi-section').removeClass('tmpl-html');
> } else {
> $('.path-section').addClass('tmpl-html');
> $('.logical-section').removeClass('tmpl-html');
> $('.nfs-section').addClass('tmpl-html');
> + $('.iscsi-section').addClass('tmpl-html');
> }
> });
> + $('#authId').click(function() {
> + if ($(this).prop("checked")) {
> + $('.authenticationfield').removeClass('tmpl-html');
> + } else {
> + $('.authenticationfield').addClass('tmpl-html');
> + }
> + });
> + $('#iscsiportId').keyup(function(event) {
> +
$(this).toggleClass("invalid-field",!/^[0-9]+$/.test($(this).val()));
> + });
> });
> };
>
> @@ -85,6 +106,8 @@ kimchi.validateForm = function() {
> return kimchi.validateDirForm();
> } else if (poolType === "netfs") {
> return kimchi.validateNfsForm();
> + } else if (poolType === "iscsi") {
> + return kimchi.validateIscsiForm();
> } else {
> return kimchi.validateLogicalForm();
> }
> @@ -107,26 +130,44 @@ kimchi.validateDirForm = function () {
> kimchi.validateNfsForm = function () {
> var nfspath = $('#nfspathId').val();
> var nfsserver = $('#nfsserverId').val();
> - if ('' === nfsserver) {
> - kimchi.message.error(i18n['msg.pool.edit.nfsserver.blank']);
> + if (!kimchi.validateServer(nfsserver)) {
> return false;
> }
> -
> if ('' === nfspath) {
> kimchi.message.error(i18n['msg.pool.edit.nfspath.blank']);
> return false;
> }
> - var domain =
"([0-9a-z_!~*'()-]+\.)*([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\.[a-z]{2,6}"
> - var ip = "(\\d{1,3}\.){3}\\d{1,3}"
> - regex = new RegExp('^' + domain + '|' + ip + '$')
> + if (!/((\/([0-9a-zA-Z-_\.]+)))$/.test(nfspath)) {
> + kimchi.message.error(i18n['msg.validate.pool.edit.nfspath']);
> + return false;
> + }
> + return true;
> +};
>
> - if(!regex.test(nfsserver)) {
> - kimchi.message.error(i18n['msg.validate.pool.edit.nfsserver']);
> +kimchi.validateIscsiForm = function() {
> + var iscsiServer = $('#iscsiserverId').val();
> + var iscsiTarget = $('#iscsiTargetId').val();
> + if (!kimchi.validateServer(iscsiServer)) {
> return false;
> }
> + if ('' === iscsiTarget) {
> + kimchi.message.error(i18n['msg.pool.edit.iscsitarget.blank']);
> + return false;
> + }
> + return true;
> +};
>
> - if (!/((\/([0-9a-zA-Z-_\.]+)))$/.test(nfspath)) {
> - kimchi.message.error(i18n['msg.validate.pool.edit.nfspath']);
> +kimchi.validateServer = function(serverField) {
> + if ('' === serverField) {
> + kimchi.message.error(i18n['msg.pool.edit.server.blank']);
> + return false;
> + }
> + var domain =
"([0-9a-z_!~*'()-]+\.)*([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\.[a-z]{2,6}"
> + var ip = "(\\d{1,3}\.){3}\\d{1,3}"
> + regex = new RegExp('^' + domain + '|' + ip + '$')
> +
> + if (!regex.test(serverField)) {
> + kimchi.message.error(i18n['msg.validate.pool.edit.server']);
> return false;
> }
> return true;
> @@ -144,6 +185,7 @@ kimchi.validateLogicalForm = function () {
> kimchi.addPool = function(event) {
> if (kimchi.validateForm()) {
> var formData = $('#form-pool-add').serializeObject();
> + delete formData.authname;
> var poolType = $("#poolType").val();
> if (poolType === 'dir') {
> formData.path = $('#pathId').val();
> @@ -158,11 +200,24 @@ kimchi.addPool = function(event) {
> }
> delete formData.devices;
> formData.source = source;
> - } else {
> + } else if (poolType === 'netfs'){
> var source = {};
> source.path = $('#nfspathId').val();
> source.host = $('#nfsserverId').val();
> formData.source = source;
> + } else {
> + var source = {};
> + source.target = $('#iscsiTargetId').val();
> + source.host = $('#iscsiserverId').val();
> + source.port = $('#iscsiportId').val();
Hello, as we discussed, if "$('#iscsiportId').val()" is empty, we
should
not assign it to source.port. Maybe you could add a "if" to check if
port is empty and only add a "port" attribute to "source" when port
is
non-empty.
Another small problem is the back-end actually expects source.port a
integer. So in all the port assignment logic can be expressed by the
following pseudo-code.
if $('#nfsserverId').val() is not empty
source.port = parseInt($('#iscsiportId').val())
ok
> + if ($('#authId').prop("checked")) {
> + source.auth = [];
> + source.auth.push({
> + "username" : $('#usernameId').val(),
> + "password" : $('#passwordId').val()
> + });
The back-end expects the auth is a dict, but here it is an array. I
change it to a dict and test the following.
if ($('#authId').prop("checked")) {
source.auth = {};
source.auth.username = $('#usernameId').val();
source.auth.password = $('#passwordId').val();
}
object not array, right? ok , change it next version.
> + }
> + formData.source = source;
> }
> if (poolType === 'logical') {
> var settings = {
> diff --git a/ui/js/src/kimchi.utils.js b/ui/js/src/kimchi.utils.js
> index 8af6a11..a23bf51 100644
> --- a/ui/js/src/kimchi.utils.js
> +++ b/ui/js/src/kimchi.utils.js
> @@ -163,3 +163,8 @@ kimchi.changetoProperUnit = function(numOrg, digits, base) {
>
> kimchi.formatMeasurement = format;
> })();
> +
> +kimchi.isUnsignedNumeric = function(number) {
> + var reg = /^d+(.d+)?$/
> + return reg.test(number);
> +}
> diff --git a/ui/pages/i18n.html.tmpl b/ui/pages/i18n.html.tmpl
> index c1fc3d1..4a02e4d 100644
> --- a/ui/pages/i18n.html.tmpl
> +++ b/ui/pages/i18n.html.tmpl
> @@ -94,11 +94,9 @@ var i18n = {
> 'msg.storagepool.confirm.delete':"$_("This will permanently
delete the Storage Pool. Would you like to continue?")",
> 'msg.pool.edit.name.blank':"$_("The storage pool name can not
be blank.")",
> 'msg.pool.edit.path.blank':"$_("The storage pool path can not
be blank.")",
> - 'msg.pool.edit.nfsserver.blank':"$_("NFS server can not be
blank.")",
> 'msg.pool.edit.nfspath.blank':"$_("NFS server mount path can
not be blank.")",
> 'msg.validate.pool.edit.name':"$_("Invalid Storage Pool name.
It may only contain letters, numbers, underscores, and hyphens.")",
> 'msg.validate.pool.edit.path':"$_("This is not a real linux
path.")",
> - 'msg.validate.pool.edit.nfsserver':"$_("This is not a valid
NFS server.")",
> 'msg.validate.pool.edit.nfspath':"$_("Invalid nfs mount
path.")",
> 'msg.kimchi.storage.pool.empty':"$_("This storage pool is
empty.")",
> 'msg.kimchi.list.volume.fail':"$_("Failed to list the storage
pool.")",
> @@ -121,7 +119,10 @@ var i18n = {
> 'action_create': "$_("Create")",
> 'msg_warning': "$_("Warning")",
> 'msg.logicalpool.confirm.delete': "$_("It will format your
disk and you will loose any data in"
> - " there, are you sure to continue?
")"
> + " there, are you sure to continue?
")",
> + 'msg.pool.edit.iscsitarget.blank': "$_("The iscsi target can
not be blank.")",
> + 'msg.pool.edit.server.blank':"$_("Server name can not be
blank.")",
> + 'msg.validate.pool.edit.server':"$_("This is not a valid
Server Name or IP. please, modify it.")"
> };
> </script>
> </body>
> diff --git a/ui/pages/storagepool-add.html.tmpl b/ui/pages/storagepool-add.html.tmpl
> index 5a2dd45..fa77a8b 100644
> --- a/ui/pages/storagepool-add.html.tmpl
> +++ b/ui/pages/storagepool-add.html.tmpl
> @@ -27,7 +27,7 @@
> <!DOCTYPE html>
> <html>
> <body>
> - <div class="window" style="width: 600px; height:
600px;">
> + <div class="window" style="width: 600px; height:
700px;">
> <header>
> <h1 class="title">$_("Define a New Storage
Pool")</h1>
> <div class="close">X</div>
> @@ -40,7 +40,7 @@
> <p class="text-help">
> $_("The name used to identify the storage pools,
and it should not be empty.")
> </p>
> - <input id="poolId" type="text"
class="text" style="width: 300px"
> + <input id="poolId"
required="required" type="text" class="text"
style="width: 300px"
> name="name">
> </div>
> </section>
> @@ -65,7 +65,7 @@
> $_("The path of the Storage Pool. Each Storage
Pool must have a unique path.")</p>
> <p class="text-help">
> $_("Kimchi will try to create the directory
when it does not already exist in your system.")</p>
> - <input id="pathId" type="text"
class="text" style="width: 300px">
> + <input id="pathId" type="text"
class="text" required="required" style="width: 300px">
> </div>
> <div class="clear"></div>
> </section>
> @@ -76,7 +76,7 @@
> <div class="field">
> <p class="text-help">
> $_("NFS server IP or hostname. It should not
be empty.")</p>
> - <input id="nfsserverId"
type="text" class="text"
> + <input id="nfsserverId"
required="required" type="text" class="text"
> style="width: 300px">
> </div>
> </section>
> @@ -84,10 +84,9 @@
> <h2>4. $_("NFS Path")</h2>
> <div class="field">
> <p class="text-help">$_("The nfs
exported path on nfs server")</p>
> - <input id="nfspathId" type="text"
class="text"
> + <input id="nfspathId"
required="required" type="text" class="text"
> style="width: 300px">
> - <input type="hidden"
id="localpathId" class="text"
> - value="none">
> + <input type="hidden"
id="localpathId" class="text" value="none">
> </div>
> <div class="clear"></div>
> </section>
> @@ -98,6 +97,37 @@
> <div class="host-partition"></div>
> </section>
> </div>
> + <div class="iscsi-section tmpl-html">
> + <section class="form-section">
> + <h2>3. $_("iSCSI Server")</h2>
> + <div class="field">
> + <p class="text-help">
> + $_("iSCSI server IP or hostname. It should not be
empty.")</p>
> + <input id="iscsiserverId"
placeholder="$_("Server")" type="text"
class="text" style="width: 300px">
> + <input id="iscsiportId"
placeholder="$_("Port")" type="text" class="text"
style="width:40px" maxlength='4'>
> + </div>
> + </section>
> + <section class="form-section">
> + <h2>4. $_("Target")</h2>
> + <div class="field">
> + <p class="text-help">$_("The iSCSI target on iSCSI
server")</p>
> + <input id="iscsiTargetId" type="text"
class="text" style="width: 300px">
> + </div>
> + </section>
> + <section class="form-section">
> + <div class="field">
> + <input type="checkbox" id="authId"
name="authname">
> + <label>$_("Add iSCSI
Authentication...")</label>
> + </div>
> + </section>
> + <section class="authenticationfield form-section tmpl-html">
> + <h2>5. $_("iSCSI Authentication")</h2>
> + <div class="field">
> + <input id="usernameId" placeholder="$_("User
Name")" type="text" class="text" style="width:
150px">
> + <input id="passwordId"
placeholder="$_("Password")" type="text"
class="text" style="width: 150px">
> + </div>
> + </section>
> + </div>
> </form>
> </div>
> <footer>
> @@ -113,8 +143,8 @@
> </script>
> <script id="partitionTmpl" type="html/text">
> <div>
> - <input type="checkbox" value="{path}"
name="devices">
> - <label>{path}</label>
> + <input type="checkbox" value="{path}"
name="source.devices">
> + <label>{path}</label>
> </div>
> </script>
> </body>
>