From fe02151008c7d31dfb4674be4bc0c3f00b4a25a2 Mon Sep 17 00:00:00 2001 From: "ye.zou" Date: Mon, 27 Apr 2026 22:19:46 +0800 Subject: [PATCH 1/7] [ai]: schema add ModelVO.pipelineTag/manifestJson and ModelServiceRefVO.isDefault/createDate/lastOpDate Resolves: ZSTAC-84025 Change-Id: Ifbb68c9d475aa19762bb053e6545381a305dfe5b --- conf/db/upgrade/V5.5.22__schema.sql | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/conf/db/upgrade/V5.5.22__schema.sql b/conf/db/upgrade/V5.5.22__schema.sql index e69de29bb2d..f680641fbdc 100644 --- a/conf/db/upgrade/V5.5.22__schema.sql +++ b/conf/db/upgrade/V5.5.22__schema.sql @@ -0,0 +1,17 @@ +-- ZSTAC-84025: Add pipelineTag to ModelVO for inference template auto-matching +CALL ADD_COLUMN('ModelVO', 'pipelineTag', 'VARCHAR(64)', 1, NULL); + +-- ZSTAC-84025: Add isDefault to ModelServiceRefVO to mark the default inference template per model +ALTER TABLE `zstack`.`ModelServiceRefVO` ADD COLUMN `isDefault` TINYINT(1) NOT NULL DEFAULT 0; + +-- Backfill isDefault: all existing refs default to 0 (no default template designated) +UPDATE `zstack`.`ModelServiceRefVO` SET `isDefault` = 0; + +-- ZSTAC-84025-F2: Add manifestJson to ModelVO so Step 1 (file format) of the auto-match Matcher can +-- parse file_types/file_extensions from the manifest returned by the aios agent. +CALL ADD_COLUMN('ModelVO', 'manifestJson', 'TEXT', 1, NULL); + +-- ZSTAC-84025: Add createDate/lastOpDate to ModelServiceRefVO so the auto-match Matcher can +-- pick the earliest isDefault=true row when DB has the rare 2+ defaults anomaly (Q5). +ALTER TABLE `zstack`.`ModelServiceRefVO` ADD COLUMN `lastOpDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; +ALTER TABLE `zstack`.`ModelServiceRefVO` ADD COLUMN `createDate` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00'; From 0311282cbd0eb4e98709973104366503a8d603ac Mon Sep 17 00:00:00 2001 From: "ye.zou" Date: Mon, 27 Apr 2026 22:19:55 +0800 Subject: [PATCH 2/7] [ai]: sdk AutoMatchModelServiceByModel action and UpdateModel.defaultModelServiceUuid Resolves: ZSTAC-84025 Change-Id: I4046976b0c4437ba4c14069946b8075393f152ed --- .../AutoMatchModelServiceByModelAction.java | 101 ++++++++++++++++++ .../AutoMatchModelServiceByModelResult.java | 39 +++++++ .../org/zstack/sdk/UpdateModelAction.java | 3 + 3 files changed, 143 insertions(+) create mode 100644 sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelAction.java create mode 100644 sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelResult.java diff --git a/sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelAction.java b/sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelAction.java new file mode 100644 index 00000000000..b9030f9b8ca --- /dev/null +++ b/sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelAction.java @@ -0,0 +1,101 @@ +package org.zstack.sdk; + +import java.util.HashMap; +import java.util.Map; +import org.zstack.sdk.*; + +public class AutoMatchModelServiceByModelAction extends AbstractAction { + + private static final HashMap parameterMap = new HashMap<>(); + + private static final HashMap nonAPIParameterMap = new HashMap<>(); + + public static class Result { + public ErrorCode error; + public org.zstack.sdk.AutoMatchModelServiceByModelResult value; + + public Result throwExceptionIfError() { + if (error != null) { + throw new ApiException( + String.format("error[code: %s, description: %s, details: %s, globalErrorCode: %s]", error.code, error.description, error.details, error.globalErrorCode) + ); + } + + return this; + } + } + + @Param(required = true, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.lang.String modelUuid; + + @Param(required = false) + public java.util.List systemTags; + + @Param(required = false) + public java.util.List userTags; + + @Param(required = false) + public String sessionId; + + @Param(required = false) + public String accessKeyId; + + @Param(required = false) + public String accessKeySecret; + + @Param(required = false) + public String requestIp; + + @NonAPIParam + public long timeout = -1; + + @NonAPIParam + public long pollingInterval = -1; + + + private Result makeResult(ApiResult res) { + Result ret = new Result(); + if (res.error != null) { + ret.error = res.error; + return ret; + } + + org.zstack.sdk.AutoMatchModelServiceByModelResult value = res.getResult(org.zstack.sdk.AutoMatchModelServiceByModelResult.class); + ret.value = value == null ? new org.zstack.sdk.AutoMatchModelServiceByModelResult() : value; + + return ret; + } + + public Result call() { + ApiResult res = ZSClient.call(this); + return makeResult(res); + } + + public void call(final Completion completion) { + ZSClient.call(this, new InternalCompletion() { + @Override + public void complete(ApiResult res) { + completion.complete(makeResult(res)); + } + }); + } + + protected Map getParameterMap() { + return parameterMap; + } + + protected Map getNonAPIParameterMap() { + return nonAPIParameterMap; + } + + protected RestInfo getRestInfo() { + RestInfo info = new RestInfo(); + info.httpMethod = "GET"; + info.path = "/ai/models/{modelUuid}/auto-match-service"; + info.needSession = true; + info.needPoll = false; + info.parameterName = ""; + return info; + } + +} diff --git a/sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelResult.java b/sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelResult.java new file mode 100644 index 00000000000..95393cb6ea0 --- /dev/null +++ b/sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelResult.java @@ -0,0 +1,39 @@ +package org.zstack.sdk; + +public class AutoMatchModelServiceByModelResult { + /** + * UUID of the recommended ModelServiceVO. May be null if FALLBACK step + * found no Transformers candidate. + */ + public java.lang.String recommendedServiceUuid; + public void setRecommendedServiceUuid(java.lang.String recommendedServiceUuid) { + this.recommendedServiceUuid = recommendedServiceUuid; + } + public java.lang.String getRecommendedServiceUuid() { + return this.recommendedServiceUuid; + } + + /** + * Which matching step produced this recommendation: + * USER_PRESET | FILE_FORMAT | PIPELINE_TAG | FALLBACK + */ + public java.lang.String matchedByStep; + public void setMatchedByStep(java.lang.String matchedByStep) { + this.matchedByStep = matchedByStep; + } + public java.lang.String getMatchedByStep() { + return this.matchedByStep; + } + + /** + * Diagnostic evidence for the match decision. + */ + public java.util.LinkedHashMap evidence; + public void setEvidence(java.util.LinkedHashMap evidence) { + this.evidence = evidence; + } + public java.util.LinkedHashMap getEvidence() { + return this.evidence; + } + +} diff --git a/sdk/src/main/java/org/zstack/sdk/UpdateModelAction.java b/sdk/src/main/java/org/zstack/sdk/UpdateModelAction.java index 3b27ed271d8..f7936631adf 100644 --- a/sdk/src/main/java/org/zstack/sdk/UpdateModelAction.java +++ b/sdk/src/main/java/org/zstack/sdk/UpdateModelAction.java @@ -58,6 +58,9 @@ public Result throwExceptionIfError() { @Param(required = false, maxLength = 255, nonempty = false, nullElements = false, emptyString = true, noTrim = false) public java.lang.String modelId; + @Param(required = false, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.lang.String defaultModelServiceUuid; + @Param(required = false) public java.util.List systemTags; From 4b352ab705d602a50fadbd51fde9acc6f8f01274 Mon Sep 17 00:00:00 2001 From: "ye.zou" Date: Mon, 27 Apr 2026 22:19:55 +0800 Subject: [PATCH 3/7] [ai]: regenerate ApiHelper.groovy with autoMatchModelServiceByModel DSL Resolves: ZSTAC-84025 Change-Id: I0df26f7367a28da9c6c825dcddcb829db133374e --- .../java/org/zstack/testlib/ApiHelper.groovy | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy b/testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy index ab4531b5ade..b505a267862 100644 --- a/testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy +++ b/testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy @@ -4769,6 +4769,33 @@ abstract class ApiHelper { } + def autoMatchModelServiceByModel(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AutoMatchModelServiceByModelAction.class) Closure c) { + def a = new org.zstack.sdk.AutoMatchModelServiceByModelAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def backupDatabaseToPublicCloud(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BackupDatabaseToPublicCloudAction.class) Closure c) { def a = new org.zstack.sdk.BackupDatabaseToPublicCloudAction() a.sessionId = Test.currentEnvSpec?.session?.uuid From 23cb7642b1fbe7fb7bd26a71412072d028fe4488 Mon Sep 17 00:00:00 2001 From: AlanJager Date: Thu, 7 May 2026 14:48:52 +0800 Subject: [PATCH 4/7] [sdk]: Update all sdks Resolves: ZSTAC-84025 Change-Id: I7a6c657369736978676164676b616b626d707974 --- sdk/src/main/java/SourceClassMap.java | 4 ++ .../java/org/zstack/sdk/AddModelAction.java | 3 ++ .../AutoMatchModelServiceByModelAction.java | 14 ++---- .../AutoMatchModelServiceByModelResult.java | 26 ++++------ .../java/org/zstack/sdk/MatchEvidence.java | 47 +++++++++++++++++++ .../main/java/org/zstack/sdk/MatchedStep.java | 8 ++++ .../zstack/sdk/ModelServiceRefInventory.java | 8 ++++ 7 files changed, 83 insertions(+), 27 deletions(-) create mode 100644 sdk/src/main/java/org/zstack/sdk/MatchEvidence.java create mode 100644 sdk/src/main/java/org/zstack/sdk/MatchedStep.java diff --git a/sdk/src/main/java/SourceClassMap.java b/sdk/src/main/java/SourceClassMap.java index 5104ebb6a6f..72fbac9b302 100644 --- a/sdk/src/main/java/SourceClassMap.java +++ b/sdk/src/main/java/SourceClassMap.java @@ -29,6 +29,8 @@ public class SourceClassMap { put("org.zstack.ai.entity.VmModelMountStatus", "org.zstack.sdk.VmModelMountStatus"); put("org.zstack.ai.message.ArchitectureImageMapping", "org.zstack.sdk.ArchitectureImageMapping"); put("org.zstack.ai.message.MaaSUsage", "org.zstack.sdk.MaaSUsage"); + put("org.zstack.ai.message.MatchEvidence", "org.zstack.sdk.MatchEvidence"); + put("org.zstack.ai.message.MatchedStep", "org.zstack.sdk.MatchedStep"); put("org.zstack.ai.message.ModelCenterServiceInventory", "org.zstack.sdk.ModelCenterServiceInventory"); put("org.zstack.ai.message.ModelCenterServiceInventory$MetaServerService", "org.zstack.sdk.MetaServerService"); put("org.zstack.ai.message.ModelCenterServiceInventory$ServiceStatus", "org.zstack.sdk.ServiceStatus"); @@ -1241,6 +1243,8 @@ public class SourceClassMap { put("org.zstack.sdk.LunInventory", "org.zstack.header.storageDevice.LunInventory"); put("org.zstack.sdk.MaaSUsage", "org.zstack.ai.message.MaaSUsage"); put("org.zstack.sdk.ManagementNodeInventory", "org.zstack.header.managementnode.ManagementNodeInventory"); + put("org.zstack.sdk.MatchEvidence", "org.zstack.ai.message.MatchEvidence"); + put("org.zstack.sdk.MatchedStep", "org.zstack.ai.message.MatchedStep"); put("org.zstack.sdk.MdevDeviceChooser", "org.zstack.pciDevice.virtual.vfio_mdev.MdevDeviceChooser"); put("org.zstack.sdk.MdevDeviceInventory", "org.zstack.pciDevice.virtual.vfio_mdev.MdevDeviceInventory"); put("org.zstack.sdk.MdevDeviceSpecInventory", "org.zstack.pciDevice.specification.mdev.MdevDeviceSpecInventory"); diff --git a/sdk/src/main/java/org/zstack/sdk/AddModelAction.java b/sdk/src/main/java/org/zstack/sdk/AddModelAction.java index 6e3d3d27bc2..eb9a4a4cbf7 100644 --- a/sdk/src/main/java/org/zstack/sdk/AddModelAction.java +++ b/sdk/src/main/java/org/zstack/sdk/AddModelAction.java @@ -73,6 +73,9 @@ public Result throwExceptionIfError() { @Param(required = false, validValues = {"Public"}, nonempty = false, nullElements = false, emptyString = true, noTrim = false) public java.lang.String shareMode; + @Param(required = false, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.lang.String defaultModelServiceUuid; + @Param(required = false) public java.lang.String resourceUuid; diff --git a/sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelAction.java b/sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelAction.java index b9030f9b8ca..51765809a69 100644 --- a/sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelAction.java +++ b/sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelAction.java @@ -17,10 +17,10 @@ public static class Result { public Result throwExceptionIfError() { if (error != null) { throw new ApiException( - String.format("error[code: %s, description: %s, details: %s, globalErrorCode: %s]", error.code, error.description, error.details, error.globalErrorCode) + String.format("error[code: %s, description: %s, details: %s, globalErrorCode: %s]", error.code, error.description, error.details, error.globalErrorCode) ); } - + return this; } } @@ -46,12 +46,6 @@ public Result throwExceptionIfError() { @Param(required = false) public String requestIp; - @NonAPIParam - public long timeout = -1; - - @NonAPIParam - public long pollingInterval = -1; - private Result makeResult(ApiResult res) { Result ret = new Result(); @@ -59,9 +53,9 @@ private Result makeResult(ApiResult res) { ret.error = res.error; return ret; } - + org.zstack.sdk.AutoMatchModelServiceByModelResult value = res.getResult(org.zstack.sdk.AutoMatchModelServiceByModelResult.class); - ret.value = value == null ? new org.zstack.sdk.AutoMatchModelServiceByModelResult() : value; + ret.value = value == null ? new org.zstack.sdk.AutoMatchModelServiceByModelResult() : value; return ret; } diff --git a/sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelResult.java b/sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelResult.java index 95393cb6ea0..9d53b9056fb 100644 --- a/sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelResult.java +++ b/sdk/src/main/java/org/zstack/sdk/AutoMatchModelServiceByModelResult.java @@ -1,10 +1,9 @@ package org.zstack.sdk; +import org.zstack.sdk.MatchedStep; +import org.zstack.sdk.MatchEvidence; + public class AutoMatchModelServiceByModelResult { - /** - * UUID of the recommended ModelServiceVO. May be null if FALLBACK step - * found no Transformers candidate. - */ public java.lang.String recommendedServiceUuid; public void setRecommendedServiceUuid(java.lang.String recommendedServiceUuid) { this.recommendedServiceUuid = recommendedServiceUuid; @@ -13,26 +12,19 @@ public java.lang.String getRecommendedServiceUuid() { return this.recommendedServiceUuid; } - /** - * Which matching step produced this recommendation: - * USER_PRESET | FILE_FORMAT | PIPELINE_TAG | FALLBACK - */ - public java.lang.String matchedByStep; - public void setMatchedByStep(java.lang.String matchedByStep) { + public MatchedStep matchedByStep; + public void setMatchedByStep(MatchedStep matchedByStep) { this.matchedByStep = matchedByStep; } - public java.lang.String getMatchedByStep() { + public MatchedStep getMatchedByStep() { return this.matchedByStep; } - /** - * Diagnostic evidence for the match decision. - */ - public java.util.LinkedHashMap evidence; - public void setEvidence(java.util.LinkedHashMap evidence) { + public MatchEvidence evidence; + public void setEvidence(MatchEvidence evidence) { this.evidence = evidence; } - public java.util.LinkedHashMap getEvidence() { + public MatchEvidence getEvidence() { return this.evidence; } diff --git a/sdk/src/main/java/org/zstack/sdk/MatchEvidence.java b/sdk/src/main/java/org/zstack/sdk/MatchEvidence.java new file mode 100644 index 00000000000..3d297660fc0 --- /dev/null +++ b/sdk/src/main/java/org/zstack/sdk/MatchEvidence.java @@ -0,0 +1,47 @@ +package org.zstack.sdk; + + + +public class MatchEvidence { + + public java.lang.String matchedRefUuid; + public void setMatchedRefUuid(java.lang.String matchedRefUuid) { + this.matchedRefUuid = matchedRefUuid; + } + public java.lang.String getMatchedRefUuid() { + return this.matchedRefUuid; + } + + public java.lang.String matchedFileExtension; + public void setMatchedFileExtension(java.lang.String matchedFileExtension) { + this.matchedFileExtension = matchedFileExtension; + } + public java.lang.String getMatchedFileExtension() { + return this.matchedFileExtension; + } + + public java.lang.String matchedPipelineTag; + public void setMatchedPipelineTag(java.lang.String matchedPipelineTag) { + this.matchedPipelineTag = matchedPipelineTag; + } + public java.lang.String getMatchedPipelineTag() { + return this.matchedPipelineTag; + } + + public java.util.List detectedPipelineTags; + public void setDetectedPipelineTags(java.util.List detectedPipelineTags) { + this.detectedPipelineTags = detectedPipelineTags; + } + public java.util.List getDetectedPipelineTags() { + return this.detectedPipelineTags; + } + + public java.lang.String warning; + public void setWarning(java.lang.String warning) { + this.warning = warning; + } + public java.lang.String getWarning() { + return this.warning; + } + +} diff --git a/sdk/src/main/java/org/zstack/sdk/MatchedStep.java b/sdk/src/main/java/org/zstack/sdk/MatchedStep.java new file mode 100644 index 00000000000..65b0607c986 --- /dev/null +++ b/sdk/src/main/java/org/zstack/sdk/MatchedStep.java @@ -0,0 +1,8 @@ +package org.zstack.sdk; + +public enum MatchedStep { + USER_PRESET, + FILE_FORMAT, + PIPELINE_TAG, + FALLBACK, +} diff --git a/sdk/src/main/java/org/zstack/sdk/ModelServiceRefInventory.java b/sdk/src/main/java/org/zstack/sdk/ModelServiceRefInventory.java index 93f3f18ea78..e658e48914c 100644 --- a/sdk/src/main/java/org/zstack/sdk/ModelServiceRefInventory.java +++ b/sdk/src/main/java/org/zstack/sdk/ModelServiceRefInventory.java @@ -28,4 +28,12 @@ public java.lang.String getModelServiceUuid() { return this.modelServiceUuid; } + public java.lang.Boolean isDefault; + public void setIsDefault(java.lang.Boolean isDefault) { + this.isDefault = isDefault; + } + public java.lang.Boolean getIsDefault() { + return this.isDefault; + } + } From 165548d901bf88ea29a2573cb3cdea31ba8ff9ca Mon Sep 17 00:00:00 2001 From: "ye.zou" Date: Thu, 7 May 2026 15:24:44 +0800 Subject: [PATCH 5/7] [ai]: make schema strict-mode safe Review found the new ModelServiceRefVO createDate column used a zero-date default, which is unsafe under strict SQL mode. The upgrade now adds the column as nullable, backfills existing rows, then tightens it to NOT NULL with CURRENT_TIMESTAMP. This also adds the shared AI error code consumed by the premium review fix. Constraint: Premium branch references CloudOperationsErrorCode from zstack utils Rejected: Keep zero-date default | fails SQL coding rules and strict-mode upgrades Confidence: high Scope-risk: narrow Tested: JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 mvn -pl utils -DskipTests install Tested: JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 mvn -pl sdk -DskipTests install Not-tested: Full database migration against a live strict-mode MySQL instance Resolves: ZSTAC-84025 Change-Id: Ic0a63eec1e3db23e4bb8843efd8e2aee143dce21 --- conf/db/upgrade/V5.5.22__schema.sql | 16 +++++++++++++++- .../clouderrorcode/CloudOperationsErrorCode.java | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/conf/db/upgrade/V5.5.22__schema.sql b/conf/db/upgrade/V5.5.22__schema.sql index f680641fbdc..000e130680c 100644 --- a/conf/db/upgrade/V5.5.22__schema.sql +++ b/conf/db/upgrade/V5.5.22__schema.sql @@ -14,4 +14,18 @@ CALL ADD_COLUMN('ModelVO', 'manifestJson', 'TEXT', 1, NULL); -- ZSTAC-84025: Add createDate/lastOpDate to ModelServiceRefVO so the auto-match Matcher can -- pick the earliest isDefault=true row when DB has the rare 2+ defaults anomaly (Q5). ALTER TABLE `zstack`.`ModelServiceRefVO` ADD COLUMN `lastOpDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; -ALTER TABLE `zstack`.`ModelServiceRefVO` ADD COLUMN `createDate` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00'; +ALTER TABLE `zstack`.`ModelServiceRefVO` ADD COLUMN `createDate` TIMESTAMP NULL DEFAULT NULL; + +DROP PROCEDURE IF EXISTS backfill_model_service_ref_create_date; +DELIMITER $$ +CREATE PROCEDURE backfill_model_service_ref_create_date() +BEGIN + UPDATE `zstack`.`ModelServiceRefVO` + SET `createDate` = CURRENT_TIMESTAMP + WHERE `createDate` IS NULL OR `createDate` = '0000-00-00 00:00:00'; +END $$ +DELIMITER ; +CALL backfill_model_service_ref_create_date(); +DROP PROCEDURE IF EXISTS backfill_model_service_ref_create_date; + +ALTER TABLE `zstack`.`ModelServiceRefVO` MODIFY COLUMN `createDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; 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 c38599da944..0c66ce52f55 100644 --- a/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java +++ b/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java @@ -14944,6 +14944,7 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_AI_10163 = "ORG_ZSTACK_AI_10163"; public static final String ORG_ZSTACK_AI_10164 = "ORG_ZSTACK_AI_10164"; public static final String ORG_ZSTACK_AI_10165 = "ORG_ZSTACK_AI_10165"; + public static final String ORG_ZSTACK_AI_10166 = "ORG_ZSTACK_AI_10166"; public static final String ORG_ZSTACK_CORE_CLOUDBUS_10000 = "ORG_ZSTACK_CORE_CLOUDBUS_10000"; From 1b617a79a52d76d50cecc5f2746946e6a19ebbcc Mon Sep 17 00:00:00 2001 From: "ye.zou" Date: Thu, 7 May 2026 15:49:23 +0800 Subject: [PATCH 6/7] [ai]: avoid second timestamp default CI hit MySQL error 1293 because ModelServiceRefVO.lastOpDate already uses TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, and older MySQL/MariaDB versions allow only one automatic TIMESTAMP column per table. Keep createDate non-zero with a fixed default while the migration backfills existing rows with CURRENT_TIMESTAMP and premium ModelServiceRefVO prePersist sets real creation time for new JPA inserts. Constraint: Older MySQL/MariaDB permits only one automatic TIMESTAMP column per table Rejected: DEFAULT CURRENT_TIMESTAMP on createDate | conflicts with lastOpDate automatic timestamp Confidence: high Scope-risk: narrow Tested: git diff --check Tested: rg createDate/current timestamp/default checks in V5.5.22__schema.sql Tested: JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 mvn -pl utils -DskipTests install Not-tested: Full Flyway migration against the CI MySQL image Resolves: ZSTAC-84025 Change-Id: I095a6818443441409c84988dafbb6c16ef5d8e54 --- conf/db/upgrade/V5.5.22__schema.sql | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/conf/db/upgrade/V5.5.22__schema.sql b/conf/db/upgrade/V5.5.22__schema.sql index 000e130680c..5d241582609 100644 --- a/conf/db/upgrade/V5.5.22__schema.sql +++ b/conf/db/upgrade/V5.5.22__schema.sql @@ -28,4 +28,7 @@ DELIMITER ; CALL backfill_model_service_ref_create_date(); DROP PROCEDURE IF EXISTS backfill_model_service_ref_create_date; -ALTER TABLE `zstack`.`ModelServiceRefVO` MODIFY COLUMN `createDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; +-- Older MySQL/MariaDB versions allow only one TIMESTAMP column with CURRENT_TIMESTAMP +-- in DEFAULT or ON UPDATE. lastOpDate already uses it, so keep createDate non-zero +-- and let ModelServiceRefVO.@PrePersist populate the real creation time for new rows. +ALTER TABLE `zstack`.`ModelServiceRefVO` MODIFY COLUMN `createDate` TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00'; From 621c2958a0e5bd2ea47b9155ac9c531f947845af Mon Sep 17 00:00:00 2001 From: "ye.zou" Date: Thu, 7 May 2026 15:57:41 +0800 Subject: [PATCH 7/7] [ai]: drop redundant isDefault backfill Code review noted that adding ModelServiceRefVO.isDefault as NOT NULL DEFAULT 0 already initializes existing rows, so the immediate UPDATE to the same value only adds unnecessary migration work. The schema keeps the defaulted column and removes the redundant write.\n\nConstraint: MySQL initializes existing rows when adding a NOT NULL column with a DEFAULT\nRejected: Keep explicit UPDATE | unnecessary table write during upgrade\nConfidence: high\nScope-risk: narrow\nTested: git diff --check\nTested: rg check for redundant isDefault UPDATE and zero-date defaults in V5.5.22__schema.sql\nTested: JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 mvn -pl utils -DskipTests install\nNot-tested: Full Flyway migration against CI database image Resolves: ZSTAC-84025 Change-Id: I062d884ed6232fa603a6ecfd68c2124db85c5ed6 --- conf/db/upgrade/V5.5.22__schema.sql | 3 --- 1 file changed, 3 deletions(-) diff --git a/conf/db/upgrade/V5.5.22__schema.sql b/conf/db/upgrade/V5.5.22__schema.sql index 5d241582609..94b14f06535 100644 --- a/conf/db/upgrade/V5.5.22__schema.sql +++ b/conf/db/upgrade/V5.5.22__schema.sql @@ -4,9 +4,6 @@ CALL ADD_COLUMN('ModelVO', 'pipelineTag', 'VARCHAR(64)', 1, NULL); -- ZSTAC-84025: Add isDefault to ModelServiceRefVO to mark the default inference template per model ALTER TABLE `zstack`.`ModelServiceRefVO` ADD COLUMN `isDefault` TINYINT(1) NOT NULL DEFAULT 0; --- Backfill isDefault: all existing refs default to 0 (no default template designated) -UPDATE `zstack`.`ModelServiceRefVO` SET `isDefault` = 0; - -- ZSTAC-84025-F2: Add manifestJson to ModelVO so Step 1 (file format) of the auto-match Matcher can -- parse file_types/file_extensions from the manifest returned by the aios agent. CALL ADD_COLUMN('ModelVO', 'manifestJson', 'TEXT', 1, NULL);