[PATCH] Add /var/spool/cron to default host configuration backup paths
by Zhou Zheng Sheng
/var/spool/cron contains user cron jobs and ".cron.hostname". It should
be included in the default backup.
Signed-off-by: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
---
plugins/ginger/ginger.conf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugins/ginger/ginger.conf b/plugins/ginger/ginger.conf
index dbb2aa2..d6dce1d 100644
--- a/plugins/ginger/ginger.conf
+++ b/plugins/ginger/ginger.conf
@@ -4,7 +4,7 @@ plugin_class = "Ginger"
uri = "/plugins/ginger"
[backup]
-default_include = ['/etc', ]
+default_include = ['/etc', '/var/spool/cron']
default_exclude = ['/etc/init.d', '/etc/rc.d', '/etc/rc?.d', ]
[/]
--
1.9.0
10 years, 4 months
[PATCH v4 0/4] Host device passthrough: Summary
by Zhou Zheng Sheng
Hi,
This patch series is to enable Kimchi to assign hos devices directly to
a VM, thus greately improve VM performance. Currently we support assigning
PCI device, USB device and SCSI LUN. For example, we can assign an NIC
to VM to improve guest network throughput, or passthrough a USB camera
to enable the guest OS to record video.
Host devices form a tree. We can assign most of the devices in the tree
to VM. By assigning a device, all the devices in its sub-tree are also
assigned. It might not make sense to assign a USB controller, because
the host may be using one of the devices connected to the controller.
Instead, Kimchi just presents the "leaf" devices to assign to guest.
In recent Linux kernel and KVM, it is able to recognize the IOMMU group
of a PCI device. The "leaf" PCI devices in the same IOMMU group should
be assigned and dismissed together. The IOMMU group is the actual
smallest isolation granularity of the PCI devices.
The first patch is to list all host devices information. It's useful on
its own to show host devices information.
The second patch is to list all eligible host devices to assign, as well
as the "affected" devices in the same IOMMU group.
The third patch creates a sub-collection "hostdevs" to the VM resource,
and deals with assigning and dismissing devices.
The fourth patch adds a sub-collection "vm_holders" to the host device
resource. It's to list all VMs that are holding the device.
I'll update API and unit test once everyone is happy with the interface
and logic.
v4:
Add new sub-collection to host device to list the VMs holding the device.
v3:
Fix a small naming error introduced by rebase.
v2:
Handle the devices in VM's sub-collection "hostdevs".
v1:
Handle the devices in VM template.
Zhou Zheng Sheng (4):
Host device passthrough: List all types of host devices
Host device passthrough: List eligible device to passthrough
Host device passthrough: Directly assign and dissmis host device from
VM
Host device passthrough: List VMs that are holding a host device
docs/API.md | 11 +-
src/kimchi/control/host.py | 16 ++
src/kimchi/control/vm/hostdevs.py | 44 ++++++
src/kimchi/featuretests.py | 10 +-
src/kimchi/hostdev.py | 263 +++++++++++++++++++++++++++++++
src/kimchi/i18n.py | 7 +
src/kimchi/mockmodel.py | 7 +-
src/kimchi/model/config.py | 2 +
src/kimchi/model/host.py | 53 +++++--
src/kimchi/model/libvirtstoragepool.py | 18 +--
src/kimchi/model/vmhostdevs.py | 277 +++++++++++++++++++++++++++++++++
src/kimchi/rollbackcontext.py | 3 +
src/kimchi/xmlutils.py | 26 +++-
tests/test_rest.py | 6 +-
tests/test_storagepool.py | 7 +-
15 files changed, 711 insertions(+), 39 deletions(-)
create mode 100644 src/kimchi/control/vm/hostdevs.py
create mode 100644 src/kimchi/hostdev.py
create mode 100644 src/kimchi/model/vmhostdevs.py
--
1.9.0
10 years, 4 months
[PATCHv3] Exception: fix exception details when not specified
by lvroyce@linux.vnet.ibm.com
From: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
v2>v3, Because kimchi exception used unicode as msg, convert it to str
to make unicode encode work.
v1>v2, Add a new type of error to cover general schema validation error.
(per Sheldon's comments)
Not every validation error needs to translate for user,
we define user interested errors,
other developer interested error should report directly by schema validator,
and handled by developer directly.
fix exception handling for this situation.
Signed-off-by: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
Signed-off-by: Zheng Sheng Zhou <zhshzhou(a)linux.vnet.ibm.com>
---
src/kimchi/control/utils.py | 6 ++++--
src/kimchi/i18n.py | 1 +
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/kimchi/control/utils.py b/src/kimchi/control/utils.py
index 5e63816..081bb81 100644
--- a/src/kimchi/control/utils.py
+++ b/src/kimchi/control/utils.py
@@ -98,8 +98,10 @@ def validate_params(params, instance, action):
try:
validator.validate(request)
except ValidationError, e:
- raise InvalidParameter(e.schema['error'], {'value': str(e.instance)})
-
+ if e.schema.get('error'):
+ raise InvalidParameter(e.schema['error'], {'value': str(e.instance)})
+ else:
+ raise InvalidParameter("KCHAPI0008E", {"err": str(e.message)})
class UrlSubNode(object):
diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
index 25b703f..4ed13fe 100644
--- a/src/kimchi/i18n.py
+++ b/src/kimchi/i18n.py
@@ -30,6 +30,7 @@ messages = {
"KCHAPI0005E": _("Create is not allowed for %(resource)s"),
"KCHAPI0006E": _("Unable to parse JSON request"),
"KCHAPI0007E": _("This API only supports JSON"),
+ "KCHAPI0008E": _("Parameters does not match requirement in schema: %(err)s"),
"KCHASYNC0001E": _("Datastore is not initiated in the model object."),
"KCHASYNC0002E": _("Unable to start task due error: %(err)s"),
--
1.8.3.2
10 years, 4 months
[PATCH 0/4] ticket support for guest
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
ticket support for guest
ShaoHe Feng (4):
update API.md
ticket in backend: add a set ticket action for VM resource
support ticket in UI.
set the password for spice and VNC page.
docs/API.md | 4 ++++
src/kimchi/control/vms.py | 1 +
src/kimchi/model/vms.py | 28 ++++++++++++++++++++++++++++
ui/js/src/kimchi.api.js | 33 ++++++++++++++++++++++++++++++++-
ui/pages/spice.html.tmpl | 3 ++-
ui/pages/websockify/console.html | 5 +++++
6 files changed, 72 insertions(+), 2 deletions(-)
--
1.9.0
10 years, 4 months
[PATCHv2 0/2] Disk attachment
by lvroyce@linux.vnet.ibm.com
From: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
Fix for ref_cnt for disk attachment.
Royce Lv (2):
disk attachment: fix ref_cnt to prevent double attach
disk attachment: avoid checking cdrom ref_cnt
src/kimchi/model/vmstorages.py | 31 ++++++++++++++++++++++++++++++-
tests/test_model.py | 1 +
2 files changed, 31 insertions(+), 1 deletion(-)
--
1.8.3.2
10 years, 4 months
[RFC] Problems with iso names while create new template
by Rodrigo Trujillo
Hi,
There is a problem while creating a new template with local isos.
If some iso is stored inside an active storagepool, then kimchi is going
to show it for selection.
Kimchi looks for any file, with any name, but of type "iso" -
IsoVolumesModel:get_list() in
src/kimchi/model/storagevolumes.py.
So, isos rename like ubuntu.iso.1 or even teste.exe will be shown to user.
Error happens if user selects one of them, because the JSON schema
restricts file names to
ends with ".iso".
According to my tests, Libvirt accepts any name, since the file is ISO
type. So, I would like to
propose to remove the ".iso" checking in the JSON schema.
This is not going to break anything in UI.
Problems would happen if user tries to create a template using the API
directly and gives a file
that is not an ISO. In this case, a error will be returned by libvirt
and triggered to user.
Patch is quite simple. Any objection ?
Rodrigo Trujillo
10 years, 4 months
[PATCH V2] Issue#361:Bugfix as disable the action button content when creating network
by Wen Wang
Bugfix that disabled the content display of the action button for an exsiting
network when creating a new network.
V1 -> V2
Accroding to Hongliang Wang, fix the bug that tabs keep shown when there
exists more than one network.
---
ui/js/src/kimchi.network.js | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/ui/js/src/kimchi.network.js b/ui/js/src/kimchi.network.js
index ca6d29b..8c037e5 100644
--- a/ui/js/src/kimchi.network.js
+++ b/ui/js/src/kimchi.network.js
@@ -165,11 +165,13 @@ kimchi.addNetworkActions = function(network) {
icons : {
secondary : "action-button-icon"
}
- }).click(function() {
+ }).click(function(event) {
+ event.stopPropagation();
+ $("*").find(".menu-container", "#" + network.name).toggle(false);
$(".menu-container", "#" + network.name).toggle();
window.scrollBy(0, 150);
});
- $(".menu-container", "#" + network.name).mouseleave(function() {
+ $(document).click(function(event) {
$(".menu-container", "#" + network.name).toggle(false);
});
};
--
1.9.1
10 years, 4 months
[PATCH v3 0/3] PCI passthrough: Summary
by Zhou Zheng Sheng
Hi,
This patch series is to enable Kimchi to assign hos devices directly to
a VM, thus greately improve VM performance. Currently we support assigning
PCI device, USB device and SCSI LUN. For example, we can assign an NIC
to VM to improve guest network throughput, or passthrough a USB camera
to enable the guest OS to record video.
Host devices form a tree. We can assign most of the devices in the tree
to VM. By assigning a device, all the devices in its sub-tree are also
assigned. It might not make sense to assign a USB controller, because
the host may be using one of the devices connected to the controller.
Instead, Kimchi just presents the "leaf" devices to assign to guest.
In recent Linux kernel and KVM, it is able to recognize the IOMMU group
of a PCI device. The "leaf" PCI devices in the same IOMMU group should
be assigned and dismissed together. The IOMMU group is the actual
smallest isolation granularity of the PCI devices.
The first patch is to list all host devices information. It's useful on
its own to show host devices information.
The second patch is to list all eligible host devices to assign, as well
as the "affected" devices in the same IOMMU group.
The third patch creates a sub-collection "hostdevs" to the VM resource,
and deals with assigning and dismissing devices.
I'll update API and unit test once everyone is happy with the interface
and logic.
v1:
Handle the devices in VM template.
v2:
Handle the devices in VM's sub-collection "hostdevs".
v3:
Fix a small naming error introduced by rebase.
Zhou Zheng Sheng (3):
PCI passthrough: list all types of host devices
PCI passthrough: list eligible device to passthrough
PCI passthrough: Directly assign and dissmis host device from VM
docs/API.md | 11 +-
src/kimchi/control/host.py | 9 ++
src/kimchi/control/vm/hostdevs.py | 44 ++++++
src/kimchi/featuretests.py | 10 +-
src/kimchi/hostdev.py | 266 +++++++++++++++++++++++++++++++++
src/kimchi/i18n.py | 7 +
src/kimchi/mockmodel.py | 7 +-
src/kimchi/model/config.py | 2 +
src/kimchi/model/host.py | 32 ++--
src/kimchi/model/libvirtstoragepool.py | 18 +--
src/kimchi/model/vmhostdevs.py | 259 ++++++++++++++++++++++++++++++++
src/kimchi/rollbackcontext.py | 3 +
src/kimchi/xmlutils.py | 26 +++-
tests/test_rest.py | 6 +-
tests/test_storagepool.py | 7 +-
15 files changed, 668 insertions(+), 39 deletions(-)
create mode 100644 src/kimchi/control/vm/hostdevs.py
create mode 100644 src/kimchi/hostdev.py
create mode 100644 src/kimchi/model/vmhostdevs.py
--
1.9.0
10 years, 4 months
[PATCH] Enable buttons only when all required data is entered
by Crístian Viana
Most forms contain fields that must be filled before they are submitted.
Some of them submit the missing data and display an error message when
something goes wrong, and some of them do not allow the user to submit
them if some data is missing.
Make the forms behavior consistent by enabling their buttons only
when the required data is entered.
Internally, the page tags all required fields with the class "required"
and whenever any of their values change, they are checke. If any
required field is empty, the submit button becomses disabled; otherwise,
it becomes enabled.
Fix GitHub issue #317 ("Inconsistent button status when adding or
creating new resources").
Signed-off-by: Crístian Viana <vianac(a)linux.vnet.ibm.com>
---
ui/css/theme-default/login-window.css | 4 --
ui/js/src/kimchi.guest_edit_main.js | 15 +++++++
ui/js/src/kimchi.login_window.js | 36 +++++++--------
ui/js/src/kimchi.storagepool_add_main.js | 75 +++++++++++++++++++++++---------
ui/js/src/kimchi.template_edit_main.js | 20 +++++++++
ui/pages/guest-edit.html.tmpl | 6 +--
ui/pages/i18n.html.tmpl | 6 ---
ui/pages/login-window.html.tmpl | 8 ++--
ui/pages/storagepool-add.html.tmpl | 6 +--
ui/pages/template-edit.html.tmpl | 8 ++--
10 files changed, 117 insertions(+), 67 deletions(-)
diff --git a/ui/css/theme-default/login-window.css b/ui/css/theme-default/login-window.css
index 8a21090..d021be6 100644
--- a/ui/css/theme-default/login-window.css
+++ b/ui/css/theme-default/login-window.css
@@ -62,10 +62,6 @@
width: 290px;
}
-#login-window .login-panel .msg-required {
- color: red;
-}
-
#login-window .login-panel button {
font-size: 18px;
height: 40px;
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js
index 0236e2d..bb4ee51 100644
--- a/ui/js/src/kimchi.guest_edit_main.js
+++ b/ui/js/src/kimchi.guest_edit_main.js
@@ -202,6 +202,21 @@ kimchi.guest_edit_main = function() {
kimchi.retrieveVM(kimchi.selectedGuest, initContent);
+ var updateSubmitButtonStatus = function() {
+ var valid = true;
+ guestEditForm.find('input.required').each(function(index, field) {
+ if (field.value === '') {
+ valid = false;
+ return;
+ }
+ });
+
+ saveButton.prop('disabled', !valid);
+ };
+
+ guestEditForm.find('input.required').on('input propertychange',
+ updateSubmitButtonStatus);
+
var submitForm = function(event) {
$(saveButton).prop('disabled', true);
var data=$('#form-guest-edit-general').serializeObject();
diff --git a/ui/js/src/kimchi.login_window.js b/ui/js/src/kimchi.login_window.js
index 9c06a50..52394a5 100644
--- a/ui/js/src/kimchi.login_window.js
+++ b/ui/js/src/kimchi.login_window.js
@@ -30,26 +30,25 @@ kimchi.login_main = function() {
$(opt).prop('selected', selectedLanguage === k);
}
+ var updateSubmitButtonStatus = function() {
+ var valid = true;
+ $('#form-login').find('input.required').each(function(index, field) {
+ if (field.value === '') {
+ valid = false;
+ return;
+ }
+ });
+
+ $('#btn-login').prop('disabled', !valid);
+ }
+
+ $('#form-login').find('input.required').on('input propertychange',
+ updateSubmitButtonStatus);
+
$('#language').on('change', function() {
kimchi.topic('languageChanged').publish($(this).val());
});
- var validateNonEmpty = function(idsArray) {
- for(var i = 0; i < idsArray.length; i++) {
- var id = idsArray[i];
- if (!$('#' + id).val()) {
- $('#' + id + '-msg').text(i18n['KCHAUTH6002E']);
- placeCursor(id);
- return false;
- }
- else {
- $('#' + id + '-msg').empty();
- }
- }
-
- return true;
- };
-
var placeCursor = function(id) {
if (id && $('#' + id).size() > 0) {
$('#' + id).focus();
@@ -66,11 +65,6 @@ kimchi.login_main = function() {
};
var login = function(event) {
-
- if (!validateNonEmpty(['username', 'password'])) {
- return false;
- }
-
$('#btn-login').text(i18n['KCHAUTH6002M']).prop('disabled', true);
var userName = $('#username').val();
diff --git a/ui/js/src/kimchi.storagepool_add_main.js b/ui/js/src/kimchi.storagepool_add_main.js
index 86dbe7f..5356985 100644
--- a/ui/js/src/kimchi.storagepool_add_main.js
+++ b/ui/js/src/kimchi.storagepool_add_main.js
@@ -122,6 +122,18 @@ kimchi.initStorageAddPage = function() {
});
});
+ var updateSubmitButtonStatus = function() {
+ var valid = true;
+ $('#form-pool-add').find('input.required').each(function(index, field) {
+ if (field.value === '') {
+ valid = false;
+ return;
+ }
+ });
+
+ $('#pool-doAdd').prop('disabled', !valid);
+ };
+
$('#poolTypeInputId').change(function() {
var poolObject = {'dir': ".path-section", 'netfs': '.nfs-section',
'iscsi': '.iscsi-section', 'scsi': '.scsi-section',
@@ -134,7 +146,49 @@ kimchi.initStorageAddPage = function() {
$(value).addClass('tmpl-html');
}
});
+
+ switch (selectType) {
+ case 'dir':
+ $('#pathId').addClass('required');
+
+ $('#nfsserverId').removeClass('required');
+ $('#nfspathId').removeClass('required');
+ $('#iscsiserverId').removeClass('required');
+ break;
+ case 'netfs':
+ $('#nfsserverId').addClass('required');
+ $('#nfspathId').addClass('required');
+
+ $('#pathId').removeClass('required');
+ $('#iscsiserverId').removeClass('required');
+ break;
+ case 'iscsi':
+ $('#iscsiserverId').addClass('required');
+
+ $('#pathId').removeClass('required');
+ $('#nfsserverId').removeClass('required');
+ $('#nfspathId').removeClass('required');
+ break;
+ case 'scsi':
+ $('#pathId').removeClass('required');
+ $('#nfsserverId').removeClass('required');
+ $('#nfspathId').removeClass('required');
+ $('#iscsiserverId').removeClass('required');
+ break;
+ case 'logical':
+ $('#pathId').removeClass('required');
+ $('#nfsserverId').removeClass('required');
+ $('#nfspathId').removeClass('required');
+ $('#iscsiserverId').removeClass('required');
+ break;
+ }
+
+ updateSubmitButtonStatus();
});
+
+ $('#form-pool-add').find('input').on('input propertychange',
+ updateSubmitButtonStatus);
+
$('#authId').click(function() {
if ($(this).prop("checked")) {
$('.authenticationfield').removeClass('tmpl-html');
@@ -150,10 +204,6 @@ kimchi.initStorageAddPage = function() {
kimchi.validateForm = function() {
var name = $('#poolId').val();
var poolType = $("#poolTypeInputId").val();
- if ('' === name) {
- kimchi.message.error.code('KCHPOOL6001E');
- return false;
- }
if (name.indexOf("/")!=-1) {
kimchi.message.error.code('KCHPOOL6004E');
return false;
@@ -173,10 +223,6 @@ kimchi.validateForm = function() {
kimchi.validateDirForm = function () {
var path = $('#pathId').val();
- if ('' === path) {
- kimchi.message.error.code('KCHPOOL6002E');
- return false;
- }
if (!/(^\/.*)$/.test(path)) {
kimchi.message.error.code('KCHAPI6003E');
return false;
@@ -190,10 +236,6 @@ kimchi.validateNfsForm = function () {
if (!kimchi.validateServer(nfsserver)) {
return false;
}
- if ('' === nfspath) {
- kimchi.message.error.code('KCHPOOL6003E');
- return false;
- }
if (!/((\/([0-9a-zA-Z-_\.]+)))$/.test(nfspath)) {
kimchi.message.error.code('KCHPOOL6005E');
return false;
@@ -203,22 +245,13 @@ kimchi.validateNfsForm = function () {
kimchi.validateIscsiForm = function() {
var iscsiServer = $('#iscsiserverId').val();
- var iscsiTarget = $('#iscsiTargetId').val();
if (!kimchi.validateServer(iscsiServer)) {
return false;
}
- if ('' === iscsiTarget) {
- kimchi.message.error.code('KCHPOOL6007E');
- return false;
- }
return true;
};
kimchi.validateServer = function(serverField) {
- if ('' === serverField) {
- kimchi.message.error.code('KCHPOOL6008E');
- return false;
- }
if(!kimchi.isServer(serverField)) {
kimchi.message.error.code('KCHPOOL6009E');
return false;
diff --git a/ui/js/src/kimchi.template_edit_main.js b/ui/js/src/kimchi.template_edit_main.js
index f0f4718..e552bf9 100644
--- a/ui/js/src/kimchi.template_edit_main.js
+++ b/ui/js/src/kimchi.template_edit_main.js
@@ -104,6 +104,26 @@ kimchi.template_edit_main = function() {
});
});
+ var updateSubmitButtonStatus = function() {
+ var valid = true;
+ templateEditForm.find('input.required').each(function(index, field) {
+ if (field.value === '') {
+ valid = false;
+ return;
+ }
+ });
+
+ if (valid) {
+ $('#tmpl-edit-button-save').removeAttr('disabled');
+ }
+ else {
+ $('#tmpl-edit-button-save').attr('disabled', 'disabled');
+ }
+ };
+
+ templateEditForm.find('input.required').on('input propertychange',
+ updateSubmitButtonStatus);
+
$('#tmpl-edit-button-cancel').on('click', function() {
kimchi.window.close();
});
diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl
index 96d907e..d35ad7a 100644
--- a/ui/pages/guest-edit.html.tmpl
+++ b/ui/pages/guest-edit.html.tmpl
@@ -49,7 +49,7 @@
</div>
<div class="guest-edit-wrapper-controls">
<input id="guest-edit-id-textbox"
- name="name" type="text" />
+ name="name" type="text" class="required" />
</div>
</div>
<div>
@@ -62,7 +62,7 @@
<input
id="guest-edit-cores-textbox"
name="cpus"
- type="text" />
+ type="text" class="required" />
</div>
</div>
<div>
@@ -74,7 +74,7 @@
<div class="guest-edit-wrapper-controls">
<input id="guest-edit-memory-textbox"
name="memory"
- type="text" />
+ type="text" class="required" />
</div>
</div>
<div>
diff --git a/ui/pages/i18n.html.tmpl b/ui/pages/i18n.html.tmpl
index 98da828..814825f 100644
--- a/ui/pages/i18n.html.tmpl
+++ b/ui/pages/i18n.html.tmpl
@@ -33,7 +33,6 @@
<script>
var i18n = {
'KCHAUTH6001E': "$_("The username or password you entered is incorrect. Please try again.")",
- 'KCHAUTH6002E': "$_("This field is required.")",
'KCHAUTH6001M': "$_("Log in")",
'KCHAUTH6002M': "$_("Logging in...")",
@@ -158,14 +157,9 @@ var i18n = {
'KCHPOOL6004M': "$_("SCSI Fibre Channel")",
'KCHPOOL6005M': "$_("No SCSI adapters found.")",
- 'KCHPOOL6001E': "$_("The storage pool name can not be blank.")",
- 'KCHPOOL6002E': "$_("The storage pool path can not be blank.")",
- 'KCHPOOL6003E': "$_("NFS server mount path can not be blank.")",
'KCHPOOL6004E': "$_("Invalid storage pool name. It should not contain '/'.")",
'KCHPOOL6005E': "$_("Invalid NFS mount path.")",
'KCHPOOL6006E': "$_("No logical device selected.")",
- 'KCHPOOL6007E': "$_("The iSCSI target can not be blank.")",
- 'KCHPOOL6008E': "$_("Server name can not be blank.")",
'KCHPOOL6009E': "$_("This is not a valid Server Name or IP. please, modify it.")",
'KCHPOOL6010M': "$_("Looking for available partitions ...")",
'KCHPOOL6011M': "$_("No available partitions found.")",
diff --git a/ui/pages/login-window.html.tmpl b/ui/pages/login-window.html.tmpl
index 3e451c4..1cd9e83 100644
--- a/ui/pages/login-window.html.tmpl
+++ b/ui/pages/login-window.html.tmpl
@@ -34,15 +34,13 @@
<div class="content login-panel">
<form id="form-login" action="/login" method="POST">
<div class="row">
- <input type="text" id="username" name="username" required="required" placeholder="$_("User Name")" />
- <div id="username-msg" class="msg-required"></div>
+ <input type="text" id="username" name="username" class="required" placeholder="$_("User Name")" />
</div>
<div class="row">
- <input type="password" id="password" name="password" required="required" placeholder="$_("Password")" />
- <div id="password-msg" class="msg-required"></div>
+ <input type="password" id="password" name="password" class="required" placeholder="$_("Password")" />
</div>
<div class="row">
- <button id="btn-login" class="btn-normal">$_("Log in")</button>
+ <button id="btn-login" class="btn-normal" disabled="true">$_("Log in")</button>
</div>
</form>
</div>
diff --git a/ui/pages/storagepool-add.html.tmpl b/ui/pages/storagepool-add.html.tmpl
index 977db66..6ce1343 100644
--- a/ui/pages/storagepool-add.html.tmpl
+++ b/ui/pages/storagepool-add.html.tmpl
@@ -36,7 +36,7 @@
<p class="text-help">
$_("The name used to identify the storage pools, and it should not be empty.")
</p>
- <input id="poolId" required="required" type="text" class="text storage-base-input-width" name="name">
+ <input id="poolId" type="text" class="text storage-base-input-width required" name="name">
</div>
</section>
<section class="form-section">
@@ -60,7 +60,7 @@
$_("The path of the Storage Pool. Each Storage Pool must have a unique path.")</p>
<p class="text-help">
$_("Kimchi will try to create the directory when it does not already exist in your system.")</p>
- <input id="pathId" type="text" class="text storage-base-input-width">
+ <input id="pathId" type="text" class="text storage-base-input-width required">
</div>
<div class="clear"></div>
</section>
@@ -152,7 +152,7 @@
</div>
<footer>
<div class="btn-group">
- <button id="pool-doAdd" class="btn-normal">
+ <button id="pool-doAdd" class="btn-normal" disabled="disabled">
<span class="text">$_("Create")</span>
</button>
</div>
diff --git a/ui/pages/template-edit.html.tmpl b/ui/pages/template-edit.html.tmpl
index 434d938..46b7058 100644
--- a/ui/pages/template-edit.html.tmpl
+++ b/ui/pages/template-edit.html.tmpl
@@ -36,7 +36,7 @@
<label for="template-edit-id-textbox">$_("Name")</label>
</div>
<div class="template-edit-wrapper-controls">
- <input id="template-edit-id-textbox" name="name" type="text" />
+ <input id="template-edit-id-textbox" name="name" type="text" class="required" />
</div>
</div>
<div>
@@ -60,7 +60,7 @@
<label for="template-edit-cpu-textbox">$_("CPU Number")</label>
</div>
<div class="template-edit-wrapper-controls">
- <input id="template-edit-cpu-textbox" name="cpus" type="text" />
+ <input id="template-edit-cpu-textbox" name="cpus" type="text" class="required" />
</div>
</div>
<div>
@@ -68,7 +68,7 @@
<label for="template-edit-memory-textbox">$_("Memory")</label>
</div>
<div class="template-edit-wrapper-controls">
- <input id="template-edit-memory-textbox" name="memory" type="text" />
+ <input id="template-edit-memory-textbox" name="memory" type="text" class="required" />
</div>
</div>
<div>
@@ -76,7 +76,7 @@
<label for="template-edit-disk-textbox">$_("Disk (GB)")</label>
</div>
<div class="template-edit-wrapper-controls">
- <input id="template-edit-disk-textbox" name="disks" type="text" />
+ <input id="template-edit-disk-textbox" name="disks" type="text" class="required" />
</div>
</div>
</fieldset>
--
1.9.0
10 years, 4 months
Improving diff hunk headers
by Christy Perez
Hi all,
I was looking over patches today and wished that there was better
context for the changed lines. Specifically, I wanted a function name
instead of just the class name.
I finally came across this e-mail [1] from someone at Red Hat:
"""
Hello,
I'm sure you're aware of hunk header lines in patches:
@@ -24,5 +24,5 @@ class SomeClass(object):
It's possible to configure which source line Git selects for the hunk
header. By default it uses non-indented lines. A "python" regexp, which
selects functions, classes and methods, is already included in Git; you
just have to enable it. I also use custom regexps for ldifs and API.txt:
$ cat ~/.gitattributes # (Or .git/info/attributes for project-specific
config)
*.py diff=python
API.txt diff=apitxt
*.ldif diff=ldif
*.update diff=ldif
$ git config -l # set with e.g. `git config --global key="value"`
...
core.attributesfile=~/.gitattributes
diff.apitxt.xfuncname=^command: .*
diff.ldif.xfuncname=^dn:.*
Enjoy your Friday!
--
Petr³
"""
We can also define our own, as per:
http://stackoverflow.com/questions/2783086/how-does-git-diff-generate-hun...
I put *.py diff=python into my kimchi project's .git/info/attributes
file, and I like these diffs a lot better.
For example (using a really old branch I should have deleted while ago!
):
@@ -37,7 +37,6 @@ class AsyncTask(object):
self.status = 'running'
self.message = 'OK'
self._save_helper()
- self._cp_request = cherrypy.serving.request
self.thread = threading.Thread(target=self._run_helper,
args=(opaque, self._status_cb))
self.thread.setDaemon(True)
@@ -37,7 +37,6 @@ class AsyncTask(object):
self.status = 'running'
self.message = 'OK'
self._save_helper()
- self._cp_request = cherrypy.serving.request
self.thread = threading.Thread(target=self._run_helper,
args=(opaque, self._status_cb))
self.thread.setDaemon(True)
@@ -60,17 +59,13 @@ class AsyncTask(object):
obj = {}
for attr in ('id', 'target_uri', 'message', 'status'):
obj[attr] = getattr(self, attr)
- try:
- with self.objstore as session:
- session.store('task', self.id, obj)
- except Exception as e:
- raise OperationFailed('KCHASYNC0002E', {'err': e.message})
+ with self.objstore as session:
+ session.store('task', self.id, obj)
def _run_helper(self, opaque, cb):
- cherrypy.serving.request = self._cp_request
try:
changes to:
diff --git a/src/kimchi/asynctask.py b/src/kimchi/asynctask.py
index e2d2dcf..8f0d96c 100644
--- a/src/kimchi/asynctask.py
+++ b/src/kimchi/asynctask.py
@@ -37,7 +37,6 @@ def __init__(self, id, target_uri, fn, objstore,
opaque=None):
self.status = 'running'
self.message = 'OK'
self._save_helper()
- self._cp_request = cherrypy.serving.request
self.thread = threading.Thread(target=self._run_helper,
args=(opaque, self._status_cb))
self.thread.setDaemon(True)
@@ -60,17 +59,13 @@ def _save_helper(self):
obj = {}
for attr in ('id', 'target_uri', 'message', 'status'):
obj[attr] = getattr(self, attr)
- try:
- with self.objstore as session:
- session.store('task', self.id, obj)
- except Exception as e:
- raise OperationFailed('KCHASYNC0002E', {'err': e.message})
+ with self.objstore as session:
So now you can see the function that the code is in, not the
larger-scope (the class).
I thought I would share, in case any one else wanted to use this.
Maybe we could even add a .gitattributes file to kimchi if others think
it's a good idea to enforce some project-specific conventions.
Happy coding!
- Christy
[1]
http://www.redhat.com/archives/freeipa-devel/2013-April/msg00381.html
10 years, 4 months