diff --git a/conf/springConfigXml/ConsoleManager.xml b/conf/springConfigXml/ConsoleManager.xml index fb023470cb2..08075821b2e 100755 --- a/conf/springConfigXml/ConsoleManager.xml +++ b/conf/springConfigXml/ConsoleManager.xml @@ -21,6 +21,7 @@ + diff --git a/console/src/main/java/org/zstack/console/ConsoleManagerImpl.java b/console/src/main/java/org/zstack/console/ConsoleManagerImpl.java index ce65fc78a39..67057da171d 100755 --- a/console/src/main/java/org/zstack/console/ConsoleManagerImpl.java +++ b/console/src/main/java/org/zstack/console/ConsoleManagerImpl.java @@ -43,7 +43,7 @@ * To change this template use File | Settings | File Templates. */ public class ConsoleManagerImpl extends AbstractService implements ConsoleManager, VmInstanceMigrateExtensionPoint, ManagementNodeChangeListener, - VmReleaseResourceExtensionPoint, SessionLogoutExtensionPoint, PostVmInstantiateResourceExtensionPoint { + VmReleaseResourceExtensionPoint, SessionLogoutExtensionPoint, PostVmInstantiateResourceExtensionPoint, KvmReportVmShutdownFromGuestEventExtensionPoint { private static CLogger logger = Utils.getLogger(ConsoleManagerImpl.class); @Autowired @@ -357,4 +357,24 @@ public void fail(ErrorCode errorCode) { public void postReleaseVmResource(VmInstanceSpec spec, Completion completion) { completion.success(); } + + @Override + public void kvmReportVmShutdownEvent(String vmUuid) { + VmInstanceVO vmvo = Q.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, vmUuid).find(); + if (vmvo == null) { + return; + } + VmInstanceInventory inv = VmInstanceInventory.valueOf(vmvo); + ConsoleBackend backend = getBackend(); + backend.deleteConsoleSession(inv, new Completion(null) { + @Override + public void success() {} + + @Override + public void fail(ErrorCode errorCode) { + logger.warn(String.format( + "failed to delete console session for vm[uuid:%s] on guest shutdown, because %s", vmUuid, errorCode)); + } + }); + } } diff --git a/test/src/test/groovy/org/zstack/test/integration/console/ConsoleProxyCase.groovy b/test/src/test/groovy/org/zstack/test/integration/console/ConsoleProxyCase.groovy index 94f1fb161d0..839cb50554a 100644 --- a/test/src/test/groovy/org/zstack/test/integration/console/ConsoleProxyCase.groovy +++ b/test/src/test/groovy/org/zstack/test/integration/console/ConsoleProxyCase.groovy @@ -2,8 +2,10 @@ package org.zstack.test.integration.console import org.springframework.http.HttpEntity import org.zstack.console.ConsoleGlobalConfig +import org.zstack.header.vm.VmInstanceConstant import org.zstack.core.CoreGlobalProperty import org.zstack.core.Platform +import org.zstack.core.cloudbus.CloudBus import org.zstack.core.db.DatabaseFacade import org.zstack.core.db.Q import org.zstack.core.gc.GCStatus @@ -12,6 +14,7 @@ import org.zstack.header.console.ConsoleProxyAgentVO import org.zstack.header.console.ConsoleProxyCommands import org.zstack.header.console.ConsoleProxyVO import org.zstack.header.console.ConsoleProxyVO_ +import org.zstack.header.vm.KvmReportVmShutdownFromGuestEventMsg import org.zstack.sdk.ConsoleInventory import org.zstack.sdk.GarbageCollectorInventory import org.zstack.sdk.SessionInventory @@ -25,6 +28,7 @@ import org.zstack.utils.data.SizeUnit class ConsoleProxyCase extends SubCase { EnvSpec env DatabaseFacade dbf + CloudBus bus; @Override void setup() { @@ -34,6 +38,7 @@ class ConsoleProxyCase extends SubCase { @Override void environment() { dbf = bean(DatabaseFacade.class) + bus = bean(CloudBus.class) env = env { account { name = "test" @@ -119,6 +124,7 @@ class ConsoleProxyCase extends SubCase { @Override void test() { env.create { + testConsoleProxyCleanupOnGuestShutdown() testUpdateConsoleProxyAgent() testConsoleProxyGC() } @@ -245,6 +251,27 @@ class ConsoleProxyCase extends SubCase { } } + void testConsoleProxyCleanupOnGuestShutdown() { + VmInstanceInventory vm = env.inventoryByName("vm") + requestConsoleAccess { + vmInstanceUuid = vm.uuid + } + def consoleProxyCount = Q.New(ConsoleProxyVO.class) + .eq(ConsoleProxyVO_.vmInstanceUuid, vm.uuid) + .count() + assert consoleProxyCount == 1 + KvmReportVmShutdownFromGuestEventMsg msg = new KvmReportVmShutdownFromGuestEventMsg() + msg.vmInstanceUuid = vm.uuid + bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, vm.uuid) + bus.send(msg) + retryInSecs { + consoleProxyCount = Q.New(ConsoleProxyVO.class) + .eq(ConsoleProxyVO_.vmInstanceUuid, vm.uuid) + .count() + assert consoleProxyCount == 0 + } + } + @Override void clean() { env.delete()