diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/group/MemorySnapshotValidatorExtensionPoint.java b/header/src/main/java/org/zstack/header/storage/snapshot/group/MemorySnapshotValidatorExtensionPoint.java
index 0d3698457f7..acdc1653390 100644
--- a/header/src/main/java/org/zstack/header/storage/snapshot/group/MemorySnapshotValidatorExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/storage/snapshot/group/MemorySnapshotValidatorExtensionPoint.java
@@ -3,7 +3,16 @@
import org.zstack.header.errorcode.ErrorCode;
/**
- * Created by LiangHanYu on 2022/6/9 18:30
+ * 内存快照验证扩展点
+ *
+ *
触发时机:创建内存快照前,验证 VM 是否符合条件
+ * 调用位置:VolumeSnapshotGroupCreator.validate()
+ *
+ * 使用场景:
+ * 各模块通过此扩展点检查 VM 的外部设备或网络引用
+ * 是否与内存快照兼容。
+ *
+ * @since 5.0.0
*/
public interface MemorySnapshotValidatorExtensionPoint {
default ErrorCode checkVmWhereMemorySnapshotExistExternalDevices(String VmInstanceUuid) {
diff --git a/header/src/main/java/org/zstack/header/vm/DetachNicExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/DetachNicExtensionPoint.java
index 8d665918a79..6c4f706bfa2 100644
--- a/header/src/main/java/org/zstack/header/vm/DetachNicExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/vm/DetachNicExtensionPoint.java
@@ -3,6 +3,11 @@
import org.zstack.header.errorcode.ErrorCode;
import org.zstack.header.network.l3.L3NetworkInventory;
+/**
+ * @deprecated This interface has no implementations and should be removed.
+ * Use {@link org.zstack.header.vm.extensions.VmInstanceDetachNicExtensionPoint} instead.
+ */
+@Deprecated
public interface DetachNicExtensionPoint {
ErrorCode validateDetachNicByDriverTypeAndClusterType(L3NetworkInventory l3, VmInstanceInventory vm);
}
diff --git a/header/src/main/java/org/zstack/header/vm/ResourceConfigMemorySnapshotExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/ResourceConfigMemorySnapshotExtensionPoint.java
index 7f45aa3d96d..dcfef17f851 100644
--- a/header/src/main/java/org/zstack/header/vm/ResourceConfigMemorySnapshotExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/vm/ResourceConfigMemorySnapshotExtensionPoint.java
@@ -2,6 +2,18 @@
import java.util.List;
+/**
+ * 内存快照资源配置归档扩展点
+ *
+ * 触发时机:创建内存快照时,归档与 VM 相关的资源配置
+ * 调用位置:MemorySnapshotManager.archiveResourceConfig()
+ *
+ * 使用场景:
+ * 当 VM 执行内存快照时,各模块通过此扩展点提供需要归档的资源配置,
+ * 以便恢复快照时可以同时恢复相关配置状态。
+ *
+ * @since 5.0.0
+ */
public interface ResourceConfigMemorySnapshotExtensionPoint {
List getNeedToArchiveResourceConfig(String resourceUuid);
}
diff --git a/header/src/main/java/org/zstack/header/vm/VmAfterAttachL3NetworkExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmAfterAttachL3NetworkExtensionPoint.java
index a651040d121..2e794002b16 100755
--- a/header/src/main/java/org/zstack/header/vm/VmAfterAttachL3NetworkExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/vm/VmAfterAttachL3NetworkExtensionPoint.java
@@ -3,8 +3,9 @@
import org.zstack.header.network.l3.L3NetworkInventory;
/**
- * Created by xing5 on 2016/4/18.
+ * @deprecated Use {@link org.zstack.header.vm.extensions.VmInstanceAttachL3NetworkExtensionPoint#afterAttachL3Network} instead.
*/
+@Deprecated
public interface VmAfterAttachL3NetworkExtensionPoint {
void vmAfterAttachL3Network(VmInstanceInventory vm, L3NetworkInventory l3);
}
diff --git a/header/src/main/java/org/zstack/header/vm/VmAfterAttachNicExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmAfterAttachNicExtensionPoint.java
index 1e553790aa1..1ed18993d4a 100644
--- a/header/src/main/java/org/zstack/header/vm/VmAfterAttachNicExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/vm/VmAfterAttachNicExtensionPoint.java
@@ -4,8 +4,9 @@
import org.zstack.header.core.NoErrorCompletion;
/**
- * Created by LiangHanYu on 2022/4/13 13:24
+ * @deprecated Use {@link org.zstack.header.vm.extensions.VmInstanceAttachL3NetworkExtensionPoint#afterAttachL3Network} instead.
*/
+@Deprecated
public interface VmAfterAttachNicExtensionPoint {
void afterAttachNic(String nicUuid, VmInstanceInventory vmInstanceInventory, Completion completion);
diff --git a/header/src/main/java/org/zstack/header/vm/VmAfterExpungeExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmAfterExpungeExtensionPoint.java
index bf36926e65f..bbb844bfce4 100755
--- a/header/src/main/java/org/zstack/header/vm/VmAfterExpungeExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/vm/VmAfterExpungeExtensionPoint.java
@@ -2,8 +2,9 @@
/**
- * Created by Mei Lei on 8/23/16.
+ * @deprecated Use {@link org.zstack.header.vm.extensions.VmExpungeExtensionPoint#afterExpunge} instead.
*/
+@Deprecated
public interface VmAfterExpungeExtensionPoint {
void vmAfterExpunge(VmInstanceInventory inv);
}
diff --git a/header/src/main/java/org/zstack/header/vm/VmBeforeAttachL3NetworkExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmBeforeAttachL3NetworkExtensionPoint.java
index c87a891d2ea..a26a21ec28f 100755
--- a/header/src/main/java/org/zstack/header/vm/VmBeforeAttachL3NetworkExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/vm/VmBeforeAttachL3NetworkExtensionPoint.java
@@ -3,8 +3,9 @@
import org.zstack.header.network.l3.L3NetworkInventory;
/**
- * Created by xing5 on 2016/4/18.
+ * @deprecated Use {@link org.zstack.header.vm.extensions.VmInstanceAttachL3NetworkExtensionPoint#beforeAttachL3Network} instead.
*/
+@Deprecated
public interface VmBeforeAttachL3NetworkExtensionPoint {
void vmBeforeAttachL3Network(VmInstanceInventory vm, L3NetworkInventory l3);
}
diff --git a/header/src/main/java/org/zstack/header/vm/VmBeforeExpungeExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmBeforeExpungeExtensionPoint.java
index 97aeeea86cf..32b12d03e68 100644
--- a/header/src/main/java/org/zstack/header/vm/VmBeforeExpungeExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/vm/VmBeforeExpungeExtensionPoint.java
@@ -2,8 +2,9 @@
/**
- * Created by Mei Lei on 8/23/16.
+ * @deprecated Use {@link org.zstack.header.vm.extensions.VmExpungeExtensionPoint#beforeExpunge} instead.
*/
+@Deprecated
public interface VmBeforeExpungeExtensionPoint {
void vmBeforeExpunge(VmInstanceInventory inv);
}
diff --git a/header/src/main/java/org/zstack/header/vm/VmDetachNicExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmDetachNicExtensionPoint.java
index af11dc0bc66..48ff3ba23ae 100755
--- a/header/src/main/java/org/zstack/header/vm/VmDetachNicExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/vm/VmDetachNicExtensionPoint.java
@@ -3,8 +3,9 @@
import org.zstack.header.errorcode.ErrorCode;
/**
- * Created by frank on 7/18/2015.
+ * @deprecated Use {@link org.zstack.header.vm.extensions.VmInstanceDetachNicExtensionPoint} instead.
*/
+@Deprecated
public interface VmDetachNicExtensionPoint {
void preDetachNic(VmNicInventory nic);
diff --git a/header/src/main/java/org/zstack/header/vm/VmFailToAttachL3NetworkExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmFailToAttachL3NetworkExtensionPoint.java
index 27f97f23ca8..86769d21d15 100755
--- a/header/src/main/java/org/zstack/header/vm/VmFailToAttachL3NetworkExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/vm/VmFailToAttachL3NetworkExtensionPoint.java
@@ -4,8 +4,9 @@
import org.zstack.header.network.l3.L3NetworkInventory;
/**
- * Created by xing5 on 2016/4/18.
+ * @deprecated Use {@link org.zstack.header.vm.extensions.VmInstanceAttachL3NetworkExtensionPoint#failedToAttachL3Network} instead.
*/
+@Deprecated
public interface VmFailToAttachL3NetworkExtensionPoint {
void vmFailToAttachL3Network(VmInstanceInventory vm, L3NetworkInventory l3, ErrorCode error);
}
diff --git a/header/src/main/java/org/zstack/header/vm/VmInstanceAttachNicExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmInstanceAttachNicExtensionPoint.java
index 9139f98508f..716b7d6231f 100644
--- a/header/src/main/java/org/zstack/header/vm/VmInstanceAttachNicExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/vm/VmInstanceAttachNicExtensionPoint.java
@@ -1,5 +1,10 @@
package org.zstack.header.vm;
+/**
+ * @deprecated This interface has no implementations and should be removed.
+ * Use {@link org.zstack.header.vm.extensions.VmInstanceAttachL3NetworkExtensionPoint} instead.
+ */
+@Deprecated
public interface VmInstanceAttachNicExtensionPoint {
void afterAttachNicToVm(VmNicInventory nic);
}
diff --git a/header/src/main/java/org/zstack/header/vm/VmInstanceDestroyExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmInstanceDestroyExtensionPoint.java
index 9e285d22fe7..f493758fbc8 100755
--- a/header/src/main/java/org/zstack/header/vm/VmInstanceDestroyExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/vm/VmInstanceDestroyExtensionPoint.java
@@ -2,6 +2,10 @@
import org.zstack.header.errorcode.ErrorCode;
+/**
+ * @deprecated Use {@link org.zstack.header.vm.extensions.VmDestroyExtensionPoint} instead.
+ */
+@Deprecated
public interface VmInstanceDestroyExtensionPoint {
String preDestroyVm(VmInstanceInventory inv);
diff --git a/header/src/main/java/org/zstack/header/vm/VmJustAfterDeleteFromDbExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmJustAfterDeleteFromDbExtensionPoint.java
index e4b11666ebc..56c463a2ddc 100644
--- a/header/src/main/java/org/zstack/header/vm/VmJustAfterDeleteFromDbExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/vm/VmJustAfterDeleteFromDbExtensionPoint.java
@@ -1,8 +1,9 @@
package org.zstack.header.vm;
/**
- * Created by Qi Le on 2019-08-21
+ * @deprecated Use {@link org.zstack.header.vm.extensions.VmDbDeleteContext} with a single-phase extension point instead.
*/
+@Deprecated
public interface VmJustAfterDeleteFromDbExtensionPoint {
void vmJustAfterDeleteFromDbExtensionPoint(VmInstanceInventory inv, String accountUuid);
}
diff --git a/header/src/main/java/org/zstack/header/vm/VmJustBeforeDeleteFromDbExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmJustBeforeDeleteFromDbExtensionPoint.java
index 4e8337ac805..584ef5ccc55 100755
--- a/header/src/main/java/org/zstack/header/vm/VmJustBeforeDeleteFromDbExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/vm/VmJustBeforeDeleteFromDbExtensionPoint.java
@@ -1,8 +1,9 @@
package org.zstack.header.vm;
/**
- * Created by xing5 on 2017/6/26.
+ * @deprecated Use {@link org.zstack.header.vm.extensions.VmDbDeleteContext} with a single-phase extension point instead.
*/
+@Deprecated
public interface VmJustBeforeDeleteFromDbExtensionPoint {
void vmJustBeforeDeleteFromDb(VmInstanceInventory inv);
}
diff --git a/header/src/main/java/org/zstack/header/vm/VmPreAttachL3NetworkExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmPreAttachL3NetworkExtensionPoint.java
index 84240ff0b11..bb40daa67e9 100755
--- a/header/src/main/java/org/zstack/header/vm/VmPreAttachL3NetworkExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/vm/VmPreAttachL3NetworkExtensionPoint.java
@@ -3,8 +3,9 @@
import org.zstack.header.network.l3.L3NetworkInventory;
/**
- * Created by xing5 on 2016/4/18.
+ * @deprecated Use {@link org.zstack.header.vm.extensions.VmInstanceAttachL3NetworkExtensionPoint#preAttachL3Network} instead.
*/
+@Deprecated
public interface VmPreAttachL3NetworkExtensionPoint {
void vmPreAttachL3Network(VmInstanceInventory vm, L3NetworkInventory l3);
}
diff --git a/header/src/main/java/org/zstack/header/vm/extensions/VmAttachL3NetworkContext.java b/header/src/main/java/org/zstack/header/vm/extensions/VmAttachL3NetworkContext.java
new file mode 100644
index 00000000000..b874a20347e
--- /dev/null
+++ b/header/src/main/java/org/zstack/header/vm/extensions/VmAttachL3NetworkContext.java
@@ -0,0 +1,67 @@
+package org.zstack.header.vm.extensions;
+
+import org.zstack.header.network.l3.L3NetworkInventory;
+import org.zstack.header.vm.VmInstanceInventory;
+import org.zstack.header.vm.VmNicInventory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Context object for VM L3 Network attachment operations.
+ *
+ * This context is passed through all lifecycle phases (pre/before/after/failedTo)
+ * allowing extensions to share state between phases.
+ */
+public class VmAttachL3NetworkContext {
+ private VmInstanceInventory vm;
+ private L3NetworkInventory l3;
+ private VmNicInventory nic;
+ private String accountUuid;
+ private Map additionalData = new HashMap<>();
+
+ public VmInstanceInventory getVm() {
+ return vm;
+ }
+
+ public void setVm(VmInstanceInventory vm) {
+ this.vm = vm;
+ }
+
+ public L3NetworkInventory getL3() {
+ return l3;
+ }
+
+ public void setL3(L3NetworkInventory l3) {
+ this.l3 = l3;
+ }
+
+ public VmNicInventory getNic() {
+ return nic;
+ }
+
+ public void setNic(VmNicInventory nic) {
+ this.nic = nic;
+ }
+
+ public String getAccountUuid() {
+ return accountUuid;
+ }
+
+ public void setAccountUuid(String accountUuid) {
+ this.accountUuid = accountUuid;
+ }
+
+ public Map getAdditionalData() {
+ return additionalData;
+ }
+
+ public void putData(String key, Object value) {
+ additionalData.put(key, value);
+ }
+
+ @SuppressWarnings("unchecked")
+ public T getData(String key) {
+ return (T) additionalData.get(key);
+ }
+}
diff --git a/header/src/main/java/org/zstack/header/vm/extensions/VmDbDeleteContext.java b/header/src/main/java/org/zstack/header/vm/extensions/VmDbDeleteContext.java
new file mode 100644
index 00000000000..7e484498952
--- /dev/null
+++ b/header/src/main/java/org/zstack/header/vm/extensions/VmDbDeleteContext.java
@@ -0,0 +1,21 @@
+package org.zstack.header.vm.extensions;
+
+import org.zstack.header.vm.VmInstanceInventory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class VmDbDeleteContext {
+ private VmInstanceInventory vm;
+ private String accountUuid;
+ private Map additionalData = new HashMap<>();
+
+ public VmInstanceInventory getVm() { return vm; }
+ public void setVm(VmInstanceInventory vm) { this.vm = vm; }
+ public String getAccountUuid() { return accountUuid; }
+ public void setAccountUuid(String accountUuid) { this.accountUuid = accountUuid; }
+ public Map getAdditionalData() { return additionalData; }
+ public void putData(String key, Object value) { additionalData.put(key, value); }
+ @SuppressWarnings("unchecked")
+ public T getData(String key) { return (T) additionalData.get(key); }
+}
diff --git a/header/src/main/java/org/zstack/header/vm/extensions/VmDestroyContext.java b/header/src/main/java/org/zstack/header/vm/extensions/VmDestroyContext.java
new file mode 100644
index 00000000000..ae5eb770b02
--- /dev/null
+++ b/header/src/main/java/org/zstack/header/vm/extensions/VmDestroyContext.java
@@ -0,0 +1,25 @@
+package org.zstack.header.vm.extensions;
+
+import org.zstack.header.errorcode.ErrorCode;
+import org.zstack.header.vm.VmInstanceInventory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class VmDestroyContext {
+ private VmInstanceInventory vm;
+ private String accountUuid;
+ private ErrorCode error;
+ private Map additionalData = new HashMap<>();
+
+ public VmInstanceInventory getVm() { return vm; }
+ public void setVm(VmInstanceInventory vm) { this.vm = vm; }
+ public String getAccountUuid() { return accountUuid; }
+ public void setAccountUuid(String accountUuid) { this.accountUuid = accountUuid; }
+ public ErrorCode getError() { return error; }
+ public void setError(ErrorCode error) { this.error = error; }
+ public Map getAdditionalData() { return additionalData; }
+ public void putData(String key, Object value) { additionalData.put(key, value); }
+ @SuppressWarnings("unchecked")
+ public T getData(String key) { return (T) additionalData.get(key); }
+}
diff --git a/header/src/main/java/org/zstack/header/vm/extensions/VmDestroyExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/extensions/VmDestroyExtensionPoint.java
new file mode 100644
index 00000000000..d62a782da5b
--- /dev/null
+++ b/header/src/main/java/org/zstack/header/vm/extensions/VmDestroyExtensionPoint.java
@@ -0,0 +1,24 @@
+package org.zstack.header.vm.extensions;
+
+import org.zstack.header.core.Completion;
+
+/**
+ * VM Instance Destroy Extension Point (unified)
+ *
+ * Trigger: When user calls DestroyVmInstance API
+ * Call site: VmInstanceBase via VmInstanceExtensionPointEmitter
+ *
+ * Phase Description:
+ *
+ * - preDestroy - Can reject the destroy operation
+ * - beforeDestroy - Preparation before destroy
+ * - afterDestroy - Post-processing after destroy
+ * - failedToDestroy - Cleanup on failure
+ *
+ */
+public interface VmDestroyExtensionPoint {
+ default String preDestroy(VmDestroyContext ctx) { return null; }
+ default void beforeDestroy(VmDestroyContext ctx) {}
+ default void afterDestroy(VmDestroyContext ctx, Completion completion) { completion.success(); }
+ default void failedToDestroy(VmDestroyContext ctx) {}
+}
diff --git a/header/src/main/java/org/zstack/header/vm/extensions/VmDetachNicContext.java b/header/src/main/java/org/zstack/header/vm/extensions/VmDetachNicContext.java
new file mode 100644
index 00000000000..bcf0129bc01
--- /dev/null
+++ b/header/src/main/java/org/zstack/header/vm/extensions/VmDetachNicContext.java
@@ -0,0 +1,67 @@
+package org.zstack.header.vm.extensions;
+
+import org.zstack.header.errorcode.ErrorCode;
+import org.zstack.header.vm.VmInstanceInventory;
+import org.zstack.header.vm.VmNicInventory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Context object for VM NIC detachment operations.
+ *
+ * This context is passed through all lifecycle phases (pre/before/after/failedTo)
+ * allowing extensions to share state between phases.
+ */
+public class VmDetachNicContext {
+ private VmInstanceInventory vm;
+ private VmNicInventory nic;
+ private String accountUuid;
+ private ErrorCode error;
+ private Map additionalData = new HashMap<>();
+
+ public VmInstanceInventory getVm() {
+ return vm;
+ }
+
+ public void setVm(VmInstanceInventory vm) {
+ this.vm = vm;
+ }
+
+ public VmNicInventory getNic() {
+ return nic;
+ }
+
+ public void setNic(VmNicInventory nic) {
+ this.nic = nic;
+ }
+
+ public String getAccountUuid() {
+ return accountUuid;
+ }
+
+ public void setAccountUuid(String accountUuid) {
+ this.accountUuid = accountUuid;
+ }
+
+ public ErrorCode getError() {
+ return error;
+ }
+
+ public void setError(ErrorCode error) {
+ this.error = error;
+ }
+
+ public Map getAdditionalData() {
+ return additionalData;
+ }
+
+ public void putData(String key, Object value) {
+ additionalData.put(key, value);
+ }
+
+ @SuppressWarnings("unchecked")
+ public T getData(String key) {
+ return (T) additionalData.get(key);
+ }
+}
diff --git a/header/src/main/java/org/zstack/header/vm/extensions/VmExpungeContext.java b/header/src/main/java/org/zstack/header/vm/extensions/VmExpungeContext.java
new file mode 100644
index 00000000000..e5c7d21f807
--- /dev/null
+++ b/header/src/main/java/org/zstack/header/vm/extensions/VmExpungeContext.java
@@ -0,0 +1,25 @@
+package org.zstack.header.vm.extensions;
+
+import org.zstack.header.errorcode.ErrorCode;
+import org.zstack.header.vm.VmInstanceInventory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class VmExpungeContext {
+ private VmInstanceInventory vm;
+ private String accountUuid;
+ private ErrorCode error;
+ private Map additionalData = new HashMap<>();
+
+ public VmInstanceInventory getVm() { return vm; }
+ public void setVm(VmInstanceInventory vm) { this.vm = vm; }
+ public String getAccountUuid() { return accountUuid; }
+ public void setAccountUuid(String accountUuid) { this.accountUuid = accountUuid; }
+ public ErrorCode getError() { return error; }
+ public void setError(ErrorCode error) { this.error = error; }
+ public Map getAdditionalData() { return additionalData; }
+ public void putData(String key, Object value) { additionalData.put(key, value); }
+ @SuppressWarnings("unchecked")
+ public T getData(String key) { return (T) additionalData.get(key); }
+}
diff --git a/header/src/main/java/org/zstack/header/vm/extensions/VmExpungeExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/extensions/VmExpungeExtensionPoint.java
new file mode 100644
index 00000000000..7b7dd9e582d
--- /dev/null
+++ b/header/src/main/java/org/zstack/header/vm/extensions/VmExpungeExtensionPoint.java
@@ -0,0 +1,24 @@
+package org.zstack.header.vm.extensions;
+
+import org.zstack.header.core.Completion;
+
+/**
+ * VM Instance Expunge Extension Point (unified)
+ *
+ * Trigger: When VM is expunged (after destroy + grace period)
+ * Call site: VmInstanceBase.expunge()
+ *
+ * Phase Description:
+ *
+ * - preExpunge - Can reject the expunge operation
+ * - beforeExpunge - Preparation before expunge
+ * - afterExpunge - Post-processing after expunge
+ * - failedToExpunge - Cleanup on failure
+ *
+ */
+public interface VmExpungeExtensionPoint {
+ default String preExpunge(VmExpungeContext ctx) { return null; }
+ default void beforeExpunge(VmExpungeContext ctx) {}
+ default void afterExpunge(VmExpungeContext ctx, Completion completion) { completion.success(); }
+ default void failedToExpunge(VmExpungeContext ctx) {}
+}
diff --git a/header/src/main/java/org/zstack/header/vm/extensions/VmInstanceAttachL3NetworkExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/extensions/VmInstanceAttachL3NetworkExtensionPoint.java
new file mode 100644
index 00000000000..fc354fb8717
--- /dev/null
+++ b/header/src/main/java/org/zstack/header/vm/extensions/VmInstanceAttachL3NetworkExtensionPoint.java
@@ -0,0 +1,63 @@
+package org.zstack.header.vm.extensions;
+
+import org.zstack.header.core.Completion;
+
+/**
+ * VM L3 Network Attachment Extension Point
+ *
+ * Trigger: When user calls AttachL3NetworkToVm API
+ * Call site: VmInstanceBase.attachL3Network()
+ *
+ * Phase Description:
+ *
+ * - preAttachL3Network - Before NIC creation, can reject the attachment
+ * - beforeAttachL3Network - NIC prepared, about to execute FlowChain
+ * - afterAttachL3Network - Attachment complete, network services configured
+ * - failedToAttachL3Network - Attachment failed, cleanup resources
+ *
+ *
+ * Method Signatures:
+ *
+ * - pre: Returns error message String, null means pass
+ * - before: Synchronous void, for preparation
+ * - after: Asynchronous with Completion, for post-processing
+ * - failedTo: Synchronous void, for cleanup
+ *
+ */
+public interface VmInstanceAttachL3NetworkExtensionPoint {
+ /**
+ * Called before NIC creation. Can reject the attachment by returning an error message.
+ *
+ * @param ctx the attachment context
+ * @return error message if rejected, null if passed
+ */
+ default String preAttachL3Network(VmAttachL3NetworkContext ctx) {
+ return null;
+ }
+
+ /**
+ * Called after NIC is prepared, before executing the attachment FlowChain.
+ *
+ * @param ctx the attachment context
+ */
+ default void beforeAttachL3Network(VmAttachL3NetworkContext ctx) {
+ }
+
+ /**
+ * Called after attachment is complete. Asynchronous for post-processing.
+ *
+ * @param ctx the attachment context (nic field is populated)
+ * @param completion callback to signal completion
+ */
+ default void afterAttachL3Network(VmAttachL3NetworkContext ctx, Completion completion) {
+ completion.success();
+ }
+
+ /**
+ * Called when attachment fails. Cleanup any resources allocated in previous phases.
+ *
+ * @param ctx the attachment context
+ */
+ default void failedToAttachL3Network(VmAttachL3NetworkContext ctx) {
+ }
+}
diff --git a/header/src/main/java/org/zstack/header/vm/extensions/VmInstanceDetachNicExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/extensions/VmInstanceDetachNicExtensionPoint.java
new file mode 100644
index 00000000000..57aea614821
--- /dev/null
+++ b/header/src/main/java/org/zstack/header/vm/extensions/VmInstanceDetachNicExtensionPoint.java
@@ -0,0 +1,63 @@
+package org.zstack.header.vm.extensions;
+
+import org.zstack.header.core.Completion;
+
+/**
+ * VM NIC Detachment Extension Point
+ *
+ * Trigger: When user calls DetachL3NetworkFromVm API
+ * Call site: VmInstanceBase.detachNic()
+ *
+ * Phase Description:
+ *
+ * - preDetachNic - Before detachment, can reject the operation
+ * - beforeDetachNic - About to execute detachment FlowChain
+ * - afterDetachNic - Detachment complete, NIC removed
+ * - failedToDetachNic - Detachment failed, restore state
+ *
+ *
+ * Method Signatures:
+ *
+ * - pre: Returns error message String, null means pass
+ * - before: Synchronous void, for preparation
+ * - after: Asynchronous with Completion, for post-processing
+ * - failedTo: Synchronous void, for cleanup
+ *
+ */
+public interface VmInstanceDetachNicExtensionPoint {
+ /**
+ * Called before NIC detachment. Can reject the operation by returning an error message.
+ *
+ * @param ctx the detachment context
+ * @return error message if rejected, null if passed
+ */
+ default String preDetachNic(VmDetachNicContext ctx) {
+ return null;
+ }
+
+ /**
+ * Called before executing the detachment FlowChain.
+ *
+ * @param ctx the detachment context
+ */
+ default void beforeDetachNic(VmDetachNicContext ctx) {
+ }
+
+ /**
+ * Called after detachment is complete. Asynchronous for post-processing.
+ *
+ * @param ctx the detachment context
+ * @param completion callback to signal completion
+ */
+ default void afterDetachNic(VmDetachNicContext ctx, Completion completion) {
+ completion.success();
+ }
+
+ /**
+ * Called when detachment fails. Restore any state changed in previous phases.
+ *
+ * @param ctx the detachment context (error field is populated)
+ */
+ default void failedToDetachNic(VmDetachNicContext ctx) {
+ }
+}
diff --git a/header/src/main/java/org/zstack/header/volume/VolumeBeforeExpungeExtensionPoint.java b/header/src/main/java/org/zstack/header/volume/VolumeBeforeExpungeExtensionPoint.java
index 673c7cbf9bd..ba4594264ac 100755
--- a/header/src/main/java/org/zstack/header/volume/VolumeBeforeExpungeExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/volume/VolumeBeforeExpungeExtensionPoint.java
@@ -4,8 +4,9 @@
import org.zstack.header.core.NoErrorCompletion;
/**
- * Created by xing5 on 2016/5/3.
+ * @deprecated Use {@link org.zstack.header.volume.extensions.VolumeExpungeExtPoint} instead.
*/
+@Deprecated
public interface VolumeBeforeExpungeExtensionPoint {
void volumePreExpunge(VolumeInventory volume);
void volumeBeforeExpunge(VolumeInventory volume, NoErrorCompletion completion);
diff --git a/header/src/main/java/org/zstack/header/volume/VolumeDeletionExtensionPoint.java b/header/src/main/java/org/zstack/header/volume/VolumeDeletionExtensionPoint.java
index 8985e000c3f..3b40566e230 100755
--- a/header/src/main/java/org/zstack/header/volume/VolumeDeletionExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/volume/VolumeDeletionExtensionPoint.java
@@ -4,8 +4,9 @@
import org.zstack.header.errorcode.ErrorCode;
/**
- * Created by frank on 6/18/2015.
+ * @deprecated Use {@link org.zstack.header.volume.extensions.VolumeDeletionExtPoint} instead.
*/
+@Deprecated
public interface VolumeDeletionExtensionPoint {
void preDeleteVolume(VolumeInventory volume);
diff --git a/header/src/main/java/org/zstack/header/volume/extensions/VolumeDeleteContext.java b/header/src/main/java/org/zstack/header/volume/extensions/VolumeDeleteContext.java
new file mode 100644
index 00000000000..7c3efdec410
--- /dev/null
+++ b/header/src/main/java/org/zstack/header/volume/extensions/VolumeDeleteContext.java
@@ -0,0 +1,25 @@
+package org.zstack.header.volume.extensions;
+
+import org.zstack.header.errorcode.ErrorCode;
+import org.zstack.header.volume.VolumeInventory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class VolumeDeleteContext {
+ private VolumeInventory volume;
+ private String accountUuid;
+ private ErrorCode error;
+ private Map additionalData = new HashMap<>();
+
+ public VolumeInventory getVolume() { return volume; }
+ public void setVolume(VolumeInventory volume) { this.volume = volume; }
+ public String getAccountUuid() { return accountUuid; }
+ public void setAccountUuid(String accountUuid) { this.accountUuid = accountUuid; }
+ public ErrorCode getError() { return error; }
+ public void setError(ErrorCode error) { this.error = error; }
+ public Map getAdditionalData() { return additionalData; }
+ public void putData(String key, Object value) { additionalData.put(key, value); }
+ @SuppressWarnings("unchecked")
+ public T getData(String key) { return (T) additionalData.get(key); }
+}
diff --git a/header/src/main/java/org/zstack/header/volume/extensions/VolumeDeletionExtPoint.java b/header/src/main/java/org/zstack/header/volume/extensions/VolumeDeletionExtPoint.java
new file mode 100644
index 00000000000..f365747c6a8
--- /dev/null
+++ b/header/src/main/java/org/zstack/header/volume/extensions/VolumeDeletionExtPoint.java
@@ -0,0 +1,24 @@
+package org.zstack.header.volume.extensions;
+
+import org.zstack.header.core.Completion;
+
+/**
+ * Volume Deletion Extension Point (unified)
+ *
+ * Trigger: When user calls DeleteDataVolume API
+ * Call site: VolumeBase.delete()
+ *
+ * Phase Description:
+ *
+ * - preDelete - Can reject the deletion
+ * - beforeDelete - Preparation before deletion
+ * - afterDelete - Post-processing after deletion
+ * - failedToDelete - Cleanup on failure
+ *
+ */
+public interface VolumeDeletionExtPoint {
+ default String preDelete(VolumeDeleteContext ctx) { return null; }
+ default void beforeDelete(VolumeDeleteContext ctx) {}
+ default void afterDelete(VolumeDeleteContext ctx, Completion completion) { completion.success(); }
+ default void failedToDelete(VolumeDeleteContext ctx) {}
+}
diff --git a/header/src/main/java/org/zstack/header/volume/extensions/VolumeExpungeContext.java b/header/src/main/java/org/zstack/header/volume/extensions/VolumeExpungeContext.java
new file mode 100644
index 00000000000..6488058d348
--- /dev/null
+++ b/header/src/main/java/org/zstack/header/volume/extensions/VolumeExpungeContext.java
@@ -0,0 +1,25 @@
+package org.zstack.header.volume.extensions;
+
+import org.zstack.header.errorcode.ErrorCode;
+import org.zstack.header.volume.VolumeInventory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class VolumeExpungeContext {
+ private VolumeInventory volume;
+ private String accountUuid;
+ private ErrorCode error;
+ private Map additionalData = new HashMap<>();
+
+ public VolumeInventory getVolume() { return volume; }
+ public void setVolume(VolumeInventory volume) { this.volume = volume; }
+ public String getAccountUuid() { return accountUuid; }
+ public void setAccountUuid(String accountUuid) { this.accountUuid = accountUuid; }
+ public ErrorCode getError() { return error; }
+ public void setError(ErrorCode error) { this.error = error; }
+ public Map getAdditionalData() { return additionalData; }
+ public void putData(String key, Object value) { additionalData.put(key, value); }
+ @SuppressWarnings("unchecked")
+ public T getData(String key) { return (T) additionalData.get(key); }
+}
diff --git a/header/src/main/java/org/zstack/header/volume/extensions/VolumeExpungeExtPoint.java b/header/src/main/java/org/zstack/header/volume/extensions/VolumeExpungeExtPoint.java
new file mode 100644
index 00000000000..b51dd4c5c15
--- /dev/null
+++ b/header/src/main/java/org/zstack/header/volume/extensions/VolumeExpungeExtPoint.java
@@ -0,0 +1,24 @@
+package org.zstack.header.volume.extensions;
+
+import org.zstack.header.core.Completion;
+
+/**
+ * Volume Expunge Extension Point (unified)
+ *
+ * Trigger: When volume is expunged (after delete + grace period)
+ * Call site: VolumeBase.expunge()
+ *
+ * Phase Description:
+ *
+ * - preExpunge - Can reject the expunge (or skip it)
+ * - beforeExpunge - Preparation before expunge
+ * - afterExpunge - Post-processing after expunge
+ * - failedToExpunge - Cleanup on failure
+ *
+ */
+public interface VolumeExpungeExtPoint {
+ default String preExpunge(VolumeExpungeContext ctx) { return null; }
+ default void beforeExpunge(VolumeExpungeContext ctx) {}
+ default void afterExpunge(VolumeExpungeContext ctx, Completion completion) { completion.success(); }
+ default void failedToExpunge(VolumeExpungeContext ctx) {}
+}