[PATCH 0/6] [WIP] update manage repository UI to work with new API

host tab table population works. Edit populates fields correctly. Parse contents from the form does not yet work. Updae needed to kimchi.form.js Consider changing the name notation from [] to . to make it simpler to parse. Haven't touched add yet, but it should be a linear extrapolation from edit->save Patch set includes latest UI from the list. Adam King (1): manageRep update to match new BE Hongliang Wang (5): Repository Management - Add i18n Strings Repository Management - Add API Support Repository Management - Add Repository Support Repository Management - Edit Repository Support Repository Management - Integrate into Host Tab docs/API.html | 978 +++++++++++++++++++++++++++++++ po/POTFILES.in | 2 + ui/css/theme-default/host.css | 8 + ui/css/theme-default/repository-add.css | 39 ++ ui/css/theme-default/repository-edit.css | 128 ++++ ui/js/src/kimchi.api.js | 76 ++- ui/js/src/kimchi.grid.js | 17 +- ui/js/src/kimchi.host.js | 186 +++++- ui/js/src/kimchi.repository_add_main.js | 84 +++ ui/js/src/kimchi.repository_edit_main.js | 99 ++++ ui/pages/i18n.html.tmpl | 19 + ui/pages/repository-add.html.tmpl | 104 ++++ ui/pages/repository-edit.html.tmpl | 115 ++++ ui/pages/tabs/host.html.tmpl | 15 + 14 files changed, 1865 insertions(+), 5 deletions(-) create mode 100644 docs/API.html create mode 100644 ui/css/theme-default/repository-add.css create mode 100644 ui/css/theme-default/repository-edit.css create mode 100644 ui/js/src/kimchi.repository_add_main.js create mode 100644 ui/js/src/kimchi.repository_edit_main.js create mode 100644 ui/pages/repository-add.html.tmpl create mode 100644 ui/pages/repository-edit.html.tmpl -- 1.8.1.4

From: Hongliang Wang <hlwang@linux.vnet.ibm.com> Add i18n translation strings for repository management. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/pages/i18n.html.tmpl | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ui/pages/i18n.html.tmpl b/ui/pages/i18n.html.tmpl index 2f47e50..e1ebd47 100644 --- a/ui/pages/i18n.html.tmpl +++ b/ui/pages/i18n.html.tmpl @@ -80,6 +80,25 @@ var i18n = { 'KCHHOST6008M': "$_("Shutting down or restarting host will cause unsaved work lost. Continue to shut down/restarting?")", + 'KCHREPO6001M': "$_("Confirm")", + 'KCHREPO6002M': "$_("Repository will be removed permanently and can't be recovered. Do you want to continue?")", + 'KCHREPO6003M': "$_("Repositories")", + 'KCHREPO6004M': "$_("ID")", + 'KCHREPO6005M': "$_("Name")", + 'KCHREPO6006M': "$_("Base URL")", + 'KCHREPO6007M': "$_("Is Mirror")", + 'KCHREPO6008M': "$_("URL Args")", + 'KCHREPO6009M': "$_("Enabled")", + 'KCHREPO6010M': "$_("GPG Check")", + 'KCHREPO6011M': "$_("GPG Key")", + 'KCHREPO6012M': "$_("Add")", + 'KCHREPO6013M': "$_("Edit")", + 'KCHREPO6014M': "$_("Remove")", + 'KCHREPO6015M': "$_("Failed.")", + 'KCHREPO6016M': "$_("Enable")", + 'KCHREPO6017M': "$_("Disable")", + + 'KCHUPD6001M': "$_("Software Updates")", 'KCHUPD6002M': "$_("Package Name")", 'KCHUPD6003M': "$_("Version")", -- 1.8.1.4

From: Hongliang Wang <hlwang@linux.vnet.ibm.com> Add API calling in kimchi.api.js. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/js/src/kimchi.api.js | 76 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index 4310435..9ceed0b 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -856,5 +856,79 @@ var kimchi = { success : onResponse, error : err }); - } + }, + + createRepository : function(settings, suc, err) { + kimchi.requestJSON({ + url : "host/repositories", + type : "POST", + contentType : "application/json", + data : JSON.stringify(settings), + dataType : "json", + success: suc, + error: err + }); + }, + + retrieveRepository : function(repository, suc, err) { + var reposID = encodeURIComponent(repository); + kimchi.requestJSON({ + url : kimchi.url + "host/repositories/" + reposID, + type : 'GET', + contentType : 'application/json', + dataType : 'json', + success : suc, + error : err + }); + }, + + updateRepository : function(name, settings, suc, err) { + var reposID = encodeURIComponent(name); + $.ajax({ + url : kimchi.url + "host/repositories/" + reposID, + type : 'PUT', + contentType : 'application/json', + data : JSON.stringify(settings), + dataType : 'json', + success : suc, + error : err + }); + }, + + enableRepository : function(name, enable, suc, err) { + var reposID = encodeURIComponent(name); + $.ajax({ + url : kimchi.url + "host/repositories/" + reposID + + '/' + (enable === true ? 'enable' : 'disable'), + type : 'POST', + contentType : 'application/json', + dataType : 'json', + success : suc, + error : err + }); + }, + + deleteRepository : function(repository, suc, err) { + var reposID = encodeURIComponent(repository); + kimchi.requestJSON({ + url : kimchi.url + 'host/repositories/' + reposID, + type : 'DELETE', + contentType : 'application/json', + dataType : 'json', + success : suc, + error : err + }); + }, + + listRepositories : function(suc, err) { + kimchi.requestJSON({ + url : kimchi.url + 'host/repositories', + type : 'GET', + contentType : 'application/json', + dataType : 'json', + resend: true, + success : suc, + error : err + }); + } }; -- 1.8.1.4

From: Hongliang Wang <hlwang@linux.vnet.ibm.com> Add repository. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/css/theme-default/repository-add.css | 39 ++++++++++++ ui/js/src/kimchi.repository_add_main.js | 84 ++++++++++++++++++++++++++ ui/pages/repository-add.html.tmpl | 104 ++++++++++++++++++++++++++++++++ 3 files changed, 227 insertions(+) create mode 100644 ui/css/theme-default/repository-add.css create mode 100644 ui/js/src/kimchi.repository_add_main.js create mode 100644 ui/pages/repository-add.html.tmpl diff --git a/ui/css/theme-default/repository-add.css b/ui/css/theme-default/repository-add.css new file mode 100644 index 0000000..2434efd --- /dev/null +++ b/ui/css/theme-default/repository-add.css @@ -0,0 +1,39 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Authors: + * Hongliang Wang <hlwang@linux.vnet.ibm.com> + * + * 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. + */ +#repository-add-window { + height: 680px; + width: 1000px; +} + +#repository-add-window .required { + color: red; + padding-left: 5px; + vertical-align: top; +} + +#repository-add-window .textbox-wrapper input[type="text"] { + box-sizing: border-box; + width: 100%; +} + +#repository-add-window .textbox-wrapper label { + vertical-align: middle; +} diff --git a/ui/js/src/kimchi.repository_add_main.js b/ui/js/src/kimchi.repository_add_main.js new file mode 100644 index 0000000..75b785e --- /dev/null +++ b/ui/js/src/kimchi.repository_add_main.js @@ -0,0 +1,84 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Authors: + * Hongliang Wang <hlwang@linux.vnet.ibm.com> + * + * 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.repository_add_main = function() { + + var addForm = $('#form-repository-add'); + var addButton = $('#button-repository-add'); + + var nameBox = $('input[name="repo_id"]', addForm); + var urlBox = $('input[name="baseurl"]', addForm); + var isMirrorButton = $('input[name="is_mirror"]', addForm); + var urlArgsBox = $('input[name="url_args"]', addForm); + var gpgkeyBox = $('input[name="gpgkey"]', addForm); + + var validateForm = function(event) { + var valid = $(urlBox).val() !== ''; + $(addButton).prop('disabled', !valid); + return valid; + }; + + $(urlBox).on('input propertychange', validateForm); + + var booleanFields = ['is_mirror']; + + var addRepository = function(event) { + var valid = validateForm(); + if(!valid) { + return false; + } + + var formData = $(addForm).serializeObject(); + for(var p in formData) { + if(formData[p] == '') { + delete formData[p]; + } + } + + $(booleanFields).each(function(i, f) { + switch(formData[f]) { + case 'true': + formData[f] = true; + break; + case 'false': + formData[f] = false; + break; + default: + delete formData[f]; + break; + } + }); + + kimchi.createRepository(formData, function() { + kimchi.topic('kimchi/repositoryAdded').publish(); + kimchi.window.close(); + }, function(jqXHR, textStatus, errorThrown) { + var reason = jqXHR && + jqXHR['responseJSON'] && + jqXHR['responseJSON']['reason']; + reason = reason ? ': ' + reason : ''; + kimchi.message.error(i18n['KCHREPO6015M'] + reason); + }); + + return false; + }; + + $(addForm).on('submit', addRepository); +}; diff --git a/ui/pages/repository-add.html.tmpl b/ui/pages/repository-add.html.tmpl new file mode 100644 index 0000000..a170f1d --- /dev/null +++ b/ui/pages/repository-add.html.tmpl @@ -0,0 +1,104 @@ +#* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Authors: + * Hongliang Wang <hlwang@linux.vnet.ibm.com> + * + * 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 kimchi.cachebust import href +#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang) +#silent _ = t.gettext +#silent _t = t.gettext +<div id="repository-add-window" class="window"> + <form id="form-repository-add"> + <header class="window-header"> + <h1 class="title">$_("Add a Repository")</h1> + <div class="close">X</div> + </header> + <div class="content"> + <section class="form-section"> + <h2>1. $_("Name")</h2> + <div class="field"> + <p class="text-help"> + $_("Unique repository name for each repository, one word.") + </p> + <div class="textbox-wrapper"> + <input type="text" class="text" name="repo_id" /> + </div> + </div> + </section> + <section class="form-section"> + <h2>2. $_("Base URL")<span class="required" role="presentation" title="$_("Required Field")">*</span></h2> + <div class="field"> + <p class="text-help"> + $_("URL to the repodata directory when \"is_mirror\" is false. Otherwise, it can be URL to the mirror system for YUM. Can be an http://, ftp:// or file:// URL.") + </p> + <div class="textbox-wrapper"> + <input type="text" class="text" name="baseurl" /> + </div> + </div> + </section> + <section class="form-section"> + <h2>3. $_("Is Mirror")</h2> + <div class="field"> + <p class="text-help"> + $_("Set the given URI of baseurl as a mirror list, instead of use baseurl in repository configuration.") + </p> + <div class="textbox-wrapper"> + <input type="radio" id="isMirrorRadioTrue" name="is_mirror" value="true" /> + <label for="isMirrorRadioTrue">$_("Yes")</label> + <input type="radio" id="isMirrorRadioFalse" name="is_mirror" value="false" /> + <label for="isMirrorRadioFalse">$_("No")</label> + </div> + </div> + </section> + <section class="form-section"> + <h2>4. $_("URL Args")</h2> + <div class="field"> + <p class="text-help"> + $_("Arguments to be passed to baseurl, like the list of APT repositories provided by the same baseurl.") + </p> + <div class="textbox-wrapper"> + <input type="text" class="text" name="url_args" /> + </div> + </div> + </section> + <section class="form-section"> + <h2>5. $_("GPG Key")</h2> + <div class="field"> + <p class="text-help"> + $_("URL pointing to the ASCII-armored GPG key file for the repository. This option is used if yum needs a public key to verify a package and the required key hasn't been imported into the RPM database.") + </p> + <div class="textbox-wrapper"> + <input type="text" class="text" name="gpgkey" /> + </div> + </div> + </section> + </div> + <footer> + <div class="btn-group"> + <button type="submit" id="button-repository-add" class="btn-normal" disabled="disabled"> + <span class="text">$_("Add")</span> + </button> + </div> + </footer> + </form> +</div> +<script> + kimchi.repository_add_main(); +</script> -- 1.8.1.4

From: Hongliang Wang <hlwang@linux.vnet.ibm.com> Edit repository support. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- ui/css/theme-default/repository-edit.css | 69 +++++++++++++++++++ ui/js/src/kimchi.repository_edit_main.js | 85 ++++++++++++++++++++++++ ui/pages/repository-edit.html.tmpl | 110 +++++++++++++++++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 ui/css/theme-default/repository-edit.css create mode 100644 ui/js/src/kimchi.repository_edit_main.js create mode 100644 ui/pages/repository-edit.html.tmpl diff --git a/ui/css/theme-default/repository-edit.css b/ui/css/theme-default/repository-edit.css new file mode 100644 index 0000000..ee6ad2e --- /dev/null +++ b/ui/css/theme-default/repository-edit.css @@ -0,0 +1,69 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * Authors: + * Hongliang Wang <hlwang@linux.vnet.ibm.com> + * + * 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. + */ +#repository-edit-window { + height: 420px; + width: 1000px; +} + +.repository-edit-fieldset { + float: left; + padding: 1em; +} + +.repository-edit-wrapper-label, .repository-edit-wrapper-controls { + display: inline-block; + height: 38px; + line-height: 38px; + margin-top: 5px; + vertical-align: top; +} + +.repository-edit-wrapper-label { + width: 150px; +} + +.repository-edit-wrapper-controls label { + vertical-align: middle; +} + +.repository-edit-wrapper-controls { + width: 300px; +} + +.repository-edit-wrapper-controls input[type="text"] { + font-size: 16px; + height: 38px; + line-height: 38px; + background: #fff; + -webkit-border-radius: 5px; + border-radius: 5px; + box-shadow: 2px 2px 2px #eee inset; + border-top: 1px solid #bbb; + border-left: 1px solid #bbb; + padding: 0 10px; + width: 250px; +} + +.repository-edit-wrapper-controls input[type="text"][disabled] { + color: #bbb; + background-color: #fafafa; + cursor: not-allowed; +} diff --git a/ui/js/src/kimchi.repository_edit_main.js b/ui/js/src/kimchi.repository_edit_main.js new file mode 100644 index 0000000..0ab008e --- /dev/null +++ b/ui/js/src/kimchi.repository_edit_main.js @@ -0,0 +1,85 @@ +/* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * 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.repository_edit_main = function() { + + var editForm = $('#form-repository-edit'); + var saveButton = $('#repository-edit-button-save'); + + kimchi.retrieveRepository(kimchi.selectedRepository, function(repository) { + for(var prop in repository) { + var control = $('input[name="' + prop + '"]', editForm); + switch($(control).attr('type')) { + case 'text': + $(control).val(repository[prop]); + break; + case 'radio': + case 'checkbox': + $(control).each(function(i, c) { + var matched = ('' + repository[prop]) == $(c).val(); + $(c).prop('checked', matched); + }); + break; + default: + break; + } + + } + + $('input', editForm).on('input propertychange', function(event) { + if($(this).val() !== '') { + $(saveButton).prop('disabled', false); + } + }); + }); + + var booleanFields = ['is_mirror', 'gpgcheck']; + + var editRepository = function(event) { + var formData = $(editForm).serializeObject(); + + $(booleanFields).each(function(i, f) { + switch(formData[f]) { + case 'true': + formData[f] = true; + break; + case 'false': + formData[f] = false; + break; + default: + delete formData[f]; + break; + } + }); + + kimchi.updateRepository(kimchi.selectedRepository, formData, function() { + kimchi.topic('kimchi/repositoryUpdated').publish(); + kimchi.window.close(); + }, function(jqXHR, textStatus, errorThrown) { + var reason = jqXHR && + jqXHR['responseJSON'] && + jqXHR['responseJSON']['reason']; + reason = reason ? ': ' + reason : ''; + kimchi.message.error(i18n['KCHREPO6015M'] + reason); + }); + + return false; + }; + + $(editForm).on('submit', editRepository); + $(saveButton).on('click', editRepository); +}; diff --git a/ui/pages/repository-edit.html.tmpl b/ui/pages/repository-edit.html.tmpl new file mode 100644 index 0000000..9fa280d --- /dev/null +++ b/ui/pages/repository-edit.html.tmpl @@ -0,0 +1,110 @@ +#* + * Project Kimchi + * + * Copyright IBM, Corp. 2013 + * + * 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 kimchi.cachebust import href +#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang) +#silent _ = t.gettext +#silent _t = t.gettext + +<div id="repository-edit-window" class="window"> + <header> + <h1 class="title">$_("Edit Repository")</h1> + <div class="close">X</div> + </header> + <div class="content"> + <form id="form-repository-edit"> + <fieldset class="repository-edit-fieldset"> + <div> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-id-textbox">$_("ID")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-id-textbox" name="repo_id" type="text" /> + </div> + </div> + <div> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-name-textbox">$_("Name")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-name-textbox" name="repo_name" type="text" /> + </div> + </div> + <div> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-baseurl-textbox">$_("Base URL")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-baseurl-textbox" name="baseurl" type="text" /> + </div> + </div> + <div> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-urlargs-textbox">$_("URL Args")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-urlargs-textbox" name="url_args" type="text" /> + </div> + </div> + </fieldset> + <fieldset class="repository-edit-fieldset"> + <div> + <div class="repository-edit-wrapper-label"> + <label>$_("Is Mirror")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-ismirror-radio-true" name="is_mirror" type="radio" value="true" /> + <label for="repository-edit-ismirror-radio-true">$_("Yes")</label> + <input id="repository-edit-ismirror-radio-false" name="is_mirror" type="radio" value="false" /> + <label for="repository-edit-ismirror-radio-false">$_("No")</label> + </div> + </div> + <div> + <div class="repository-edit-wrapper-label"> + <label>$_("GPG Check")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-gpgcheck-radio-true" name="gpgcheck" type="radio" value="true" /> + <label for="repository-edit-gpgcheck-radio-true">$_("Yes")</label> + <input id="repository-edit-gpgcheck-radio-false" name="gpgcheck" type="radio" value="false" /> + <label for="repository-edit-gpgcheck-radio-false">$_("No")</label> + </div> + </div> + <div> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-gpgkey-textbox">$_("GPG Key")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-gpgkey-textbox" name="gpgkey" type="text" /> + </div> + </div> + </fieldset> + </form> + </div> + <footer> + <div class="btn-group"> + <button id="repository-edit-button-save" class="btn-normal"> + <span class="text">$_("Save")</span> + </button> + </div> + </footer> +</div> +<script type="text/javascript"> + kimchi.repository_edit_main(); +</script> -- 1.8.1.4

From: Hongliang Wang <hlwang@linux.vnet.ibm.com> Integrate add/enable/disalbe/edit/remove a repository feature into host tab. Signed-off-by: Hongliang Wang <hlwang@linux.vnet.ibm.com> --- po/POTFILES.in | 2 + ui/css/theme-default/host.css | 40 ++++++++++ ui/js/src/kimchi.host.js | 170 ++++++++++++++++++++++++++++++++++++++++++ ui/pages/tabs/host.html.tmpl | 13 ++++ 4 files changed, 225 insertions(+) diff --git a/po/POTFILES.in b/po/POTFILES.in index 4ff7eaa..955a675 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -7,6 +7,8 @@ ui/pages/i18n.html.tmpl ui/pages/kimchi-ui.html.tmpl ui/pages/login-window.html.tmpl ui/pages/report-add.html.tmpl +ui/pages/repository-add.html.tmpl +ui/pages/repository-edit.html.tmpl ui/pages/storagepool-add.html.tmpl ui/pages/tabs/guests.html.tmpl ui/pages/tabs/host.html.tmpl diff --git a/ui/css/theme-default/host.css b/ui/css/theme-default/host.css index 0f8b941..9aca5cd 100644 --- a/ui/css/theme-default/host.css +++ b/ui/css/theme-default/host.css @@ -253,3 +253,43 @@ width: 846px; } /* End of Software Updates */ + +/* Repository */ +.host-panel #repositories-grid { + border-color: #ddd; + height: 200px; + width: 850px; +} + +.repository-id { + width: 70px; +} + +.repository-name { + width: 180px; +} + +.repository-baseurl { + width: 300px; +} + +.repository-ismirror { + width: 60px; +} + +.repository-urlargs { + width: 70px; +} + +.repository-enabled { + width: 60px; +} + +.repository-gpgcheck { + width: 60px; +} + +.repository-gpgkey { + width: 300px; +} +/* End of Repository */ diff --git a/ui/js/src/kimchi.host.js b/ui/js/src/kimchi.host.js index 6300f37..9604d89 100644 --- a/ui/js/src/kimchi.host.js +++ b/ui/js/src/kimchi.host.js @@ -22,6 +22,157 @@ kimchi.host_main = function() { $(header).attr('aria-expanded', toExpand ? 'true' : 'false'); }; + var repositoriesGridID = 'repositories-grid'; + var repositoriesGrid = null; + var initRepositoriesGrid = function(repositories) { + repositoriesGrid = new kimchi.widget.Grid({ + container: 'repositories-grid-container', + id: repositoriesGridID, + title: i18n['KCHREPO6003M'], + toolbarButtons: [{ + id: repositoriesGridID + '-add-button', + label: i18n['KCHREPO6012M'], + onClick: function(event) { + kimchi.window.open('repository-add.html'); + } + }, { + id: repositoriesGridID + '-enable-button', + label: i18n['KCHREPO6016M'], + disabled: true, + onClick: function(event) { + var repository = repositoriesGrid.getSelected(); + if(!repository) { + return; + } + var name = repository['repo_id']; + var enable = !repository['enabled']; + $(this).prop('disabled', true); + kimchi.enableRepository(name, enable, function() { + kimchi.topic('kimchi/repositoryUpdated').publish(); + }); + } + }, { + id: repositoriesGridID + '-edit-button', + label: i18n['KCHREPO6013M'], + disabled: true, + onClick: function(event) { + var repository = repositoriesGrid.getSelected(); + if(!repository) { + return; + } + kimchi.selectedRepository = repository['repo_id']; + kimchi.window.open('repository-edit.html'); + } + }, { + id: repositoriesGridID + '-remove-button', + label: i18n['KCHREPO6014M'], + disabled: true, + onClick: function(event) { + var repository = repositoriesGrid.getSelected(); + if(!repository) { + return; + } + + var settings = { + title : i18n['KCHREPO6001M'], + content : i18n['KCHREPO6002M'], + confirm : i18n['KCHAPI6004M'], + cancel : i18n['KCHAPI6003M'] + }; + + kimchi.confirm(settings, function() { + kimchi.deleteRepository( + repository['repo_id'], + function(result) { + kimchi.topic('kimchi/repositoryDeleted').publish(result); + }, function(error) { + } + ); + }); + } + }], + onRowSelected: function(row) { + var repository = repositoriesGrid.getSelected(); + if(!repository) { + return; + } + + $('#' + repositoriesGridID + '-remove-button') + .prop('disabled', false); + $('#' + repositoriesGridID + '-edit-button') + .prop('disabled', false); + + var enabled = repository['enabled']; + $('#' + repositoriesGridID + '-enable-button') + .text(i18n[enabled ? 'KCHREPO6017M' : 'KCHREPO6016M']) + .prop('disabled', false); + }, + frozenFields: [], + fields: [{ + name: 'repo_id', + label: i18n['KCHREPO6004M'], + 'class': 'repository-id' + }, { + name: 'repo_name', + label: i18n['KCHREPO6005M'], + 'class': 'repository-name' + }, { + name: 'enabled', + label: i18n['KCHREPO6009M'], + 'class': 'repository-enabled' + }, { + name: 'baseurl', + label: i18n['KCHREPO6006M'], + makeTitle: true, + 'class': 'repository-baseurl' + }, { + name: 'url_args', + label: i18n['KCHREPO6008M'], + 'class': 'repository-urlargs' + }, { + name: 'is_mirror', + label: i18n['KCHREPO6007M'], + 'class': 'repository-ismirror' + }, { + name: 'gpgcheck', + label: i18n['KCHREPO6010M'], + 'class': 'repository-gpgcheck' + }, { + name: 'gpgkey', + label: i18n['KCHREPO6011M'], + 'class': 'repository-gpgkey' + }], + data: listRepositories + }); + }; + + var listRepositories = function(gridCallback) { + kimchi.listRepositories(function(repositories) { + $.each(repositories, function(i, item) { + repositories[i]['rowno'] = i + 1; + }); + + if($.isFunction(gridCallback)) { + gridCallback(repositories); + } + else { + if(repositoriesGrid) { + repositoriesGrid.setData(repositories); + } + else { + initRepositoriesGrid(repositories); + } + } + }); + + $('#' + repositoriesGridID + '-remove-button') + .prop('disabled', true); + $('#' + repositoriesGridID + '-edit-button') + .prop('disabled', true); + $('#' + repositoriesGridID + '-enable-button') + .prop('disabled', true); + }; + var softwareUpdatesGridID = 'software-updates-grid'; var softwareUpdatesGrid = null; var progressAreaID = 'software-updates-progress-textarea'; @@ -271,6 +422,17 @@ kimchi.host_main = function() { }); kimchi.getCapabilities(function(capabilities) { + if(capabilities['repo_mngt_tool']) { + $('#repository-management-section').removeClass('hidden'); + initRepositoriesGrid(); + kimchi.topic('kimchi/repositoryAdded') + .subscribe(listRepositories); + kimchi.topic('kimchi/repositoryUpdated') + .subscribe(listRepositories); + kimchi.topic('kimchi/repositoryDeleted') + .subscribe(listRepositories); + } + if(capabilities['update_tool']) { $('#software-update-section').removeClass('hidden'); initSoftwareUpdatesGrid(); @@ -552,6 +714,14 @@ kimchi.host_main = function() { delete kimchi.hostTimer; } + repositoriesGrid && repositoriesGrid.destroy(); + kimchi.topic('kimchi/repositoryAdded') + .unsubscribe(listRepositories); + kimchi.topic('kimchi/repositoryUpdated') + .unsubscribe(listRepositories); + kimchi.topic('kimchi/repositoryDeleted') + .unsubscribe(listRepositories); + softwareUpdatesGrid && softwareUpdatesGrid.destroy(); kimchi.topic('kimchi/softwareUpdated').unsubscribe(listSoftwareUpdates); diff --git a/ui/pages/tabs/host.html.tmpl b/ui/pages/tabs/host.html.tmpl index 179deba..4933b31 100644 --- a/ui/pages/tabs/host.html.tmpl +++ b/ui/pages/tabs/host.html.tmpl @@ -120,6 +120,19 @@ </div> </div> </div> + <div id="repositories-section" class="host-section"> + <h3 class="section-header" + aria-controls="content-repositories"> + $_("Repositories") + </h3> + <div id="content-repositories" class="section-content"> + <div class="section-row"> + <div class="section-value"> + <div id="repositories-grid-container"></div> + </div> + </div> + </div> + </div> <div id="software-update-section" class="host-section hidden"> <h3 class="section-header" aria-controls="content-software-update"> -- 1.8.1.4

--- docs/API.html | 978 +++++++++++++++++++++++++++++++ ui/css/theme-default/host.css | 32 - ui/css/theme-default/repository-edit.css | 61 +- ui/js/src/kimchi.grid.js | 17 +- ui/js/src/kimchi.host.js | 144 ++--- ui/js/src/kimchi.repository_edit_main.js | 34 +- ui/pages/repository-edit.html.tmpl | 55 +- ui/pages/tabs/host.html.tmpl | 4 +- 8 files changed, 1188 insertions(+), 137 deletions(-) create mode 100644 docs/API.html diff --git a/docs/API.html b/docs/API.html new file mode 100644 index 0000000..6f4c925 --- /dev/null +++ b/docs/API.html @@ -0,0 +1,978 @@ +<h2>Project Kimchi REST API Specification</h2> +<p>The Kimchi API provides all functionality to the application and may be used +directly by external tools. In the following sections you will find the +specification of all Collections and Resource types that are supported and the +URIs where they can be accessed. In order to use the API effectively, please +the following general conventions:</p> +<ul> +<li>The <strong>Content Type</strong> of the API is JSON. When making HTTP requests to this + API you should specify the following headers:<ul> +<li>Accept: application/json</li> +<li>Content-type: application/json</li> +</ul> +</li> +<li>A <strong>Collection</strong> is a group of Resources of a given type.<ul> +<li>A <strong>GET</strong> request retrieves a list of summarized Resource representations + This summary <em>may</em> include all or some of the Resource properties but + <em>must</em> include a link to the full Resource representation.</li> +<li>A <strong>POST</strong> request will create a new Resource in the Collection. The set + of Resource properties <em>must</em> be specified as a JSON object in the request + body.</li> +<li>No other HTTP methods are supported for Collections</li> +</ul> +</li> +<li>A <strong>Resource</strong> is a representation of a singular object in the API (eg. + Virtual Machine).<ul> +<li>A <strong>GET</strong> request retrieves the full Resource representation.</li> +<li>A <strong>DELETE</strong> request will delete the Resource. This request <em>may</em> contain + a JSON object which specifies optional parameters.</li> +<li>A <strong>PUT</strong> request is used to modify the properties of a Resource (eg. + Change the name of a Virtual Machine). This kind of request <em>must not</em> + alter the live state of the Resource. Only <em>actions</em> may alter live state.</li> +<li>A <strong>POST</strong> request commits an <em>action</em> upon a Resource (eg. Start a + Virtual Machine). This request is made to a URI relative to the Resource + URI. Available <em>actions</em> are described within the <em>actions</em> property of a + Resource representation. The request body <em>must</em> contain a JSON object + which specifies parameters.</li> +</ul> +</li> +<li>URIs begin with a '/' to indicate the root of the API.<ul> +<li>Variable segments in the URI begin with a ':' and should replaced with the + appropriate resource identifier.</li> +</ul> +</li> +</ul> +<h3>Collection: Virtual Machines</h3> +<p><strong>URI:</strong> /vms</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve a summarized list of all defined Virtual Machines</li> +<li><strong>POST</strong>: Create a new Virtual Machine<ul> +<li>name <em>(optional)</em>: The name of the VM. Used to identify the VM in this + API. If omitted, a name will be chosen based on the template used.</li> +<li>template: The URI of a Template to use when building the VM</li> +<li>storagepool <em>(optional)</em>: Assign a specific Storage Pool to the new VM</li> +<li>graphics <em>(optional)</em>: Specify the graphics paramenter for this vm<ul> +<li>type: The type of graphics. It can be VNC or spice or None.<ul> +<li>vnc: Graphical display using the Virtual Network + Computing protocol</li> +<li>spice: Graphical display using the Simple Protocol for + Independent Computing Environments</li> +<li>null: Graphics is disabled or type not supported</li> +</ul> +</li> +<li>listen: The network which the vnc/spice server listens on.</li> +</ul> +</li> +<li>volumes <em>(optional)</em>: List of Fibre channel LUN names to be assigned as + disk to VM. Required if pool is type SCSI.</li> +</ul> +</li> +</ul> +<h3>Resource: Virtual Machine</h3> +<p><strong>URI:</strong> /vms/<em>:name</em></p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve the full description of a Virtual Machine<ul> +<li>name: The name of the VM. Used to identify the VM in this API</li> +<li>state: Indicates the current state in the VM lifecycle<ul> +<li>running: The VM is powered on</li> +<li>paused: The VMs virtual CPUs are paused</li> +<li>shutoff: The VM is powered off</li> +</ul> +</li> +<li>stats: Virtual machine statistics:<ul> +<li>cpu_utilization: A number between 0 and 100 which indicates the + percentage of CPU utilization.</li> +<li>net_throughput: Expresses total network throughput for reads and + writes across all virtual interfaces (kb/s).</li> +<li>net_throughput_peak: The highest recent value of 'net_throughput'.</li> +<li>io_throughput: Expresses the total IO throughput for reads and + writes across all virtual disks (kb/s).</li> +<li>io_throughput_peak: The highest recent value of 'io_throughput'.</li> +</ul> +</li> +<li>uuid: UUID of the VM.</li> +<li>memory: The amount of memory assigned to the VM (in MB)</li> +<li>cpus: The number of CPUs assigned to the VM</li> +<li>screenshot: A link to a recent capture of the screen in PNG format</li> +<li>icon: A link to an icon that represents the VM</li> +<li>graphics: A dict to show detail of VM graphics.<ul> +<li>type: The type of graphics. It can be VNC or spice or None.<ul> +<li>vnc: Graphical display using the Virtual Network + Computing protocol</li> +<li>spice: Graphical display using the Simple Protocol for + Independent Computing Environments</li> +<li>null: Graphics is disabled or type not supported</li> +</ul> +</li> +<li>listen: The network which the vnc/spice server listens on.</li> +<li>port: The real port number of the graphics, vnc or spice. Users + can use this port to connect to the vm with general vnc/spice + clients.</li> +</ul> +</li> +</ul> +</li> +<li><strong>DELETE</strong>: Remove the Virtual Machine</li> +<li><strong>PUT</strong>: update the parameters of existed VM<ul> +<li>name: New name for this VM (only applied for shutoff VM)</li> +</ul> +</li> +<li><strong>POST</strong>: <em>See Virtual Machine Actions</em></li> +</ul> +<p><strong>Actions (POST):</strong></p> +<ul> +<li>start: Power on a VM</li> +<li>stop: Power off forcefully</li> +<li>connect: Prepare the connection for spice or vnc</li> +</ul> +<h3>Sub-resource: Virtual Machine Screenshot</h3> +<p><strong>URI:</strong> /vms/<em>:name</em>/screenshot</p> +<p>Represents a snapshot of the Virtual Machine's primary monitor.</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Redirect to the latest screenshot of a Virtual Machine in PNG format</li> +</ul> +<h3>Sub-collection: Virtual Machine storages</h3> +<p><strong>URI:</strong> /vms/<em>:name</em>/storages +<em> <strong>GET</strong>: Retrieve a summarized list of all storages of specified guest +</em> <strong>POST</strong>: Attach a new storage or virtual drive to specified virtual machine. + * dev: The name of the storage in the vm. + * type: The type of the storage (currently supports 'cdrom' only). + * path: Path of cdrom iso.</p> +<h3>Sub-resource: storage</h3> +<p><strong>URI:</strong> /vms/<em>:name</em>/storages/<em>:dev</em> +<em> <strong>GET</strong>: Retrieve storage information + * dev: The name of the storage in the vm. + * type: The type of the storage ('cdrom' only for now). + * path: Path of cdrom iso.</em> <strong>PUT</strong>: Update storage information + * path: Path of cdrom iso. Can not be blank. +* <strong>DELETE</strong>: Remove the storage.</p> +<h3>Collection: Templates</h3> +<p><strong>URI:</strong> /templates</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve a summarized list of all defined Templates</li> +<li> +<p><strong>POST</strong>: Create a new Template</p> +<ul> +<li>name: The name of the Template. Used to identify the Template in this API</li> +<li>os_distro <em>(optional)</em>: The operating system distribution</li> +<li>os_version <em>(optional)</em>: The version of the operating system distribution</li> +<li>cpus <em>(optional)</em>: The number of CPUs assigned to the VM. Default is 1.</li> +<li>memory <em>(optional)</em>: The amount of memory assigned to the VM. + Default is 1024M.</li> +<li>cdrom <em>(required)</em>: A volume name or URI to an ISO image.</li> +<li>storagepool <em>(optional)</em>: URI of the storagepool. + Default is '/storagepools/default'</li> +<li>networks <em>(optional)</em>: list of networks will be assigned to the new VM. + Default is '[default]'</li> +<li> +<p>disks <em>(optional)</em>: An array of requested disks with the following optional fields + (either <em>size</em> or <em>volume</em> must be specified):</p> +<ul> +<li>index: The device index</li> +<li>size: The device size in GB</li> +</ul> +</li> +<li> +<p>graphics <em>(optional)</em>: The graphics paramenters of this template</p> +<ul> +<li>type: The type of graphics. It can be VNC or spice or None.<ul> +<li>vnc: Graphical display using the Virtual Network + Computing protocol</li> +<li>spice: Graphical display using the Simple Protocol for + Independent Computing Environments</li> +<li>null: Graphics is disabled or type not supported</li> +</ul> +</li> +<li>listen: The network which the vnc/spice server listens on.</li> +</ul> +</li> +</ul> +</li> +</ul> +<h3>Sub-Collection: Virtual Machine Network Interfaces</h3> +<p><strong>URI:</strong> /vms/<em>:name</em>/ifaces</p> +<p>Represents all network interfaces attached to a Virtual Machine.</p> +<p><strong>Methods:</strong></p> +<ul> +<li> +<p><strong>GET</strong>: Retrieve a summarized list of all network interfaces attached to a Virtual Machine.</p> +</li> +<li> +<p><strong>POST</strong>: attach a network interface to VM</p> +<ul> +<li>model <em>(optional)</em>: model of emulated network interface card. It can be one of these models: + ne2k_pci, i82551, i82557b, i82559er, rtl8139, e1000, pcnet and virtio. + When model is missing, libvirt will set 'rtl8139' as default value.</li> +<li>network <em>(optional)</em>: the name of resource network, it is required when the + interface type is network.</li> +<li>type: The type of VM network interface that libvirt supports. + Now kimchi just supports 'network' type.</li> +</ul> +</li> +</ul> +<h3>Sub-Resource: Virtual Machine Network Interface</h3> +<p><strong>URI:</strong> /vms/<em>:name</em>/ifaces/<em>:mac</em></p> +<p>A interface represents available network interface on VM.</p> +<p><strong>Methods:</strong></p> +<ul> +<li> +<p><strong>GET</strong>: Retrieve the full description of the VM network interface</p> +<ul> +<li>bridge <em>(optional)</em>: the name of resource bridge, only be available when the + interface type is bridge.</li> +<li>mac: Media Access Control Address of the VM interface.</li> +<li>model <em>(optional)</em>: model of emulated network interface card. It will be one of these models: + ne2k_pci, i82551, i82557b, i82559er, rtl8139, e1000, pcnet and virtio.</li> +<li>network <em>(optional)</em>: the name of resource network, only be available when the + interface type is network.</li> +<li>type: The type of VM network interface that libvirt supports. + It will be one of these types: 'network', 'bridge', 'user','ethernet', + 'direct', 'hostdev', 'mcast', 'server' and 'client'.</li> +</ul> +</li> +<li> +<p><strong>DELETE</strong>: detach the network interface from VM</p> +</li> +</ul> +<p><strong>Actions (POST):</strong></p> +<p><em>No actions defined</em></p> +<h3>Resource: Template</h3> +<p><strong>URI:</strong> /templates/<em>:name</em></p> +<p><strong>Methods:</strong></p> +<ul> +<li> +<p><strong>GET</strong>: Retrieve the full description of a Template</p> +<ul> +<li>name: A name for this template</li> +<li>folder: A virtual path which can be used to organize Templates in a user + interface. The format is an array of path components.</li> +<li>icon: A URI to a PNG image representing this template</li> +<li>os_distro: The operating system distribution</li> +<li>os_version: The version of the operating system distribution</li> +<li>cpus: The number of CPUs assigned to the VM</li> +<li>memory: The amount of memory assigned to the VM</li> +<li>cdrom: A volume name or URI to an ISO image</li> +<li>storagepool: URI of the storagepool where template allocates vm storage.</li> +<li>networks <em>(optional)</em>: list of networks will be assigned to the new VM.</li> +<li>disks: An array of requested disks with the following optional fields + (either <em>size</em> or <em>volume</em> must be specified):<ul> +<li>index: The device index</li> +<li>size: The device size in GB</li> +<li>volume: A volume name that contains the initial disk contents</li> +</ul> +</li> +<li>graphcis: A dict of graphics paramenters of this template<ul> +<li>type: The type of graphics. It can be VNC or spice or None.<ul> +<li>vnc: Graphical display using the Virtual Network + Computing protocol</li> +<li>spice: Graphical display using the Simple Protocol for + Independent Computing Environments</li> +<li>null: Graphics is disabled or type not supported</li> +</ul> +</li> +<li>listen: The network which the vnc/spice server listens on.</li> +</ul> +</li> +<li>invalid: A dict indicates which paramenters of this template are invalid.<ul> +<li>networks <em>(optional)</em>: An array of invalid network names.</li> +<li>cdrom <em>(optional)</em>: An array of invalid cdrom names.</li> +<li>disks <em>(optional)</em>: An array of invalid volume names.</li> +<li>storagepools <em>(optional)</em>: An array of invalid storagepool names.</li> +</ul> +</li> +</ul> +</li> +<li> +<p><strong>DELETE</strong>: Remove the Template</p> +</li> +<li><strong>POST</strong>: <em>See Template Actions</em></li> +<li><strong>PUT</strong>: update the parameters of existed template<ul> +<li>name: A name for this template</li> +<li>folder: A virtual path which can be used to organize Templates in the user + interface. The format is an array of path components.</li> +<li>icon: A URI to a PNG image representing this template</li> +<li>os_distro: The operating system distribution</li> +<li>os_version: The version of the operating system distribution</li> +<li>cpus: The number of CPUs assigned to the VM</li> +<li>memory: The amount of memory assigned to the VM</li> +<li>cdrom: A volume name or URI to an ISO image</li> +<li>storagepool: URI of the storagepool where template allocates vm storage.</li> +<li>networks <em>(optional)</em>: list of networks will be assigned to the new VM.</li> +<li>disks: An array of requested disks with the following optional fields + (either <em>size</em> or <em>volume</em> must be specified):<ul> +<li>index: The device index</li> +<li>size: The device size in GB</li> +<li>volume: A volume name that contains the initial disk contents</li> +</ul> +</li> +<li>graphcis <em>(optional)</em>: A dict of graphics paramenters of this template<ul> +<li>type: The type of graphics. It can be VNC or spice or None.<ul> +<li>vnc: Graphical display using the Virtual Network + Computing protocol</li> +<li>spice: Graphical display using the Simple Protocol for + Independent Computing Environments</li> +<li>null: Graphics is disabled or type not supported</li> +</ul> +</li> +<li>listen: The network which the vnc/spice server listens on.</li> +</ul> +</li> +</ul> +</li> +</ul> +<p><strong>Actions (POST):</strong></p> +<ul> +<li>clone: clone a template from an existing template with different name. + It will provide a reasonable default name with "-cloneN" as suffix + for the new clone template. The "N" means the number of clone times.</li> +</ul> +<h3>Collection: Storage Pools</h3> +<p><strong>URI:</strong> /storagepools</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve a summarized list of all defined Storage Pools</li> +<li><strong>POST</strong>: Create a new Storage Pool<ul> +<li>name: The name of the Storage Pool.</li> +<li>type: The type of the defined Storage Pool. + Supported types: 'dir', 'kimchi-iso', 'netfs', 'logical', 'iscsi', 'scsi'</li> +<li>path: The path of the defined Storage Pool. + For 'kimchi-iso' pool refers to targeted deep scan path. + Pool types: 'dir', 'kimchi-iso'.</li> +<li>source: Dictionary containing source information of the pool.<ul> +<li>host: IP or hostname of server for a pool backed from a remote host. + Pool types: 'netfs', 'iscsi'.</li> +<li>path: Export path on NFS server for NFS pool. + Pool types: 'netfs'.</li> +<li>devices: Array of devices to be used in the Storage Pool + Pool types: 'logical'.</li> +<li>target: Target IQN of an iSCSI pool. + Pool types: 'iscsi'.</li> +<li>port <em>(optional)</em>: Listening port of a remote storage server. + Pool types: 'iscsi'.</li> +<li>auth <em>(optional)</em>: Storage back-end authentication information. + Pool types: 'iscsi'.<ul> +<li>username: Login username of the iSCSI target.</li> +<li>password: Login password of the iSCSI target.</li> +</ul> +</li> +<li>adapter_name <em>(optional)</em>: Scsi host name.</li> +</ul> +</li> +</ul> +</li> +</ul> +<h3>Resource: Storage Pool</h3> +<p><strong>URI:</strong> /storagepools/<em>:name</em></p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve the full description of a Storage Pool<ul> +<li>name: The name of the Storage Pool + Used to identify the Storage Pool in this API + 'kimchi_isos' is a reserved storage pool + which aggregates all ISO images + across all active storage pools into a single view.</li> +<li>state: Indicates the current state of the Storage Pool<ul> +<li>active: The Storage Pool is ready for use</li> +<li>inactive: The Storage Pool is not available</li> +</ul> +</li> +<li>path: The path of the defined Storage Pool</li> +<li>type: The type of the Storage Pool</li> +<li>capacity: The total space which can be used to store volumes + The unit is Bytes</li> +<li>allocated: The amount of space which is being used to store volumes + The unit is Bytes</li> +<li>available: Free space available for creating new volumes in the pool</li> +<li>nr_volumes: The number of storage volumes for active pools, 0 for inactive pools</li> +<li>autostart: Whether the storage pool will be enabled + automatically when the system boots</li> +<li>source: Source of the storage pool,<ul> +<li>addr: mount address of this storage pool(for 'netfs' pool)</li> +<li>path: export path of this storage pool(for 'netfs' pool)</li> +</ul> +</li> +</ul> +</li> +<li><strong>PUT</strong>: Set whether the Storage Pool should be enabled automatically when the + system boots<ul> +<li>autostart: Toggle the autostart flag of the VM. This flag sets whether + the Storage Pool should be enabled automatically when the + system boots</li> +<li>disks: Adds one or more disks to the pool (for 'logical' pool only)</li> +</ul> +</li> +<li><strong>DELETE</strong>: Remove the Storage Pool</li> +<li><strong>POST</strong>: <em>See Storage Pool Actions</em></li> +</ul> +<p><strong>Actions (POST):</strong></p> +<ul> +<li>activate: Activate an inactive Storage Pool</li> +<li>deactivate: Deactivate an active Storage Pool</li> +</ul> +<h3>Collection: Storage Volumes</h3> +<p><strong>URI:</strong> /storagepools/<em>:poolname</em>/storagevolumes</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve a summarized list of all defined Storage Volumes + in the defined Storage Pool</li> +<li><strong>POST</strong>: Create a new Storage Volume in the Storage Pool<ul> +<li>name: The name of the Storage Volume</li> +<li>type: The type of the defined Storage Volume</li> +<li>capacity: The total space which can be used to store volumes + The unit is MBytes</li> +<li>format: The format of the defined Storage Volume</li> +</ul> +</li> +</ul> +<h3>Resource: Storage Volume</h3> +<p><strong>URI:</strong> /storagepools/<em>:poolname</em>/storagevolumes/<em>:name</em></p> +<p><strong>Methods:</strong></p> +<ul> +<li> +<p><strong>GET</strong>: Retrieve the full description of a Storage Volume</p> +<ul> +<li>name: The name of the Storage Volume + Used to identify the Storage Volume in this API</li> +<li>type: The type of the Storage Volume</li> +<li>capacity: The total space which can be used to store data + The unit is Bytes</li> +<li>allocation: The amount of space which is being used to store data + The unit is Bytes</li> +<li>format: The format of the file or volume</li> +<li>path: Full path of the volume on the host filesystem.</li> +<li>os_distro <em>(optional)</em>: os distribution of the volume, for iso volume only.</li> +<li>os_version <em>(optional)</em>: os version of the volume, for iso volume only.</li> +<li>bootable <em>(optional)</em>: True if iso image is bootable and not corrupted.</li> +<li>ref_cnt: Number of vms which used this volume, + 0 for volumes which are available for attachment. + >1 indicate number of vms used this volume.</li> +</ul> +</li> +<li> +<p><strong>DELETE</strong>: Remove the Storage Volume</p> +</li> +<li><strong>POST</strong>: <em>See Storage Volume Actions</em></li> +</ul> +<p><strong>Actions (POST):</strong></p> +<ul> +<li>resize: Resize a Storage Volume<ul> +<li>size: resize the total space which can be used to store data + The unit is MBytes</li> +</ul> +</li> +<li>wipe: Wipe a Storage Volume</li> +</ul> +<h3>Collection: Interfaces</h3> +<p><strong>URI:</strong> /interfaces</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve a summarized list of current Interfaces</li> +</ul> +<h3>Resource: Interface</h3> +<p><strong>URI:</strong> /interfaces/<em>:name</em></p> +<p>A interface represents available interface on host.</p> +<p><strong>Methods:</strong></p> +<ul> +<li> +<p><strong>GET</strong>: Retrieve the full description of the Interface</p> +<ul> +<li>name: The name of the interface.</li> +<li>status: The current status of the Interface.<ul> +<li>active: The interface is active.</li> +<li>inactive: The interface is inactive.</li> +</ul> +</li> +<li>ipaddr: The ip address assigned to this interface in subnet.</li> +<li>netmask: Is used to divide an IP address into subnets and specify the + networks available hosts</li> +<li>type: The net device type of the interface.</li> +<li>nic: Network interface controller that connects a computer to a + computer network</li> +<li>vlan: A logical interface that represents a VLAN in all Layer 3 + activities the unit may participate in</li> +<li>bonding: The combination of network interfaces on one host for redundancy + and/or increased throughput.</li> +<li>bridge: A network device that connects multiple network segments.</li> +</ul> +</li> +<li> +<p><strong>POST</strong>: <em>See Interface Actions</em></p> +</li> +</ul> +<p><strong>Actions (POST):</strong></p> +<p><em>No actions defined</em></p> +<h3>Collection: Networks</h3> +<p><strong>URI:</strong> /networks</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve a summarized list of all defined Networks</li> +<li><strong>POST</strong>: Create a new Network<ul> +<li>name: The name of the Network</li> +<li>subnet <em>(optional)</em>: Network segment in slash-separated format with ip address and + prefix or netmask. It is always ignored for bridge network.</li> +<li>connection: Specifies how this network should be connected to the other + networks visible to this host.<ul> +<li>isolated: Create a private, isolated virtual network.</li> +<li>nat: Outgoing traffic will be routed through the host.</li> +<li>bridge: All traffic on this network will be bridged through the indicated + interface.</li> +</ul> +</li> +<li>interface: The name of a network interface on the host. + For bridge network, the interface can be a bridge or nic/bonding + device. For isolated or NAT network, the interface is ignored.</li> +<li>in_use: True if network is in use by a template or virtual machine; + False, otherwise.</li> +</ul> +</li> +</ul> +<h3>Resource: Network</h3> +<p><strong>URI:</strong> /networks/<em>:name</em></p> +<p><strong>Methods:</strong></p> +<ul> +<li> +<p><strong>GET</strong>: Retrieve the full description of a Network</p> +<ul> +<li>name: The name of the Network + Used to identify the Network in this API</li> +<li>state: Indicates the current state of the Network<ul> +<li>active: The Network is ready for use</li> +<li>inactive: The Network is not available</li> +</ul> +</li> +<li>autostart: Network autostart onboot</li> +<li>vms: all vms attached to this network</li> +<li>subnet: Network segment in slash-separated format with ip address and prefix</li> +<li>dhcp: DHCP services on the virtual network is enabled.<ul> +<li>start: start boundary of a pool of addresses to be provided to DHCP clients.</li> +<li>end: end boundary of a pool of addresses to be provided to DHCP clients.</li> +</ul> +</li> +<li>connection: Specifies how this network should be connected to the other networks + visible to this host.<ul> +<li>isolated: A private, isolated virtual network. + The VMs attached to it can not be reached by the systems + outside of this network and vice versa.</li> +<li>nat: Outgoing traffic will be routed through the host. + The VM attached to it will have internet access via the host but + other computers will not be able to connect to the VM.</li> +<li>bridge: Aggregated Public Network. + The VM that joines this network is seen as a peer on this network + and it may offer network services such as HTTP or SSH.</li> +</ul> +</li> +<li>interface: The name of a bridge network interface on the host. All traffic + on this network will be bridged through the indicated interface. + The interface is a bridge or ethernet/bonding device.</li> +</ul> +</li> +<li> +<p><strong>DELETE</strong>: Remove the Network</p> +</li> +<li><strong>POST</strong>: <em>See Network Actions</em></li> +</ul> +<p><strong>Actions (POST):</strong></p> +<ul> +<li>activate: Activate an inactive Network</li> +<li>deactivate: Deactivate an active Network</li> +</ul> +<h3>Collection: Tasks</h3> +<p><strong>URI:</strong> /tasks</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve a summarized list of current Tasks</li> +</ul> +<h3>Resource: Task</h3> +<p><strong>URI:</strong> /tasks/<em>:id</em></p> +<p>A task represents an asynchronous operation that is being performed by the +server.</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve the full description of the Task<ul> +<li>id: The Task ID is used to identify this Task in the API.</li> +<li>status: The current status of the Task<ul> +<li>running: The task is running</li> +<li>finished: The task has finished successfully</li> +<li>failed: The task failed</li> +</ul> +</li> +<li>message: Human-readable details about the Task status</li> +</ul> +</li> +<li><strong>POST</strong>: <em>See Task Actions</em></li> +</ul> +<p><strong>Actions (POST):</strong></p> +<p><em>No actions defined</em></p> +<h3>Resource: Configuration</h3> +<p><strong>URI:</strong> /config</p> +<p>Contains information about the application environment and configuration.</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve configuration information<ul> +<li>http_port: The port number on which the server is listening</li> +<li>display_proxy_port: Port for vnc and spice's websocket proxy to listen on</li> +</ul> +</li> +<li><strong>POST</strong>: <em>See Configuration Actions</em></li> +</ul> +<p><strong>Actions (POST):</strong></p> +<p><em>No actions defined</em></p> +<h3>Resource: Capabilities</h3> +<p><strong>URI:</strong> /config/capabilities</p> +<p>Contains information about the host capabilities: iso streaming, screenshot +creation.</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve capabilities information<ul> +<li>libvirt_stream_protocols: list of which network protocols are accepted + for iso streaming by libvirt</li> +<li>qemu_stream: True, if QEMU supports ISO streaming; False, otherwise</li> +<li>screenshot: True, if libvirt stream functionality can create screenshot + file without problems; False, otherwise or None if the functionality was + not tested yet</li> +<li>system_report_tool: True if the is some debug report tool installed on + the system; False, otherwise.</li> +<li>update_tool: True if there is a compatible package manager for the + system; False, otherwise</li> +<li>repo_mngt_tool: 'deb', 'yum' or None - when the repository management + tool is not identified</li> +</ul> +</li> +<li><strong>POST</strong>: <em>See Configuration Actions</em></li> +</ul> +<p><strong>Actions (POST):</strong></p> +<p><em>No actions defined</em></p> +<h3>Collection: Storage Servers</h3> +<p><strong>URI:</strong> /storageservers</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve a summarized list of used storage servers.<ul> +<li>Parameters:<ul> +<li>_target_type: Filter server list with given type, currently support 'netfs'.</li> +</ul> +</li> +</ul> +</li> +</ul> +<h3>Resource: Storage Server</h3> +<p><strong>URI:</strong> /storageservers/<em>:host</em></p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve description of a Storage Server<ul> +<li>host: IP or host name of storage server</li> +</ul> +</li> +</ul> +<h3>Collection: Storage Targets</h3> +<p><strong>URI:</strong> /storageservers/<em>:name</em>/storagetargets</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve a list of available storage targets.<ul> +<li>Parameters:<ul> +<li>_target_type: Filter target list with given type, currently support 'netfs'.</li> +</ul> +</li> +<li>Response: A list with storage targets information.<ul> +<li>host: IP or host name of storage server of this target.</li> +<li>target_type: Type of storage target, supported: 'nfs'.</li> +<li>target: Storage target path.</li> +</ul> +</li> +</ul> +</li> +</ul> +<h3>Collection: Distros</h3> +<p><strong>URI:</strong> /config/distros</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve a summarized list of all Distros</li> +</ul> +<h3>Resource: Distro</h3> +<p><strong>URI:</strong> /config/distros/<em>:name</em></p> +<p>Contains information about the OS distribution.</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve a OS distribution information.<ul> +<li>name: The name of the Distro.</li> +<li>os_distro: The operating system distribution.</li> +<li>os_version: The version of the operating system distribution.</li> +<li>path: A URI to an ISO image.</li> +</ul> +</li> +</ul> +<p><strong>Actions (POST):</strong></p> +<p><em>No actions defined</em></p> +<h4>Collection: Debug Reports</h4> +<p><strong>URI:</strong> /debugreports</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve a summarized list of all available Debug Reports</li> +<li><strong>POST</strong>: Create a new Debug Report. This POST method is different + from the other ones. The return resource is a task resource which + is identified by the url below<ul> +<li>task resource. * See Resource: Task *</li> +</ul> +</li> +</ul> +<h3>Resource: Debug Report</h3> +<p><strong>URI:</strong> /debugreports/<em>:name</em></p> +<p>A Debug Report is an archive of logs and other information about the host that +is used to diagnose and debug problems. The exact format and contents are +specific to the low level collection tool being used.</p> +<p><strong>Methods:</strong></p> +<ul> +<li> +<p><strong>GET</strong>: Retrieve the full description of Debug Report</p> +<ul> +<li>name: The debug report name used to identify the report</li> +<li>file: The debug report file name used to identify the report</li> +<li>time: The time when the debug report is created</li> +</ul> +</li> +<li> +<p><strong>DELETE</strong>: Remove the Debug Report</p> +<ul> +<li>name: The debug report name used to identify the report</li> +</ul> +</li> +<li> +<p><strong>POST</strong>: <em>See Debug Report Actions</em></p> +</li> +</ul> +<p><strong>Actions (POST):</strong></p> +<p><em>No actions defined</em></p> +<h3>Sub-resource: Debug Report content</h3> +<p><strong>URI:</strong> /debugreports/<em>:name</em>/content</p> +<p>It is the sub-resource of Debug Report and the client use it to get the real content +of the Debug Report file from the server</p> +<ul> +<li><strong>GET</strong>: Retrieve the content of a Debug Report file</li> +</ul> +<p><strong>Actions (POST):</strong></p> +<p><em>No actions defined</em></p> +<h3>Resource: Host</h3> +<p><strong>URI:</strong> /host +Contains information of host.</p> +<p><strong>Methods:</strong></p> +<ul> +<li> +<p><strong>GET</strong>: Retrieve host static information</p> +<ul> +<li>memory: Total size of host physical memory + The unit is Bytes</li> +<li>cpu: The model name of host CPU</li> +<li>os_distro: The OS distribution that runs on host</li> +<li>os_version: The version of OS distribution</li> +<li>os_codename: The code name of OS distribution</li> +</ul> +</li> +<li> +<p><strong>POST</strong>: <em>See Host Actions</em></p> +</li> +</ul> +<p><strong>Actions (POST):</strong></p> +<ul> +<li>reboot: Restart the host machine. + Only allowed if there is not vm running.</li> +<li>shutdown: Power off the host machine. + Only allowed if there is not vm running.</li> +<li>swupdate: Start the update of packages in background and return a Task resource<ul> +<li>task resource. * See Resource: Task *</li> +</ul> +</li> +</ul> +<h3>Resource: HostStats</h3> +<p><strong>URI:</strong> /host/stats</p> +<p>Contains the host sample data.</p> +<p><strong>Methods:</strong></p> +<ul> +<li> +<p><strong>GET</strong>: Retrieve host sample data</p> +<ul> +<li>cpu_utilization: A number between 0 and 100 which indicates the + percentage of CPU utilization.</li> +<li>memory: memory statistics of host<ul> +<li>total: Total amount of memory. The unit is Bytes.</li> +<li>free: The amount of memory left unused by the system. The unit is Bytes.</li> +<li>buffers: The amount of memory used for file buffers. The unit is Bytes.</li> +<li>cached: The amount of memory used as cache memory. The unit is Bytes.</li> +<li>avail: The total amount of buffer, cache and free memory. The unit is Bytes.</li> +</ul> +</li> +<li>disk_read_rate: Expresses the total IO throughput for reads across + all disks (B/s).</li> +<li>disk_write_rate: Expresses the total IO throughput for writes across + all disks (B/s).</li> +<li>net_sent_rate: Expresses the total network throughput for writes across + all interfaces (B/s).</li> +<li>net_recv_rate: Expresses the total network throughput for reads across + all interfaces (B/s).</li> +</ul> +</li> +<li> +<p><strong>POST</strong>: <em>See HostStats Actions</em></p> +</li> +</ul> +<p><strong>Actions (POST):</strong></p> +<p><em>No actions defined</em></p> +<h3>Collection: Plugins</h3> +<p><strong>URI:</strong> /plugins</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve a summarized list names of all UI Plugins</li> +</ul> +<h3>Collection: Partitions</h3> +<p><strong>URI:</strong> /host/partitions</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieves a detailed list of all partitions of the host.</li> +</ul> +<h3>Resource: Partition</h3> +<p><strong>URI:</strong> /host/partitions/<em>:name</em></p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve the description of a single Partition:<ul> +<li>name: The name of the partition. Used to identify it in this API</li> +<li>path: The device path of this partition.</li> +<li>type: The type of the partition:<ul> +<li>part: a standard partition</li> +<li>lvm: a partition that belongs to a lvm</li> +</ul> +</li> +<li>fstype: The file system type of the partition</li> +<li>size: The total size of the partition, in bytes</li> +<li>mountpoint: If the partition is mounted, represents the mountpoint. + Otherwise blank.</li> +</ul> +</li> +</ul> +<h3>Collection: Devices</h3> +<p><strong>URI:</strong> /host/devices</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieves list of host pci devices (Node Devices). + Currently only scsi_host devices are supported:<ul> +<li>Parameters:<ul> +<li>_cap: Filter node device list with given node device capability. + To list Fibre Channel SCSI Host devices, use "_cap=fc_host".</li> +</ul> +</li> +</ul> +</li> +</ul> +<h3>Resource: Device</h3> +<p><strong>URI:</strong> /host/devices/<em>:name</em></p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve information of a single pci device. + Currently only scsi_host devices are supported:<ul> +<li>name: The name of the device.</li> +<li>adapter_type: The capability type of the scsi_host device (fc_host). + Empty if pci device is not scsi_host.</li> +<li>wwnn: The HBA Word Wide Node Name. + Empty if pci device is not scsi_host.</li> +<li>wwpn: The HBA Word Wide Port Name + Empty if pci device is not scsi_host.</li> +</ul> +</li> +</ul> +<h3>Collection: Host Packages Update</h3> +<p><strong>URI:</strong> /host/packagesupdate</p> +<p>Contains the information and action of packages update in the host.</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieves a list of all packages to be updated in the host:</li> +</ul> +<h3>Resource: Host Package Update</h3> +<p><strong>URI:</strong> /host/packagesupdate/<em>:name</em></p> +<p>Contains the information for a specific package to be updated.</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieves a full description of a package:<ul> +<li>package_name: The name of the package to be updated</li> +<li>arch: The architecture of the package</li> +<li>version: The new version of the package</li> +<li>repository: The repository name from where package will be downloaded</li> +</ul> +</li> +</ul> +<h3>Collection: Host Repositories</h3> +<p><strong>URI:</strong> /host/repositories</p> +<p><strong>Methods:</strong></p> +<ul> +<li><strong>GET</strong>: Retrieve a summarized list of all repositories available</li> +<li><strong>POST</strong>: Add a new repository<ul> +<li>baseurl: URL to the repodata directory when "is_mirror" is false. +Otherwise, it can be URL to the mirror system for YUM. Can be an +http://, ftp:// or file:// URL.</li> +<li>repo_id <em>(optional)</em>: Unique YUM repository ID</li> +<li>config: A dictionary that contains specific data according to repository + type.<ul> +<li>mirrorlist <em>(optional)</em>: Specifies a URL to a file containing a + list of baseurls for YUM repository</li> +<li>dist: Distribution to DEB repository</li> +<li>comps <em>(optional)</em>: List of components to DEB repository</li> +</ul> +</li> +</ul> +</li> +</ul> +<h3>Resource: Repository</h3> +<p><strong>URI:</strong> /host/repositories/<em>:repo-id</em></p> +<p><strong>Methods:</strong></p> +<ul> +<li> +<p><strong>GET</strong>: Retrieve the full description of a Repository</p> +<ul> +<li>repo_id: Unique repository name for each repository, one word.</li> +<li>baseurl: URL to the repodata directory when "is_mirror" is false. +Otherwise, it can be URL to the mirror system for YUM. Can be an +http://, ftp:// or file:// URL.</li> +<li>enabled: True, when repository is enabled; False, otherwise</li> +<li>config: A dictionary that contains specific data according to repository + type.<ul> +<li>repo_name: Human-readable string describing the YUM repository.</li> +<li>mirrorlist: Specifies a URL to a file containing a list of baseurls + for YUM repository</li> +<li>gpgcheck: True, to enable GPG signature verification; False, otherwise.</li> +<li>gpgkey: URL pointing to the ASCII-armored GPG key file for the YUM + repository.</li> +<li>dist: Distribution to DEB repository</li> +<li>comps: List of components to DEB repository</li> +</ul> +</li> +</ul> +</li> +<li> +<p><strong>DELETE</strong>: Remove the Repository</p> +</li> +<li><strong>POST</strong>: <em>See Repository Actions</em></li> +<li><strong>PUT</strong>: update the parameters of existing Repository<ul> +<li>repo_id: Unique repository name for each repository, one word.</li> +<li>baseurl: URL to the repodata directory when "is_mirror" is false. +Otherwise, it can be URL to the mirror system for YUM. Can be an +http://, ftp:// or file:// URL.</li> +<li>config: A dictionary that contains specific data according to repository + type.<ul> +<li>repo_name: Human-readable string describing the YUM repository.</li> +<li>mirrorlist: Specifies a URL to a file containing a list of baseurls + for YUM repository</li> +<li>gpgcheck: True, to enable GPG signature verification; False, otherwise.</li> +<li>gpgkey: URL pointing to the ASCII-armored GPG key file for the YUM + repository.</li> +<li>dist: Distribution to DEB repository</li> +<li>comps: List of components to DEB repository</li> +</ul> +</li> +</ul> +</li> +</ul> +<p><strong>Actions (POST):</strong></p> +<ul> +<li>enable: Enable the Repository as package source</li> +<li>disable: Disable the Repository as package source</li> +</ul> \ No newline at end of file diff --git a/ui/css/theme-default/host.css b/ui/css/theme-default/host.css index 9aca5cd..0ca6684 100644 --- a/ui/css/theme-default/host.css +++ b/ui/css/theme-default/host.css @@ -260,36 +260,4 @@ height: 200px; width: 850px; } - -.repository-id { - width: 70px; -} - -.repository-name { - width: 180px; -} - -.repository-baseurl { - width: 300px; -} - -.repository-ismirror { - width: 60px; -} - -.repository-urlargs { - width: 70px; -} - -.repository-enabled { - width: 60px; -} - -.repository-gpgcheck { - width: 60px; -} - -.repository-gpgkey { - width: 300px; -} /* End of Repository */ diff --git a/ui/css/theme-default/repository-edit.css b/ui/css/theme-default/repository-edit.css index ee6ad2e..df6bbdb 100644 --- a/ui/css/theme-default/repository-edit.css +++ b/ui/css/theme-default/repository-edit.css @@ -26,6 +26,7 @@ .repository-edit-fieldset { float: left; padding: 1em; + width: 450px; } .repository-edit-wrapper-label, .repository-edit-wrapper-controls { @@ -59,11 +60,69 @@ border-top: 1px solid #bbb; border-left: 1px solid #bbb; padding: 0 10px; - width: 250px; + width: 400px; } + +.repository-edit-wrapper-controls input[type="text"][readonly] { + color: #bbb; + background-color: #fafafa; +} + + .repository-edit-wrapper-controls input[type="text"][disabled] { color: #bbb; background-color: #fafafa; cursor: not-allowed; } + +/* +.repository-gpgcheck { + width: 60px; +} + +.yum .repository-id{ + width: 70px; +} + +.yum .repository-gpgkey { + width: 400px; +} + +.yum .repository-mirrorlist { + width: 400px; +} +*/ + +.yum .repository-dist { + display: none; +} + +.yum .repository-comps { + display: none; +} + +.deb .repository-id{ + display: none; +} + +.deb .repository-name { + display: none; +} + +.deb .repository-gpgkey { + display: none; +} + +.deb .repository-mirrorlist { + display: none; +} +/* +.deb .repository-dist { + width: 300px; +} + +.deb .repository-comps { + width: 400px; +} +*/ diff --git a/ui/js/src/kimchi.grid.js b/ui/js/src/kimchi.grid.js index e5892ff..d06e72c 100644 --- a/ui/js/src/kimchi.grid.js +++ b/ui/js/src/kimchi.grid.js @@ -166,8 +166,21 @@ kimchi.widget.Grid = function(params) { $.each(data, function(i, row) { var rowNode = $('<tr></tr>').appendTo(tbody); $.each(fields, function(fi, field) { - var fieldName = field['name']; - var value = (row[fieldName]==null) ? '' : row[fieldName]; + var fieldName = field['name'].split('.'); + var tmpRow=row; + for(var i=0;tmpRow && i<fieldName.length;i++) { + tmpRow=tmpRow[fieldName[i]]; + } + var value; + if (!tmpRow) { + value=''; + } + else if (Array.isArray(tmpRow)) { + value=tmpRow.toString(); + } + else { + value=tmpRow; + } $('<td><div class="cell-text-wrapper"' + (field['makeTitle'] === true ? ' title="' + value + '"' diff --git a/ui/js/src/kimchi.host.js b/ui/js/src/kimchi.host.js index 9604d89..b19683a 100644 --- a/ui/js/src/kimchi.host.js +++ b/ui/js/src/kimchi.host.js @@ -22,21 +22,76 @@ kimchi.host_main = function() { $(header).attr('aria-expanded', toExpand ? 'true' : 'false'); }; - var repositoriesGridID = 'repositories-grid'; var repositoriesGrid = null; - var initRepositoriesGrid = function(repositories) { + var initRepositoriesGrid = function(repo_type) { + var gridFields=[]; + if (repo_type == "yum") { + gridFields=[{ + name: 'repo_id', + label: i18n['KCHREPO6004M'], + 'class': 'repository-id' + }, { + name: 'config.repo_name', + label: i18n['KCHREPO6005M'], + 'class': 'repository-name' + }, { + name: 'enabled', + label: i18n['KCHREPO6009M'], + 'class': 'repository-enabled' + }]; + } + else if (repo_type == "deb") { + gridFields=[{ + name: 'baseurl', + label: i18n['KCHREPO6006M'], + makeTitle: true, + 'class': 'repository-baseurl' + }, { + name: 'enabled', + label: i18n['KCHREPO6009M'], + 'class': 'repository-enabled' + }, { + name: 'config.dist', + label: "dist", + 'class': 'repository-gpgcheck' + }, { + name: 'config.comps', + label: "comps", + 'class': 'repository-gpgcheck' + }]; + } + else { + gridFields=[{ + name: 'repo_id', + label: i18n['KCHREPO6004M'], + 'class': 'repository-id' + }, { + name: 'enabled', + label: i18n['KCHREPO6009M'], + 'class': 'repository-enabled' + }, { + name: 'baseurl', + label: i18n['KCHREPO6006M'], + makeTitle: true, + 'class': 'repository-baseurl' + }, { + name: 'gpgcheck', + label: i18n['KCHREPO6010M'], + 'class': 'repository-gpgcheck' + }]; + } repositoriesGrid = new kimchi.widget.Grid({ container: 'repositories-grid-container', - id: repositoriesGridID, + id: 'repositories-grid', title: i18n['KCHREPO6003M'], toolbarButtons: [{ - id: repositoriesGridID + '-add-button', + id: 'repositories-grid-add-button', label: i18n['KCHREPO6012M'], onClick: function(event) { - kimchi.window.open('repository-add.html'); + kimchi.window.open({url:'repository-add.html', class: repo_type}); } }, { - id: repositoriesGridID + '-enable-button', + id: 'repositories-grid-enable-button', label: i18n['KCHREPO6016M'], disabled: true, onClick: function(event) { @@ -52,7 +107,7 @@ kimchi.host_main = function() { }); } }, { - id: repositoriesGridID + '-edit-button', + id: 'repositories-grid-edit-button', label: i18n['KCHREPO6013M'], disabled: true, onClick: function(event) { @@ -61,10 +116,10 @@ kimchi.host_main = function() { return; } kimchi.selectedRepository = repository['repo_id']; - kimchi.window.open('repository-edit.html'); + kimchi.window.open({url:'repository-edit.html', class: repo_type}); } }, { - id: repositoriesGridID + '-remove-button', + id: 'repositories-grid-remove-button', label: i18n['KCHREPO6014M'], disabled: true, onClick: function(event) { @@ -96,62 +151,21 @@ kimchi.host_main = function() { if(!repository) { return; } - - $('#' + repositoriesGridID + '-remove-button') - .prop('disabled', false); - $('#' + repositoriesGridID + '-edit-button') - .prop('disabled', false); - + $('#repositories-grid-remove-button').prop('disabled', false); + $('#repositories-grid-edit-button').prop('disabled', false); var enabled = repository['enabled']; - $('#' + repositoriesGridID + '-enable-button') + $('#repositories-grid-enable-button') .text(i18n[enabled ? 'KCHREPO6017M' : 'KCHREPO6016M']) .prop('disabled', false); }, frozenFields: [], - fields: [{ - name: 'repo_id', - label: i18n['KCHREPO6004M'], - 'class': 'repository-id' - }, { - name: 'repo_name', - label: i18n['KCHREPO6005M'], - 'class': 'repository-name' - }, { - name: 'enabled', - label: i18n['KCHREPO6009M'], - 'class': 'repository-enabled' - }, { - name: 'baseurl', - label: i18n['KCHREPO6006M'], - makeTitle: true, - 'class': 'repository-baseurl' - }, { - name: 'url_args', - label: i18n['KCHREPO6008M'], - 'class': 'repository-urlargs' - }, { - name: 'is_mirror', - label: i18n['KCHREPO6007M'], - 'class': 'repository-ismirror' - }, { - name: 'gpgcheck', - label: i18n['KCHREPO6010M'], - 'class': 'repository-gpgcheck' - }, { - name: 'gpgkey', - label: i18n['KCHREPO6011M'], - 'class': 'repository-gpgkey' - }], + fields: gridFields, data: listRepositories }); }; var listRepositories = function(gridCallback) { kimchi.listRepositories(function(repositories) { - $.each(repositories, function(i, item) { - repositories[i]['rowno'] = i + 1; - }); - if($.isFunction(gridCallback)) { gridCallback(repositories); } @@ -160,17 +174,15 @@ kimchi.host_main = function() { repositoriesGrid.setData(repositories); } else { - initRepositoriesGrid(repositories); + initRepositoriesGrid(); + repositoriesGrid.setData(repositories); } } }); - $('#' + repositoriesGridID + '-remove-button') - .prop('disabled', true); - $('#' + repositoriesGridID + '-edit-button') - .prop('disabled', true); - $('#' + repositoriesGridID + '-enable-button') - .prop('disabled', true); + $('#repositories-grid-remove-button').prop('disabled', true); + $('#repositories-grid-edit-button').prop('disabled', true); + $('#repositories-grid-enable-button').prop('disabled', true); }; var softwareUpdatesGridID = 'software-updates-grid'; @@ -252,7 +264,7 @@ kimchi.host_main = function() { }); }; - var reportGridID = 'available-reports-grid'; + var reportGridID = 'available-reports-grid' var reportGrid = null; var initReportGrid = function(reports) { reportGrid = new kimchi.widget.Grid({ @@ -422,9 +434,9 @@ kimchi.host_main = function() { }); kimchi.getCapabilities(function(capabilities) { - if(capabilities['repo_mngt_tool']) { - $('#repository-management-section').removeClass('hidden'); - initRepositoriesGrid(); + if((capabilities['repo_mngt_tool']) && (capabilities['repo_mngt_tool']!="None")) { + initRepositoriesGrid(capabilities['repo_mngt_tool']); + $('#repositories-section').switchClass('hidden', capabilities['repo_mngt_tool']); kimchi.topic('kimchi/repositoryAdded') .subscribe(listRepositories); kimchi.topic('kimchi/repositoryUpdated') @@ -459,7 +471,7 @@ kimchi.host_main = function() { $('#host-content-container').html(templated); initPage(); - initTracker(); +// initTracker(); }); var StatsMgr = function() { diff --git a/ui/js/src/kimchi.repository_edit_main.js b/ui/js/src/kimchi.repository_edit_main.js index 0ab008e..46614c7 100644 --- a/ui/js/src/kimchi.repository_edit_main.js +++ b/ui/js/src/kimchi.repository_edit_main.js @@ -15,30 +15,44 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -kimchi.repository_edit_main = function() { - - var editForm = $('#form-repository-edit'); - var saveButton = $('#repository-edit-button-save'); - kimchi.retrieveRepository(kimchi.selectedRepository, function(repository) { - for(var prop in repository) { - var control = $('input[name="' + prop + '"]', editForm); +kimchi.repository_fillForm = function(form, name, values) { + var name= (name=="" || !name) ? "%s" : name; + for(var prop in values) { + if ((typeof(values[prop])==="object") && !Array.isArray(values[prop])) { +// kimchi.repository_fillForm(form, prefix + prop + ".", values[prop]); + tmpName=name.replace("%s", prop+"[%s]" ); + kimchi.repository_fillForm(form, tmpName, values[prop]); + } + else { + tmpName=name.replace("%s", prop ); + var control = $('input[name="' + tmpName + '"]', form); switch($(control).attr('type')) { case 'text': - $(control).val(repository[prop]); + $(control).val(values[prop]); break; case 'radio': case 'checkbox': $(control).each(function(i, c) { - var matched = ('' + repository[prop]) == $(c).val(); + var matched = ('' + values[prop]) == $(c).val(); $(c).prop('checked', matched); }); break; default: break; } - } + } +} + +kimchi.repository_edit_main = function() { + + var editForm = $('#form-repository-edit'); + var saveButton = $('#repository-edit-button-save'); + + kimchi.retrieveRepository(kimchi.selectedRepository, function(repository) { + kimchi.repository_fillForm(editForm,"",repository); + $('input', editForm).on('input propertychange', function(event) { if($(this).val() !== '') { diff --git a/ui/pages/repository-edit.html.tmpl b/ui/pages/repository-edit.html.tmpl index 9fa280d..83fc09f 100644 --- a/ui/pages/repository-edit.html.tmpl +++ b/ui/pages/repository-edit.html.tmpl @@ -30,68 +30,73 @@ <div class="content"> <form id="form-repository-edit"> <fieldset class="repository-edit-fieldset"> - <div> + <div class="repository-id"> <div class="repository-edit-wrapper-label"> <label for="repository-edit-id-textbox">$_("ID")</label> </div> <div class="repository-edit-wrapper-controls"> - <input id="repository-edit-id-textbox" name="repo_id" type="text" /> + <input id="repository-edit-id-textbox" name="repo_id" type="text" readonly="readonly"/> </div> </div> - <div> + <div class="repository-name"> <div class="repository-edit-wrapper-label"> <label for="repository-edit-name-textbox">$_("Name")</label> </div> <div class="repository-edit-wrapper-controls"> - <input id="repository-edit-name-textbox" name="repo_name" type="text" /> + <input id="repository-edit-name-textbox" name="config[repo_name]" type="text" /> </div> </div> - <div> + <div class="repository-dist"> <div class="repository-edit-wrapper-label"> - <label for="repository-edit-baseurl-textbox">$_("Base URL")</label> + <label for="repository-edit-urlargs-textbox">$_("Distribution")</label> </div> <div class="repository-edit-wrapper-controls"> - <input id="repository-edit-baseurl-textbox" name="baseurl" type="text" /> + <input id="repository-edit-urlargs-textbox" name="config[dist]" type="text" /> </div> - </div> - <div> + </div> + <div class="repository-gpgcheck"> <div class="repository-edit-wrapper-label"> - <label for="repository-edit-urlargs-textbox">$_("URL Args")</label> + <label>$_("GPG Check")</label> </div> <div class="repository-edit-wrapper-controls"> - <input id="repository-edit-urlargs-textbox" name="url_args" type="text" /> + <input id="repository-edit-gpgcheck-radio-true" name="config[gpgcheck]" type="radio" value="true" /> + <label for="repository-edit-gpgcheck-radio-true">$_("Yes")</label> + <input id="repository-edit-gpgcheck-radio-false" name="config[gpgcheck]" type="radio" value="false" /> + <label for="repository-edit-gpgcheck-radio-false">$_("No")</label> </div> </div> </fieldset> <fieldset class="repository-edit-fieldset"> - <div> + <div class="repository-url"> <div class="repository-edit-wrapper-label"> - <label>$_("Is Mirror")</label> + <label for="repository-edit-baseurl-textbox">$_("URL")</label> </div> <div class="repository-edit-wrapper-controls"> - <input id="repository-edit-ismirror-radio-true" name="is_mirror" type="radio" value="true" /> - <label for="repository-edit-ismirror-radio-true">$_("Yes")</label> - <input id="repository-edit-ismirror-radio-false" name="is_mirror" type="radio" value="false" /> - <label for="repository-edit-ismirror-radio-false">$_("No")</label> + <input id="repository-edit-baseurl-textbox" name="baseurl" type="text" /> </div> </div> - <div> + <div class="repository-mirrorlist"> <div class="repository-edit-wrapper-label"> - <label>$_("GPG Check")</label> + <label for="repository-edit-urlargs-textbox">$_("Mirror List URL")</label> </div> <div class="repository-edit-wrapper-controls"> - <input id="repository-edit-gpgcheck-radio-true" name="gpgcheck" type="radio" value="true" /> - <label for="repository-edit-gpgcheck-radio-true">$_("Yes")</label> - <input id="repository-edit-gpgcheck-radio-false" name="gpgcheck" type="radio" value="false" /> - <label for="repository-edit-gpgcheck-radio-false">$_("No")</label> + <input id="repository-edit-urlargs-textbox" name="config[mirrorlist]" type="text" /> + </div> + </div> + <div class="repository-comps"> + <div class="repository-edit-wrapper-label"> + <label for="repository-edit-urlargs-textbox">$_("Components")</label> + </div> + <div class="repository-edit-wrapper-controls"> + <input id="repository-edit-urlargs-textbox" name="config[comps]" type="text" /> </div> </div> - <div> + <div class="repository-gpgkey"> <div class="repository-edit-wrapper-label"> <label for="repository-edit-gpgkey-textbox">$_("GPG Key")</label> </div> <div class="repository-edit-wrapper-controls"> - <input id="repository-edit-gpgkey-textbox" name="gpgkey" type="text" /> + <input id="repository-edit-gpgkey-textbox" name="config[gpgkey]" type="text" /> </div> </div> </fieldset> diff --git a/ui/pages/tabs/host.html.tmpl b/ui/pages/tabs/host.html.tmpl index 4933b31..eabf9a0 100644 --- a/ui/pages/tabs/host.html.tmpl +++ b/ui/pages/tabs/host.html.tmpl @@ -80,6 +80,7 @@ </div> </div> </div> +<!-- <div class="host-section"> <h3 class="section-header" aria-controls="content-sys-statistics"> @@ -120,7 +121,8 @@ </div> </div> </div> - <div id="repositories-section" class="host-section"> +--> + <div id="repositories-section" class="host-section hidden"> <h3 class="section-header" aria-controls="content-repositories"> $_("Repositories") -- 1.8.1.4
participants (1)
-
Adam King