[PATCH RFC] Discover Kimchi peers using openSLP
by Aline Manera
GET /peers
[
"https://ubuntu-vm:8001",
"https://rhel-vm:8001",
]
How to test it?
- Install openslp and openslp-server
- Start opnslp service: servicd slpd start
- Make sure to open openSLP port (427 UDP and TCP) on firewall
I tested it using VMs as they are in the same host network.
TODO:
#1: Add option on Kimchi config file to enable/disable this feature
#2: Update /config/capabilities to return if federation is enabled or not
GET /config/capabilities
{ ...
federation: enable|disable
}
#3: Create README-federation file to provide details on how to enable this feature
#4: Update API.md, mockmodel and test cases
Aline Manera (1):
Discover Kimchi peers using openSLP
src/kimchi/control/peers.py | 29 ++++++++++++++++++++++++++
src/kimchi/model/peers.py | 50 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+)
create mode 100644 src/kimchi/control/peers.py
create mode 100644 src/kimchi/model/peers.py
--
1.9.3
10 years, 4 months
[PATCH] Fix UI: Show proper message when detaching a guest storage
by Rodrigo Trujillo
Whenever an user tries to detach a storage from a guest, the
confirmation message always contains "CDROM". This patch fix this
problem, so when the storage type is "disk", it shows the right
message.
Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo(a)linux.vnet.ibm.com>
---
ui/js/src/kimchi.guest_edit_main.js | 2 ++
ui/pages/guest-edit.html.tmpl | 4 ++--
ui/pages/i18n.json.tmpl | 1 +
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js
index 7d24b44..01d8045 100644
--- a/ui/js/src/kimchi.guest_edit_main.js
+++ b/ui/js/src/kimchi.guest_edit_main.js
@@ -107,6 +107,8 @@ kimchi.guest_edit_main = function() {
confirm : i18n['KCHAPI6002M'],
cancel : i18n['KCHAPI6003M']
};
+ if ($(this).data('type') == "disk")
+ settings['content'] = i18n['KCHVMCD6009M'];
var dev = $(this).data('dev');
kimchi.confirm(settings, function() {
diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl
index f24f7de..ed7ddeb 100644
--- a/ui/pages/guest-edit.html.tmpl
+++ b/ui/pages/guest-edit.html.tmpl
@@ -169,7 +169,7 @@
title='$_("Replace")'>
</button>
<button class="guest-edit-cdrom-button detach"
- data-vm="{vm}" data-dev="{dev}"
+ data-vm="{vm}" data-dev="{dev}" data-type="{type}"
title='$_("Detach")'>
</button>
<button class="guest-edit-cdrom-button save hidden"
@@ -213,7 +213,7 @@
</span>
<span class="action-area">
<button class="guest-edit-cdrom-button detach"
- data-vm="{vm}" data-dev="{dev}"
+ data-vm="{vm}" data-dev="{dev}" data-type="{type}"
title="$_("Detach")">
</button>
</span>
diff --git a/ui/pages/i18n.json.tmpl b/ui/pages/i18n.json.tmpl
index 697f946..ccfb081 100644
--- a/ui/pages/i18n.json.tmpl
+++ b/ui/pages/i18n.json.tmpl
@@ -135,6 +135,7 @@
"KCHVMCD6006M": "$_("Successfully attached!")",
"KCHVMCD6007M": "$_("Successfully replaced!")",
"KCHVMCD6008M": "$_("Successfully detached!")",
+ "KCHVMCD6009M": "$_("This disk will be detached permanently and you can re-attach it. Continue to detach it?")",
"KCHNET6001E": "$_("The VLAN id must be between 1 and 4094.")",
--
1.9.3
10 years, 4 months
[PATCHv2] Refactor vmstorage name generation
by lvroyce@linux.vnet.ibm.com
From: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
We generated all storage name with 'hd' prefix,
which is not proper for scsi and virtio disk.
So refactor name generation to produce proper device name.
Signed-off-by: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
---
src/kimchi/model/vmstorages.py | 46 ++++++++++++++++++++++--------------------
1 file changed, 24 insertions(+), 22 deletions(-)
diff --git a/src/kimchi/model/vmstorages.py b/src/kimchi/model/vmstorages.py
index b5311db..513f756 100644
--- a/src/kimchi/model/vmstorages.py
+++ b/src/kimchi/model/vmstorages.py
@@ -38,6 +38,7 @@ from kimchi.vmdisks import get_device_xml, get_vm_disk, get_vm_disk_list
from kimchi.vmdisks import DEV_TYPE_SRC_ATTR_MAP
HOTPLUG_TYPE = ['scsi', 'virtio']
+PREFIX_MAP = {'ide': 'hd', 'virtio': 'vd', 'scsi': 'sd'}
def _get_device_bus(dev_type, dom):
@@ -140,17 +141,8 @@ class VMStoragesModel(object):
def create(self, vm_name, params):
dom = VMModel.get_vm(vm_name, self.conn)
- # Use device name passed or pick next
- dev_name = params.get('dev', None)
- if dev_name is None:
- params['dev'] = self._get_storage_device_name(vm_name)
- else:
- devices = self.get_list(vm_name)
- if dev_name in devices:
- raise OperationFailed(
- 'KCHVMSTOR0004E',
- {'dev_name': dev_name, 'vm_name': vm_name})
-
+ params['bus'] = _get_device_bus(params['type'], dom)
+ self._get_storage_device_name(vm_name, params)
# Path will never be blank due to API.json verification.
# There is no need to cover this case here.
params['format'] = 'raw'
@@ -171,7 +163,6 @@ class VMStoragesModel(object):
params['format'] = vol_info['format']
params['path'] = vol_info['path']
params['src_type'] = _check_path(params['path'])
- params['bus'] = _get_device_bus(params['type'], dom)
if (params['bus'] not in HOTPLUG_TYPE
and DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
raise InvalidOperation('KCHVMSTOR0011E')
@@ -187,16 +178,27 @@ class VMStoragesModel(object):
raise OperationFailed("KCHVMSTOR0008E", {'error': e.message})
return params['dev']
- def _get_storage_device_name(self, vm_name):
- dev_list = [dev for dev in self.get_list(vm_name)
- if dev.startswith('hd')]
- if len(dev_list) == 0:
- return 'hda'
- dev_list.sort()
- last_dev = dev_list.pop()
- # TODO: Improve to device names "greater then" hdz
- next_dev_letter_pos = string.ascii_lowercase.index(last_dev[2]) + 1
- return 'hd' + string.ascii_lowercase[next_dev_letter_pos]
+ def _get_storage_device_name(self, vm_name, params):
+ if params.get('dev') is None:
+ bus_prefix = PREFIX_MAP[params['bus']]
+ dev_list = [dev for dev in self.get_list(vm_name)
+ if dev.startswith(bus_prefix)]
+ if len(dev_list) == 0:
+ params['dev'] = bus_prefix + 'a'
+ else:
+ dev_list.sort()
+ last_dev = dev_list.pop()
+ # TODO: Improve to device names "greater then" hdz
+ next_dev_letter_pos =\
+ string.ascii_lowercase.index(last_dev[2]) + 1
+ params['dev'] =\
+ bus_prefix + string.ascii_lowercase[next_dev_letter_pos]
+
+ devices = self.get_list(vm_name)
+ if params['dev'] in devices:
+ raise OperationFailed(
+ 'KCHVMSTOR0004E',
+ {'dev_name': params['dev'], 'vm_name': vm_name})
def get_list(self, vm_name):
dom = VMModel.get_vm(vm_name, self.conn)
--
1.8.3.2
10 years, 4 months
[PATCH] Fix Key Error when editing CD ROM path
by Christy Perez
lxml only accepts strings as parameters when looking
up xml elements. The port for remote ISO was being
passed in as an int, and a KeyError was thrown.
This patch just casts the ints to strings for the
lookups.
Signed-off-by: Christy Perez <christy(a)linux.vnet.ibm.com>
---
src/kimchi/model/vmstorages.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/kimchi/model/vmstorages.py b/src/kimchi/model/vmstorages.py
index cd985fa..5543f40 100644
--- a/src/kimchi/model/vmstorages.py
+++ b/src/kimchi/model/vmstorages.py
@@ -68,7 +68,8 @@ def _get_storage_xml(params, ignore_source=False):
if src_type == 'network':
output = urlparse.urlparse(params.get('path'))
host = E.host(name=output.hostname, port=
- output.port or socket.getservbyname(output.scheme))
+ str(output.port) or
+ str(socket.getservbyname(output.scheme)))
source = E.source(protocol=output.scheme, name=output.path)
source.append(host)
disk.append(source)
--
1.9.3
10 years, 4 months
[PATCH] Refactor vmstorage name generation
by lvroyce@linux.vnet.ibm.com
From: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
We generated all storage name with 'hd' prefix,
which is not proper for scsi and virtio disk.
So refactor name generation to produce proper device name.
Signed-off-by: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
---
src/kimchi/model/vmstorages.py | 46 ++++++++++++++++++++++--------------------
1 file changed, 24 insertions(+), 22 deletions(-)
diff --git a/src/kimchi/model/vmstorages.py b/src/kimchi/model/vmstorages.py
index b5311db..9ae8584 100644
--- a/src/kimchi/model/vmstorages.py
+++ b/src/kimchi/model/vmstorages.py
@@ -38,6 +38,7 @@ from kimchi.vmdisks import get_device_xml, get_vm_disk, get_vm_disk_list
from kimchi.vmdisks import DEV_TYPE_SRC_ATTR_MAP
HOTPLUG_TYPE = ['scsi', 'virtio']
+prefix_map = {'ide': 'hd', 'virtio': 'vd', 'scsi': 'sd'}
def _get_device_bus(dev_type, dom):
@@ -140,17 +141,8 @@ class VMStoragesModel(object):
def create(self, vm_name, params):
dom = VMModel.get_vm(vm_name, self.conn)
- # Use device name passed or pick next
- dev_name = params.get('dev', None)
- if dev_name is None:
- params['dev'] = self._get_storage_device_name(vm_name)
- else:
- devices = self.get_list(vm_name)
- if dev_name in devices:
- raise OperationFailed(
- 'KCHVMSTOR0004E',
- {'dev_name': dev_name, 'vm_name': vm_name})
-
+ params['bus'] = _get_device_bus(params['type'], dom)
+ self._get_storage_device_name(vm_name, params)
# Path will never be blank due to API.json verification.
# There is no need to cover this case here.
params['format'] = 'raw'
@@ -171,7 +163,6 @@ class VMStoragesModel(object):
params['format'] = vol_info['format']
params['path'] = vol_info['path']
params['src_type'] = _check_path(params['path'])
- params['bus'] = _get_device_bus(params['type'], dom)
if (params['bus'] not in HOTPLUG_TYPE
and DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
raise InvalidOperation('KCHVMSTOR0011E')
@@ -187,16 +178,27 @@ class VMStoragesModel(object):
raise OperationFailed("KCHVMSTOR0008E", {'error': e.message})
return params['dev']
- def _get_storage_device_name(self, vm_name):
- dev_list = [dev for dev in self.get_list(vm_name)
- if dev.startswith('hd')]
- if len(dev_list) == 0:
- return 'hda'
- dev_list.sort()
- last_dev = dev_list.pop()
- # TODO: Improve to device names "greater then" hdz
- next_dev_letter_pos = string.ascii_lowercase.index(last_dev[2]) + 1
- return 'hd' + string.ascii_lowercase[next_dev_letter_pos]
+ def _get_storage_device_name(self, vm_name, params):
+ if params.get('dev') is None:
+ bus_prefix = prefix_map[params['bus']]
+ dev_list = [dev for dev in self.get_list(vm_name)
+ if dev.startswith(bus_prefix)]
+ if len(dev_list) == 0:
+ params['dev'] = bus_prefix + 'a'
+ else:
+ dev_list.sort()
+ last_dev = dev_list.pop()
+ # TODO: Improve to device names "greater then" hdz
+ next_dev_letter_pos =\
+ string.ascii_lowercase.index(last_dev[2]) + 1
+ params['dev'] =\
+ bus_prefix + string.ascii_lowercase[next_dev_letter_pos]
+
+ devices = self.get_list(vm_name)
+ if params['dev'] in devices:
+ raise OperationFailed(
+ 'KCHVMSTOR0004E',
+ {'dev_name': params['dev'], 'vm_name': vm_name})
def get_list(self, vm_name):
dom = VMModel.get_vm(vm_name, self.conn)
--
1.8.3.2
10 years, 4 months
[PATCHv2] Reject cdrom update when protocol is not supported by libvirt
by lvroyce@linux.vnet.ibm.com
From: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
v1>v2, fix pep8.
When remote iso protocol is not supported by libvirt,
even if we work around by qemu command,
it will mess up device list logic.
So reject this use case.
Signed-off-by: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
---
src/kimchi/i18n.py | 1 +
src/kimchi/model/vmstorages.py | 4 ++++
tests/test_model.py | 16 +++++++++++++++-
3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
index 2eae7e8..f5ef275 100644
--- a/src/kimchi/i18n.py
+++ b/src/kimchi/i18n.py
@@ -255,6 +255,7 @@ messages = {
"KCHVMSTOR0015E": _("Cannot lookup disk path information by given pool/volume: %(error)s"),
"KCHVMSTOR0016E": _("Volume already been used by other vm"),
"KCHVMSTOR0017E": _("Only one of path or pool/volume can be specified to add a new virtual machine disk"),
+ "KCHVMSTOR0018E": _("Remote ISO update/attach is not supported by your libvirt version"),
"KCHREPOS0001E": _("YUM Repository ID must be one word only string."),
"KCHREPOS0002E": _("Repository URL must be an http://, ftp:// or file:// URL."),
diff --git a/src/kimchi/model/vmstorages.py b/src/kimchi/model/vmstorages.py
index e5be17c..72bdccc 100644
--- a/src/kimchi/model/vmstorages.py
+++ b/src/kimchi/model/vmstorages.py
@@ -29,6 +29,7 @@ from lxml.builder import E
from kimchi.exception import InvalidOperation, InvalidParameter, NotFoundError
from kimchi.exception import OperationFailed
+from kimchi.model.config import CapabilitiesModel
from kimchi.model.vms import DOM_STATE_MAP, VMModel
from kimchi.model.storagevolumes import StorageVolumeModel
from kimchi.model.utils import get_vm_config_flag
@@ -38,6 +39,7 @@ from kimchi.vmdisks import get_device_xml, get_vm_disk, get_vm_disk_list
from kimchi.vmdisks import DEV_TYPE_SRC_ATTR_MAP
HOTPLUG_TYPE = ['scsi', 'virtio']
+caps = CapabilitiesModel()
def _get_device_bus(dev_type, dom):
@@ -69,6 +71,8 @@ def _get_storage_xml(params, ignore_source=False):
output = urlparse.urlparse(params.get('path'))
port = str(output.port or socket.getservbyname(output.scheme))
host = E.host(name=output.hostname, port=port)
+ if output.scheme not in caps.libvirt_stream_protocols:
+ raise InvalidOperation("KCHVMSTOR0018E")
source = E.source(protocol=output.scheme, name=output.path)
source.append(host)
disk.append(source)
diff --git a/tests/test_model.py b/tests/test_model.py
index 7fd0f00..ef0a0e6 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -29,6 +29,7 @@ import tempfile
import threading
import time
import unittest
+import urlparse
import uuid
@@ -38,6 +39,7 @@ import utils
from kimchi import netinfo
from kimchi.exception import InvalidOperation, InvalidParameter
from kimchi.exception import NotFoundError, OperationFailed
+from kimchi.featuretests import FeatureTests
from kimchi.iscsi import TargetClient
from kimchi.model import model
from kimchi.rollbackcontext import RollbackContext
@@ -397,13 +399,25 @@ class ModelTests(unittest.TestCase):
valid_remote_iso_path = utils.get_remote_iso_path()
cdrom_args = {"type": "cdrom",
"path": valid_remote_iso_path}
+ protocol = urlparse.urlparse(valid_remote_iso_path).scheme
+ if not FeatureTests.libvirt_supports_iso_stream(protocol):
+ self.assertRaises(InvalidOperation, inst.vmstorages_create,
+ vm_name, cdrom_args)
+ return
+
cdrom_dev = inst.vmstorages_create(vm_name, cdrom_args)
storage_list = inst.vmstorages_get_list(vm_name)
self.assertEquals(prev_count + 1, len(storage_list))
# Update remote-backed cdrom with the same ISO
+ protocol = urlparse.urlparse(valid_remote_iso_path).scheme
+ if not FeatureTests.libvirt_supports_iso_stream(protocol):
+ self.assertRaises(InvalidOperation, inst.vmstorage_update,
+ vm_name, cdrom_dev,
+ {'path': valid_remote_iso_path})
+ return
inst.vmstorage_update(vm_name, cdrom_dev,
- {'path': valid_remote_iso_path})
+ {'path': valid_remote_iso_path})
cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
cur_cdrom_path = re.sub(":80/", '/', cdrom_info['path'])
self.assertEquals(valid_remote_iso_path, cur_cdrom_path)
--
1.8.3.2
10 years, 4 months
[PATCH] Remote ISO attachment: fix UI to accept remote ISO link for cdrom attachment
by lvroyce@linux.vnet.ibm.com
From: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
UI just accept local ISO as cdrom attachment before,
enable remote ISO link for it.
Signed-off-by: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
---
ui/js/src/kimchi.guest_storage_add.main.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/js/src/kimchi.guest_storage_add.main.js b/ui/js/src/kimchi.guest_storage_add.main.js
index 1f4c4bd..a8c5acb 100644
--- a/ui/js/src/kimchi.guest_storage_add.main.js
+++ b/ui/js/src/kimchi.guest_storage_add.main.js
@@ -109,7 +109,7 @@ kimchi.guest_storage_add_main = function() {
});
var validateCDROM = function(settings) {
- if (/^(\/.*)+$/.test(settings['path']))
+ if (/^((https|http|ftp|ftps|tftp|\/).*)+$/.test(settings['path']))
return true;
else {
kimchi.message.error.code('KCHVMSTOR0001E');
--
1.8.3.2
10 years, 4 months
[PATCH v2 0/3] Update remote CD ROM
by Christy Perez
This patchset adds changes to allow a user to update a CD ROM created
with a remote ISO. It fixes a KeyError issue, improves the way a remote
ISO file is verified, and adds unit tests.
Note: Currently updating a CD ROM created with a local iso using a remote
ISO is not supported. This patchset does not address that issue,
but does add a test for it. This patchset is primarily to correct the
KeyError and prevent a regression when trying to update a remote ISO's
file.
Christy Perez (3):
Fix Key Error when editing CD ROM path
Fix verification of remote ISO
Add unit tests for remote-backed CD ROM updates.
src/kimchi/model/vmstorages.py | 2 +-
src/kimchi/utils.py | 21 +++++++++++-----
tests/test_model.py | 55 +++++++++++++++++++++++++++++++++++++++++-
tests/utils.py | 21 +++++++++++++++-
4 files changed, 90 insertions(+), 9 deletions(-)
--
1.9.3
10 years, 4 months
[PATCH] UI: refactor guest edit code.
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
We don not need a special "save" button for permission form.
All form in guest edit tab can share the same "save" button.
also, we will add a password form, it will also share this button.
Signed-off-by: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
Signed-off-by: Simon Jin <simonjin(a)linux.vnet.ibm.com>
---
ui/css/theme-default/guest-edit.css | 5 -----
ui/js/src/kimchi.guest_edit_main.js | 40 +++++++++++++++++++++----------------
ui/pages/guest-edit.html.tmpl | 3 ---
3 files changed, 23 insertions(+), 25 deletions(-)
diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css
index 1092cc9..74c2237 100644
--- a/ui/css/theme-default/guest-edit.css
+++ b/ui/css/theme-default/guest-edit.css
@@ -261,8 +261,3 @@
width: 46%;
float: right;
}
-
-#form-guest-edit-permission-save {
- float: right;
- margin-right: 10px;
-}
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js
index 38a2bc0..7d24b44 100644
--- a/ui/js/src/kimchi.guest_edit_main.js
+++ b/ui/js/src/kimchi.guest_edit_main.js
@@ -19,13 +19,11 @@ kimchi.guest_edit_main = function() {
var buttonContainer = $('#action-button-container');
$('#guest-edit-tabs').tabs({
beforeActivate: function(event, ui) {
+ var display_list = ['form-guest-edit-general', 'form-guest-edit-permission']
$(buttonContainer).addClass('hidden');
- $("#form-guest-edit-permission-save").addClass('hidden');
var deactivated = ui['newPanel'];
- if($(deactivated).attr('id') === 'form-guest-edit-general') {
+ if(display_list.indexOf($(deactivated).attr('id')) >= 0) {
$(buttonContainer).removeClass('hidden');
- }else if($(deactivated).attr('id') === 'form-guest-edit-permission'){
- $("#form-guest-edit-permission-save").removeClass('hidden');
}
}
});
@@ -335,18 +333,6 @@ kimchi.guest_edit_main = function() {
filterNodes("", $("#permission-avail-users"));
filterNodes("", $("#permission-avail-groups"));
});
- $("#form-guest-edit-permission-save").on("click", function(){
- var content = { users: [], groups: [] };
- $("#permission-sel-users").children().each(function(){
- content.users.push($("label", this).text());
- });
- $("#permission-sel-groups").children().each(function(){
- content.groups.push($("label", this).text());
- });
- kimchi.updateVM(kimchi.selectedGuest, content, function(){
- kimchi.window.close();
- });
- });
};
var initContent = function(guest) {
@@ -393,7 +379,7 @@ kimchi.guest_edit_main = function() {
kimchi.retrieveVM(kimchi.selectedGuest, initContent);
- var submitForm = function(event) {
+ var generalSubmit = function(event) {
$(saveButton).prop('disabled', true);
var data=$('#form-guest-edit-general').serializeObject();
if(data['memory']!=undefined) {
@@ -410,7 +396,27 @@ kimchi.guest_edit_main = function() {
kimchi.message.error(err.responseJSON.reason);
$(saveButton).prop('disabled', false);
});
+ }
+ var permissionSubmit = function(event) {
+ var content = { users: [], groups: [] };
+ $("#permission-sel-users").children().each(function(){
+ content.users.push($("label", this).text());
+ });
+ $("#permission-sel-groups").children().each(function(){
+ content.groups.push($("label", this).text());
+ });
+ kimchi.updateVM(kimchi.selectedGuest, content, function(){
+ kimchi.window.close();
+ });
+ }
+
+ // tap map, "general": 0, "storage": 1, "interface": 2, "permission": 3, "password": 4
+ var submit_map = {0: generalSubmit, 3:permissionSubmit};
+ var submitForm = function(event) {
+ var current = $('#guest-edit-tabs').tabs( "option", "active" );
+ var submitFun = submit_map[current];
+ submitFun && submitFun(event);
event.preventDefault();
};
diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl
index 1c1d7d4..f24f7de 100644
--- a/ui/pages/guest-edit.html.tmpl
+++ b/ui/pages/guest-edit.html.tmpl
@@ -150,9 +150,6 @@
<span class="text">$_("Save")</span>
</button>
</div>
- <button id="form-guest-edit-permission-save" class="btn-normal hidden">
- <span class="text">$_("Save")</span>
- </button>
</footer>
</div>
<script id="cdrom-row-tmpl" type="text/html">
--
1.9.3
10 years, 4 months
[PATCH v4 0/3] Update Remote CD ROM
by Christy Perez
Aline pointed out some test failures I'd assumed were the same as
failures on the mater branch, but were actually as result of the
changes to check for valid url paths. The fix was causing a false
negative to be returned for valid repository URLs.
The only change in this patchset versus the previous (v3) version
is 2/3: Fix verification of remote ISO. 1/3 and 3/3 are the same
as version 3.
Christy Perez (3):
Fix Key Error when editing CD ROM path
Fix verification of remote ISO
Add unit tests for remote-backed CD ROM updates.
src/kimchi/model/vmstorages.py | 2 +-
src/kimchi/utils.py | 26 ++++++++++++++++++++++----
tests/test_model.py | 23 ++++++++++++++++++++++-
tests/utils.py | 20 +++++++++++++++++++-
4 files changed, 64 insertions(+), 7 deletions(-)
--
1.9.3
10 years, 4 months