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()