[PATCH] Addition of custom mac address field for interfaces v3
by bbaude@redhat.com
From: Brent Baude <bbaude(a)redhat.com>
Fixed json issue and included comments from pvital
---
docs/API.md | 1 +
src/kimchi/API.json | 6 ++++++
src/kimchi/control/vms.py | 2 +-
src/kimchi/exception.py | 1 -
src/kimchi/i18n.py | 4 ++++
src/kimchi/model/vmifaces.py | 38 +++++++++++++++++++++++++++++--------
tests/test_model.py | 12 ++++++++++++
ui/css/theme-default/guest-edit.css | 4 ++--
ui/js/src/kimchi.guest_edit_main.js | 18 ++++++++++++------
ui/pages/guest-edit.html.tmpl | 11 ++++++++---
10 files changed, 76 insertions(+), 21 deletions(-)
diff --git a/docs/API.md b/docs/API.md
index b679ce7..4f92eaa 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -221,6 +221,7 @@ Represents all network interfaces attached to a Virtual Machine.
interface type is network.
* type: The type of VM network interface that libvirt supports.
Now kimchi just supports 'network' type.
+ * custommac: A custom MAC address for the interface
### Sub-Resource: Virtual Machine Network Interface
diff --git a/src/kimchi/API.json b/src/kimchi/API.json
index b8604d2..e46aedc 100644
--- a/src/kimchi/API.json
+++ b/src/kimchi/API.json
@@ -334,6 +334,12 @@
"type": "string",
"pattern": "^ne2k_pci|i82551|i82557b|i82559er|rtl8139|e1000|pcnet|virtio$",
"error": "KCHVMIF0006E"
+ },
+ "custommac": {
+ "description": "optional custom mac address for the network interface",
+ "type": "string",
+ "pattern": "^(?i)([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$",
+ "error": "KCHVMIF0009E"
}
}
},
diff --git a/src/kimchi/control/vms.py b/src/kimchi/control/vms.py
index 88d8a81..627f1cc 100644
--- a/src/kimchi/control/vms.py
+++ b/src/kimchi/control/vms.py
@@ -36,7 +36,7 @@ class VM(Resource):
super(VM, self).__init__(model, ident)
self.role_key = 'guests'
self.update_params = ["name", "users", "groups", "cpus", "memory",
- "graphics"]
+ "graphics", "custommac"]
self.screenshot = VMScreenShot(model, ident)
self.uri_fmt = '/vms/%s'
for ident, node in sub_nodes.items():
diff --git a/src/kimchi/exception.py b/src/kimchi/exception.py
index 039152a..7ab1878 100644
--- a/src/kimchi/exception.py
+++ b/src/kimchi/exception.py
@@ -46,7 +46,6 @@ class KimchiException(Exception):
msg = self._get_translation()
else:
msg = _messages.get(code, code)
-
msg = unicode(msg, 'utf-8') % args
pattern = "%s: %s" % (code, msg)
Exception.__init__(self, pattern)
diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
index 9e66c68..8690657 100644
--- a/src/kimchi/i18n.py
+++ b/src/kimchi/i18n.py
@@ -105,6 +105,10 @@ messages = {
"KCHVMIF0006E": _("Invalid network model card specified for virtual machine interface"),
"KCHVMIF0007E": _("Specify type and network to add a new virtual machine interface"),
"KCHVMIF0008E": _("Specify type and network to update a virtual machine interface"),
+ "KCHVMIF0009E": _("Invalid MAC address format. Expected a 12 character hexadecimal value separated by colons(:)"),
+ "KCHVMIF0010E": _("The custom MAC address %(value) is already in use on this guest"),
+ "KCHVMIF0011E": _("Libvirt requires a unicast MAC address which %(value) is not."),
+
"KCHTMPL0001E": _("Template %(name)s already exists"),
"KCHTMPL0002E": _("Template %(name)s does not exist"),
diff --git a/src/kimchi/model/vmifaces.py b/src/kimchi/model/vmifaces.py
index 66b3827..ef67d34 100644
--- a/src/kimchi/model/vmifaces.py
+++ b/src/kimchi/model/vmifaces.py
@@ -18,6 +18,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import random
+import re
import libvirt
from lxml import etree, objectify
@@ -45,6 +46,20 @@ class VMIfacesModel(object):
random.randint(0x00, 0xff)]
return ':'.join(map(lambda x: "%02x" % x, mac))
+ def checkduplicatemacs(vm, custommac):
+ macs = self.get_list(vm)
+ if custommac in macs:
+ raise InvalidParameter("KCHVMIF0010E", {'custommac': mac})
+
+ def validMac(mymac):
+ pattern = r'^(?i)([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$'
+ if bool(re.match(pattern, mac)) is not True:
+ raise InvalidParameter("KCHVMIF0009E", {'custommac': mac})
+ else:
+ # Checking for multicast
+ if (int(mymac.split(":")[0], 16) & 0x1) == 1:
+ raise InvalidParameter("KCHVMIF0011E", {'custommac': mac})
+
conn = self.conn.get()
networks = conn.listNetworks() + conn.listDefinedNetworks()
@@ -56,14 +71,22 @@ class VMIfacesModel(object):
if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
raise InvalidOperation("KCHVMIF0003E")
- macs = (iface.mac.get('address')
- for iface in self.get_vmifaces(vm, self.conn))
-
- mac = randomMAC()
- while True:
- if mac not in macs:
- break
+ if 'custommac' not in params:
+ macs = (iface.mac.get('address')
+ for iface in self.get_vmifaces(vm, self.conn))
mac = randomMAC()
+ while True:
+ if mac not in macs:
+ break
+ mac = randomMAC()
+
+ else:
+ if len(params['custommac']) == 0:
+ mac = randomMAC()
+ else:
+ mac = params["custommac"]
+ validMac(mac)
+ checkduplicatemacs(vm, mac)
children = [E.mac(address=mac)]
("network" in params.keys() and
@@ -75,7 +98,6 @@ class VMIfacesModel(object):
xml = etree.tostring(E.interface(*children, **attrib))
dom.attachDeviceFlags(xml, libvirt.VIR_DOMAIN_AFFECT_CURRENT)
-
return mac
@staticmethod
diff --git a/tests/test_model.py b/tests/test_model.py
index ceedc6f..59c3e50 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -219,6 +219,18 @@ class ModelTests(unittest.TestCase):
self.assertEquals("default", iface['network'])
self.assertEquals("e1000", iface["model"])
+ # custom MAC address test
+ iface_args = {"type": "network",
+ "network": "test-network",
+ "model": "virtio",
+ "custommac": "52:54:00:17:cd:e7"}
+ mac = inst.vmifaces_create('kimchi-ifaces', iface_args)
+ iface = inst.vmiface_lookup('kimchi-ifaces', mac)
+ self.assertEquals("52:54:00:17:cd:e7", iface['mac'])
+ self.assertRaises(InvalidParameter, inst.vmifaces_create,
+ 'kimchi-ifaces', iface_args)
+ rollback.prependDefer(inst.vmiface_delete, 'kimchi-ifaces', mac)
+
@unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
def test_vm_disk(self):
disk_path = '/tmp/existent2.iso'
diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css
index 74c2237..f0e1bb0 100644
--- a/ui/css/theme-default/guest-edit.css
+++ b/ui/css/theme-default/guest-edit.css
@@ -112,7 +112,7 @@
#form-guest-edit-storage .cell,
.guest-edit-interface .cell {
display: inline-block;
- width: 250px;
+ width: 150px;
}
#form-guest-edit-storage .cell.dev {
@@ -130,7 +130,7 @@
}
.guest-edit-interface .body select {
- width: 180px;
+ width: 150px;
padding: 0px;
}
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js
index c281289..7baf296 100644
--- a/ui/js/src/kimchi.guest_edit_main.js
+++ b/ui/js/src/kimchi.guest_edit_main.js
@@ -176,7 +176,10 @@ kimchi.guest_edit_main = function() {
var toggleEdit = function(item, on){
$("label", item).toggleClass("hide", on);
$("select", item).toggleClass("hide", !on);
- $(".action-area", item).toggleClass("hide");
+ $("input", item).toggleClass("hide", !on);
+ $(".action-area#editmode", item).toggleClass("hide", !on);
+ $(".action-area#viewmode", item).toggleClass("hide", on);
+
};
var addItem = function(data) {
var itemNode = $.parseHTML(kimchi.substitute($('#interface-tmpl').html(),data));
@@ -215,20 +218,23 @@ kimchi.guest_edit_main = function() {
var item = $(this).parent().parent();
var interface = {
network: $("select", item).val(),
- type: "network"
+ type: "network",
+ custommac: $("input",item).val().toLowerCase()
};
- var postUpdate = function(){
+ var postUpdate = function(mymac){
$("label", item).text(interface.network);
- toggleEdit(item, false);
+ $("label#custommac", item).text(mymac);
+ toggleEdit(item.prop, false);
};
if(item.prop("id")==""){
kimchi.createGuestInterface(kimchi.selectedGuest, interface, function(data){
item.prop("id", data.mac);
- postUpdate();
+ $("label#custommac", item).text(data.mac)
+ postUpdate(data.mac);
});
}else{
kimchi.updateGuestInterface(kimchi.selectedGuest, item.prop("id"), interface, function(){
- postUpdate();
+ postUpdate(data.mac);
});
}
});
diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl
index 0b7dad3..0aa9f3b 100644
--- a/ui/pages/guest-edit.html.tmpl
+++ b/ui/pages/guest-edit.html.tmpl
@@ -108,7 +108,8 @@
<div class="header">
<span class="cell">$_("Network")</span>
<span class="cell">$_("Type")</span>
- <button class="add action-area"></button>
+ <span class="cell">$_("MAC")</span>
+ <button id="interfaceadd" class="add action-area"></button>
</div>
<div class="body"></div>
</form>
@@ -192,10 +193,14 @@
<span class="cell">
<span>{type}</span>
</span>
- <span class="action-area {editMode}">
+ <span class="cell">
+ <label class="{viewMode}" id="custommac">{mac}</label>
+ <input type="text" id="insertmac" class="{editMode}"/>
+ </span>
+ <span class="action-area {editMode}" id="editmode">
<button class="save"></button><button class="cancel"></button>
</span>
- <span class="action-area {viewMode}">
+ <span class="action-area {viewMode}" id="viewmode">
<button class="edit"></button><button class="delete"></button>
</span>
<div>
--
1.9.3
10 years, 3 months
[PATCH] Addition of custom mac address field for interfaces v3
by bbaude@redhat.com
From: Brent Baude <bbaude(a)redhat.com>
Add tests and regex to json per peer review. Also changed the error type
to InvalidParameter
---
docs/API.md | 1 +
src/kimchi/API.json | 6 ++++++
src/kimchi/control/vms.py | 2 +-
src/kimchi/exception.py | 3 ++-
src/kimchi/i18n.py | 4 ++++
src/kimchi/model/vmifaces.py | 38 +++++++++++++++++++++++++++++--------
tests/test_model.py | 12 ++++++++++++
ui/css/theme-default/guest-edit.css | 4 ++--
ui/js/src/kimchi.guest_edit_main.js | 18 ++++++++++++------
ui/pages/guest-edit.html.tmpl | 11 ++++++++---
10 files changed, 78 insertions(+), 21 deletions(-)
diff --git a/docs/API.md b/docs/API.md
index b679ce7..4f92eaa 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -221,6 +221,7 @@ Represents all network interfaces attached to a Virtual Machine.
interface type is network.
* type: The type of VM network interface that libvirt supports.
Now kimchi just supports 'network' type.
+ * custommac: A custom MAC address for the interface
### Sub-Resource: Virtual Machine Network Interface
diff --git a/src/kimchi/API.json b/src/kimchi/API.json
index b8604d2..e46aedc 100644
--- a/src/kimchi/API.json
+++ b/src/kimchi/API.json
@@ -334,6 +334,12 @@
"type": "string",
"pattern": "^ne2k_pci|i82551|i82557b|i82559er|rtl8139|e1000|pcnet|virtio$",
"error": "KCHVMIF0006E"
+ },
+ "custommac": {
+ "description": "optional custom mac address for the network interface",
+ "type": "string",
+ "pattern": "^(?i)([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$",
+ "error": "KCHVMIF0009E"
}
}
},
diff --git a/src/kimchi/control/vms.py b/src/kimchi/control/vms.py
index 88d8a81..627f1cc 100644
--- a/src/kimchi/control/vms.py
+++ b/src/kimchi/control/vms.py
@@ -36,7 +36,7 @@ class VM(Resource):
super(VM, self).__init__(model, ident)
self.role_key = 'guests'
self.update_params = ["name", "users", "groups", "cpus", "memory",
- "graphics"]
+ "graphics", "custommac"]
self.screenshot = VMScreenShot(model, ident)
self.uri_fmt = '/vms/%s'
for ident, node in sub_nodes.items():
diff --git a/src/kimchi/exception.py b/src/kimchi/exception.py
index 039152a..ebe03ae 100644
--- a/src/kimchi/exception.py
+++ b/src/kimchi/exception.py
@@ -46,7 +46,8 @@ class KimchiException(Exception):
msg = self._get_translation()
else:
msg = _messages.get(code, code)
-
+ print msg
+ print args
msg = unicode(msg, 'utf-8') % args
pattern = "%s: %s" % (code, msg)
Exception.__init__(self, pattern)
diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
index 9e66c68..86f4e50 100644
--- a/src/kimchi/i18n.py
+++ b/src/kimchi/i18n.py
@@ -105,6 +105,10 @@ messages = {
"KCHVMIF0006E": _("Invalid network model card specified for virtual machine interface"),
"KCHVMIF0007E": _("Specify type and network to add a new virtual machine interface"),
"KCHVMIF0008E": _("Specify type and network to update a virtual machine interface"),
+ "KCHVMIF0009E": _("The custom MAC address is not properly formatted as 12 character hexadecimal value separated by colons(:)"),
+ "KCHVMIF0010E": _("The custom MAC address is already in use on this guest"),
+ "KCHVMIF0011E": _("Libvirt requires you use a unicast MAC address."),
+
"KCHTMPL0001E": _("Template %(name)s already exists"),
"KCHTMPL0002E": _("Template %(name)s does not exist"),
diff --git a/src/kimchi/model/vmifaces.py b/src/kimchi/model/vmifaces.py
index 66b3827..ef67d34 100644
--- a/src/kimchi/model/vmifaces.py
+++ b/src/kimchi/model/vmifaces.py
@@ -18,6 +18,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import random
+import re
import libvirt
from lxml import etree, objectify
@@ -45,6 +46,20 @@ class VMIfacesModel(object):
random.randint(0x00, 0xff)]
return ':'.join(map(lambda x: "%02x" % x, mac))
+ def checkduplicatemacs(vm, custommac):
+ macs = self.get_list(vm)
+ if custommac in macs:
+ raise InvalidParameter("KCHVMIF0010E", {'custommac': mac})
+
+ def validMac(mymac):
+ pattern = r'^(?i)([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$'
+ if bool(re.match(pattern, mac)) is not True:
+ raise InvalidParameter("KCHVMIF0009E", {'custommac': mac})
+ else:
+ # Checking for multicast
+ if (int(mymac.split(":")[0], 16) & 0x1) == 1:
+ raise InvalidParameter("KCHVMIF0011E", {'custommac': mac})
+
conn = self.conn.get()
networks = conn.listNetworks() + conn.listDefinedNetworks()
@@ -56,14 +71,22 @@ class VMIfacesModel(object):
if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
raise InvalidOperation("KCHVMIF0003E")
- macs = (iface.mac.get('address')
- for iface in self.get_vmifaces(vm, self.conn))
-
- mac = randomMAC()
- while True:
- if mac not in macs:
- break
+ if 'custommac' not in params:
+ macs = (iface.mac.get('address')
+ for iface in self.get_vmifaces(vm, self.conn))
mac = randomMAC()
+ while True:
+ if mac not in macs:
+ break
+ mac = randomMAC()
+
+ else:
+ if len(params['custommac']) == 0:
+ mac = randomMAC()
+ else:
+ mac = params["custommac"]
+ validMac(mac)
+ checkduplicatemacs(vm, mac)
children = [E.mac(address=mac)]
("network" in params.keys() and
@@ -75,7 +98,6 @@ class VMIfacesModel(object):
xml = etree.tostring(E.interface(*children, **attrib))
dom.attachDeviceFlags(xml, libvirt.VIR_DOMAIN_AFFECT_CURRENT)
-
return mac
@staticmethod
diff --git a/tests/test_model.py b/tests/test_model.py
index ceedc6f..59c3e50 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -219,6 +219,18 @@ class ModelTests(unittest.TestCase):
self.assertEquals("default", iface['network'])
self.assertEquals("e1000", iface["model"])
+ # custom MAC address test
+ iface_args = {"type": "network",
+ "network": "test-network",
+ "model": "virtio",
+ "custommac": "52:54:00:17:cd:e7"}
+ mac = inst.vmifaces_create('kimchi-ifaces', iface_args)
+ iface = inst.vmiface_lookup('kimchi-ifaces', mac)
+ self.assertEquals("52:54:00:17:cd:e7", iface['mac'])
+ self.assertRaises(InvalidParameter, inst.vmifaces_create,
+ 'kimchi-ifaces', iface_args)
+ rollback.prependDefer(inst.vmiface_delete, 'kimchi-ifaces', mac)
+
@unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
def test_vm_disk(self):
disk_path = '/tmp/existent2.iso'
diff --git a/ui/css/theme-default/guest-edit.css b/ui/css/theme-default/guest-edit.css
index 74c2237..f0e1bb0 100644
--- a/ui/css/theme-default/guest-edit.css
+++ b/ui/css/theme-default/guest-edit.css
@@ -112,7 +112,7 @@
#form-guest-edit-storage .cell,
.guest-edit-interface .cell {
display: inline-block;
- width: 250px;
+ width: 150px;
}
#form-guest-edit-storage .cell.dev {
@@ -130,7 +130,7 @@
}
.guest-edit-interface .body select {
- width: 180px;
+ width: 150px;
padding: 0px;
}
diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js
index c281289..7baf296 100644
--- a/ui/js/src/kimchi.guest_edit_main.js
+++ b/ui/js/src/kimchi.guest_edit_main.js
@@ -176,7 +176,10 @@ kimchi.guest_edit_main = function() {
var toggleEdit = function(item, on){
$("label", item).toggleClass("hide", on);
$("select", item).toggleClass("hide", !on);
- $(".action-area", item).toggleClass("hide");
+ $("input", item).toggleClass("hide", !on);
+ $(".action-area#editmode", item).toggleClass("hide", !on);
+ $(".action-area#viewmode", item).toggleClass("hide", on);
+
};
var addItem = function(data) {
var itemNode = $.parseHTML(kimchi.substitute($('#interface-tmpl').html(),data));
@@ -215,20 +218,23 @@ kimchi.guest_edit_main = function() {
var item = $(this).parent().parent();
var interface = {
network: $("select", item).val(),
- type: "network"
+ type: "network",
+ custommac: $("input",item).val().toLowerCase()
};
- var postUpdate = function(){
+ var postUpdate = function(mymac){
$("label", item).text(interface.network);
- toggleEdit(item, false);
+ $("label#custommac", item).text(mymac);
+ toggleEdit(item.prop, false);
};
if(item.prop("id")==""){
kimchi.createGuestInterface(kimchi.selectedGuest, interface, function(data){
item.prop("id", data.mac);
- postUpdate();
+ $("label#custommac", item).text(data.mac)
+ postUpdate(data.mac);
});
}else{
kimchi.updateGuestInterface(kimchi.selectedGuest, item.prop("id"), interface, function(){
- postUpdate();
+ postUpdate(data.mac);
});
}
});
diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl
index 0b7dad3..0aa9f3b 100644
--- a/ui/pages/guest-edit.html.tmpl
+++ b/ui/pages/guest-edit.html.tmpl
@@ -108,7 +108,8 @@
<div class="header">
<span class="cell">$_("Network")</span>
<span class="cell">$_("Type")</span>
- <button class="add action-area"></button>
+ <span class="cell">$_("MAC")</span>
+ <button id="interfaceadd" class="add action-area"></button>
</div>
<div class="body"></div>
</form>
@@ -192,10 +193,14 @@
<span class="cell">
<span>{type}</span>
</span>
- <span class="action-area {editMode}">
+ <span class="cell">
+ <label class="{viewMode}" id="custommac">{mac}</label>
+ <input type="text" id="insertmac" class="{editMode}"/>
+ </span>
+ <span class="action-area {editMode}" id="editmode">
<button class="save"></button><button class="cancel"></button>
</span>
- <span class="action-area {viewMode}">
+ <span class="action-area {viewMode}" id="viewmode">
<button class="edit"></button><button class="delete"></button>
</span>
<div>
--
1.9.3
10 years, 3 months
Proposals for next release
by Aline Manera
Hi all,
I'd like to share with you what I have in mind for the next release.
Most of the items listed below have already come up on ML before.
*A) Upload file to storage pool*
In the current code, the upload function is disabled as it does not
work well with files larger than 500MB.
When trying to upload a file with 500MB the browser stops responding
and after some time it crashes.
From a quick investigation, I identified it happens prior to send
the data to server:
var uploadFile = function() {
var blobFile = $(localFileBox)[0].files[0];
var fileName = blobFile.name;
var fd = new FormData();
fd.append('name', fileName);
*fd.append('file', blobFile)*
....
}
We need check if there is a way to solve it on UI by changing the
data structure or how it is loaded or think about a solution involving
backend.
*B) Reduce imported code*
Kimchi imports some code: python-websockets, novnc, spice and jquery
libs
Some of them (to don't say most of them) are already packaged in
some Linux distributions (Fedora, Ubuntu, etc)
We should check the availability of those packages in the all
supported distros and when possible remove the imported code from git
repository and add it as a dependency.
*It is a requirement**to have Kimchi on Fedora.*
*C) MockModel refactor*
The mockmodel was designed to provide a way to user tests Kimchi
without affecting the system (by "kimchid --test") and also to make the
tests easier to do.
But in fact, we have a bunch of code that completely differs from
the real model, so the developer needs to do 2 kinds of implementations
while developing a new feature.
My proposal is simplify that by using Model() with "test:///default"
URI.
This configuration does not affect the system in real and also can
provide us a way to test the new feature in a closer scenario to the
real one: by connecting to libvirt and doing the operations.
As you may know "test:///default" driver has some limitations that
prevents some operations, for example, screenshots.
To solve it we could only override what is not supported by this
driver and create a simpler mockmodel.
Example:
class MockModel(Model):
super(Model, self).__init__("test:///default")
def vmscreenshot_lookup():
# do some mock code
I think in this way we will have a significant reduction in our
mockmodel code.
*D) VM Template refactor*
More and more the user will be able to change the VM configuration
and it implies in generating a XML code related to the new item to be
attached to the VM.
But it is also done in the Template level. Because that we have a
lot of duplicated code related to the XML generation on VM and Template.
Some of them using etree.builder and others using pure strings.
My idea is to create a xml python module to hold all the XML
manipulation about to element type.
Example:
src/kimchi/xml/iface.py
src/kimchi/xml/disk.py
src/kimchi/xml/graphics.py
src/kimchi/xml/domain.py
Each of these files will be responsible to handle the XML
generation and manipulation using *etree*.
Then when needed, while changing VM configuration or Template, we
use the same code from our xml module.
*E) Allow user adds volumes from different pools to a Template*
*(depends on D)*
Today the user can only use one disk in a Template.
We should provide a way to user select multiple volumes from
different storage pools in a Template.
The user should be able to specific a pool and a disk size to Kimchi
automatically creates a volume according to those inputs.
So user can specify a pool and a volume OR a pool and a disk size.
From UI perspective, we will need a bigger refactor on it. Maybe
displaying the Template information in tabs (the same way we did when
editing a VM)
*F) Guest disk hot plug* *(depends on D)*
Allow attaching a disk to a running guest.
*G) PCI passthrough*
*H) SMT support*
Kimchi should enable SMT on guests when it improves performance
according to host architecture and choose the best configuration to user
(SMT8, 4 or 2)
This kind of information must not be prompted to user as it is only
for expert users and can block entry level users (our main focus)
So our algorithm must be good enough to do the right choice
according to host and guest configuration.
*I) Snapshot support*
Allow users create, revert and delete a snapshot.
*J) Guest cloning*
*K) LDAP authentication support*
We need to think also how to enable authorization on a LDAP
authentication.
In my first view, I think we need to provide a way to sysadmin lists
the IDs to have admin role in the Kimchi config file.
What about the groups? Should we use LDAP domains instead of groups?
And we also need to change UI when setting users and groups, as
there is no way to list all users in a LDAP server.
On Kimchi configuration file we can have an authentication section
like below:
[authentication]
method = pam | ldap
ldap_server =
ldap_search =
ldap_domain =
ldap_admin_users =
*L) Allow user changes graphics type on guest*
User should be able to change from VNC to Spice on a existing guest
*M) Add support for serial console*
*N) Live migration*
Start some investigation on how to do that
----
Yeap! A lot of cool features and just a piece of our backlog... ;-)
That is a brainstorm. So please, your comments/suggestions are more than
welcome!
Thanks,
Aline Manera
10 years, 3 months