Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -472,9 +472,9 @@ public void done(ErrorCodeList errorCodeList) {
.flatMap(List::stream).map(VmCdRomInventory::getUuid)
.collect(Collectors.toList());
dbf.removeByPrimaryKeys(cdRomUuids, VmCdRomVO.class);
dbf.removeByPrimaryKeys(vminvs.stream().map(p -> p.getInventory().getUuid())
.collect(Collectors.toList()),
VmInstanceVO.class);

List<String> vmUuidList = transform(vminvs, p -> p.getInventory().getUuid());
dbf.removeByPrimaryKeys(vmUuidList, VmInstanceVO.class);
}

completion.success();
Expand Down
19 changes: 14 additions & 5 deletions conf/db/zsv/V5.0.0__schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,35 @@ CREATE TABLE IF NOT EXISTS `zstack`.`VmHostFileVO` (
`uuid` char(32) NOT NULL UNIQUE,
`vmInstanceUuid` char(32) NOT NULL,
`hostUuid` char(32) NOT NULL,
`type` varchar(64) NOT NULL COMMENT 'NvRam, TpmState, NvRamBackup, TpmStateBackup',
`type` varchar(64) NOT NULL COMMENT 'NvRam, TpmState',
`path` varchar(1024) NOT NULL COMMENT 'Absolute path of the file on the host',
`lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`createDate` timestamp NOT NULL DEFAULT '1999-12-31 23:59:59',
PRIMARY KEY (`uuid`),
INDEX `idxVmHostFileVOVmInstanceUuid` (`vmInstanceUuid`),
INDEX `idxVmHostFileVOHostUuid` (`hostUuid`),
CONSTRAINT `fkVmHostFileVOVmInstanceVO` FOREIGN KEY (`vmInstanceUuid`) REFERENCES `VmInstanceEO` (`uuid`) ON DELETE CASCADE,
CONSTRAINT `fkVmHostFileVOHostVO` FOREIGN KEY (`hostUuid`) REFERENCES `HostEO` (`uuid`) ON DELETE CASCADE,
UNIQUE KEY `ukVmHostFileVO` (`vmInstanceUuid`, `hostUuid`, `type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `zstack`.`VmHostFileContentVO` (
CREATE TABLE IF NOT EXISTS `zstack`.`VmHostBackupFileVO` (
`uuid` char(32) NOT NULL UNIQUE,
`vmInstanceUuid` char(32) NOT NULL,
`type` varchar(64) NOT NULL COMMENT 'NvRam, TpmState',
`lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`createDate` timestamp NOT NULL DEFAULT '1999-12-31 23:59:59',
PRIMARY KEY (`uuid`),
INDEX `idxVmHostBackupFileVOVmInstanceUuid` (`vmInstanceUuid`),
UNIQUE KEY `ukVmHostBackupFileVO` (`vmInstanceUuid`, `type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `zstack`.`VmHostFileContentVO` (
`uuid` char(32) NOT NULL UNIQUE COMMENT 'VmHostFileVO.uuid or VmHostBackupFileVO.uuid',
`content` MEDIUMBLOB DEFAULT NULL,
`format` varchar(64) NOT NULL COMMENT 'Raw, TarballGzip',
`lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`createDate` timestamp NOT NULL DEFAULT '1999-12-31 23:59:59',
PRIMARY KEY (`uuid`),
CONSTRAINT `fkVmHostFileContentVOVmHostFileVO` FOREIGN KEY (`uuid`) REFERENCES `VmHostFileVO` (`uuid`) ON DELETE CASCADE
CONSTRAINT `fkVmHostFileContentVOResourceVO` FOREIGN KEY (`uuid`) REFERENCES `ResourceVO` (`uuid`) ON DELETE CASCADE
Comment on lines +26 to +44
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

缺少升级迁移,老库上的备份文件会卡在旧模型里。

这里新增了 VmHostBackupFileVO,同时把 VmHostFileContentVO 的关联语义切到了 ResourceVO,但当前写法只会影响全新库。对已升级环境,已存在的 VmHostFileContentVO 不会被重建,外键仍然指向旧的 VmHostFileVO;另外旧表里的 NvRamBackup/TpmStateBackup 历史记录也没有迁到新表。结果就是升级后备份文件元数据/内容可能一部分还留在旧模型里,新的 clone/TPM 路径会出现查不到或插入失败。

建议补一段幂等迁移:条件式创建新表、把旧 VmHostFileVO 中的 backup 类型搬到 VmHostBackupFileVO(并做类型映射)、再按 information_schema 条件式重建 VmHostFileContentVO 的外键到 ResourceVO

As per coding guidelines, **/*.sql: Review the SQL code, make sure has no errors and confirm that: Upgrading scene has been carefully handled.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@conf/db/zsv/V5.0.0__schema.sql` around lines 28 - 47, Add an idempotent
migration that (1) conditionally CREATE TABLE VmHostBackupFileVO if not exists
(preserving PRIMARY KEY uuid, UNIQUE ukVmHostFileVO and FK
fkVmHostBackupFileVOVmInstanceVO), (2) MOVE existing backup rows from the old
VmHostFileVO into VmHostBackupFileVO mapping old types (e.g. NvRamBackup ->
NvRam, TpmStateBackup -> TpmState), preserving uuid, vmInstanceUuid,
createDate/lastOpDate and skipping duplicates, (3) update VmHostFileContentVO
foreign key: check information_schema for existing FK pointing to VmHostFileVO
and, if present, DROP that FK and ADD CONSTRAINT fkVmHostFileContentVOResourceVO
to reference ResourceVO(uuid) (do this conditionally so repeated runs are safe),
and (4) ensure all data rows in VmHostFileContentVO whose uuid belonged to moved
backup files remain consistent (adjust uuids or copy records as needed) and wrap
the whole migration in transactions to be idempotent and safe for upgrades.

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- Feature: KMS | ZSPHER-46, ZSPHER-60, ZSPHER-61, ZSPHER-62
Expand Down
1 change: 1 addition & 0 deletions conf/persistence.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<class>org.zstack.header.managementnode.ManagementNodeContextVO</class>
<class>org.zstack.header.tpm.entity.TpmVO</class>
<class>org.zstack.header.vm.additions.VmHostFileVO</class>
<class>org.zstack.header.vm.additions.VmHostBackupFileVO</class>
<class>org.zstack.header.vm.additions.VmHostFileContentVO</class>
<class>org.zstack.header.zone.ZoneVO</class>
<class>org.zstack.header.zone.ZoneEO</class>
Expand Down
4 changes: 4 additions & 0 deletions conf/springConfigXml/Kvm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -262,13 +262,17 @@
<bean id="KvmSecureBootManager" class="org.zstack.kvm.efi.KvmSecureBootManager">
<zstack:plugin>
<zstack:extension interface="org.zstack.header.Component"/>
<zstack:extension interface="org.zstack.header.Service" />
</zstack:plugin>
</bean>

<bean id="KvmSecureBootExtensions" class="org.zstack.kvm.efi.KvmSecureBootExtensions">
<zstack:plugin>
<zstack:extension interface="org.zstack.kvm.KVMStartVmExtensionPoint" />
<zstack:extension interface="org.zstack.header.vm.PreVmInstantiateResourceExtensionPoint" />
<zstack:extension interface="org.zstack.header.vm.VmInstanceDestroyExtensionPoint" />
</zstack:plugin>
</bean>

<bean id="DummyTpmEncryptedResourceKeyBackend" class="org.zstack.kvm.tpm.DummyTpmEncryptedResourceKeyBackend"/>
</beans>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@PythonClass
public interface VmInstanceConstant {
String SERVICE_ID = "vmInstance";
String SECURE_BOOT_SERVICE_ID = "secureBoot";
String ACTION_CATEGORY = "instance";
@PythonClass
String USER_VM_TYPE = "UserVm";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package org.zstack.header.vm.additions;

import org.zstack.header.vm.VmInstanceEO;
import org.zstack.header.vo.EntityGraph;
import org.zstack.header.vo.ForeignKey;
import org.zstack.header.vo.ResourceVO;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Table;
import java.sql.Timestamp;

/**
* Virtual Machine Host-side File Value Object (Backup files)
*
* Include: NvRam / TpmState files
*/
@Entity
@Table
@EntityGraph(
friends = {
@EntityGraph.Neighbour(type = VmInstanceEO.class, myField = "vmInstanceUuid", targetField = "uuid"),
}
)
public class VmHostBackupFileVO extends ResourceVO {
@Column
@ForeignKey(parentEntityClass = VmInstanceEO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE)
private String vmInstanceUuid;
@Column
@Enumerated(EnumType.STRING)
private VmHostFileType type;
@Column
private Timestamp createDate;
@Column
private Timestamp lastOpDate;

public String getVmInstanceUuid() {
return vmInstanceUuid;
}

public void setVmInstanceUuid(String vmInstanceUuid) {
this.vmInstanceUuid = vmInstanceUuid;
}

public VmHostFileType getType() {
return type;
}

public void setType(VmHostFileType type) {
this.type = type;
}

public Timestamp getCreateDate() {
return createDate;
}

public void setCreateDate(Timestamp createDate) {
this.createDate = createDate;
}

public Timestamp getLastOpDate() {
return lastOpDate;
}

public void setLastOpDate(Timestamp lastOpDate) {
this.lastOpDate = lastOpDate;
}

@Override
public String toString() {
return "VmHostBackupFileVO{" +
"vmInstanceUuid='" + vmInstanceUuid + '\'' +
", type=" + type +
", createDate=" + createDate +
", lastOpDate=" + lastOpDate +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.zstack.header.vm.additions;

import org.zstack.header.vo.ResourceVO_;

import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.StaticMetamodel;
import java.sql.Timestamp;

@StaticMetamodel(VmHostBackupFileVO.class)
public class VmHostBackupFileVO_ extends ResourceVO_ {
public static volatile SingularAttribute<VmHostBackupFileVO, String> vmInstanceUuid;
public static volatile SingularAttribute<VmHostBackupFileVO, VmHostFileType> type;
public static volatile SingularAttribute<VmHostBackupFileVO, Timestamp> createDate;
public static volatile SingularAttribute<VmHostBackupFileVO, Timestamp> lastOpDate;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,4 @@
public enum VmHostFileType {
NvRam,
TpmState,
NvRamBackup,
TpmStateBackup,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.zstack.kvm.efi;

import org.zstack.header.message.NeedReplyMessage;

import java.util.List;

public class CloneVmHostFileMsg extends NeedReplyMessage {
private String srcVmUuid;
private List<String> dstVmUuidList;
private Boolean resetTpm;

public String getSrcVmUuid() {
return srcVmUuid;
}

public void setSrcVmUuid(String srcVmUuid) {
this.srcVmUuid = srcVmUuid;
}

public List<String> getDstVmUuidList() {
return dstVmUuidList;
}

public void setDstVmUuidList(List<String> dstVmUuidList) {
this.dstVmUuidList = dstVmUuidList;
}

public Boolean getResetTpm() {
return resetTpm;
}

public void setResetTpm(Boolean resetTpm) {
this.resetTpm = resetTpm;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.zstack.kvm.efi;

import org.zstack.header.message.MessageReply;

public class CloneVmHostFileReply extends MessageReply {
}
Loading