Skip to content
This repository has been archived by the owner on Feb 20, 2018. It is now read-only.

Commit

Permalink
Delete vm via endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Stanislav Zubov authored and Stanislav Zubov committed Oct 29, 2015
1 parent 4fece14 commit 6d53e22
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 22 deletions.
5 changes: 1 addition & 4 deletions core/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from core.logger import log
from core.exceptions import SessionException

from vmpool.endpoint import delete_vm
from core.video import VNCVideoHelper

from flask import current_app
Expand Down Expand Up @@ -121,11 +120,9 @@ def delete(self, message=""):
self.save()

current_app.sessions.remove(self)
if hasattr(self, "endpoint"):
if hasattr(self, "endpoint") and self.endpoint:
log.info("Deleting VM for session: %s" % self.id)
self.endpoint.delete()
else:
delete_vm(self.endpoint_name)
log.info("Session %s deleted. %s" % (self.id, message))

def succeed(self):
Expand Down
76 changes: 75 additions & 1 deletion tests/unit/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from tests.unit.helpers import server_is_up, server_is_down, \
new_session_request, get_session_request, delete_session_request, \
vmmaster_label, run_script, request_with_drop, BaseTestCase, \
set_primary_key, DatabaseMock
set_primary_key, wait_for, DatabaseMock


from nose.twistedtools import reactor
Expand Down Expand Up @@ -473,6 +473,80 @@ def test_req_closed_when_request_append_to_queue(self):

self.assertEqual(0, self.pool.count())

def test_req_closed_when_platform_queued(self):
"""
- wait until platform is queued
- check queue state
- drop request while platform is queued
Expected: platform no more in queue
"""
import vmpool.virtual_machines_pool as vmp
with patch.object(vmp, 'pool', Mock()) as p:
p.has = Mock(return_value=False)
p.can_produce = Mock(return_value=True)

from vmpool.vmqueue import q

def wait_for_platform_in_queue():
wait_for(lambda: q, timeout=2)
self.assertEqual(len(q), 1)
self.assertEqual(
q[0].dc, self.desired_caps["desiredCapabilities"]
)

request_with_drop(
self.address, self.desired_caps, wait_for_platform_in_queue
)
wait_for(lambda: not q, timeout=2)
self.assertEqual(len(q), 0)

@patch.multiple(
"vmpool.clone.KVMClone",
clone_origin=Mock(),
define_clone=Mock(),
start_virtual_machine=Mock(),
drive_path=Mock()
)
def test_req_closed_when_vm_is_spawning(self):
"""
- waiting for clone spawning to begin
- drop request while vm is spawning
Expected: queue is empty, vm spawned and then deleted
"""

vm_mock = Mock()
vm_mock.delete = Mock()

def just_sleep(*args, **kwargs):
time.sleep(2)
return vm_mock

from vmpool.virtual_machines_pool import pool
with patch.object(
pool, 'has', Mock(return_value=False)
), patch.object(
pool, 'can_produce', Mock(return_value=True)
), patch(
'vmpool.platforms.KVMOrigin.make_clone',
Mock(side_effect=just_sleep)
) as make_clone:
from vmpool.vmqueue import q

def wait_for_vm_start_tp_spawn():
wait_for(lambda: make_clone.called, timeout=2)
self.assertTrue(make_clone.called)
self.assertEqual(len(q), 1)

request_with_drop(
self.address, self.desired_caps, wait_for_vm_start_tp_spawn
)

wait_for(lambda: not q, timeout=2)
self.assertEqual(len(q), 0)

wait_for(lambda: vm_mock.delete.called)
vm_mock.delete.assert_any_call()


class TestServerShutdown(BaseTestServer):
def setUp(self):
Expand Down
8 changes: 3 additions & 5 deletions vmpool/clone.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,12 @@ def __init__(self, origin, prefix):
def delete(self):
log.info("Deleting kvm clone: {}".format(self.name))
self.ready = False

utils.delete_file(self.drive_path)
utils.delete_file(self.dumpxml_file)
try:
domain = self.conn.lookupByName(self.name)
domain.destroy()
if domain.isActive():
domain.destroy()
domain.undefine()
except libvirtError:
# not running
Expand All @@ -112,7 +112,6 @@ def delete(self):
except ValueError, e:
log.warning(e)
pass

pool.remove_vm(self)
VirtualMachine.delete(self)

Expand Down Expand Up @@ -258,7 +257,6 @@ def get_ip(self):

@threaded_wait
def _wait_for_activated_service(self, method=None):
from time import sleep
config_create_check_retry_count, config_create_check_pause = \
config.VM_CREATE_CHECK_ATTEMPTS, config.VM_CREATE_CHECK_PAUSE
config_ping_retry_count, config_ping_timeout = \
Expand Down Expand Up @@ -286,7 +284,7 @@ def _wait_for_activated_service(self, method=None):
"check this VM" % (self.name, p))

create_check_retry += 1
sleep(config_create_check_pause)
time.sleep(config_create_check_pause)

elif self.vm_has_created():
if method is not None:
Expand Down
23 changes: 15 additions & 8 deletions vmpool/endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,38 @@ def new_vm(desired_caps):
platform = platform.encode('utf-8')

if not platform:
raise CreationException('Platform parameter for '
'new endpoint not found in dc')
raise CreationException(
'Platform parameter for new endpoint not found in dc'
)

if not Platforms.check_platform(platform):
raise PlatformException('No such platform %s' % platform)

delayed_vm = q.enqueue(desired_caps)
yield delayed_vm

for condition in generator_wait_for(
lambda: delayed_vm.vm, timeout=config.GET_VM_TIMEOUT):
lambda: delayed_vm.vm, timeout=config.GET_VM_TIMEOUT
):
yield delayed_vm

if not delayed_vm.vm:
raise CreationException("Сouldn't create vm with platform %s" % platform)
raise CreationException(
"Timeout while waiting for vm with platform %s" % platform
)

yield delayed_vm.vm

for condition in generator_wait_for(
lambda: delayed_vm.vm.ready, timeout=config.GET_VM_TIMEOUT):
lambda: delayed_vm.vm.ready, timeout=config.GET_VM_TIMEOUT
):
yield delayed_vm.vm

if not delayed_vm.vm.ready:
raise CreationException('Timeout while building vm %s '
'(platform: %s)' % (delayed_vm.vm.id, platform))
raise CreationException(
'Timeout while building vm %s (platform: %s)' %
(delayed_vm.vm.id, platform)
)

log.info('Got vm for request with params: %s' % delayed_vm.vm.info)
yield delayed_vm.vm
Expand All @@ -69,4 +77,3 @@ def delete_vm(endpoint_name):
else:
msg = "Vm %s not found in pool or vm is busy" % endpoint_name
log.info(msg)

12 changes: 8 additions & 4 deletions vmpool/virtual_machines_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ def count(cls):
@classmethod
def can_produce(cls, platform):
if cls.count() >= Platforms.can_produce(platform):
log.info('Can\'t produce new virtual machine with platform %s: '
'not enough Instances resources' % platform)
log.debug(
'Can\'t produce new virtual machine with platform %s: '
'not enough Instances resources' % platform
)
return False
else:
return True
Expand All @@ -77,9 +79,11 @@ def get_by_platform(cls, platform=None):
if platform:
for vm in sorted(cls.pool, key=lambda v: v.created,
reverse=True):
log.info("Got VM %s (ip=%s, ready=%s, checking="
"%s)" % (vm.name, vm.ip, vm.ready, vm.checking))
if vm.platform == platform and vm.ready and not vm.checking:
log.info(
"Got VM %s (ip=%s, ready=%s, checking=%s)" %
(vm.name, vm.ip, vm.ready, vm.checking)
)
if vm.ping_vm():
cls.pool.remove(vm)
cls.using.append(vm)
Expand Down
4 changes: 4 additions & 0 deletions vmpool/vmqueue.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ def run(self):
try:
self.queue.dequeue(delayed_vm)
except QueueItemNotFound:
log.info(
"VM %s (%s) is no longer required" %
(vm.name, vm.ip)
)
vm.delete()
else:
delayed_vm.vm = vm
Expand Down

0 comments on commit 6d53e22

Please sign in to comment.