Commit 5e2a3982 by Chif Gergő

update the instance create, add common acions, add template to instance

parent 2cd38e18
Pipeline #792 failed with stages
in 59 seconds
# Generated by Django 2.2.3 on 2019-07-22 12:16
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('instance', '0009_auto_20190715_1354'),
('instance', '0009_auto_20190715_0929'),
]
operations = [
]
# Generated by Django 2.2.3 on 2019-07-22 12:17
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('template', '0006_auto_20190719_1416'),
('instance', '0010_merge_20190722_1216'),
]
operations = [
migrations.AddField(
model_name='instance',
name='template',
field=models.ForeignKey(help_text='The base image of the vm', null=True, on_delete='DO_NOTHING', related_name='vm', to='template.ImageTemplate'),
),
]
...@@ -15,6 +15,17 @@ ACCESS_METHODS = tuple( ...@@ -15,6 +15,17 @@ ACCESS_METHODS = tuple(
[(key, val[0]) for key, val in settings.VM_ACCESS_PROTOCOLS.items()] [(key, val[0]) for key, val in settings.VM_ACCESS_PROTOCOLS.items()]
) )
interface = OSVirtualMachineManager(settings.CONNECTION)
ACTIONS = {
"start": interface.start_vm,
"stop": interface.stop_vm,
"suspend": interface.suspend_vm,
"wake_up": interface.wake_up_vm,
"reset": interface.reset_vm,
"reboot": interface.reboot_vm,
}
class Lease(models.Model): class Lease(models.Model):
""" Users can use the virtual machine until the lease dates. """ Users can use the virtual machine until the lease dates.
...@@ -44,7 +55,6 @@ class Flavor(models.Model): ...@@ -44,7 +55,6 @@ class Flavor(models.Model):
@classmethod @classmethod
def create(cls, name, description, ram=0, vcpu=0, def create(cls, name, description, ram=0, vcpu=0,
initial_disk=0, priority=0): initial_disk=0, priority=0):
interface = OSVirtualMachineManager(settings.CONNECTION)
try: try:
remote_flavor = interface.create_flavor(name, ram, vcpu, initial_disk) remote_flavor = interface.create_flavor(name, ram, vcpu, initial_disk)
...@@ -70,6 +80,7 @@ class Flavor(models.Model): ...@@ -70,6 +80,7 @@ class Flavor(models.Model):
class Instance(models.Model): class Instance(models.Model):
"""Virtual machine instance. """Virtual machine instance.
""" """
from template.models import ImageTemplate
name = models.CharField(max_length=100, name = models.CharField(max_length=100,
help_text="Human readable name of instance") help_text="Human readable name of instance")
...@@ -101,11 +112,9 @@ class Instance(models.Model): ...@@ -101,11 +112,9 @@ class Instance(models.Model):
default=False, default=False,
) )
# image = models.ForeignKey(TemplateImage, related_name="vm", null=True, template = models.ForeignKey(ImageTemplate, related_name="vm", null=True,
# help_text="The base image of the vm") help_text="The base image of the vm",
# on_delete="DO_NOTHING")
# snapshot = models.ForeignKey(Snapshot, related_name="vm", null=True,
# help_text="The base snapshot of the vm")
disks = models.ManyToManyField(Disk, related_name="instance", disks = models.ManyToManyField(Disk, related_name="instance",
help_text="Disks attached to instance", help_text="Disks attached to instance",
...@@ -119,9 +128,10 @@ class Instance(models.Model): ...@@ -119,9 +128,10 @@ class Instance(models.Model):
related_name='instances') related_name='instances')
@classmethod @classmethod
def create(cls, lease, owner, flavor, remote_id, params): def create(cls, lease, owner, flavor, template, remote_id, params):
params["password"] = cls.generate_password()
inst = cls(lease=lease, flavor=flavor, owner=owner, inst = cls(lease=lease, flavor=flavor, owner=owner,
remote_id=remote_id, **params) remote_id=remote_id, template=template, **params)
inst.full_clean() inst.full_clean()
inst.save() inst.save()
...@@ -132,15 +142,15 @@ class Instance(models.Model): ...@@ -132,15 +142,15 @@ class Instance(models.Model):
def create_instance_from_template(cls, params, template, owner, lease, def create_instance_from_template(cls, params, template, owner, lease,
disks, networks, flavor): disks, networks, flavor):
# TODO: attach disks when the remote instance created # TODO: attach disks when the remote instance created
interface = OSVirtualMachineManager(settings.CONNECTION)
try: try:
remote_inst = interface.create_vm_from_template(params["name"], remote_inst = interface.create_vm_from_template(params["name"],
template.remote_ID, template.image.remote_id,
flavor.remote_id, flavor.remote_id,
networks, networks,
) )
remote_id = remote_inst.id remote_id = remote_inst.id
new_inst = cls.create(lease, owner, flavor, remote_id, params) new_inst = cls.create(lease, owner, flavor, template,
remote_id, params)
return new_inst return new_inst
except Exception as e: except Exception as e:
logger.error(str(e)) logger.error(str(e))
...@@ -164,10 +174,24 @@ class Instance(models.Model): ...@@ -164,10 +174,24 @@ class Instance(models.Model):
) )
def delete(self): def delete(self):
interface = OSVirtualMachineManager(settings.CONNECTION)
try: try:
interface.destroy_vm(self.remote_id) interface.destroy_vm(self.remote_id)
super(Instance, self).delete() super(Instance, self).delete()
except Exception as e: except Exception as e:
if e.OpenStackError: if e.OpenStackError:
logger.error("Can not delete the instance in remote cloud") logger.error("Can not delete the instance in remote cloud")
def execute_common_action(self, action):
if ACTIONS[action]:
return ACTIONS[action](self.remote_id)
else:
raise ValueError("This action is not supported!")
def get_remote_instance(self):
return interface.get_vm(self.remote_id)
@classmethod
def generate_password(self):
return User.objects.make_random_password(
allowed_chars='abcdefghijklmnopqrstuvwx'
'ABCDEFGHIJKLMNOPQRSTUVWX123456789')
...@@ -8,7 +8,17 @@ class InstanceSerializer(serializers.ModelSerializer): ...@@ -8,7 +8,17 @@ class InstanceSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Instance model = Instance
fields = ("name", "description", "system", "lease", "flavor") fields = (
"name",
"description",
"system",
"lease",
"flavor",
"password",
"template",
"time_of_suspend",
"time_of_delete")
read_only_fields = ("password", "template", "time_of_suspend", "time_of_delete")
class FlavorSerializer(serializers.ModelSerializer): class FlavorSerializer(serializers.ModelSerializer):
......
...@@ -4,13 +4,16 @@ from django.conf import settings ...@@ -4,13 +4,16 @@ from django.conf import settings
from rest_framework.viewsets import ViewSet, ModelViewSet from rest_framework.viewsets import ViewSet, ModelViewSet
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import status from rest_framework import status
from rest_framework.decorators import action
from template.serializers import InstanceFromTemplateSerializer
from interface_openstack.implementation.vm.instance import ( from interface_openstack.implementation.vm.instance import (
OSVirtualMachineManager OSVirtualMachineManager
) )
from instance.models import Instance, Flavor, Lease from instance.models import Instance, Flavor, Lease
from instance.serializers import InstanceSerializer, FlavorSerializer from instance.serializers import InstanceSerializer, FlavorSerializer
from template.models import ImageTemplate from template.models import ImageTemplate
from template.serializers import ImageTemplateModelSerializer
class InstanceViewSet(ViewSet): class InstanceViewSet(ViewSet):
...@@ -28,8 +31,8 @@ class InstanceViewSet(ViewSet): ...@@ -28,8 +31,8 @@ class InstanceViewSet(ViewSet):
def create(self, request): def create(self, request):
data = request.data data = request.data
template = ImageTemplate.objects.get(pk=data["template"]) template = ImageTemplate.objects.get(pk=data["template"])
flavor = Flavor.objects.get(pk=data["flavor"]) # flavor = Flavor.objects.get(pk=data["flavor"])
lease = Lease.objects.get(pk=data["lease"]) # lease = Lease.objects.get(pk=data["lease"])
newInstance = Instance.create_instance_from_template( newInstance = Instance.create_instance_from_template(
params={"name": data["name"], params={"name": data["name"],
...@@ -37,21 +40,21 @@ class InstanceViewSet(ViewSet): ...@@ -37,21 +40,21 @@ class InstanceViewSet(ViewSet):
"access_method": data["access"], "access_method": data["access"],
"system": data["system"], "system": data["system"],
}, },
lease=lease, lease=template.lease,
networks=template.networks, networks=[{"uuid": "7485b41f-2524-4399-a20b-4b2c7ee9fd01"}],
template=template, template=template,
flavor=flavor, flavor=template.flavor,
owner=request.user, owner=request.user,
disks=template.disks disks=None
) )
return Response(newInstance.pk) return Response(newInstance.pk)
def retrieve(self, request): def retrieve(self, request, pk):
instance = self.get_object(pk) instance = self.get_object(pk)
instanceDict = InstanceSerializer(instance).data instanceDict = InstanceSerializer(instance).data
interface = OSVirtualMachineManager(settings.CONNECTION) print(instanceDict)
remoteInstance = interface.get_vm(instance.remote_id) remoteInstance = instance.get_remote_instance()
remoteInstanceDict = remoteInstance.__dict__ remoteInstanceDict = remoteInstance.__dict__
merged_dict = {**instanceDict, **remoteInstanceDict} merged_dict = {**instanceDict, **remoteInstanceDict}
...@@ -71,6 +74,26 @@ class InstanceViewSet(ViewSet): ...@@ -71,6 +74,26 @@ class InstanceViewSet(ViewSet):
instance.delete() instance.delete()
return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_204_NO_CONTENT)
@action(detail=True, methods=["post"])
def template(self, request, pk):
instance = self.get_object(pk)
serializer = InstanceFromTemplateSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
data = serializer.validated_data
new_template = ImageTemplate.create_from_instance(data["name"],
data["description"],
instance,
request.user)
serializer = ImageTemplateModelSerializer(instance=new_template)
return Response(serializer.data)
@action(detail=True, methods=["POST"])
def actions(self, request, pk):
instance = self.get_object(pk)
success = instance.execute_common_action(action=request.data["action"])
return Response(success)
class FlavorViewSet(ViewSet): class FlavorViewSet(ViewSet):
""" """
......
...@@ -2,10 +2,8 @@ from django.db import models ...@@ -2,10 +2,8 @@ from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.conf import settings from django.conf import settings
from image.models import Disk from image.models import Disk, Image
from image.models import Image from instance.models import Lease, Flavor
from instance.models import Lease
from instance.models import Flavor
from interface_openstack.implementation.storage.openstack_snapshot_manager import SnapshotManager from interface_openstack.implementation.storage.openstack_snapshot_manager import SnapshotManager
......
# from django.shortcuts import render # from django.shortcuts import render
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import action
from template.serializers import InstanceFromTemplateSerializer
from template.serializers import ImageTemplateModelSerializer from template.serializers import ImageTemplateModelSerializer
from template.models import ImageTemplate from template.models import ImageTemplate
...@@ -38,14 +35,3 @@ class ImageTemplateViewSet(ModelViewSet): ...@@ -38,14 +35,3 @@ class ImageTemplateViewSet(ModelViewSet):
request.data.pop(key, None) request.data.pop(key, None)
return super(ImageTemplateViewSet, self).update(request, partial=True) return super(ImageTemplateViewSet, self).update(request, partial=True)
@action(detail=True, methods=["post"])
def template(self, request, pk):
instance = self.get_object(pk)
serializer = InstanceFromTemplateSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
data = serializer.validated_data
new_template = ImageTemplate.create_from_instance(data["name"], data["description"],
instance, request.user)
serializer = ImageTemplateModelSerializer(instance=new_template)
return Response(serializer.data)
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