Commit a586fa25 by Őry Máté

Merge branch 'issue-41' into 'master'

Create activity on console use

*    add concurrency_check arg to instance activity
*    test ^
*   create activity on console access fixes #41
parents bedb2e12 7f6baffa
...@@ -182,12 +182,14 @@ class VmDetailVncTokenView(CheckedDetailView): ...@@ -182,12 +182,14 @@ class VmDetailVncTokenView(CheckedDetailView):
if not self.object.has_level(request.user, 'operator'): if not self.object.has_level(request.user, 'operator'):
raise PermissionDenied() raise PermissionDenied()
if self.object.node: if self.object.node:
port = self.object.vnc_port with instance_activity(code_suffix='console-accessed',
host = str(self.object.node.host.ipv4) instance=self.object, user=request.user,
value = signing.dumps({'host': host, concurrency_check=False):
'port': port}, port = self.object.vnc_port
key=getenv("PROXY_SECRET", 'asdasd')), host = str(self.object.node.host.ipv4)
return HttpResponse('vnc/?d=%s' % value) value = signing.dumps({'host': host, 'port': port},
key=getenv("PROXY_SECRET", 'asdasd')),
return HttpResponse('vnc/?d=%s' % value)
else: else:
raise Http404() raise Http404()
......
...@@ -46,10 +46,11 @@ class InstanceActivity(ActivityModel): ...@@ -46,10 +46,11 @@ class InstanceActivity(ActivityModel):
return self.activity_code.split('.')[-1].replace('_', ' ').capitalize() return self.activity_code.split('.')[-1].replace('_', ' ').capitalize()
@classmethod @classmethod
def create(cls, code_suffix, instance, task_uuid=None, user=None): def create(cls, code_suffix, instance, task_uuid=None, user=None,
concurrency_check=True):
# Check for concurrent activities # Check for concurrent activities
active_activities = instance.activity_log.filter(finished__isnull=True) active_activities = instance.activity_log.filter(finished__isnull=True)
if active_activities.exists(): if concurrency_check and active_activities.exists():
raise ActivityInProgressError(active_activities[0]) raise ActivityInProgressError(active_activities[0])
act = cls(activity_code='vm.Instance.' + code_suffix, act = cls(activity_code='vm.Instance.' + code_suffix,
...@@ -58,10 +59,10 @@ class InstanceActivity(ActivityModel): ...@@ -58,10 +59,10 @@ class InstanceActivity(ActivityModel):
act.save() act.save()
return act return act
def create_sub(self, code_suffix, task_uuid=None): def create_sub(self, code_suffix, task_uuid=None, concurrency_check=True):
# Check for concurrent activities # Check for concurrent activities
active_children = self.children.filter(finished__isnull=True) active_children = self.children.filter(finished__isnull=True)
if active_children.exists(): if concurrency_check and active_children.exists():
raise ActivityInProgressError(active_children[0]) raise ActivityInProgressError(active_children[0])
act = InstanceActivity( act = InstanceActivity(
...@@ -73,10 +74,10 @@ class InstanceActivity(ActivityModel): ...@@ -73,10 +74,10 @@ class InstanceActivity(ActivityModel):
@contextmanager @contextmanager
def sub_activity(self, code_suffix, on_abort=None, on_commit=None, def sub_activity(self, code_suffix, on_abort=None, on_commit=None,
task_uuid=None): task_uuid=None, concurrency_check=True):
"""Create a transactional context for a nested instance activity. """Create a transactional context for a nested instance activity.
""" """
act = self.create_sub(code_suffix, task_uuid) act = self.create_sub(code_suffix, task_uuid, concurrency_check)
return activitycontextimpl(act, on_abort=on_abort, on_commit=on_commit) return activitycontextimpl(act, on_abort=on_abort, on_commit=on_commit)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
...@@ -87,10 +88,11 @@ class InstanceActivity(ActivityModel): ...@@ -87,10 +88,11 @@ class InstanceActivity(ActivityModel):
@contextmanager @contextmanager
def instance_activity(code_suffix, instance, on_abort=None, on_commit=None, def instance_activity(code_suffix, instance, on_abort=None, on_commit=None,
task_uuid=None, user=None): task_uuid=None, user=None, concurrency_check=True):
"""Create a transactional context for an instance activity. """Create a transactional context for an instance activity.
""" """
act = InstanceActivity.create(code_suffix, instance, task_uuid, user) act = InstanceActivity.create(code_suffix, instance, task_uuid, user,
concurrency_check)
return activitycontextimpl(act, on_abort=on_abort, on_commit=on_commit) return activitycontextimpl(act, on_abort=on_abort, on_commit=on_commit)
......
...@@ -4,7 +4,7 @@ from django.utils.translation import ugettext_lazy as _ ...@@ -4,7 +4,7 @@ from django.utils.translation import ugettext_lazy as _
from mock import Mock, MagicMock, patch from mock import Mock, MagicMock, patch
from ..models import ( from ..models import (
Lease, Node, Interface, Instance, InstanceTemplate, Lease, Node, Interface, Instance, InstanceTemplate, InstanceActivity,
) )
from ..models.instance import find_unused_port, ActivityInProgressError from ..models.instance import find_unused_port, ActivityInProgressError
...@@ -118,3 +118,50 @@ class NodeTestCase(TestCase): ...@@ -118,3 +118,50 @@ class NodeTestCase(TestCase):
node.STATES = Node.STATES node.STATES = Node.STATES
self.assertEqual(Node.get_state(node), "ONLINE") self.assertEqual(Node.get_state(node), "ONLINE")
assert isinstance(Node.get_status_display(node), _("").__class__) assert isinstance(Node.get_status_display(node), _("").__class__)
class InstanceActivityTestCase(TestCase):
def test_create_concurrency_check(self):
instance = MagicMock(spec=Instance)
instance.activity_log.filter.return_value.exists.return_value = True
with self.assertRaises(ActivityInProgressError):
InstanceActivity.create("test", instance, concurrency_check=True)
def test_create_no_concurrency_check(self):
instance = MagicMock(spec=Instance)
instance.activity_log.filter.return_value.exists.return_value = True
original_method = InstanceActivity.create.__func__
with patch('vm.models.activity.InstanceActivity') as ia, \
patch('vm.models.activity.timezone.now'):
# ia.__init__ = MagicMock() raises AttributeError
original_method(ia, "test", instance, concurrency_check=False)
ia.save.assert_called()
# ia.__init__.assert_called_with(activity_code='vm.Instance.test',
# instance=instance, parent=None,
# resultant_state=None, started=now,
# task_uuid=None, user=None)
def test_create_sub_concurrency_check(self):
iaobj = MagicMock(spec=InstanceActivity)
iaobj.children.filter.return_value.exists.return_value = True
with self.assertRaises(ActivityInProgressError):
InstanceActivity.create_sub(iaobj, "test", concurrency_check=True)
def test_create_sub_no_concurrency_check(self):
iaobj = MagicMock(spec=InstanceActivity)
iaobj.activity_code = 'test'
iaobj.children.filter.return_value.exists.return_value = True
original_method = InstanceActivity.create_sub
with patch('vm.models.activity.InstanceActivity') as ia, \
patch('vm.models.activity.timezone.now'):
original_method(iaobj, "test", concurrency_check=False)
ia.save.assert_called()
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