Commit a2911611 by Kálmán Viktor

occi: link storage to computes

parent 33c94c56
import re
from django.shortcuts import get_object_or_404
from django.contrib.auth.models import User
from django.template.loader import render_to_string
from django.utils import timezone
......@@ -43,6 +44,8 @@ occi_os_tpl_regex = re.compile(
'class="mixin"; ?location=".*"; ?title=".*"$'
)
occi_attribute_link_regex = '^/%s/(?P<id>\d+)/?'
class Category():
"""Represents a Category object
......@@ -395,7 +398,7 @@ class StorageLink(Link):
def init_attrs(self, instance, disk):
self.attrs = {}
self.attrs['occi.core.id'] = "%d_at_%d" % (disk.pk, instance.pk)
self.attrs['occi.core.id'] = "vm%d_disk%d" % (instance.pk, disk.pk)
self.attrs['occi.core.target'] = Storage(disk).render_location()
self.attrs['occi.core.source'] = Compute(instance).render_location()
# deviceid? mountpoint?
......@@ -404,10 +407,40 @@ class StorageLink(Link):
self.instance = instance
self.disk = disk
@classmethod
def create_object(cls, data):
attributes = {}
for d in data:
attr = occi_attribute_regex.match(d)
if attr:
attributes[attr.group("attribute")] = attr.group("value")
source = attributes.get("occi.core.source")
target = attributes.get("occi.core.target")
if not (source and target):
return None
# TODO user
user = User.objects.get(username="test")
g = re.match(occi_attribute_link_regex % "storage", target)
disk_pk = g.group("id")
g = re.match(occi_attribute_link_regex % "vm", source)
vm_pk = g.group("id")
disk = get_object_or_404(Disk, pk=disk_pk)
vm = get_object_or_404(Instance, pk=vm_pk)
vm.attach_disk(user=user, disk=disk)
cls.location = "%sstoragelink/%svm_%sdisk" % (OCCI_ADDR, vm_pk,
disk_pk)
return cls
def render_location(self):
return "/link/storagelink/%d_at_%d" % (self.disk.pk, self.instance.pk)
return "/link/storagelink/vm%d_disk%d" % (instance.pk, disk.pk)
def render_body(self):
def render_as_link(self):
kind = STORAGE_LINK_KIND
return render_to_string("occi/link.html", {
......@@ -417,6 +450,14 @@ class StorageLink(Link):
'attrs': self.attrs,
})
def render_as_category(self):
kind = STORAGE_LINK_KIND
return render_to_string("occi/storagelink.html", {
'kind': kind,
'attrs': self.attrs,
})
"""predefined stuffs
......
......@@ -9,5 +9,5 @@ Category: compute; scheme="{{ kind.scheme }}"; class="{{ kind.class }}";
{% endfor %}
{% for l in links %}
{{ l.render_body }}
{{ l.render_as_link }}
{% endfor %}
Category: compute; scheme="{{ kind.scheme }}"; class="{{ kind.class }}";
{% for k, v in attrs.items %}
X-OCCI-Attribute: {{ k }}={% if v.isdigit == False or k == "occi.core.id" %}"{{ v }}"{% else %}{{ v }}{% endif %}
{% endfor %}
......@@ -20,7 +20,7 @@ from django.conf.urls import url, patterns
from occi.views import (
QueryInterface, ComputeInterface, VmInterface, OsTplInterface,
StorageInterface, DiskInterface,
StorageInterface, DiskInterface, StorageLinkInterface
)
urlpatterns = patterns(
......@@ -31,4 +31,8 @@ urlpatterns = patterns(
url(r'^vm/(?P<pk>\d+)/$', VmInterface.as_view(), name="occi.vm"),
url(r'^storage/$', StorageInterface.as_view(), name="occi.storage"),
url(r'^disk/(?P<pk>\d+)/$', DiskInterface.as_view(), name="occi.disk"),
url(r'^link/storagelink/$', StorageLinkInterface.as_view()),
url(r'^link/storagelink/vm(?P<vm_pk>\d+)_disk(?P<disk_pk>\d+)/$',
StorageLinkInterface.as_view(), name="occi.storagelink"),
)
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import View, DetailView
......@@ -10,6 +11,7 @@ from .occi import (
Compute,
Storage,
OsTemplate,
StorageLink,
COMPUTE_KIND,
STORAGE_KIND,
LINK_KIND,
......@@ -184,3 +186,40 @@ class DiskInterface(DetailView):
@method_decorator(csrf_exempt)
def dispatch(self, *args, **kwargs):
return super(DiskInterface, self).dispatch(*args, **kwargs)
class StorageLinkInterface(View):
def get_vm_and_disk(self):
vm = get_object_or_404(Instance, pk=self.kwargs['vm_pk'])
disk = get_object_or_404(Disk, pk=self.kwargs['disk_pk'])
return vm, disk
def get(self, request, *args, **kwargs):
vm, disk = self.get_vm_and_disk()
sl = StorageLink(instance=vm, disk=disk)
return HttpResponse(
sl.render_as_category(),
content_type="text/plain",
)
def post(self, request, *args, **kwargs):
# we don't support actions for storagelinks
# (they don't even exist in the model)
if request.GET.get("action"):
return HttpResponse("", status=500)
else:
data = get_post_data_from_request(request)
sl = StorageLink.create_object(data=data)
response = HttpResponse(
"X-OCCI-Location: %s" % sl.location,
status=201,
content_type="text/plain",
)
return response
return HttpResponse()
@method_decorator(csrf_exempt)
def dispatch(self, *args, **kwargs):
return super(StorageLinkInterface, self).dispatch(*args, **kwargs)
......@@ -817,7 +817,7 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
return acts
def get_merged_activities(self, user=None):
whitelist = ("create_disk", "download_disk")
whitelist = ("create_disk", "download_disk", "attach_disk")
acts = self.get_activities(user)
merged_acts = []
latest = None
......
......@@ -1284,3 +1284,39 @@ class DetachNetwork(DetachMixin, AbstractNetworkOperation):
id = "_detach_network"
name = _("detach network")
task = vm_tasks.detach_network
@register_operation
class AttachDiskOperation(InstanceOperation):
id = 'attach_disk'
name = _("attach disk")
description = _("Attach an already created disk to the virtual machine.")
required_perms = ()
accept_states = ('STOPPED', 'PENDING', 'RUNNING')
def _operation(self, user, activity, disk):
devnums = list(ascii_lowercase)
for d in self.instance.disks.all():
devnums.remove(d.dev_num)
disk.dev_num = devnums.pop(0)
disk.save()
self.instance.disks.add(disk)
if self.instance.is_running:
with activity.sub_activity(
'deploying_disk',
readable_name=ugettext_noop("deploying disk")
):
disk.deploy()
self.instance._attach_disk(parent_activity=activity, disk=disk)
activity.result = create_readable(
ugettext_noop("%(name)s (#%(pk)s), dev num: %(dev_num)s"),
name=disk.name, pk=disk.pk, dev_num=disk.dev_num
)
def get_activity_name(self, kwargs):
return create_readable(
ugettext_noop("attach disk %(name)s"),
name=kwargs['disk'].name)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment