[PATCH] issue #445: Request /peers on every click
by Aline Manera
The peers information was only request after login. But as the
information can change during the login time, it is better to request it
on every menu selection.
Also fix some typos: drowdown to dropdown.
Signed-off-by: Aline Manera <alinefm(a)linux.vnet.ibm.com>
---
ui/css/theme-default/topbar.css | 4 ++--
ui/js/src/kimchi.main.js | 49 +++++++++++++++++++++++++++++------------
ui/pages/kimchi-ui.html.tmpl | 6 ++---
3 files changed, 40 insertions(+), 19 deletions(-)
diff --git a/ui/css/theme-default/topbar.css b/ui/css/theme-default/topbar.css
index 127c56a..d21fc50 100644
--- a/ui/css/theme-default/topbar.css
+++ b/ui/css/theme-default/topbar.css
@@ -194,7 +194,7 @@ a#btn-logout:hover {
width: 0;
}
-.peers .drowdown {
+.peers .dropdown {
top: 45px;
right: 110px;
color: black;
@@ -204,7 +204,7 @@ a#btn-logout:hover {
width: inherit;
}
-.peers .drowdown a {
+.peers .dropdown a {
display: block;
padding: 10px;
}
diff --git a/ui/js/src/kimchi.main.js b/ui/js/src/kimchi.main.js
index a3305e9..a8ae42a 100644
--- a/ui/js/src/kimchi.main.js
+++ b/ui/js/src/kimchi.main.js
@@ -20,24 +20,13 @@ kimchi.tabMode = {};
kimchi.capabilities = undefined;
kimchi.getCapabilities(function(result) {
kimchi.capabilities = result;
- kimchi.setupPeers();
+
+ if(kimchi.capabilities.federation=="on")
+ $('#peers').removeClass('hide-content');
}, function() {
kimchi.capabilities = {};
});
-kimchi.setupPeers = function(){
- if(kimchi.capabilities.federation=="on"){
- $('#peers').removeClass('hide-content');
- kimchi.getPeers(function(data){
- var hints = $('p', $('.drowdown', '#peers'));
- data.length==0 ? hints.toggleClass('hide-content'): hints.addClass('hide-content');
- for(var i=0; i<data.length; i++){
- $('.drowdown', '#peers').append("<a href='"+data[i]+"' target='_blank'>"+data[i]+"</a>");
- }
- });
- }
-};
-
kimchi.main = function() {
kimchi.isLoggingOut = false;
kimchi.popable();
@@ -220,7 +209,11 @@ kimchi.main = function() {
* 2) hashchange event
* 3) Tab list click event
* 4) Log-out button click event
+ * 5) About button click event
+ * 6) Help button click event
+ * 7) Peers button click event
*/
+ var searchingPeers = false;
var initListeners = function() {
kimchi.topic('languageChanged').subscribe(onLanguageChanged);
kimchi.topic('redirect').subscribe(onKimchiRedirect);
@@ -260,12 +253,40 @@ kimchi.main = function() {
kimchi.message.error(err.responseJSON.reason);
});
});
+
+ // Set handler for about button
$('#btn-about').on('click', function(event) {
kimchi.window.open({"content": $('#about-tmpl').html()});
event.preventDefault();
});
+ // Set handler for help button
$('#btn-help').on('click', kimchi.getHelp);
+
+ // Set handler to peers drop down
+ $('#peers').on('click', function() {
+
+ // Check if any request is in progress
+ if ($('.popover', '#peers').is(':visible') || searchingPeers == true)
+ return
+
+ $('#search-peers').show();
+ $('#no-peers').addClass('hide-content');
+ $('a', '#peers').remove();
+
+ searchingPeers = true;
+
+ kimchi.getPeers(function(data){
+ $('#search-peers').hide();
+ if (data.length == 0)
+ $('#no-peers').removeClass('hide-content');
+
+ for(var i=0; i<data.length; i++){
+ $('.dropdown', '#peers').append("<a href='"+data[i]+"' target='_blank'>"+data[i]+"</a>");
+ }
+ searchingPeers = false;
+ });
+ });
};
var initUI = function() {
diff --git a/ui/pages/kimchi-ui.html.tmpl b/ui/pages/kimchi-ui.html.tmpl
index 867ee36..aee3c4a 100644
--- a/ui/pages/kimchi-ui.html.tmpl
+++ b/ui/pages/kimchi-ui.html.tmpl
@@ -74,9 +74,9 @@
<div id="peers" class="peers hide-content popable">
<span>$_("Peers")</span>
<span class="arrow"></span>
- <div class="drowdown popover right-side">
- <p>$_("Searching")...</p>
- <p class="hide-content">$_("No peers found.")</p>
+ <div class="dropdown popover right-side">
+ <p id="search-peers">$_("Searching")...</p>
+ <p id="no-peers" class="hide-content">$_("No peers found.")</p>
</div>
</div>
</li>
--
1.9.3
10 years, 3 months
[PATCH] issue #462: Do not allow user to enter non-integer template disk size
by Crístian Viana
If the user enters a non-integer template disk size (e.g. 10.5), guests
created with that template fail to start.
In order to simplify the user experience, all numeric values are
supposed to be consistent. Currently, all numeric values (except the
template disk size) are integer numbers, so it's more consistent for the
user to use integer numbers here as well.
Signed-off-by: Crístian Viana <vianac(a)linux.vnet.ibm.com>
---
src/kimchi/API.json | 2 +-
src/kimchi/i18n.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/kimchi/API.json b/src/kimchi/API.json
index f262e1c..5b752dc 100644
--- a/src/kimchi/API.json
+++ b/src/kimchi/API.json
@@ -585,7 +585,7 @@
},
"size": {
"description": "Size (GB) of the disk",
- "type": "number",
+ "type": "integer",
"minimum": 1,
"error": "KCHTMPL0022E"
}
diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
index 8315d1d..635d6b9 100644
--- a/src/kimchi/i18n.py
+++ b/src/kimchi/i18n.py
@@ -128,7 +128,7 @@ messages = {
"KCHTMPL0019E": _("The volume %(volume)s is not in storage pool %(pool)s"),
"KCHTMPL0020E": _("Unable to create template due error: %(err)s"),
"KCHTMPL0021E": _("Unable to delete template due error: %(err)s"),
- "KCHTMPL0022E": _("Disk size must be greater than 1GB."),
+ "KCHTMPL0022E": _("Disk size must be an integer greater than 1GB."),
"KCHTMPL0023E": _("Template base image must be a valid local image file"),
"KCHTMPL0024E": _("Cannot identify base image %(path)s format"),
--
1.9.3
10 years, 3 months
[PATCH] build: Add README-federation.md to Kimchi package
by Aline Manera
README-federation.md guides user on how to enable federation feature on
Kimchi so it needs to be installed too.
Signed-off-by: Aline Manera <alinefm(a)linux.vnet.ibm.com>
---
contrib/kimchi.spec.fedora.in | 1 +
contrib/kimchi.spec.suse.in | 1 +
docs/Makefile.am | 1 +
3 files changed, 3 insertions(+)
diff --git a/contrib/kimchi.spec.fedora.in b/contrib/kimchi.spec.fedora.in
index bd1f04d..4327376 100644
--- a/contrib/kimchi.spec.fedora.in
+++ b/contrib/kimchi.spec.fedora.in
@@ -161,6 +161,7 @@ rm -rf $RPM_BUILD_ROOT
%{python_sitelib}/kimchi/plugins/*.py*
%{_datadir}/kimchi/doc/API.md
%{_datadir}/kimchi/doc/README.md
+%{_datadir}/kimchi/doc/README-federation.md
%{_datadir}/kimchi/doc/kimchi-guest.png
%{_datadir}/kimchi/doc/kimchi-templates.png
%{_prefix}/share/locale/*/LC_MESSAGES/kimchi.mo
diff --git a/contrib/kimchi.spec.suse.in b/contrib/kimchi.spec.suse.in
index d0bf317..4386d2d 100644
--- a/contrib/kimchi.spec.suse.in
+++ b/contrib/kimchi.spec.suse.in
@@ -82,6 +82,7 @@ rm -rf $RPM_BUILD_ROOT
%{python_sitelib}/kimchi/plugins/*.py*
%{_datadir}/kimchi/doc/API.md
%{_datadir}/kimchi/doc/README.md
+%{_datadir}/kimchi/doc/README-federation.md
%{_datadir}/kimchi/doc/kimchi-guest.png
%{_datadir}/kimchi/doc/kimchi-templates.png
%{_prefix}/share/locale/*/LC_MESSAGES/kimchi.mo
diff --git a/docs/Makefile.am b/docs/Makefile.am
index f195cbc..679aa18 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -22,6 +22,7 @@ docdir = $(datadir)/kimchi/doc
dist_doc_DATA = \
API.md \
README.md \
+ README-federation.md \
kimchi-guest.png \
kimchi-templates.png \
$(NULL)
--
1.9.3
10 years, 3 months
[PATCH] issue #447: Remove downloaded volume if an error occurs
by Crístian Viana
If a storage volume is being downloaded by Kimchi and an error occurs
(e.g. timeout, network down, no available disk space), whatever has been
downloaded so far is kept on the storage pool.
Remove the partially downloaded storage volume if an error occurs during
the operation.
Signed-off-by: Crístian Viana <vianac(a)linux.vnet.ibm.com>
---
src/kimchi/model/storagevolumes.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/kimchi/model/storagevolumes.py b/src/kimchi/model/storagevolumes.py
index f9f226f..ac6887a 100644
--- a/src/kimchi/model/storagevolumes.py
+++ b/src/kimchi/model/storagevolumes.py
@@ -204,6 +204,8 @@ class StorageVolumesModel(object):
downloaded_size += len(chunk_data)
cb('%s/%s' % (downloaded_size, remote_size))
except Exception, e:
+ if os.path.isfile(file_path):
+ os.remove(file_path)
raise OperationFailed('KCHVOL0007E', {'name': name,
'pool': pool_name,
'err': e.message})
--
1.9.3
10 years, 3 months
[PATCH] issue #432: Display unique values for iSCSI targets
by Aline Manera
When creating a iSCSI pool, the iSCSI targets were listed twice on
openSUSE systems as returned by iscsiadm.
opensuse-vm:~ # iscsiadm -m discovery -t sendtargets -p localhost
[::1]:3260,1 iqn.2014-09.mydomain:alinefm
[fe80::5054:ff:fe29:5551]:3260,1 iqn.2014-09.mydomain:alinefm
To avoid confusion, display unique values.
Signed-off-by: Aline Manera <alinefm(a)linux.vnet.ibm.com>
---
src/kimchi/model/storagetargets.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/kimchi/model/storagetargets.py b/src/kimchi/model/storagetargets.py
index dd72814..30717fd 100644
--- a/src/kimchi/model/storagetargets.py
+++ b/src/kimchi/model/storagetargets.py
@@ -83,7 +83,7 @@ class StorageTargetsModel(object):
# Filter target_list to not not show the used paths
target_list = [elem for elem in target_list
if elem.get('target') not in used_paths]
- return target_list
+ return [dict(t) for t in set(tuple(t.items()) for t in target_list)]
def _get_storage_server_spec(self, **kwargs):
# Required parameters:
--
1.9.3
10 years, 3 months
[PATCH] Update Chinese transtation to po
by Wen Wang
From: Wen Wang <wenwang(a)linux.vnet.ibm.com>
V1 -> V2:
Translation improved
Update the Chinese translation support
Signed-off-by: Wen Wang <wenwang(a)linux.vnet.ibm.com>
---
po/zh_CN.po | 199 ++++++++++++++++++++++++++++++-----------------------------
1 files changed, 101 insertions(+), 98 deletions(-)
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 29a615b..30d825f 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -20,14 +20,14 @@ msgid ""
msgstr ""
"Project-Id-Version: kimchi 0.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-09-16 14:11-0300\n"
+"POT-Creation-Date: 2014-09-23 14:42+0800\n"
"PO-Revision-Date: 2013-06-27 10:48+0000\n"
"Last-Translator: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>\n"
"Language-Team: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>\n"
-"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Language: zh_CN\n"
"Generated-By: pygettext.py 1.5\n"
"X-Poedit-Country: CHINA\n"
"X-Poedit-Language: Chinese\n"
@@ -35,7 +35,7 @@ msgstr ""
#, python-format
msgid "Unknown parameter %(value)s"
-msgstr ""
+msgstr "未知变量 %(value)s"
#, python-format
msgid "Delete is not allowed for %(resource)s"
@@ -64,7 +64,7 @@ msgid "Parameters does not match requirement in schema: %(err)s"
msgstr "参数不符合要求的格式:%(err)s"
msgid "You don't have permission to perform this operation."
-msgstr ""
+msgstr "您没有权限执行这项操作。"
msgid "Datastore is not initiated in the model object."
msgstr "尚未为model对象初始化数据存储。"
@@ -111,7 +111,7 @@ msgstr "无法登录iSCSI主机%(host)s上的目标%(target)s。"
#, python-format
msgid "Unable to find ISO file %(filename)s"
-msgstr ""
+msgstr "未能找到ISO文件 %(filename)s"
#, python-format
msgid "The ISO file %(filename)s is not bootable"
@@ -141,8 +141,8 @@ msgstr "ISO文件%(filename)s的卷描述符格式错误"
msgid ""
"The hypervisor doesn't have permission to use this ISO %(filename)s. "
"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the "
-"'%(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"file access control lists for '%(user)s' user if possible, or add the '%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
"'path_to_iso'.Details: %(err)s"
msgstr ""
"hypervisor没有访问ISO文件%(filename)s的权限。可以将ISO移到/var/lib/libvirt目"
@@ -150,14 +150,14 @@ msgstr ""
"或者为所有的用户增加访问权限 'chmod -R o+x '(不推荐)。详情:%(err)s"
msgid "An error occurred when probing image OS information."
-msgstr ""
+msgstr "搜索镜像操作系统信息时发生错误。"
msgid "No OS information found in given image."
-msgstr ""
+msgstr "在指定的镜像文件中未发现操作系统信息。"
#, python-format
msgid "Unable to read image file %(filename)s"
-msgstr ""
+msgstr "未能读取镜像文件 %(filename)s"
#, python-format
msgid "Virtual machine %(name)s already exists"
@@ -172,6 +172,8 @@ msgid ""
"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
"in use or the virtual machine is not powered off."
msgstr ""
+"未能实现虚拟机 %(name)s 重命名,名称 %(new_name)s 已被使用或者该虚拟机未关"
+"机。"
#, python-format
msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
@@ -182,7 +184,7 @@ msgstr "该服务器不支持远程ISO镜像。"
#, python-format
msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
+msgstr "虚拟机 %(name)s 不支持快照"
#, python-format
msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
@@ -198,21 +200,21 @@ msgstr "不能获取虚拟机%(name)s。详情:%(err)s"
#, python-format
msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
+msgstr "虚拟机%(name)s已关机,连接失败。"
msgid "Virtual machine name must be a string"
msgstr "虚拟机名字必须是个字符串"
#, python-format
msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
+msgstr "无效的虚拟机模板URI %(value)s"
#, python-format
msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
+msgstr "无效的虚拟机存储池URI %(value)s"
msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
+msgstr "虚拟机图形界面仅支持Spice以及VNC"
msgid "Graphics address to listen on must be IPv4 or IPv6"
msgstr "远程图形访问的监听地址必须是IPv4或IPv6地址。"
@@ -237,13 +239,13 @@ msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
msgstr "未能重置虚拟机%(name)s。详情:%(err)s"
msgid "User name list must be an array"
-msgstr ""
+msgstr "用户名列表必须为一个数组"
msgid "User name must be a string"
msgstr "用户名必须是一个字符串"
msgid "Group name list must be an array"
-msgstr ""
+msgstr "组名称列表必须为一个数组"
msgid "Group name must be a string"
msgstr "用户组名称必须是一个字符串"
@@ -266,10 +268,10 @@ msgid ""
msgstr "无法获得虚拟机 %(name)s的元数据,详情:%(err)s"
msgid "The guest console password must be a string."
-msgstr ""
+msgstr "客户机控制台密码必须为一个字符串。"
msgid "The life time for the guest console password must be a number."
-msgstr ""
+msgstr "客户机命令行密码有效时间必须是一个数字。"
#, python-format
msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
@@ -354,17 +356,17 @@ msgid "Invalid storage pool URI %(value)s specified for template"
msgstr "给模板指定了无效的存储池URI %(value)s"
msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr ""
+msgstr "指定一个ISO镜像作为创建模板的CDROM或者基础镜像"
msgid "All networks for the template must be specified in a list."
msgstr "为模板指定的网络必须在一个列表中"
msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
+msgstr "当存储池类型为iSCSI或者SCSI的时候须为模板指定一个卷"
#, python-format
msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
+msgstr "卷%(volume)s不在存储池%(pool)s中"
#, python-format
msgid "Unable to create template due error: %(err)s"
@@ -378,11 +380,11 @@ msgid "Disk size must be greater than 1GB."
msgstr "磁盘大小必须大于1GB。"
msgid "Template base image must be a valid local image file"
-msgstr ""
+msgstr "模板基础镜像必须为一个有效的本地镜像文件"
#, python-format
msgid "Cannot identify base image %(path)s format"
-msgstr ""
+msgstr "未能识别基础镜像%(path)s格式"
#, python-format
msgid "Storage pool %(name)s already exists"
@@ -410,8 +412,8 @@ msgstr "不能创建存储池 %(name)s。详情: %(err)s"
#, python-format
msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: "
-"%(err)s"
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
msgstr "不能获取储存池%(name)s中卷的数目。详情: %(err)s"
#, python-format
@@ -441,7 +443,7 @@ msgstr "不支持的存储池类型:%(type)s"
#, python-format
msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
+msgstr "查询存储池XML到%(pool)s时出现错误"
msgid "Storage pool name must be a string"
msgstr "存储池名字必须是一个字符串"
@@ -449,7 +451,7 @@ msgstr "存储池名字必须是一个字符串"
msgid ""
"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
"iso"
-msgstr ""
+msgstr "存储池类型仅支持dir,netfs,logical,iscsi,isci以及kimchi-iso"
msgid "Storage pool path must be a string"
msgstr "存储池路径必须是字符串"
@@ -458,7 +460,7 @@ msgid "Storage pool host must be a IP or hostname"
msgstr "存储池主机必须是一个IP后者主机名"
msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
+msgstr "存储池设备必须为块设备的一个绝对路径"
msgid "Storage pool devices parameter must be a list"
msgstr "存储池设备参数必须是一个列表"
@@ -470,23 +472,23 @@ msgid "Port of a remote storage server must be an integer between 1 and 65535"
msgstr "远程存储服务器的端口必须是1到65535之间的整数"
msgid "iSCSI target username must be a string"
-msgstr ""
+msgstr "iSCSI目标用户名必须为一个字符串"
msgid "iSCSI target password must be a string"
-msgstr ""
+msgstr "iSCSI目标密码必须为一个字符串"
msgid "Specify name and type to create a storage pool"
msgstr "为新存储池指定名字和类型"
#, python-format
msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool "
-"%(pool)s."
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
msgstr "%(disk)s 不是有效的磁盘/分区。不能被添加到存储池%(pool)s中"
#, python-format
msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
+msgstr "未能实现逻辑池%(pool)s的扩展,详情:%(err)s"
msgid "The parameter disks only can be updated for logical storage pool."
msgstr "只有逻辑存储池支持更新磁盘参数。"
@@ -540,7 +542,7 @@ msgstr "存储池%(pool)s中没有存储卷%(name)s"
msgid ""
"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
"not active"
-msgstr ""
+msgstr "未能创建存储卷%(volume)s,因为存储池%(pool)s 未被激活"
#, python-format
msgid "Specify %(item)s in order to create storage volume %(volume)s"
@@ -559,8 +561,8 @@ msgstr "不能列出存储卷,因为存储池%(pool)s没有激活"
#, python-format
msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: "
-"%(err)s"
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
+"(err)s"
msgstr "不能在存储池%(pool)s中创建存储卷%(name)s。详情:%(err)s"
#, python-format
@@ -603,17 +605,17 @@ msgstr "存储卷信息更新失败。详情:%(err)s"
#, python-format
msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
+msgstr "只能对参数%(param)s中的一个进行指定"
#, python-format
msgid "Create volume from %(param)s is not supported"
-msgstr ""
+msgstr "不支持从%(param)s创建虚拟机"
msgid "Storage volume capacity must be an integer number."
-msgstr ""
+msgstr "存储卷容量必须为一个整数"
msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
+msgstr "存储卷URL必须为http://,https://,ftp://或ftps://"
#, python-format
msgid "Interface %(name)s does not exist"
@@ -711,19 +713,21 @@ msgstr "不能创建诊断报告%(name)s。详情:%(err)s"
#, python-format
msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
+msgstr "未能找到指定名称%(name)s的调试报告"
#, python-format
msgid "Unable to generate debug report %(name)s. Details: %(err)s"
msgstr "不能生成诊断报告%(name)s。详情:%(err)s"
msgid "You should give a name for the debug report file."
-msgstr ""
+msgstr "您应当为调试报告文件指定一个名称。"
msgid ""
"Debug report name must be a string. Only letters, digits, underscore ('_') "
"and hyphen ('-') are allowed."
msgstr ""
+"调试报告名称必须为一个字符串。只有英文字符,数字,下划线('_')以及连字符('-')"
+"为合法字符。"
#, python-format
msgid ""
@@ -780,31 +784,23 @@ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
msgstr "命令'%(cmd)s'运行%(seconds)s秒后超时。"
msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid vm storage device name"
-msgstr "无效的虚拟机存储设备名称"
+msgstr "未能选择一个虚拟机名称"
msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
msgstr "无效的存储类型。支持类型为:'cdrom','disk'"
#, python-format
msgid "The path '%(value)s' is not a valid local/remote path for the device"
-msgstr ""
-
-#, python-format
-msgid ""
-"Device name %(dev_name)s already exists in the virtual machine %(vm_name)s"
-msgstr ""
+msgstr "路径'%(value)s'不是设备的有效本地/远程路径"
msgid "Only CDROM path can be update."
-msgstr ""
+msgstr "仅支持CDROM路径更新。"
#, python-format
msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine "
-"%(vm_name)s"
-msgstr ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr "存储设备%(dev_name)s在虚拟机%(vm_name)s中不存在"
#, python-format
msgid "Error while creating new storage device: %(error)s"
@@ -819,7 +815,7 @@ msgid "Error while removing storage device: %(error)s"
msgstr "移除存储设备时出错:%(error)s"
msgid "Do not support IDE device hot plug"
-msgstr ""
+msgstr "不支持IDE设备的热插拔"
msgid ""
"Specify type and path or type and pool/volume to add a new virtual machine "
@@ -835,10 +831,10 @@ msgstr "控制器类型为%(type)s的设备达到上限%(limit)s"
#, python-format
msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
+msgstr "未能为给出的存储池/存储卷找到对应磁盘路径信息:%(error)s"
msgid "Volume already in use by other virtual machine."
-msgstr ""
+msgstr "该卷已经被其他虚拟机使用。"
msgid ""
"Only one of path or pool/volume can be specified to add a new virtual "
@@ -1140,7 +1136,7 @@ msgid "No such data available."
msgstr "没有可用的数据"
msgid "Options needed."
-msgstr ""
+msgstr "需要选项。"
msgid ""
"Can not contact the host system. Verify the host system is up and that you "
@@ -1161,13 +1157,13 @@ msgid "Warning"
msgstr "警告"
msgid "Creating..."
-msgstr ""
+msgstr "正在创建..."
msgid "Loading..."
msgstr "正在加载..."
msgid "An error occurred while checking for packages update."
-msgstr ""
+msgstr "查找软件包更新时出现错误。"
msgid "Retry"
msgstr "重试"
@@ -1176,7 +1172,7 @@ msgid "Detailed message:"
msgstr "详细消息:"
msgid "No ISO found"
-msgstr ""
+msgstr "没有发现ISO文件"
msgid "This is not a valid ISO file."
msgstr "这不是一个有效的ISO文件"
@@ -1279,7 +1275,7 @@ msgid "Updating..."
msgstr "正在更新..."
msgid "Failed to retrieve packages update information."
-msgstr ""
+msgstr "查找软件包更新信息失败。"
msgid "Failed to update package(s)."
msgstr "更新软件包失败"
@@ -1343,11 +1339,11 @@ msgid "Note the guest OS may ignore this request. Would you like to continue?"
msgstr "注意,客户机操作系统可能会忽略这个请求,确认要继续吗?"
msgid "Virtual Machine delete Confirmation"
-msgstr ""
+msgstr "虚拟机删除确认"
msgid ""
"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
+msgstr "该虚拟机不是一个稳定的虚拟机,关机将会删除它,是否继续?"
msgid ""
"This CDROM will be detached permanently and you can re-attach it. Continue "
@@ -1372,7 +1368,7 @@ msgstr "成功卸载"
msgid ""
"This disk will be detached permanently and you can re-attach it. Continue to "
"detach it?"
-msgstr ""
+msgstr "该磁盘将会被永久卸载,你可以重新添加它,继续执行卸载操作吗?"
msgid "The VLAN id must be between 1 and 4094."
msgstr "VLAN 标识符必须在1至4094之间"
@@ -1414,46 +1410,46 @@ msgid "No SCSI adapters found."
msgstr "没有发现SCSI适配器"
msgid "Loading iSCSI targets..."
-msgstr ""
+msgstr "读取iSCSI目标..."
msgid "No iSCSI found. Please input one."
-msgstr ""
+msgstr "未能找到iSCSI,请输入一个"
msgid "Failed to load iSCSI targets."
-msgstr ""
+msgstr "读取iSCSI目标失败。"
msgid "The storage pool name can not be blank."
-msgstr "存储池的名称不能为空"
+msgstr "存储池的名称不能为空。"
msgid "The storage pool path can not be blank."
-msgstr "存储池的路径不能为空"
+msgstr "存储池的路径不能为空。"
msgid "NFS server mount path can not be blank."
-msgstr "NFS服务器挂载路径不能为空"
+msgstr "NFS服务器挂载路径不能为空。"
msgid "Invalid storage pool name. It should not contain '/'."
msgstr "无效的存储池的名字。名字中不能包含‘/’。"
msgid "Invalid NFS mount path."
-msgstr "无效的NFS挂载路径"
+msgstr "无效的NFS挂载路径。"
msgid "No logical device selected."
-msgstr "没有选择逻辑设备"
+msgstr "没有选择逻辑设备。"
msgid "The iSCSI target can not be blank."
-msgstr "iSCSI目标不能为空"
+msgstr "iSCSI目标不能为空。"
msgid "Server name can not be blank."
-msgstr "服务器不能为空"
+msgstr "服务器不能为空。"
msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
+msgstr "这不是你个有效的服务器名称或IP地址,请对其进行修改。"
msgid "Looking for available partitions ..."
msgstr "查找有效的分区 ..."
msgid "No available partitions found."
-msgstr "没有发现模板"
+msgstr "没有发现模板。"
msgid ""
"This storage pool is not persistent. Instead of deactivate, this action will "
@@ -1461,28 +1457,28 @@ msgid ""
msgstr "对于非持久存储池,这个操作将会永久删除存储池而不是停用。是否继续?"
msgid "Unable to retrieve partitions information."
-msgstr ""
+msgstr "未能找到分区信息。"
msgid "In progress..."
-msgstr ""
+msgstr "正在进行..."
msgid "Failed!"
-msgstr ""
+msgstr "失败!"
msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
+msgstr "CDROM路径需要一个有效的本地/远程路径且不能为空。"
msgid "Disk pool or volume cannot be blank."
msgstr "存储池或卷不能为空"
msgid "Peers"
-msgstr ""
+msgstr "对等机"
msgid "Searching"
-msgstr ""
+msgstr "正在查询"
msgid "No peers found."
-msgstr ""
+msgstr "没有发现对等机。"
msgid "Help"
msgstr "帮助"
@@ -1520,15 +1516,15 @@ msgstr ""
"含字母、数字、下划线 ('_') 和连字符('-')"
msgid "Rename a Debug Report"
-msgstr ""
+msgstr "重命名一个调试报告"
msgid ""
"The name used to identify the report. Name can contain: letters, digits and "
"hyphen (\"-\")."
-msgstr ""
+msgstr "报告的唯一表示名称,名称可以包含:英文字符,数字和连字符(\"-\")。"
msgid "Submit"
-msgstr ""
+msgstr "提交"
msgid "Add a Repository"
msgstr "增加一个软件仓库"
@@ -1649,19 +1645,19 @@ msgid "Please, wait..."
msgstr "请等待..."
msgid "Add a Volume to Storage Pool"
-msgstr ""
+msgstr "为存储池添加一个卷"
msgid "Fetch from remote URL"
-msgstr ""
+msgstr "从远程URL获取"
msgid "Enter the remote URL here."
-msgstr ""
+msgstr "在这里输入远程URL。"
msgid "Upload an file"
-msgstr ""
+msgstr "上传一个文件"
msgid "Choose the ISO file (with .iso suffix) you want to upload."
-msgstr ""
+msgstr "选择您需要上传的ISO文件(以.iso为后缀名)。"
msgid "Add Template"
msgstr "创建模板"
@@ -1673,7 +1669,7 @@ msgid "Local ISO Image"
msgstr "本地ISO镜像"
msgid "Local Image File"
-msgstr ""
+msgstr "本地镜像文件"
msgid "Remote ISO Image"
msgstr "远程ISO镜像"
@@ -1730,7 +1726,7 @@ msgid "CDROM"
msgstr "光驱"
msgid "Image File"
-msgstr ""
+msgstr "镜像文件"
msgid "Graphics"
msgstr "图形"
@@ -1832,7 +1828,7 @@ msgid "Activate"
msgstr "激活"
msgid "Add Volume"
-msgstr ""
+msgstr "添加卷"
msgid "Extend"
msgstr "扩展"
@@ -1851,3 +1847,10 @@ msgstr "没有发现模板"
msgid "Clone"
msgstr "制作副本"
+
+#~ msgid "Invalid vm storage device name"
+#~ msgstr "无效的虚拟机存储设备名称"
+
+#~ msgid ""
+#~ "Device name %(dev_name)s already exists in the virtual machine %(vm_name)s"
+#~ msgstr "设备名称%(dev_name)s已经存在于虚拟机%(vm_name)s"
--
1.7.1
10 years, 3 months
[PATCH v2] issue #433: Fix repository tests
by Crístian Viana
This is the difference between this and the previous patchset (v1):
- The test comments have been updated to reflect the actual tests.
- The tests which try to create/update repositories with wrong data have been
rewritten. Now there is a list of repositories with wrong data specific to each
distribution (i.e. yum/apt), so each one of them only tests what is relevant.
That means that Ubuntu won't test Fedora's specific features, like
'mirrorlist', and Fedora won't test Ubuntu's specific features, like 'dist'.
Crístian Viana (1):
issue #433: Fix repository tests
src/kimchi/repositories.py | 2 ++
tests/test_model.py | 86 +++++++++++++++++++++++++++-------------------
2 files changed, 52 insertions(+), 36 deletions(-)
--
1.9.3
10 years, 3 months
[PATCH] issue #437: Only allow a bootable image file to be used on template
by Aline Manera
While creating a template from a image file, the latter must be a
bootable image.
As probe_image() does all the verifications regarding the image file,
the exception must be raised in order to inform user about the problem.
Also update the test case accordingly.
Signed-off-by: Aline Manera <alinefm(a)linux.vnet.ibm.com>
---
src/kimchi/vmtemplate.py | 8 ++------
tests/test_model.py | 29 +++++++++++++++++++++++------
2 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/src/kimchi/vmtemplate.py b/src/kimchi/vmtemplate.py
index 4994a5f..5f22db9 100644
--- a/src/kimchi/vmtemplate.py
+++ b/src/kimchi/vmtemplate.py
@@ -29,8 +29,7 @@ from distutils.version import LooseVersion
from kimchi import osinfo
-from kimchi.exception import InvalidParameter, IsoFormatError, ImageFormatError
-from kimchi.exception import MissingParameter
+from kimchi.exception import InvalidParameter, IsoFormatError, MissingParameter
from kimchi.imageinfo import probe_image, probe_img_info
from kimchi.isoinfo import IsoImage
from kimchi.utils import check_url_path, pool_name_from_uri
@@ -96,10 +95,7 @@ class VMTemplate(object):
if 'base' in d.keys():
base_imgs.append(d)
if scan:
- try:
- distro, version = probe_image(d['base'])
- except ImageFormatError:
- pass
+ distro, version = probe_image(d['base'])
if 'size' not in d.keys():
d['size'] = probe_img_info(d['base'])['virtual-size']
diff --git a/tests/test_model.py b/tests/test_model.py
index d458478..63be20e 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -37,8 +37,8 @@ import kimchi.objectstore
import utils
from kimchi import netinfo
from kimchi.config import paths
-from kimchi.exception import InvalidOperation, InvalidParameter
-from kimchi.exception import NotFoundError, OperationFailed
+from kimchi.exception import ImageFormatError, InvalidOperation
+from kimchi.exception import InvalidParameter, NotFoundError, OperationFailed
from kimchi.iscsi import TargetClient
from kimchi.model import model
from kimchi.rollbackcontext import RollbackContext
@@ -126,10 +126,27 @@ class ModelTests(unittest.TestCase):
rollback.prependDefer(inst.storagevolume_delete, 'default', vol)
params = {'name': 'test', 'disks': [{'base': vol_path}]}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
-
- params = {'name': 'kimchi-vm', 'template': '/templates/test'}
+ self.assertRaises(ImageFormatError, inst.templates_create, params)
+
+ # Hack the model objstore to add a new template
+ # It is needed as the image file must be a bootable image when
+ # using model
+ # As it is difficult to create one on test runtime, inject a
+ # template with an empty image file to the objstore to test the
+ # feature
+ tmpl_name = "img-tmpl"
+ tmpl_info = {"cpus": 1, "cdrom": "",
+ "graphics": {"type": "vnc", "listen": "127.0.0.1"},
+ "networks": ["default"], "memory": 1024, "folder": [],
+ "icon": "images/icon-vm.png",
+ "os_distro": "unknown", "os_version": "unknown",
+ "disks": [{"base": vol_path, "size": 10}],
+ "storagepool": "/storagepools/default"}
+
+ with inst.objstore as session:
+ session.store('template', tmpl_name, tmpl_info)
+
+ params = {'name': 'kimchi-vm', 'template': '/templates/img-tmpl'}
inst.vms_create(params)
rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
--
1.9.3
10 years, 3 months
[PATCH] issue #417: Validate image file path when creating a new template
by Aline Manera
To create a template using an image file, the user must specify an existing
file on system.
Add this verification to avoid error while dealing with guestfs.
Signed-off-by: Aline Manera <alinefm(a)linux.vnet.ibm.com>
---
src/kimchi/i18n.py | 1 +
src/kimchi/imageinfo.py | 14 ++++++++++----
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
index 552be25..8315d1d 100644
--- a/src/kimchi/i18n.py
+++ b/src/kimchi/i18n.py
@@ -65,6 +65,7 @@ messages = {
"KCHIMG0001E": _("An error occurred when probing image OS information."),
"KCHIMG0002E": _("No OS information found in given image."),
"KCHIMG0003E": _("Unable to read image file %(filename)s"),
+ "KCHIMG0004E": _("Image file must be an existing file on system. %(filename)s is not a valid input."),
"KCHVM0001E": _("Virtual machine %(name)s already exists"),
"KCHVM0002E": _("Virtual machine %(name)s does not exist"),
diff --git a/src/kimchi/imageinfo.py b/src/kimchi/imageinfo.py
index f4c6356..89d1e0a 100644
--- a/src/kimchi/imageinfo.py
+++ b/src/kimchi/imageinfo.py
@@ -1,7 +1,7 @@
#
# Kimchi
#
-# Copyright IBM Corp, 2014
+# Copyright IBM, Corp. 2014
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,7 @@ import os
import sys
import guestfs
-from kimchi.exception import ImageFormatError, TimeoutExpired
+from kimchi.exception import ImageFormatError, InvalidParameter, TimeoutExpired
from kimchi.utils import run_command, kimchi_log
@@ -42,15 +42,21 @@ def probe_img_info(path):
def probe_image(image_path):
+ if not os.path.isfile(image_path):
+ raise InvalidParameter("KCHIMG0004E", {'filename': image_path})
+
+ if not os.access(image_path, os.R_OK):
+ raise ImageFormatError("KCHIMG0003E", {'filename': image_path})
+
g = guestfs.GuestFS(python_return_dict=True)
g.add_drive_opts(image_path, readonly=1)
g.launch()
- if not os.access(image_path, os.R_OK):
- raise ImageFormatError("KCHIMG0003E", {'filename': image_path})
+
try:
roots = g.inspect_os()
except:
raise ImageFormatError("KCHIMG0001E")
+
if len(roots) == 0:
raise ImageFormatError("KCHIMG0002E")
--
1.9.3
10 years, 3 months
[PATCH V4] Bugfix#424: Edit Template, "Disk (GB)" is changing with storage pool
by Wen Wang
From: Wen Wang <wenwang(a)linux.vnet.ibm.com>
V3 -> V4:
Change the variable name that store "Disk(GB)" into the format without
"kimchi" and fixed oneline of error coding.
V2 -> V3:
Make the value of "Disk(GB)" inputbox consistent with user input. If
choosing iSCSI or SCSI, inputbox is disabled and value of "Disk(GB)" is
refreshed with the system. If changing back, the value stays the same
with user last input.
V1 -> V2:
Considering iSCSI and SCSI situation that we need to have the input box
disabled when choosing iSCSI and SCSI for storage pool and enable when
choosing others.
This patch fix the bug that value of "Disk(GB)" input box is changing
with the item of "Storage Pool" in "Templates" --> "Actions" --> "Edit"
-->"Edit Templates" dialogue. This might be comfusing to user when
changing the "Storage Pool", "Disk(GB)" is changed with it without even
notice. This might confuse the users and is not necessary. Solved by
removing the change.
Signed-off-by: Wen Wang <wenwang(a)linux.vnet.ibm.com>
---
ui/js/src/kimchi.template_edit_main.js | 13 ++++++-------
1 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/ui/js/src/kimchi.template_edit_main.js b/ui/js/src/kimchi.template_edit_main.js
index cb43091..2f4cc9a 100644
--- a/ui/js/src/kimchi.template_edit_main.js
+++ b/ui/js/src/kimchi.template_edit_main.js
@@ -19,6 +19,7 @@ kimchi.template_edit_main = function() {
var templateEditForm = $('#form-template-edit');
var origDisks;
var origPool;
+ var templateDiskSize;
$('#template-name', templateEditForm).val(kimchi.selectedTemplate);
kimchi.retrieveTemplate(kimchi.selectedTemplate, function(template) {
origDisks = template.disks;
@@ -40,6 +41,7 @@ kimchi.template_edit_main = function() {
}
var disks = template.disks;
$('input[name="disks"]').val(disks[0].size);
+ templateDiskSize = $('input[name="disks"]').val();
if (disks[0].volume) {
var spool_value = $('#form-template-edit [name="storagepool"]').val();
$('input[name="storagepool"]', templateEditForm).val(spool_value + '/' + disks[0].volume);
@@ -131,16 +133,13 @@ kimchi.template_edit_main = function() {
kimchi.message.error(err.responseJSON.reason);
});
} else {
- if (origPool == storagepool) {
- // Previous disk size value
- $('input[name="disks"]', templateEditForm).val(origDisks[0].size);
- } else {
- // Default disk size value
- $('input[name="disks"]', templateEditForm).val(10);
- }
$('input[name="disks"]', templateEditForm).removeAttr('disabled');
+ $('input[name="disks"]', templateEditForm).val(templateDiskSize);
}
});
+ $('input[name="disks"]', templateEditForm).keyup(function() {
+ templateDiskSize = $('input[name="disks"]', templateEditForm).val();
+ });
$('#tmpl-edit-button-save').on('click', function() {
var editableFields = [ 'name', 'cpus', 'memory', 'storagepool', 'disks', 'graphics'];
--
1.7.1
10 years, 3 months