diff --git a/instances/templates/instance.html b/instances/templates/instance.html
index 5a43dcd..79cfe41 100644
--- a/instances/templates/instance.html
+++ b/instances/templates/instance.html
@@ -309,6 +309,11 @@
{% trans "Resize Instance" %}
+
@@ -390,6 +395,88 @@
{% endif %}
+
+ {% if request.user.is_superuser or userinstace.is_change %}
+
+ {% else %}
+ {% trans "You don't have permission for resizing instance" %}
+
+ {% endif %}
+
+
diff --git a/instances/views.py b/instances/views.py
index 8dd0a3f..d6d5c61 100644
--- a/instances/views.py
+++ b/instances/views.py
@@ -4,7 +4,7 @@ import json
import socket
import crypt
import re
-from string import letters, digits
+import string
from random import choice
from bisect import insort
from django.http import HttpResponse, HttpResponseRedirect
@@ -18,6 +18,7 @@ from accounts.models import UserInstance, UserSSHKey
from vrtManager.hostdetails import wvmHostDetails
from vrtManager.instance import wvmInstance, wvmInstances
from vrtManager.connection import connection_manager
+from vrtManager.create import wvmCreate
from vrtManager.util import randomPasswd
from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE
from webvirtcloud.settings import QEMU_KEYMAPS, QEMU_CONSOLE_TYPES
@@ -279,13 +280,25 @@ def instance(request, compute_id, vname):
msg += " (%s > %s)" % (disk_size, ua.max_disk_size)
return msg
+ def get_new_disk_dev(disks, bus):
+ if bus == "virtio":
+ dev_base = "vd"
+ else:
+ dev_base = "sd"
+ existing_devs = [ disk['dev'] for disk in disks ]
+ for l in string.lowercase:
+ dev = dev_base + l
+ if dev not in existing_devs:
+ return dev
+ raise Exception(_('None available device name'))
+
try:
conn = wvmInstance(compute.hostname,
compute.login,
compute.password,
compute.type,
vname)
-
+
status = conn.get_status()
autostart = conn.get_autostart()
vcpu = conn.get_vcpu()
@@ -318,6 +331,13 @@ def instance(request, compute_id, vname):
console_passwd = conn.get_console_passwd()
clone_free_names = get_clone_free_names()
user_quota_msg = check_user_quota(0, 0, 0, 0)
+ storages = sorted(conn.get_storages())
+ cache_modes = sorted(conn.get_cache_modes().items())
+ default_cache = settings.INSTANCE_VOLUME_DEFAULT_CACHE
+ default_format = settings.INSTANCE_VOLUME_DEFAULT_FORMAT
+ formats = conn.get_image_formats()
+ default_bus = settings.INSTANCE_VOLUME_DEFAULT_BUS
+ busses = conn.get_busses()
try:
instance = Instance.objects.get(compute_id=compute_id, name=vname)
@@ -457,6 +477,27 @@ def instance(request, compute_id, vname):
addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#resize')
+ if 'addvolume' in request.POST and (request.user.is_superuser or userinstace.is_change):
+ connCreate = wvmCreate(compute.hostname,
+ compute.login,
+ compute.password,
+ compute.type)
+ storage = request.POST.get('storage', '')
+ name = request.POST.get('name', '')
+ extension = request.POST.get('extension', '')
+ format = request.POST.get('format', '')
+ size = request.POST.get('size', 0)
+ meta_prealloc = request.POST.get('meta_prealloc', False)
+ bus = request.POST.get('bus', '')
+ cache = request.POST.get('cache', '')
+ target = get_new_disk_dev(disks, bus)
+
+ path = connCreate.create_volume(storage, name, size, format, meta_prealloc, extension)
+ conn.attach_disk(path, target, subdriver=format, cache=cache, targetbus=bus)
+ msg = _('Attach new disk')
+ addlogmsg(request.user.username, instance.name, msg)
+ return HttpResponseRedirect(request.get_full_path() + '#resize')
+
if 'umount_iso' in request.POST:
image = request.POST.get('path', '')
dev = request.POST.get('umount_iso', '')
diff --git a/vrtManager/connection.py b/vrtManager/connection.py
index c62c6e4..b9c6a26 100644
--- a/vrtManager/connection.py
+++ b/vrtManager/connection.py
@@ -380,6 +380,25 @@ class wvmConnect(object):
interface.append(inface)
return interface
+ 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 get_busses(self):
+ """Get available busses"""
+ return [ 'ide', 'scsi', 'usb', 'virtio' ]
+
+ def get_image_formats(self):
+ """Get available image formats"""
+ return [ 'raw', 'qcow', 'qcow2' ]
+
def get_iface(self, name):
return self.wvm.interfaceLookupByName(name)
diff --git a/vrtManager/create.py b/vrtManager/create.py
index 15f1cd8..9fc8d98 100644
--- a/vrtManager/create.py
+++ b/vrtManager/create.py
@@ -48,23 +48,12 @@ 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):
+ def create_volume(self, storage, name, size, format='qcow2', metadata=False, image_extension='img'):
size = int(size) * 1073741824
stg = self.get_storage(storage)
storage_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type")
if storage_type == 'dir':
- name += '.img'
+ name += '.' + image_extension
alloc = 0
else:
alloc = size
diff --git a/vrtManager/instance.py b/vrtManager/instance.py
index 0777b35..14feab1 100644
--- a/vrtManager/instance.py
+++ b/vrtManager/instance.py
@@ -340,6 +340,22 @@ class wvmInstance(wvmConnect):
xmldom = ElementTree.tostring(tree)
self._defineXML(xmldom)
+ def attach_disk(self, source, target, sourcetype='file', type='disk', driver='qemu', subdriver='raw', cache='none', targetbus='ide'):
+ tree = ElementTree.fromstring(self._XMLDesc(0))
+ xml_disk = """
+