From f18ff25a5c755083002607ad8af2874d912e9ec0 Mon Sep 17 00:00:00 2001 From: shenjin Date: Fri, 16 Jan 2026 17:09:46 +0800 Subject: [PATCH] [ceph]: support thirdparty_ceph to bm root volume support thirdparty_ceph to bm root volume Resolves: ZSTAC-73396 Change-Id: I6f6f616777677a6f74696c6c736c737a626f7863 (cherry picked from commit 827e880804d9a68e5212abaa5b562793995d032f) --- conf/db/upgrade/V5.5.6__schema.sql | 75 +++++++++++++++++++ .../ceph/primary/CephPrimaryStorageBase.java | 64 ++++++++++++++++ ...torageCheckInstanceTypeExtensionPoint.java | 13 ++++ .../sdk/BareMetal2ChassisNicInventory.java | 8 ++ .../sdk/BareMetal2InstanceInventory.java | 12 +-- ...reMetal2InstanceProvisionNicInventory.java | 16 ++++ .../CloudOperationsErrorCode.java | 8 ++ 7 files changed, 190 insertions(+), 6 deletions(-) create mode 100644 plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageCheckInstanceTypeExtensionPoint.java diff --git a/conf/db/upgrade/V5.5.6__schema.sql b/conf/db/upgrade/V5.5.6__schema.sql index 69eee484a0e..f7f53781a02 100644 --- a/conf/db/upgrade/V5.5.6__schema.sql +++ b/conf/db/upgrade/V5.5.6__schema.sql @@ -6,3 +6,78 @@ ALTER TABLE `GuestVmScriptExecutedRecordDetailVO` CALL ADD_COLUMN('PciDeviceVO', 'vmPciDeviceAddress', 'varchar(32)', 1, NULL); CALL ADD_COLUMN('MdevDeviceVO', 'mdevDeviceAddress', 'varchar(32)', 1, NULL); + +DELIMITER $$ + +CREATE PROCEDURE UpdateBareMetal2InstanceProvisionNicVO() +BEGIN + DECLARE instanceUuid_exists INT; + DECLARE isPrimaryProvisionNic_exists_in_ProvisionNicVO INT; + DECLARE isPrimaryProvisionNic_exists_in_ChassisNicVO INT; + + DECLARE EXIT HANDLER FOR SQLEXCEPTION + BEGIN + ROLLBACK; + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'An error occurred during the update process.'; + END; + + START TRANSACTION; + + SELECT COUNT(*) + INTO instanceUuid_exists + FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_SCHEMA = 'zstack' + AND TABLE_NAME = 'BareMetal2InstanceProvisionNicVO' + AND COLUMN_NAME = 'instanceUuid'; + + IF instanceUuid_exists = 0 THEN + CALL ADD_COLUMN('BareMetal2InstanceProvisionNicVO', 'instanceUuid', 'VARCHAR(32)', FALSE, ''); + + UPDATE `zstack`.`BareMetal2InstanceProvisionNicVO` + SET `instanceUuid` = `uuid`; + + ALTER TABLE `zstack`.`BareMetal2InstanceProvisionNicVO` + DROP FOREIGN KEY `fkBareMetal2InstanceProvisionNicVOInstanceVO`; + + CALL ADD_CONSTRAINT('BareMetal2InstanceProvisionNicVO', 'fkBareMetal2InstanceProvisionNicVOInstanceVO', + 'instanceUuid', 'BareMetal2InstanceVO', 'uuid', 'CASCADE'); + + UPDATE `zstack`.`BareMetal2InstanceProvisionNicVO` + SET `uuid` = REPLACE(UUID(), '-', ''); + END IF; + + SELECT COUNT(*) + INTO isPrimaryProvisionNic_exists_in_ProvisionNicVO + FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_SCHEMA = 'zstack' + AND TABLE_NAME = 'BareMetal2InstanceProvisionNicVO' + AND COLUMN_NAME = 'isPrimaryProvisionNic'; + + IF isPrimaryProvisionNic_exists_in_ProvisionNicVO = 0 THEN + CALL ADD_COLUMN('BareMetal2InstanceProvisionNicVO', 'isPrimaryProvisionNic', 'BOOLEAN', FALSE, FALSE); + + UPDATE `zstack`.`BareMetal2InstanceProvisionNicVO` + SET `isPrimaryProvisionNic` = TRUE; + END IF; + + SELECT COUNT(*) + INTO isPrimaryProvisionNic_exists_in_ChassisNicVO + FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_SCHEMA = 'zstack' + AND TABLE_NAME = 'BareMetal2ChassisNicVO' + AND COLUMN_NAME = 'isPrimaryProvisionNic'; + + IF isPrimaryProvisionNic_exists_in_ChassisNicVO = 0 THEN + CALL ADD_COLUMN('BareMetal2ChassisNicVO', 'isPrimaryProvisionNic', 'BOOLEAN', FALSE, FALSE); + + UPDATE `zstack`.`BareMetal2ChassisNicVO` + SET `isPrimaryProvisionNic` = TRUE + WHERE `isProvisionNic` = TRUE; + END IF; + + COMMIT; +END$$ + +DELIMITER ; +CALL UpdateBareMetal2InstanceProvisionNicVO(); +DROP PROCEDURE IF EXISTS UpdateBareMetal2InstanceProvisionNicVO; diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java index d8349cd8f2a..9d5f9266c25 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java @@ -54,8 +54,12 @@ import org.zstack.header.storage.primary.*; import org.zstack.header.storage.primary.VolumeSnapshotCapability.VolumeSnapshotArrangementType; import org.zstack.header.storage.snapshot.*; +import org.zstack.header.tag.SystemTagVO; +import org.zstack.header.tag.SystemTagVO_; import org.zstack.header.vm.VmInstanceSpec; import org.zstack.header.vm.VmInstanceSpec.ImageSpec; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vm.VmInstanceVO_; import org.zstack.header.vo.ResourceVO; import org.zstack.header.volume.*; import org.zstack.identity.AccountManager; @@ -485,6 +489,8 @@ public static class CloneRsp extends AgentResponse { public Long size; public Long actualSize; public String installPath; + public String volumeId; + public String volumeStatus; public String getInstallPath() { return installPath; @@ -493,6 +499,22 @@ public String getInstallPath() { public void setInstallPath(String installPath) { this.installPath = installPath; } + + public String getVolumeId() { + return volumeId; + } + + public void setVolumeId(String volumeId) { + this.volumeId = volumeId; + } + + public String getVolumeStatus() { + return volumeStatus; + } + + public void setVolumeStatus(String volumeStatus) { + this.volumeStatus = volumeStatus; + } } public static class FlattenCmd extends AgentCommand implements HasThreadContext { @@ -2636,6 +2658,40 @@ public void run(final FlowTrigger trigger, Map data) { CloneCmd cmd = new CloneCmd(); cmd.srcPath = cloneInstallPath; cmd.dstPath = volumePath; + List exts = pluginRgty.getExtensionList(CephPrimaryStorageCheckInstanceTypeExtensionPoint.class); + for (CephPrimaryStorageCheckInstanceTypeExtensionPoint ext : exts) { + Boolean result = ext.isSupportCloneByThirdParty(msg.getVolume().getVmInstanceUuid()); + if (!result) { + break; + } + boolean isRootVolume = Q.New(VolumeVO.class) + .eq(VolumeVO_.uuid, msg.getVolume().getUuid()) + .eq(VolumeVO_.type, VolumeType.Root) + .isExists(); + boolean isBareMetal2Instance = Q.New(VmInstanceVO.class) + .eq(VmInstanceVO_.uuid, msg.getVolume().getVmInstanceUuid()) + .eq(VmInstanceVO_.type, "baremetal2") + .isExists(); + boolean hasToken = CephSystemTags.THIRDPARTY_PLATFORM.hasTag(msg.getPrimaryStorageUuid()); + if (isRootVolume && isBareMetal2Instance && hasToken) { + CephPrimaryStorageVO cephPrimaryStorageVO = dbf.findByUuid(msg.getPrimaryStorageUuid(), CephPrimaryStorageVO.class); + String monIp = cephPrimaryStorageVO.getMons() + .stream() + .filter(v -> v.getStatus() == MonStatus.Connected) + .map(CephPrimaryStorageMonVO::getHostname) + .findAny() + .orElseThrow(() -> new OperationFailureException( + operr("all ceph mons of primary storage[uuid:%s] are not in Connected state", cephPrimaryStorageVO.getUuid()) + )); + cmd.token = CephSystemTags.THIRDPARTY_PLATFORM.getTokenByResourceUuid(msg.getPrimaryStorageUuid(), + CephSystemTags.THIRDPARTY_PLATFORM_TOKEN); + cmd.monIp = monIp; + cmd.tpTimeout = CephGlobalConfig.THIRD_PARTY_SDK_TIMEOUT.value(String.class); + VolumeVO vo = Q.New(VolumeVO.class) + .eq(VolumeVO_.uuid, msg.getVolume().getUuid()).find(); + ext.convertToBlockVolume(vo); + } + } httpCall(CLONE_PATH, cmd, CloneRsp.class, new ReturnValueCompletion(trigger) { @Override @@ -2646,6 +2702,14 @@ public void fail(ErrorCode err) { @Override public void success(CloneRsp ret) { actualSize = ret.actualSize; + List exts = pluginRgty.getExtensionList(CephPrimaryStorageCheckInstanceTypeExtensionPoint.class); + for (CephPrimaryStorageCheckInstanceTypeExtensionPoint ext : exts) { + if (!ext.isBlockVolume(msg.getVolume().getUuid())) { + break; + } + volumePath = ret.installPath == null ? volumePath : makeVolumeInstallPathByTargetPool(ret.installPath, targetCephPoolName); + ext.populateBlockVolumeDetails(msg.getVolume().getUuid(), ret.volumeId, ret.volumeStatus); + } trigger.next(); } }); diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageCheckInstanceTypeExtensionPoint.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageCheckInstanceTypeExtensionPoint.java new file mode 100644 index 00000000000..7c670128680 --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageCheckInstanceTypeExtensionPoint.java @@ -0,0 +1,13 @@ +package org.zstack.storage.ceph.primary; + +import org.zstack.header.volume.VolumeVO; + +public interface CephPrimaryStorageCheckInstanceTypeExtensionPoint { + Boolean isSupportCloneByThirdParty(String uuid); + + void convertToBlockVolume(VolumeVO vo); + + Boolean isBlockVolume(String uuid); + + void populateBlockVolumeDetails(String uuid, String volumeId, String volumeStatus); +} diff --git a/sdk/src/main/java/org/zstack/sdk/BareMetal2ChassisNicInventory.java b/sdk/src/main/java/org/zstack/sdk/BareMetal2ChassisNicInventory.java index 4586cbaa65d..3325ebb5eb2 100644 --- a/sdk/src/main/java/org/zstack/sdk/BareMetal2ChassisNicInventory.java +++ b/sdk/src/main/java/org/zstack/sdk/BareMetal2ChassisNicInventory.java @@ -52,6 +52,14 @@ public java.lang.Boolean getIsProvisionNic() { return this.isProvisionNic; } + public java.lang.Boolean isPrimaryProvisionNic; + public void setIsPrimaryProvisionNic(java.lang.Boolean isPrimaryProvisionNic) { + this.isPrimaryProvisionNic = isPrimaryProvisionNic; + } + public java.lang.Boolean getIsPrimaryProvisionNic() { + return this.isPrimaryProvisionNic; + } + public java.sql.Timestamp createDate; public void setCreateDate(java.sql.Timestamp createDate) { this.createDate = createDate; diff --git a/sdk/src/main/java/org/zstack/sdk/BareMetal2InstanceInventory.java b/sdk/src/main/java/org/zstack/sdk/BareMetal2InstanceInventory.java index d4c75d84a34..2ddc554a904 100644 --- a/sdk/src/main/java/org/zstack/sdk/BareMetal2InstanceInventory.java +++ b/sdk/src/main/java/org/zstack/sdk/BareMetal2InstanceInventory.java @@ -1,6 +1,6 @@ package org.zstack.sdk; -import org.zstack.sdk.BareMetal2InstanceProvisionNicInventory; + public class BareMetal2InstanceInventory extends org.zstack.sdk.VmInstanceInventory { @@ -84,12 +84,12 @@ public boolean getIsLatestAgent() { return this.isLatestAgent; } - public BareMetal2InstanceProvisionNicInventory provisionNic; - public void setProvisionNic(BareMetal2InstanceProvisionNicInventory provisionNic) { - this.provisionNic = provisionNic; + public java.util.List provisionNics; + public void setProvisionNics(java.util.List provisionNics) { + this.provisionNics = provisionNics; } - public BareMetal2InstanceProvisionNicInventory getProvisionNic() { - return this.provisionNic; + public java.util.List getProvisionNics() { + return this.provisionNics; } } diff --git a/sdk/src/main/java/org/zstack/sdk/BareMetal2InstanceProvisionNicInventory.java b/sdk/src/main/java/org/zstack/sdk/BareMetal2InstanceProvisionNicInventory.java index 50bbe756736..4f25c5ebb9e 100644 --- a/sdk/src/main/java/org/zstack/sdk/BareMetal2InstanceProvisionNicInventory.java +++ b/sdk/src/main/java/org/zstack/sdk/BareMetal2InstanceProvisionNicInventory.java @@ -52,6 +52,22 @@ public java.lang.String getGateway() { return this.gateway; } + public java.lang.String instanceUuid; + public void setInstanceUuid(java.lang.String instanceUuid) { + this.instanceUuid = instanceUuid; + } + public java.lang.String getInstanceUuid() { + return this.instanceUuid; + } + + public java.lang.Boolean isPrimaryProvisionNic; + public void setIsPrimaryProvisionNic(java.lang.Boolean isPrimaryProvisionNic) { + this.isPrimaryProvisionNic = isPrimaryProvisionNic; + } + public java.lang.Boolean getIsPrimaryProvisionNic() { + return this.isPrimaryProvisionNic; + } + public java.lang.String metadata; public void setMetadata(java.lang.String metadata) { this.metadata = metadata; diff --git a/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java b/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java index 7907558db2a..5110cfd2484 100644 --- a/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java +++ b/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java @@ -7678,6 +7678,10 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_BAREMETAL2_INSTANCE_10087 = "ORG_ZSTACK_BAREMETAL2_INSTANCE_10087"; + public static final String ORG_ZSTACK_BAREMETAL2_INSTANCE_10088 = "ORG_ZSTACK_BAREMETAL2_INSTANCE_10088"; + + public static final String ORG_ZSTACK_BAREMETAL2_INSTANCE_10089 = "ORG_ZSTACK_BAREMETAL2_INSTANCE_10089"; + public static final String ORG_ZSTACK_CRYPTO_SECURITYMACHINE_SECRETRESOURCEPOOL_10000 = "ORG_ZSTACK_CRYPTO_SECURITYMACHINE_SECRETRESOURCEPOOL_10000"; public static final String ORG_ZSTACK_CRYPTO_SECURITYMACHINE_SECRETRESOURCEPOOL_10001 = "ORG_ZSTACK_CRYPTO_SECURITYMACHINE_SECRETRESOURCEPOOL_10001"; @@ -13706,6 +13710,10 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_BAREMETAL2_CHASSIS_10023 = "ORG_ZSTACK_BAREMETAL2_CHASSIS_10023"; + public static final String ORG_ZSTACK_BAREMETAL2_CHASSIS_10024 = "ORG_ZSTACK_BAREMETAL2_CHASSIS_10024"; + + public static final String ORG_ZSTACK_BAREMETAL2_CHASSIS_10025 = "ORG_ZSTACK_BAREMETAL2_CHASSIS_10025"; + public static final String ORG_ZSTACK_BAREMETAL2_CLUSTER_10000 = "ORG_ZSTACK_BAREMETAL2_CLUSTER_10000"; public static final String ORG_ZSTACK_BAREMETAL2_CLUSTER_10001 = "ORG_ZSTACK_BAREMETAL2_CLUSTER_10001";