Skip to content

Commit 17b20fd

Browse files
authored
Merge pull request #682 from jschoiRR/mold-main#2025
[Mold API] 데이터베이스 업그레이드 체크시 버그 수정/ 빌드 오류 소스 정리작업
2 parents 818773e + 2a6763d commit 17b20fd

File tree

9 files changed

+4799
-4727
lines changed

9 files changed

+4799
-4727
lines changed

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,6 +1311,7 @@ public class ApiConstants {
13111311
public static final String CURRENT_VM_ID = "currentvmid";
13121312

13131313
public static final String RESULT_REDFISH_DATA = "redfishdata";
1314+
public static final String EXTERNAL_ENTITY = "externalEntity";
13141315

13151316
/**
13161317
* This enum specifies IO Drivers, each option controls specific policies on I/O.

engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java

Lines changed: 88 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -451,23 +451,26 @@ public void check() {
451451
try {
452452
initializeDatabaseEncryptors();
453453

454-
// DB version 테이블의 latest 행 삭제
455-
final CloudStackVersion dbVersionInitial = CloudStackVersion.parse(_dao.getCurrentVersion());
456-
deleteCurrentVersionRowIfPresent(dbVersionInitial);
457-
454+
// 1) 코드(설치될) 버전 먼저 파싱
458455
final String currentVersionValue = this.getClass().getPackage().getImplementationVersion();
459456
if (StringUtils.isBlank(currentVersionValue)) return;
460457
final CloudStackVersion currentVersion = CloudStackVersion.parse(currentVersionValue);
461458

459+
// 2) DB 최신 버전 읽기
460+
final CloudStackVersion dbLatestVersion = CloudStackVersion.parse(_dao.getCurrentVersion());
461+
462+
// 3) 베이스라인 보장 + (db==code) 같으면 삭제 스킵
463+
enforceBaselineThenDeleteLastVersionIfNeeded(dbLatestVersion, currentVersion);
464+
462465
///////////////////// Ablestack 업그레이드 //////////////////////////
463466
beforeUpgradeAblestack("Bronto");
464467
beforeUpgradeAblestack("Cerato");
465468
beforeUpgradeAblestack("Diplo");
466469
///////////////////// Ablestack 업그레이드 //////////////////////////
467470

468-
// 삭제 후 DB 버전 재조회
471+
// 4) 재조회 후 본 업그레이드 진행
469472
final CloudStackVersion dbVersion = CloudStackVersion.parse(_dao.getCurrentVersion());
470-
LOGGER.info("After deletion, DB version = {} , Code version = {}", dbVersion, currentVersion);
473+
LOGGER.info("After enforcement, DB version = {} , Code version = {}", dbVersion, currentVersion);
471474

472475
String csVersion = SystemVmTemplateRegistration.parseMetadataFile();
473476
final CloudStackVersion sysVmVersion = CloudStackVersion.parse(csVersion);
@@ -495,6 +498,85 @@ public void check() {
495498
}
496499
}
497500

501+
private void enforceBaselineThenDeleteLastVersionIfNeeded(final CloudStackVersion dbLatestVersion,
502+
final CloudStackVersion currentVersion) {
503+
final String BASELINE_VERSION = "4.0.0";
504+
final TransactionLegacy txn = TransactionLegacy.open("enforce-baseline-then-delete-last");
505+
txn.start();
506+
try {
507+
final Connection conn = txn.getConnection();
508+
509+
// 0) DB 최신버전 == 코드버전이면 삭제/삽입 모두 스킵
510+
final boolean sameAsCode = (dbLatestVersion != null
511+
&& currentVersion != null
512+
&& dbLatestVersion.compareTo(currentVersion) == 0);
513+
if (sameAsCode) {
514+
LOGGER.info("DB latest version equals code version (db={}, code={}). Skipping baseline insert and deletion.",
515+
dbLatestVersion, currentVersion);
516+
txn.commit();
517+
return;
518+
}
519+
520+
// 1) sameAsCode == false 인 경우에만 베이스라인 보장 (없으면 삽입)
521+
final String insertIfMissingSql =
522+
"INSERT INTO `cloud`.`version` (`version`, `step`, `updated`) " +
523+
"SELECT ?, 'Complete', NOW() FROM DUAL " +
524+
"WHERE NOT EXISTS (SELECT 1 FROM `cloud`.`version` WHERE `version` = ?)";
525+
try (PreparedStatement ins = conn.prepareStatement(insertIfMissingSql)) {
526+
ins.setString(1, BASELINE_VERSION);
527+
ins.setString(2, BASELINE_VERSION);
528+
int inserted = ins.executeUpdate();
529+
if (inserted > 0) {
530+
LOGGER.info("Inserted baseline version row: {}", BASELINE_VERSION);
531+
txn.commit();
532+
return; // 여기서 종료
533+
}
534+
}
535+
536+
// 2) 삭제 대상: dbLatestVersion 의 최신 1건 (단, 베이스라인이면 삭제 금지)
537+
if (dbLatestVersion != null
538+
&& currentVersion != null
539+
&& dbLatestVersion.compareTo(currentVersion) != 0
540+
&& !BASELINE_VERSION.equals(dbLatestVersion.toString())) {
541+
542+
final String deleteLatestOneSql =
543+
"DELETE FROM `cloud`.`version` " +
544+
"WHERE `id` IN ( " +
545+
" SELECT id FROM ( " +
546+
" SELECT `id` " +
547+
" FROM `cloud`.`version` " +
548+
" WHERE `version` = ? AND (`step` IS NULL OR `step` = 'Complete') " +
549+
" ORDER BY COALESCE(`updated`, FROM_UNIXTIME(0)) DESC " +
550+
" LIMIT 1 " +
551+
" ) AS _x " +
552+
")";
553+
try (PreparedStatement delLatest = conn.prepareStatement(deleteLatestOneSql)) {
554+
delLatest.setString(1, dbLatestVersion.toString());
555+
int deleted = delLatest.executeUpdate();
556+
if (deleted > 0) {
557+
LOGGER.warn("Deleted {} latest row for version {}", deleted, dbLatestVersion.toString());
558+
txn.commit();
559+
return;
560+
} else {
561+
LOGGER.info("No deletable row found for targetVersion={}; skipping targeted delete.",
562+
dbLatestVersion.toString());
563+
}
564+
}
565+
} else {
566+
// null-safe 로깅
567+
LOGGER.info("Target version is baseline or null ({}). Skipping targeted delete.",
568+
String.valueOf(dbLatestVersion));
569+
}
570+
571+
txn.commit();
572+
} catch (SQLException e) {
573+
txn.rollback();
574+
LOGGER.error("Failed in enforceBaselineThenDeleteLastVersionIfNeeded", e);
575+
} finally {
576+
txn.close();
577+
}
578+
}
579+
498580
// Cloudstack DB 업데이트 전 Ablestack DB 업데이트 진행
499581
public void beforeUpgradeAblestack (String ablestackVersion) {
500582
TransactionLegacy txn = TransactionLegacy.open("Upgrade");
@@ -530,27 +612,6 @@ public void beforeUpgradeAblestack (String ablestackVersion) {
530612
}
531613
}
532614

533-
private void deleteCurrentVersionRowIfPresent(final CloudStackVersion currentVersion) {
534-
TransactionLegacy txn = TransactionLegacy.open("delete-current-version-row");
535-
txn.start();
536-
try {
537-
Connection conn = txn.getConnection();
538-
try (PreparedStatement ps = conn.prepareStatement(
539-
"DELETE FROM `cloud`.`version` WHERE `version` = ? AND (`step` IS NULL OR `step` = 'Complete')")) {
540-
ps.setString(1, currentVersion.toString());
541-
int deleted = ps.executeUpdate();
542-
LOGGER.warn("Deleted {} row(s) from cloud.version for {}", deleted, currentVersion);
543-
}
544-
txn.commit();
545-
} catch (SQLException e) {
546-
txn.rollback();
547-
LOGGER.error("Unable to delete current version row", e);
548-
throw new CloudRuntimeException("Unable to delete current version row", e);
549-
} finally {
550-
txn.close();
551-
}
552-
}
553-
554615
// Cloudstack DB 업데이트 후 Ablestack DB 업데이트 진행
555616
public void afterUpgradeAblestack (String ablestackVersion) {
556617
TransactionLegacy txn = TransactionLegacy.open("Upgrade");

engine/schema/src/main/resources/META-INF/db/schema-41720to41800.sql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ CALL `cloud`.`ADD_GUEST_OS_AND_HYPERVISOR_MAPPING` (1, 'Red Hat Enterprise Linux
4343
CALL `cloud`.`ADD_GUEST_OS_AND_HYPERVISOR_MAPPING` (1, 'Rocky Linux 9', 'VMware', '7.0.3.0', 'otherLinux64Guest');
4444

4545
-- Add support for VMware 8.0 and 8.0a (8.0.0.1)
46-
`cloud`.`hypervisor_capabilities` (uuid, hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_data_volumes_limit, max_hosts_per_cluster, storage_motion_supported, vm_snapshot_enabled) values (UUID(), 'VMware', '8.0', 1024, 0, 59, 64, 1, 1);
46+
INSERT IGNORE INTO `cloud`.`hypervisor_capabilities` (uuid, hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_data_volumes_limit, max_hosts_per_cluster, storage_motion_supported, vm_snapshot_enabled) values (UUID(), 'VMware', '8.0', 1024, 0, 59, 64, 1, 1);
4747
INSERT IGNORE INTO `cloud`.`hypervisor_capabilities` (uuid, hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_data_volumes_limit, max_hosts_per_cluster, storage_motion_supported, vm_snapshot_enabled) values (UUID(), 'VMware', '8.0.0.1', 1024, 0, 59, 64, 1, 1);
4848
INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) SELECT UUID(),'VMware', '8.0', guest_os_name, guest_os_id, utc_timestamp(), 0 FROM `cloud`.`guest_os_hypervisor` WHERE hypervisor_type='VMware' AND hypervisor_version='7.0.3.0';
4949
INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) SELECT UUID(),'VMware', '8.0.0.1', guest_os_name, guest_os_id, utc_timestamp(), 0 FROM `cloud`.`guest_os_hypervisor` WHERE hypervisor_type='VMware' AND hypervisor_version='7.0.3.0';
@@ -257,11 +257,11 @@ WHERE n.`state` = 'Setup'
257257
AND n.`removed` IS NULL
258258
AND n.`guest_type` = 'Isolated'
259259
AND o.`is_persistent` = 1
260-
AND m.network_offering_id IS NULL; -- 서비스 매핑이 한 건도 없는 오퍼링만
260+
AND m.network_offering_id IS NULL;
261261

262262
----- PR Quota custom tariffs #5909---
263263
-- Create column 'uuid'
264-
CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.quota_tariff','uuid','VARCHAR(40) DEFAULT NULL');
264+
CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.quota_tariff','uuid','VARCHAR(40)');
265265

266266
UPDATE `cloud_usage`.`quota_tariff`
267267
SET `uuid` = UUID()

plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/SAML2LogoutAPIAuthenticatorCmd.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import org.apache.cloudstack.saml.SAML2AuthManager;
3131
import org.apache.cloudstack.saml.SAMLPluginConstants;
3232
import org.apache.cloudstack.saml.SAMLProviderMetadata;
33-
import org.apache.cloudstack.saml.SAMLProviderMetadata;
3433
import org.apache.cloudstack.saml.SAMLUtils;
3534
import org.opensaml.DefaultBootstrap;
3635
import org.opensaml.saml2.core.LogoutRequest;

server/src/main/java/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10022,7 +10022,7 @@ public UserVm createCloneVM(CloneVMCmd cmd, Long rootVolumeId) throws Concurrent
1002210022
null, new HashMap<>(), null, new HashMap<>(), dynamicScalingEnabled, null, null);
1002310023
}
1002410024
} catch (CloudRuntimeException e) {
10025-
_templateMgr.delete(curAccount.getId(), template.getId(), zoneId);
10025+
// _templateMgr.delete(curAccount.getId(), template.getId(), zoneId);
1002610026
throw new CloudRuntimeException("Unable to create the clone VM record");
1002710027
}
1002810028
return vmResult;

ui/public/locales/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4877,5 +4877,6 @@
48774877
"label.predictedmedialifeleftpercent": "Media Life",
48784878
"label.hardware.storage.enclosurelist": "Enclosures",
48794879
"label.switches": "Switches",
4880-
"message.redfishdata.loading": "Query may take some time."
4880+
"message.redfishdata.loading": "Query may take some time.",
4881+
"message.migrate.instance.to.host.extraconfig" : "<br>(The virtual machine is using host devices (ExtraConfig) and live migration may fail. Do you want to proceed anyway?)"
48814882
}

0 commit comments

Comments
 (0)