diff --git a/accounts/templatetags/tags_fingerprint.py b/accounts/templatetags/tags_fingerprint.py index d15c473..5688039 100644 --- a/accounts/templatetags/tags_fingerprint.py +++ b/accounts/templatetags/tags_fingerprint.py @@ -9,4 +9,4 @@ register = template.Library() def ssh_to_fingerprint(line): key = base64.b64decode(line.strip().split()[1].encode('ascii')) fp_plain = hashlib.md5(key).hexdigest() - return ':'.join(a+b for a, b in zip(fp_plain[::2], fp_plain[1::2])) + return ':'.join(a + b for a, b in zip(fp_plain[::2], fp_plain[1::2])) diff --git a/conf/requirements.txt b/conf/requirements.txt index 63f4677..e01113b 100644 --- a/conf/requirements.txt +++ b/conf/requirements.txt @@ -1,5 +1,6 @@ -Django==1.8.2 -websockify==0.7.0 +Django==1.8.11 +websockify==0.8.0 gunicorn==19.3.0 -libvirt-python==1.2.16 -http://github.com/retspen/retspen.github.io/raw/master/libxml2-python-2.9.1.tar.gz +libvirt-python==1.3.2 +#http://github.com/retspen/retspen.github.io/raw/master/libxml2-python-2.9.1.tar.gz +http://git.gnome.org/browse/libxml2/snapshot/libxml2-2.9.1.tar.gz#egg=libxml2-python&subdirectory=python diff --git a/console/templates/console-base.html b/console/templates/console-base.html new file mode 100644 index 0000000..d0e0e7a --- /dev/null +++ b/console/templates/console-base.html @@ -0,0 +1,127 @@ +{% load i18n %} + + + + + + + + + + +{% block head %}{% endblock %} + + + + + +
+{% block content %}{% endblock %} +
+ + + + + +{% block foot %}{% endblock %} + + diff --git a/console/templates/console-spice.html b/console/templates/console-spice.html index 4704ef3..1a1cbf8 100644 --- a/console/templates/console-spice.html +++ b/console/templates/console-spice.html @@ -1,333 +1,194 @@ +{% extends "console-base.html" %} {% load i18n %} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +{% load staticfiles %} +{% block head %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - -
-
-
+ } - - - + var password = '{{ console_passwd }}'; + log_info('Connecting ...'); + connect(uri,password); + +{% endblock %} diff --git a/console/templates/console-vnc.html b/console/templates/console-vnc.html index 59d0afa..b0a3334 100644 --- a/console/templates/console-vnc.html +++ b/console/templates/console-vnc.html @@ -1,48 +1,37 @@ +{% extends "console-base.html" %} {% load i18n %} - - - - - - - - -
-
- - - - - -
-
{% trans "Loading..." %}
-
-
- - - - - +{% load staticfiles %} +{% block head %} + - - -
-
-
+{% endblock %} + +{% block navbarmenu %} + +
  • {% trans "Show Keyboad" %}
  • +{% endblock %} + +{% block content %} +
    {% trans "Canvas not supported." %} -
    +
    + + + + + +{% endblock %} + +{% block foot %} - - +{% endblock %} diff --git a/create/forms.py b/create/forms.py index 5b9fab5..fccf944 100644 --- a/create/forms.py +++ b/create/forms.py @@ -40,6 +40,7 @@ class NewVMForm(forms.Form): storage = forms.CharField(max_length=20, required=False) template = forms.CharField(required=False) images = forms.CharField(required=False) + cache_mode = forms.CharField(error_messages={'required': _('Please select HDD cache mode')}) hdd_size = forms.IntegerField(required=False) meta_prealloc = forms.BooleanField(required=False) virtio = forms.BooleanField(required=False) diff --git a/create/templates/create_instance.html b/create/templates/create_instance.html index 37189b7..9df7326 100644 --- a/create/templates/create_instance.html +++ b/create/templates/create_instance.html @@ -77,6 +77,23 @@ +
    + +
    + +
    + +
    +
    + +
    + +
    +
    @@ -159,6 +176,16 @@
    +
    + +
    + +
    +
    @@ -258,6 +285,7 @@
    +
    -
    - -
    - -
    - -
    @@ -415,4 +436,4 @@ var editor = ace.edit("editor"); editor.getSession().setMode("ace/mode/xml"); -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/create/views.py b/create/views.py index 3f97606..6c223da 100644 --- a/create/views.py +++ b/create/views.py @@ -41,6 +41,7 @@ def create_instance(request, compute_id): networks = sorted(conn.get_networks()) instances = conn.get_instances() get_images = sorted(conn.get_storages_images()) + cache_modes = sorted(conn.get_cache_modes().items()) mac_auto = util.randomMAC() except libvirtError as lib_err: error_messages.append(lib_err) @@ -122,11 +123,15 @@ def create_instance(request, compute_id): volumes[path] = conn.get_volume_type(path) except libvirtError as lib_err: error_messages.append(lib_err.message) + if data['cache_mode'] not in conn.get_cache_modes(): + error_msg = _("Invalid cache mode") + error_messages.append(error_msg) if not error_messages: uuid = util.randomUUID() try: conn.create_instance(data['name'], data['memory'], data['vcpu'], data['host_model'], - uuid, volumes, data['networks'], data['virtio'], data['mac']) + uuid, volumes, data['cache_mode'], data['networks'], data['virtio'], + data['mac']) create_instance = Instance(compute_id=compute_id, name=data['name'], uuid=uuid) create_instance.save() return HttpResponseRedirect(reverse('instance', args=[compute_id, data['name']])) diff --git a/instances/views.py b/instances/views.py index 83c80e8..5fcce4a 100644 --- a/instances/views.py +++ b/instances/views.py @@ -103,7 +103,7 @@ def instances(request): conn.start(name) addlogmsg(request.user.username, instance.name, msg) return HttpResponseRedirect(request.get_full_path()) - + if 'getvvfile' in request.POST: msg = _("Send console.vv file") addlogmsg(request.user.username, instance.name, msg) diff --git a/vrtManager/create.py b/vrtManager/create.py index fc32177..473b9d2 100644 --- a/vrtManager/create.py +++ b/vrtManager/create.py @@ -7,9 +7,17 @@ from webvirtcloud.settings import QEMU_CONSOLE_DEFAULT_TYPE def get_rbd_storage_data(stg): xml = stg.XMLDesc(0) ceph_user = util.get_xml_path(xml, "/pool/source/auth/@username") - ceph_host = util.get_xml_path(xml, "/pool/source/host/@name") - secrt_uuid = util.get_xml_path(xml, "/pool/source/auth/secret/@uuid") - return ceph_user, secrt_uuid, ceph_host + + def get_ceph_hosts(ctx): + hosts = [] + for host in ctx.xpathEval("/pool/source/host"): + name = host.prop("name") + if name: + hosts.append({'name': name, 'port': host.prop("port")}) + return hosts + ceph_hosts = util.get_xml_path(xml, func=get_ceph_hosts) + secret_uuid = util.get_xml_path(xml, "/pool/source/auth/secret/@uuid") + return ceph_user, secret_uuid, ceph_hosts class wvmCreate(wvmConnect): @@ -40,6 +48,17 @@ class wvmCreate(wvmConnect): """Get guest capabilities""" return util.get_xml_path(self.get_cap_xml(), "/capabilities/host/cpu/arch") + def get_cache_modes(self): + """Get cache available modes""" + return { + 'default': 'Default', + 'none': 'Disabled', + 'writethrough': 'Write through', + 'writeback': 'Write back', + 'directsync': 'Direct sync', # since libvirt 0.9.5 + 'unsafe': 'Unsafe', # since libvirt 0.9.7 + } + def create_volume(self, storage, name, size, format='qcow2', metadata=False): size = int(size) * 1073741824 stg = self.get_storage(storage) @@ -121,7 +140,7 @@ class wvmCreate(wvmConnect): vol = self.get_volume_by_path(path) vol.delete() - def create_instance(self, name, memory, vcpu, host_model, uuid, images, networks, virtio, mac=None): + def create_instance(self, name, memory, vcpu, host_model, uuid, images, cache_mode, networks, virtio, mac=None): """ Create VM function """ @@ -162,19 +181,27 @@ class wvmCreate(wvmConnect): stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") if stg_type == 'rbd': - ceph_user, secrt_uuid, ceph_host = get_rbd_storage_data(stg) + ceph_user, secret_uuid, ceph_hosts = get_rbd_storage_data(stg) xml += """ - + - - - """ % (img_type, ceph_user, secrt_uuid, image, ceph_host) + """ % (img_type, cache_mode, ceph_user, secret_uuid, image) + if isinstance(ceph_hosts, list): + for host in ceph_hosts: + if host.get('port'): + xml += """ + """ % (host.get('name'), host.get('port')) + else: + xml += """ + """ % host.get('name') + xml += """ + """ else: xml += """ - - """ % (img_type, image) + + """ % (img_type, cache_mode, image) if virtio: xml += """""" % (disk_letters.pop(0),) diff --git a/vrtManager/instance.py b/vrtManager/instance.py index 08e0c39..e792e13 100644 --- a/vrtManager/instance.py +++ b/vrtManager/instance.py @@ -82,7 +82,7 @@ class wvmInstances(wvmConnect): dom = self.get_instance(name) xml = dom.XMLDesc(VIR_DOMAIN_XML_SECURE) self.wvm.defineXML(xml) - + def graphics_type(self, name): inst = self.get_instance(name) console_type = util.get_xml_path(inst.XMLDesc(0), "/domain/devices/graphics/@type")