[PATCH] Typo: Rename function create_defautl_network
by Crístian Viana
The inner function create_defautl_network is mistyped.
Fix the function name by renaming it to create_default_network.
Signed-off-by: Crístian Viana <vianac(a)linux.vnet.ibm.com>
---
src/kimchi/model/networks.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/kimchi/model/networks.py b/src/kimchi/model/networks.py
index 63886e0..85148a0 100644
--- a/src/kimchi/model/networks.py
+++ b/src/kimchi/model/networks.py
@@ -43,7 +43,7 @@ class NetworksModel(object):
self._default_network_check()
def _default_network_check(self):
- def create_defautl_network():
+ def create_default_network():
try:
subnet = self._get_available_address(knetwork.DefaultNetsPool)
params = {"name": "default", "connection": "nat",
@@ -59,7 +59,7 @@ class NetworksModel(object):
try:
net = conn.networkLookupByName("default")
except libvirt.libvirtError:
- net = create_defautl_network()
+ net = create_default_network()
if net.isActive() == 0:
try:
@@ -72,7 +72,7 @@ class NetworksModel(object):
# libvirt do not support update IP element, so delete the
# the network and create new one.
net.undefine()
- create_defautl_network()
+ create_default_network()
else:
kimchi_log.error("Fatal: Cannot activate default network "
"because of %s, exit kimchid", e.message)
--
1.9.3
10 years, 6 months
[PATCH V2 0/2] bug fix: redirect to the protected page after login
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
V1 -> V2:
remove kimchisession hook
ShaoHe Feng (2):
bug fix: redirect to the protected page after login
remove kimchisession hook and add the same logic to root.get
src/kimchi/auth.py | 31 ++++++++++++-------------------
src/kimchi/config.py.in | 4 ----
src/kimchi/root.py | 40 +++++++++++++++++++++++++---------------
src/kimchi/server.py | 2 --
tests/test_config.py.in | 4 ----
ui/pages/login.html.tmpl | 3 ++-
6 files changed, 39 insertions(+), 45 deletions(-)
--
1.9.3
10 years, 6 months
[PATCH V2] Update i18n package scripts(Chinese)
by Wen Wang
From: Wen Wang <wenwang(a)linux.vnet.ibm.com>
V1 -> V2
Only zh_CN.po file is included. remove the correct the fuzzy part and
have the missed translation done.
Finished English to Chinese translation
Signed-off-by: Wen Wang <wenwang(a)linux.vnet.ibm.com>
---
po/zh_CN.po | 118 ++++++++++++++++++++++++++++++-----------------------------
1 files changed, 60 insertions(+), 58 deletions(-)
diff --git a/po/zh_CN.po b/po/zh_CN.po
index caef515..1e7a7ad 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -24,10 +24,10 @@ msgstr ""
"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"
@@ -64,11 +64,11 @@ msgstr "尚未为model对象初始化数据存储。"
#, python-format
msgid "Unable to start task due error: %(err)s"
-msgstr ""
+msgstr "由于错误%(err)s任务启动失败"
#, python-format
msgid "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
-msgstr ""
+msgstr "用户'%(username)s'身份验证失败.[错误代码:%(code)s]"
msgid "You are not authorized to access Kimchi"
msgstr "您没有被授权访问Kimchi"
@@ -134,8 +134,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目"
@@ -174,7 +174,7 @@ msgstr "不能创建虚拟机%(name)s。详情:%(err)s"
#, python-format
msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr ""
+msgstr "不能更新虚拟机%(name)s。详情:%(err)s"
#, python-format
msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
@@ -210,39 +210,39 @@ msgstr "不能启动虚拟机 %(name)s. 详情:%(err)s"
#, python-format
msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr ""
+msgstr "不能关闭虚拟机%(name)s。详情:%(err)s"
#, python-format
msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "不能删除虚拟机 %(name)s. 详情:%(err)s"
+msgstr "不能删除虚拟机 %(name)s。详情:%(err)s"
#, python-format
msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr ""
+msgstr "未能重置虚拟机%(name)s。详情:%(err)s"
msgid "User names list must be an array"
-msgstr ""
+msgstr "用户名列表必须是一个数组"
msgid "User name must be a string"
-msgstr ""
+msgstr "用户名必须是一个字符串"
msgid "Group names list must be an array"
-msgstr ""
+msgstr "用户组名称列表必须是一个数组"
msgid "Group name must be a string"
-msgstr ""
+msgstr "用户组名称必须是一个字符串"
#, python-format
msgid "User(s) '%(users)s' do not exist"
-msgstr ""
+msgstr "用户'%(users)s'不存在"
#, python-format
msgid "Group(s) '%(groups)s' do not exist"
-msgstr ""
+msgstr "用户组'%(groups)s'不存在"
#, python-format
msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr ""
+msgstr "未能关闭虚拟机%(name)s。详情:%(err)s"
#, python-format
msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
@@ -311,7 +311,7 @@ msgid "Template distribution version must be a string"
msgstr "模板的发行版版本号必须是一个字符串"
msgid "The number of CPUs must be an integer greater than 0"
-msgstr ""
+msgstr "CPU数量必须为一个大于0的整数"
msgid "Amount of memory (MB) must be an integer greater than 512"
msgstr "总内存数(MB为单位)必须是一个大于512的整数"
@@ -338,11 +338,11 @@ msgstr "存储池%(pool)s中没有存储卷%(volume)s"
#, python-format
msgid "Unable to create template due error: %(err)s"
-msgstr ""
+msgstr "由于错误:%(err)s,未能创建模板"
#, python-format
msgid "Unable to delete template due error: %(err)s"
-msgstr ""
+msgstr "由于错误:%(err)s,未能删除模板"
#, python-format
msgid "Storage pool %(name)s already exists"
@@ -370,8 +370,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
@@ -438,8 +438,8 @@ 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
@@ -484,7 +484,7 @@ msgstr "卷组'%(name)s'已经存在,请选择其它的名字来创建逻辑
#, python-format
msgid "Unable to update database with deep scan information due error: %(err)s"
-msgstr ""
+msgstr "由于错误:%(err)s,未能使用深度检索信息进行数据库更新"
#, python-format
msgid "Storage volume %(name)s already exists"
@@ -517,8 +517,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
@@ -557,7 +557,7 @@ msgstr "存储卷需要名字"
#, python-format
msgid ""
"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
+msgstr "由于错误%(err)s,未能使用存储卷信息进行数据库更新"
#, python-format
msgid "Interface %(name)s does not exist"
@@ -634,13 +634,13 @@ msgstr "不能以桥设备%(name)s作为VLAN的trunk设备。"
#, python-format
msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr ""
+msgstr "网络接口启动失败 %(iface)s:%(err)s。"
#, python-format
msgid ""
"Failed to activate interface %(iface)s. Please check the physical link "
"status."
-msgstr ""
+msgstr "网络接口%(err)s启动失败,请检查网络连接情况。"
#, python-format
msgid "Debug report %(name)s does not exist"
@@ -720,10 +720,10 @@ msgid "Unable to choose a virutal machine name"
msgstr "不能选择虚拟机名字"
msgid "Invalid CDROM device name"
-msgstr "无效的CDROM设备名字"
+msgstr "无效的CDROM设备名称"
msgid "Invalid storage type. Types supported: 'cdrom'"
-msgstr "无效的存储类型。支持的类型:'cdrom'"
+msgstr "无效的存储类型。支持类型为:'cdrom'"
#, python-format
msgid "The path '%(value)s' is not valid local/remote path for the device"
@@ -753,14 +753,14 @@ msgid "Do not support guest CDROM hot plug attachment"
msgstr "不支持客户机热插拔CDROM"
msgid "Specify type and path to add a new virtual machine disk"
-msgstr "为新虚拟机磁盘指定类型和路径"
+msgstr "为新的虚拟机磁盘指定类型和路径"
msgid "Specify path to update virtual machine disk"
msgstr "指定更新虚拟机磁盘的路径"
#, python-format
msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
+msgstr "控制器类型为%(type)s的设备达到上限%(limit)s"
msgid "YUM Repository ID must be one word only string."
msgstr "YUM软件仓库ID必须是只包含一个单词的字符串"
@@ -910,25 +910,25 @@ msgid "Create"
msgstr "创建"
msgid "Replace a CDROM of VM"
-msgstr ""
+msgstr "替换一个虚拟机的CDROM"
msgid "Device Name"
-msgstr ""
+msgstr "设备名称"
msgid "The name used to identify the CDROM. Read-only."
-msgstr ""
+msgstr "这个名称曾经用来对CDROM进行唯一标识,类型为只读。"
msgid "Device Type"
-msgstr ""
+msgstr "设备类型"
msgid "The device type. Currently, only \"cdrom\" is supported."
-msgstr ""
+msgstr "设备类型。目前仅支持设备类型:\"cdrom\"。 "
msgid "ISO File Path"
-msgstr ""
+msgstr "ISO文件路径"
msgid "The ISO file path in the server."
-msgstr ""
+msgstr "服务器端所使用的ISO文件路径"
msgid "Replace"
msgstr "替换"
@@ -952,7 +952,7 @@ msgid "CPUs"
msgstr "中央处理器"
msgid "Memory (MB)"
-msgstr ""
+msgstr "内存(MB)"
msgid "Icon"
msgstr "图标"
@@ -976,18 +976,18 @@ msgid "Manage Media"
msgstr "管理光盘介质"
msgid "Add a Storage Device to VM"
-msgstr ""
+msgstr "为虚拟机添加一个存储设备"
msgid ""
"The name used to identify the device. If omitted, a name will be chosen "
"automatically."
-msgstr ""
+msgstr "这个名称曾经被一个设备占用,如果不能使用,系统会自动生成一个名称"
msgid "File Path"
-msgstr ""
+msgstr "文件路径"
msgid "The ISO file path in the server for CDROM."
-msgstr ""
+msgstr "服务器端CDROM所使用的ISO文件路径"
msgid "Start"
msgstr "启用"
@@ -996,7 +996,7 @@ msgid "Reset"
msgstr "重置"
msgid "Power Off"
-msgstr ""
+msgstr "关闭电源"
msgid "Actions"
msgstr "操作"
@@ -1008,7 +1008,7 @@ msgid "Edit"
msgstr "编辑"
msgid "Shut Down"
-msgstr ""
+msgstr "关机"
msgid "Delete"
msgstr "删除"
@@ -1229,26 +1229,26 @@ msgid ""
msgstr "这将删除虚拟机和它的虚拟磁盘。该操作不能撤销,继续吗?"
msgid "Power off Confirmation"
-msgstr ""
+msgstr "关闭电源确认"
msgid ""
"This action may produce undesirable results, for example unflushed disk "
"cache in the guest. Would you like to continue?"
-msgstr ""
+msgstr "这样做可能导致不良后果,比如客户机磁盘缓存未刷新,确认要继续吗?"
msgid "Reset Confirmation"
-msgstr ""
+msgstr "重置确认"
msgid ""
"There is a risk of data loss caused by reset without the guest OS shutdown. "
"Would you like to continue?"
-msgstr ""
+msgstr "在客户机操作系统未关闭的情况下重置有风险导致数据丢失,确认要继续吗?"
msgid "Shut Down Confirmation"
-msgstr ""
+msgstr "关机确认"
msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr ""
+msgstr "注意,客户机操作系统可能会忽略这个请求,确认要继续吗?"
msgid ""
"This CDROM will be detached permanently and you can re-attach it. Continue "
@@ -1287,7 +1287,8 @@ msgstr "创建一个网络"
msgid ""
"This network is not persistent. Instead of stop, this action will "
"permanently delete it. Would you like to continue?"
-msgstr ""
+msgstr "这是一个临时的网络配置,该操作会永久地删除这个网络而不是停止其运行,"
+"确定要继续吗?"
msgid ""
"This will permanently delete the storage pool. Would you like to continue?"
@@ -1349,13 +1350,13 @@ msgid "Help"
msgstr "帮助"
msgid "About"
-msgstr ""
+msgstr "关于"
msgid "Log out"
msgstr "登出"
msgid "Version:"
-msgstr ""
+msgstr "版本:"
msgid "Log In"
msgstr "登录"
@@ -1400,7 +1401,7 @@ msgstr "必需的字段"
msgid "URL to the repository. Supported protocols are http, ftp, and file."
msgstr "软件仓库的URL,支持的协议有http、ftp、和file"
-msgid "Repository is a mirror"
+msgid "Repository is a mirror."
msgstr "软件仓库是一个镜像"
msgid "Distribution"
@@ -1678,4 +1679,5 @@ msgid "No templates found."
msgstr "没有发现模板"
msgid "Clone"
-msgstr ""
+msgstr "复制"
+
--
1.7.1
10 years, 6 months
[PATCH V2 0/4] bug fix: accept all characters for network name except / and "
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
V1 - V2
just restrict " and /.
" is not allowed in dnsmasq configure file.
/ is not allowed in a linux file name.
we should not put extra restrictions.
ShaoHe Feng (4):
bug fix: network name can be any characters except " and /
network name support unicode.
escape < > and & in in xml for network name.
escape special characters for jQuery selector.
src/kimchi/model/networks.py | 11 ++++++++---
ui/js/src/kimchi.network.js | 28 ++++++++++++++--------------
ui/js/src/kimchi.utils.js | 7 +++++++
ui/pages/tabs/network.html.tmpl | 2 +-
4 files changed, 30 insertions(+), 18 deletions(-)
--
1.9.3
10 years, 6 months
[PATCH] Bug Fix: Fix network list layout.
by Wen Wang
From: Wen Wang <wenwang(a)linux.vnet.ibm.com>
Changed back layout of netwrok list to the same style of other kimchi
lists. Squeeze the one space that appears between the network list label
"<span>"
Signed-off-by: Wen Wang <wenwang(a)linux.vnet.ibm.com>
---
ui/pages/tabs/network.html.tmpl | 24 ++++++++++++------------
1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/ui/pages/tabs/network.html.tmpl b/ui/pages/tabs/network.html.tmpl
index 36bb492..18fccef 100644
--- a/ui/pages/tabs/network.html.tmpl
+++ b/ui/pages/tabs/network.html.tmpl
@@ -33,12 +33,12 @@
<div id="network-content" class="network">
<div class="list">
<div class="header">
- <span class="column column-name">$_("Network Name")</span>
- <span class="column column-state">$_("State")</span>
- <span class="column column-type">$_("Network Type")</span>
- <span class="column column-interface">$_("Interface")</span>
- <span class="column column-space">$_("Address Space")</span>
- <span class="column">$_("Actions")</span>
+ <span class="column column-name">$_("Network Name")</span><!--
+ --><span class="column column-state">$_("State")</span><!--
+ --><span class="column column-type">$_("Network Type")</span><!--
+ --><span class="column column-interface">$_("Interface")</span><!--
+ --><span class="column column-space">$_("Address Space")</span><!--
+ --><span class="column">$_("Actions")</span>
</div>
<div id="networkBody" class="empty-when-logged-off"></div>
</div>
@@ -99,12 +99,12 @@
</div>
<script id="networkItem" type="text/html">
<div id='{name}' class='item remove-when-logged-off'>
- <span class='column column-name cell' title="{name}">{name}</span>
- <span class='column column-state cell'><span class='network-state {state}'></span></span>
- <span class='column column-type cell'>{type}</span>
- <span class='column column-interface cell'>{interface}</span>
- <span class='column column-space cell'>{addrSpace}</span>
- <span class='column-action'>
+ <span class='column column-name cell' title="{name}">{name}</span><!--
+ --><span class='column column-state cell'><span class='network-state {state}'></span></span><!--
+ --><span class='column column-type cell'>{type}</span><!--
+ --><span class='column column-interface cell'>{interface}</span><!--
+ --><span class='column column-space cell'>{addrSpace}</span><!--
+ --><span class='column-action'>
<span class="ui-button-secondary dropdown popable action-button">
$_("Actions")
<ul class='popover actionsheet right-side menu-container'>
--
1.7.1
10 years, 6 months
[PATCH V4] Issue#361:Bugfix disable the action button content when creating network
by Wen Wang
From: Hongliang Wang <hlwang(a)linux.vnet.ibm.com>
V3 -> V4
Allow window automatically scroll to the bottom when popup list is too long
that part of it is off sight. (Hongliang Wang).
V2 -> V3
Eliminate menu drop down when click "Action" -> "User"(Hongliang Wang)
V1 -> V2
Accroding to Hongliang Wang, fix the bug that tabs keep shown when there
exists more than one network.
Bugfix that disabled the content display of the action button for an
exsiting
network when creating a new network.
Signed-off-by: Hongliang Wang <hlwang(a)linux.vnet.ibm.com>
Signed-off-by: Wen Wang <wenwang(a)linux.vnet.ibm.com>
---
ui/css/theme-default/network.css | 4 +
ui/css/theme-default/popover.css | 3 -
ui/js/src/kimchi.network.js | 118 +++++++++++++++++++-------------------
ui/js/src/kimchi.popable.js | 25 ++++-----
ui/pages/tabs/network.html.tmpl | 38 +++++++------
5 files changed, 93 insertions(+), 95 deletions(-)
diff --git a/ui/css/theme-default/network.css b/ui/css/theme-default/network.css
index ec999e2..df66b75 100644
--- a/ui/css/theme-default/network.css
+++ b/ui/css/theme-default/network.css
@@ -303,3 +303,7 @@
padding: 10px;
width: 100%;
}
+
+.ui-state-default a {
+ color: #212121;
+}
\ No newline at end of file
diff --git a/ui/css/theme-default/popover.css b/ui/css/theme-default/popover.css
index 945a5c2..a2ad39d 100644
--- a/ui/css/theme-default/popover.css
+++ b/ui/css/theme-default/popover.css
@@ -65,9 +65,6 @@
left: auto;
right: 22px;
}
-.open>.popover {
- display: block;
-}
/* Generated at http://colorzilla.com/gradient-editor/ */
.actionsheet {
diff --git a/ui/js/src/kimchi.network.js b/ui/js/src/kimchi.network.js
index 54a6594..16b9ca6 100644
--- a/ui/js/src/kimchi.network.js
+++ b/ui/js/src/kimchi.network.js
@@ -100,78 +100,76 @@ kimchi.stopNetwork = function(network,menu) {
}
kimchi.addNetworkActions = function(network) {
- $(".menu-container", "#" + network.name).menu({
- position : {
- my : "left top",
- at : "left bottom",
- of : "#" + network.name
- },
- select : function(evt, ui) {
- $(".menu-container", "#" + network.name).toggle(false);
- var menu = $(evt.currentTarget).parent();
- if ($(evt.currentTarget).attr("nwAct") === "start") {
- $(".network-state", $("#" + network.name)).switchClass("down", "nw-loading");
- $("[nwAct='start']", menu).addClass("ui-state-disabled");
- $("[nwAct='delete']", menu).addClass("ui-state-disabled");
- $(":first-child", $("[nwAct='delete']", menu)).attr("disabled", true);
- kimchi.toggleNetwork(network.name, true, function() {
- $("[nwAct='start']", menu).addClass("hide-action-item");
- $("[nwAct='start']", menu).removeClass("ui-state-disabled");
- $("[nwAct='stop']", menu).removeClass("hide-action-item");
- if (network.in_use) {
- $("[nwAct='stop']", menu).addClass("ui-state-disabled");
- }
- $(".network-state", $("#" + network.name)).switchClass("nw-loading", "up");
- }, function(err) {
- $(".network-state", $("#" + network.name)).switchClass("nw-loading","down");
- $("[nwAct='start']", menu).removeClass("ui-state-disabled");
- if (!network.in_use) {
- $("[nwAct='delete']", menu).removeClass("ui-state-disabled");
- }
- $(":first-child", $("[nwAct='delete']", menu)).removeAttr("disabled");
- kimchi.message.error(err.responseJSON.reason);
- });
- } else if ($(evt.currentTarget).attr("nwAct") === "stop") {
- if (!network.persistent) {
- var settings = {
- title : i18n['KCHAPI6001M'],
- content : i18n['KCHNET6004M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- kimchi.confirm(settings, function() {
- kimchi.stopNetwork(network, menu);
- $(evt.currentTarget).parents(".item").remove();
- }, null);
+ $(".menu-container", "#" + network.name).menu();
+
+ $('#' + network.name).on('click', '.menu-container li', function(evt) {
+ var menu = $(evt.currentTarget).parent();
+ if ($(evt.currentTarget).attr("nwAct") === "start") {
+ $(".network-state", $("#" + network.name)).switchClass("down", "nw-loading");
+ $("[nwAct='start']", menu).addClass("ui-state-disabled");
+ $("[nwAct='delete']", menu).addClass("ui-state-disabled");
+ $(":first-child", $("[nwAct='delete']", menu)).attr("disabled", true);
+ kimchi.toggleNetwork(network.name, true, function() {
+ $("[nwAct='start']", menu).addClass("hide-action-item");
+ $("[nwAct='start']", menu).removeClass("ui-state-disabled");
+ $("[nwAct='stop']", menu).removeClass("hide-action-item");
+ network.state = "up";
+ if (network.in_use) {
+ $("[nwAct='stop']", menu).addClass("ui-state-disabled");
}
- else {
- kimchi.stopNetwork(network, menu);
+ $(".network-state", $("#" + network.name)).switchClass("nw-loading", "up");
+ }, function(err) {
+ $(".network-state", $("#" + network.name)).switchClass("nw-loading","down");
+ $("[nwAct='start']", menu).removeClass("ui-state-disabled");
+ if (!network.in_use) {
+ $("[nwAct='delete']", menu).removeClass("ui-state-disabled");
}
- } else if ($(evt.currentTarget).attr("nwAct") === "delete") {
- kimchi.confirm({
- title : i18n['KCHAPI6006M'],
- content : i18n['KCHNET6002M'],
+ $(":first-child", $("[nwAct='delete']", menu)).removeAttr("disabled");
+ kimchi.message.error(err.responseJSON.reason);
+ });
+ } else if ($(evt.currentTarget).attr("nwAct") === "stop") {
+ if (network.in_use) {
+ return false;
+ }
+ if (!network.persistent) {
+ var settings = {
+ title : i18n['KCHAPI6001M'],
+ content : i18n['KCHNET6004M'],
confirm : i18n['KCHAPI6002M'],
cancel : i18n['KCHAPI6003M']
- }, function() {
- kimchi.deleteNetwork(network.name, function() {
- $(evt.currentTarget).parents(".item").remove();
- });
+ };
+ kimchi.confirm(settings, function() {
+ kimchi.stopNetwork(network, menu);
+ $(evt.currentTarget).parents(".item").remove();
}, null);
}
+ else {
+ kimchi.stopNetwork(network, menu);
+ network.state = "down";
+ }
+ } else if ($(evt.currentTarget).attr("nwAct") === "delete") {
+ if (network.state === "up") {
+ return false;
+ }
+ kimchi.confirm({
+ title : i18n['KCHAPI6006M'],
+ content : i18n['KCHNET6002M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ }, function() {
+ kimchi.deleteNetwork(network.name, function() {
+ $(evt.currentTarget).parents(".item").remove();
+ });
+ }, null);
}
});
- $(".column-action", "#" + network.name).children(":first").button({
+
+ $("#networkBody .column-action .popable").button({
icons : {
secondary : "action-button-icon"
}
- }).click(function() {
- $(".menu-container", "#" + network.name).toggle();
- window.scrollBy(0, 150);
- });
- $(".menu-container", "#" + network.name).mouseleave(function() {
- $(".menu-container", "#" + network.name).toggle(false);
});
+
};
kimchi.initNetworkCreation = function() {
diff --git a/ui/js/src/kimchi.popable.js b/ui/js/src/kimchi.popable.js
index 295eaed..aafcaf4 100644
--- a/ui/js/src/kimchi.popable.js
+++ b/ui/js/src/kimchi.popable.js
@@ -17,21 +17,18 @@
*/
kimchi.popable = function() {
$(document).click(function(e) {
- $('.popable').removeClass('open');
- });
- $(document).on("click", ".popable", function(e) {
- var isOpen = $(this).hasClass('open');
- $(".popable").removeClass('open');
- if (!isOpen && $(this).find('ul').html() !== '') {
- $(this).addClass('open');
- }
+ $('.popable').each(function(i, n) {
+ n === e.target || $.contains(n, e.target) ||
+ $('.popover', n).toggle(false);
+ });
+ });
+ $(document).on('click', '.popable', function(e) {
+ var popup = $('.popover', this)[0];
+ $(popup).toggle();
// Scroll the popup menu into viewport if invisible.
- var popMenu = $('.popover', this).get(0);
- false === kimchi.isElementInViewport(popMenu) &&
- popMenu.scrollIntoView();
-
- e.preventDefault();
- e.stopPropagation();
+ !$(popup).is(':visible') ||
+ kimchi.isElementInViewport(popup) ||
+ popup.scrollIntoView();
});
};
diff --git a/ui/pages/tabs/network.html.tmpl b/ui/pages/tabs/network.html.tmpl
index 35380f4..30c9f29 100644
--- a/ui/pages/tabs/network.html.tmpl
+++ b/ui/pages/tabs/network.html.tmpl
@@ -33,12 +33,12 @@
<div id="network-content" class="network">
<div class="list">
<div class="header">
- <span class="column column-name">$_("Network Name")</span><!--
- --><span class="column column-state">$_("State")</span><!--
- --><span class="column column-type">$_("Network Type")</span><!--
- --><span class="column column-interface">$_("Interface")</span><!--
- --><span class="column column-space">$_("Address Space")</span><!--
- --><span class="column">$_("Actions")</span>
+ <span class="column column-name">$_("Network Name")</span>
+ <span class="column column-state">$_("State")</span>
+ <span class="column column-type">$_("Network Type")</span>
+ <span class="column column-interface">$_("Interface")</span>
+ <span class="column column-space">$_("Address Space")</span>
+ <span class="column">$_("Actions")</span>
</div>
<div id="networkBody" class="empty-when-logged-off"></div>
</div>
@@ -99,18 +99,20 @@
</div>
<script id="networkItem" type="text/html">
<div id='{name}' class='item remove-when-logged-off'>
- <span class='column column-name cell' title="{name}">{name}</span><!--
- --><span class='column column-state cell'><span class='network-state {state}'></span></span><!--
- --><span class='column column-type cell'>{type}</span><!--
- --><span class='column column-interface cell'>{interface}</span><!--
- --><span class='column column-space cell'>{addrSpace}</span><!--
- --><span class='column-action'>
- <span class="ui-button-secondary dropdown action-button">$_("Actions")</span>
- <ul class='popover actionsheet right-side menu-container'>
- <li nwAct="start" class='{startClass}'><a>$_("Start")</a></li>
- <li nwAct="stop" class='{stopClass}'><a {deleteDisabled}>$_("Stop")</a></li>
- <li nwAct="delete" class='{deleteClass}'><a {deleteDisabled} class='red'>$_("Delete")</a></li>
- </ul>
+ <span class='column column-name cell' title="{name}">{name}</span>
+ <span class='column column-state cell'><span class='network-state {state}'></span></span>
+ <span class='column column-type cell'>{type}</span>
+ <span class='column column-interface cell'>{interface}</span>
+ <span class='column column-space cell'>{addrSpace}</span>
+ <span class='column-action'>
+ <span class="ui-button-secondary dropdown popable action-button">
+ $_("Actions")
+ <ul class='popover actionsheet right-side menu-container'>
+ <li nwAct="start" class='{startClass}'><a class='button-big'>$_("Start")</a></li>
+ <li nwAct="stop" class='{stopClass}'><a {stopDisabled} class='button-big'>$_("Stop")</a></li>
+ <li nwAct="delete" class='{deleteClass}'><a {deleteDisabled} class='red'>$_("Delete")</a></li>
+ </ul>
+ </span>
</span>
</div>
</script>
--
1.7.1
10 years, 6 months
[PATCHv3 0/2] Issue#348: Add loading icon when nfs mount is in progress
by lvroyce@linux.vnet.ibm.com
From: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
Royce Lv (2):
Fix typo of storage pool add
Issue#348: Fix UI for nfs mount
ui/css/theme-default/storage.css | 7 +++++++
ui/js/src/kimchi.storagepool_add_main.js | 10 ++++++++++
ui/pages/storagepool-add.html.tmpl | 3 ++-
3 files changed, 19 insertions(+), 1 deletion(-)
--
1.8.3.2
10 years, 6 months
[PATCH] redirect to the former page when user just add a single html page
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
add a next attribute in login html page.
if "next" is not None, it means there is a html protected page user
want to access. after authentication success, redirect to it.
if "next" is None, then redirect to the last page recorde in th the
cookie.
Test this case:
1. input a protected page URL in the browser.
such as:
https://localhost:8001/spice.html?port=64667&listen=localhost&token=vmnam...
2. input a wrong password or username:
it should report:
"The username or password you entered is incorrect. Please try again."
3. input the right password and username:
It should redirect to the former page.
https://localhost:8001/spice.html?port=64667&listen=localhost&token=vmnam...
Signed-off-by: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
---
src/kimchi/auth.py | 18 ++++++++++++------
src/kimchi/root.py | 34 +++++++++++++++++++---------------
ui/pages/login.html.tmpl | 3 ++-
3 files changed, 33 insertions(+), 22 deletions(-)
diff --git a/src/kimchi/auth.py b/src/kimchi/auth.py
index 59889ed..c7f94a7 100644
--- a/src/kimchi/auth.py
+++ b/src/kimchi/auth.py
@@ -28,7 +28,6 @@
import re
import termios
import time
-import urllib2
from kimchi import template
@@ -43,9 +42,13 @@
def redirect_login():
- next_url = urllib2.quote(
- cherrypy.request.path_info.encode('utf-8'), safe="")
- raise cherrypy.HTTPRedirect("/login.html?next=%s" % next_url, 303)
+ url = "/login.html"
+ if cherrypy.request.path_info.endswith(".html"):
+ next_url = cherrypy.serving.request.request_line.split()[1]
+ next_url = base64.urlsafe_b64encode(next_url)
+ url = "/login.html?next=%s" % next_url
+
+ raise cherrypy.HTTPRedirect(url, 303)
def debug(msg):
@@ -194,7 +197,7 @@ def check_auth_httpba():
return login(username, password)
-def login(username, password):
+def login(username, password, **kwargs):
try:
if not authenticate(username, password):
debug("User cannot be verified with the supplied password")
@@ -202,7 +205,10 @@ def login(username, password):
except PAM.error, (resp, code):
if (cherrypy.request.path_info == "/login" and
not template.can_accept('application/json')):
- raise cherrypy.HTTPRedirect("/login.html?error=userPassWrong", 303)
+ next_url = kwargs.get("next")
+ url = "/login.html?error=userPassWrong"
+ url = url if next_url is None else url + "&next=%s" % next_url
+ raise cherrypy.HTTPRedirect(url, 303)
msg_args = {'username': username, 'code': code}
raise OperationFailed("KCHAUTH0001E", msg_args)
diff --git a/src/kimchi/root.py b/src/kimchi/root.py
index f2b6a53..82bd97b 100644
--- a/src/kimchi/root.py
+++ b/src/kimchi/root.py
@@ -17,6 +17,7 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+import base64
import cherrypy
import json
import os
@@ -122,25 +123,28 @@ def __init__(self, model, dev_env):
def login(self, *args, **kwargs):
username = kwargs.get('username')
password = kwargs.get('password')
- # forms base authentication
+ # traditional form base authentication
+ kwa = {}
if username is not None:
- next_url = cherrypy.request.cookie.get("lastPage")
+ # UI can parser the redirect url by "next" query parameter
+ next_url = kwargs.get('next')
+ next_url = next_url[0] if(type(next_url) is list) else next_url
if next_url is None:
- # UI can parser the redirect url by "next" query parameter
- next_url = kwargs.get('next', "/")
- next_url = next_url[0] if(type(next_url) is list) else next_url
+ lastPage = cherrypy.request.cookie.get("lastPage")
+ next_url = lastPage.value if lastPage is not None else "/"
else:
- next_url = next_url.value
- auth.login(username, password)
+ kwa = {"next": next_url.encode("utf-8")}
+ next_url = base64.urlsafe_b64decode(next_url.encode("utf-8"))
+ auth.login(username, password, **kwa)
raise cherrypy.HTTPRedirect(next_url, 303)
- else:
- try:
- params = parse_request()
- username = params['username']
- password = params['password']
- except KeyError, item:
- e = MissingParameter('KCHAUTH0003E', {'item': str(item)})
- raise cherrypy.HTTPError(400, e.message)
+
+ try:
+ params = parse_request()
+ username = params['username']
+ password = params['password']
+ except KeyError, item:
+ e = MissingParameter('KCHAUTH0003E', {'item': str(item)})
+ raise cherrypy.HTTPError(400, e.message)
try:
user_info = auth.login(username, password)
diff --git a/ui/pages/login.html.tmpl b/ui/pages/login.html.tmpl
index 0fa7122..f8f683d 100644
--- a/ui/pages/login.html.tmpl
+++ b/ui/pages/login.html.tmpl
@@ -21,6 +21,7 @@
#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang)
#silent _ = t.gettext
#silent _t = t.gettext
+#silent next = "?next=%s" % $getVar('data.next', '') if $getVar('data.next', '') else ""
#from kimchi.config import get_version
<!DOCTYPE html>
<html lang="$lang.lang[0]">
@@ -99,7 +100,7 @@ function init() {
<div id="messUserPass" class="err-mess" style="display: none;">$_("The username or password you entered is incorrect. Please try again.")</div>
<div id="messSession" class="err-mess" style="display: none;">$_("Session timeout, please re-login.")</div>
</div>
- <form id="form-login" action="/login" method="POST" class="login-panel" onsubmit="updateBtnLabel();">
+ <form id="form-login" action="/login$next" method="POST" class="login-panel" onsubmit="updateBtnLabel();">
<div class="row">
<input type="text" id="username" name="username" required="required" placeholder="$_("User Name")" autofocus/>
<div id="username-msg" class="msg-required"></div>
--
1.9.3
10 years, 6 months
[PATCH v4 0/8] Debug Report Rename Feature
by Hongliang Wang
Enable debug report rename feature in this patch set.
Please apply the following patch set first:
* [PATCH v4 0/4] Fix: Report Overwritten when Provided Name Existing
v3 -> v4:
4a) Updated according to dependency changes
v2 -> v3:
3a) Added check for name existence when renaming a report
(Yu Xin's comment)
v1 -> v2:
2a) Retrieved the Right Generated Time for Debug Report
(Wen Wang's comment)
2b) Sorted debug reports by Generated Time Descendingly
(Wen Wang's comment)
2c) Enabled Form Fields after Request Processed
(Yuxin's comment)
Hongliang Wang (8):
Debug Report Rename: Update API.json
Debug Report Rename: Update API.md
Debug Report Rename: Implement Back-end
Debug Report: Use Generated Time instead of Most Changed Time
Debug Report: Sort Reports by Generated Time Descendingly
Debug Report Rename UI: Add API in kimchi.api.js
Debug Report Rename UI: Add Rename Page
Debug Report Rename UI: Enable Rename in Host Tab
docs/API.md | 3 ++
src/kimchi/API.json | 11 +++++++
src/kimchi/control/debugreports.py | 8 ++++-
src/kimchi/model/debugreports.py | 18 +++++++++++-
ui/css/theme-default/report-rename.css | 22 ++++++++++++++
ui/js/src/kimchi.api.js | 12 ++++++++
ui/js/src/kimchi.host.js | 35 +++++++++++++++-------
ui/js/src/kimchi.report_rename_main.js | 41 ++++++++++++++++++++++++++
ui/pages/report-rename.html.tmpl | 53 ++++++++++++++++++++++++++++++++++
9 files changed, 190 insertions(+), 13 deletions(-)
create mode 100644 ui/css/theme-default/report-rename.css
create mode 100644 ui/js/src/kimchi.report_rename_main.js
create mode 100644 ui/pages/report-rename.html.tmpl
--
1.8.1.4
10 years, 6 months
[PATCH V2 0/2] List iSCSI targets available for initiator while creating iSCSI Pool
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
V1 - V2:
support port argument for iscsi server
ShaoHe Feng (2):
List iSCSI server for initiator while creating iSCSI Pool
List iSCSI targets available for initiator while creating iSCSI Pool
docs/API.md | 9 +++++++--
src/kimchi/API.json | 9 +++++++--
src/kimchi/model/storagepools.py | 4 +++-
src/kimchi/model/storageservers.py | 9 ++++++---
src/kimchi/model/storagetargets.py | 28 ++++++++++++++++++++--------
5 files changed, 43 insertions(+), 16 deletions(-)
--
1.9.3
10 years, 6 months