Skip to content

Commit 250163f

Browse files
author
gitlab
committed
Merge branch 'zsv-ldap@@2' into 'feature-zsv-5.0.0-vm-support-vtpm-and-secuceboot'
<feature>[kvm]: introduce SyncVmHostFilesFromHostMsg See merge request zstackio/zstack!9430
2 parents 4c4b4c4 + 5153432 commit 250163f

4 files changed

Lines changed: 254 additions & 200 deletions

File tree

plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootExtensions.java

Lines changed: 30 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.zstack.header.tpm.entity.TpmVO_;
3030
import org.zstack.header.vm.DiskAO;
3131
import org.zstack.header.vm.PreVmInstantiateResourceExtensionPoint;
32+
import org.zstack.header.vm.VmInstanceConstant;
3233
import org.zstack.header.vm.VmInstanceDestroyExtensionPoint;
3334
import org.zstack.header.vm.VmInstanceInventory;
3435
import org.zstack.header.vm.VmInstanceSpec;
@@ -37,7 +38,6 @@
3738
import org.zstack.header.vm.VmPreMigrationExtensionPoint;
3839
import org.zstack.header.vm.additions.VmHostBackupFileVO;
3940
import org.zstack.header.vm.additions.VmHostBackupFileVO_;
40-
import org.zstack.header.vm.additions.VmHostFileContentFormat;
4141
import org.zstack.header.vm.additions.VmHostFileContentVO;
4242
import org.zstack.header.vm.additions.VmHostFileContentVO_;
4343
import org.zstack.header.vm.additions.VmHostFileType;
@@ -70,7 +70,6 @@
7070
import javax.persistence.Tuple;
7171
import java.sql.Timestamp;
7272
import java.time.Instant;
73-
import java.util.ArrayList;
7473
import java.util.Base64;
7574
import java.util.Collections;
7675
import java.util.List;
@@ -82,8 +81,6 @@
8281
import static org.zstack.header.vm.VmMigrationType.HostMigration;
8382
import static org.zstack.kvm.KVMConstant.*;
8483
import static org.zstack.utils.CollectionDSL.list;
85-
import static org.zstack.utils.CollectionUtils.findOneOrNull;
86-
import static org.zstack.utils.CollectionUtils.transform;
8784

8885
public class KvmSecureBootExtensions implements KVMStartVmExtensionPoint,
8986
PreVmInstantiateResourceExtensionPoint,
@@ -224,135 +221,6 @@ public void fail(ErrorCode errorCode) {
224221
.start();
225222
}
226223

227-
public static class SyncVmHostFilesFromHostContext {
228-
public String hostUuid;
229-
public String vmUuid;
230-
231-
public String nvRamPath;
232-
public String tpmStateFolder;
233-
}
234-
235-
public void syncVmHostFilesFromHost(SyncVmHostFilesFromHostContext context, Completion completion) {
236-
KvmCommandSender sender = new KvmCommandSender(context.hostUuid);
237-
238-
ReadVmHostFileContentCmd cmd = new ReadVmHostFileContentCmd();
239-
cmd.setHostFiles(new ArrayList<>());
240-
if (context.tpmStateFolder != null) {
241-
VmHostFileTO to = new VmHostFileTO();
242-
to.setPath(context.tpmStateFolder);
243-
to.setType(VmHostFileType.TpmState.toString());
244-
cmd.getHostFiles().add(to);
245-
}
246-
if (context.nvRamPath != null) {
247-
VmHostFileTO to = new VmHostFileTO();
248-
to.setPath(context.nvRamPath);
249-
to.setType(VmHostFileType.NvRam.toString());
250-
cmd.getHostFiles().add(to);
251-
}
252-
253-
sender.send(cmd, READ_VM_HOST_FILE_PATH, wrapper -> {
254-
ReadVmHostFileContentResponse readRsp = wrapper.getResponse(ReadVmHostFileContentResponse.class);
255-
return readRsp.isSuccess() ? null :
256-
operr("failed to read file content response").withException(readRsp.getError());
257-
}, new ReturnValueCompletion<KvmResponseWrapper>(completion) {
258-
@Override
259-
public void success(KvmResponseWrapper wrapper) {
260-
ReadVmHostFileContentResponse readRsp = wrapper.getResponse(ReadVmHostFileContentResponse.class);
261-
if (!readRsp.isSuccess()) {
262-
completion.fail(operr("failed to read file content response").withException(readRsp.getError()));
263-
return;
264-
}
265-
266-
final List<VmHostFileVO> existsFiles = Q.New(VmHostFileVO.class)
267-
.eq(VmHostFileVO_.vmInstanceUuid, context.vmUuid)
268-
.eq(VmHostFileVO_.hostUuid, context.hostUuid)
269-
.in(VmHostFileVO_.path, cmd.getPaths())
270-
.list();
271-
final List<String> existsContentUuid;
272-
if (!existsFiles.isEmpty()) {
273-
existsContentUuid = Q.New(VmHostFileContentVO.class)
274-
.in(VmHostFileContentVO_.uuid, transform(existsFiles, VmHostFileVO::getUuid))
275-
.select(VmHostFileContentVO_.uuid)
276-
.listValues();
277-
} else {
278-
existsContentUuid = Collections.emptyList();
279-
}
280-
281-
List<ErrorCode> errors = new ArrayList<>();
282-
for (String path : cmd.getPaths()) {
283-
VmHostFileTO to = findOneOrNull(readRsp.getHostFiles(), item -> item.getPath().equals(path));
284-
if (to == null) {
285-
continue;
286-
}
287-
if (to.getError() != null) {
288-
errors.add(operr("failed to read file %s", path)
289-
.withOpaque("path", path)
290-
.withException(to.getError()));
291-
continue;
292-
}
293-
294-
VmHostFileType type = Objects.equals(path, context.nvRamPath) ?
295-
VmHostFileType.NvRam : VmHostFileType.TpmState;
296-
297-
VmHostFileVO file = findOneOrNull(existsFiles, item -> item.getPath().equals(path));
298-
boolean fileExists = file != null;
299-
300-
Timestamp now = Timestamp.from(Instant.now());
301-
if (fileExists) {
302-
SQL.New(VmHostFileVO.class)
303-
.eq(VmHostFileVO_.uuid, file.getUuid())
304-
.set(VmHostFileVO_.lastOpDate, now)
305-
.update();
306-
} else {
307-
file = new VmHostFileVO();
308-
file.setUuid(Platform.getUuid());
309-
file.setHostUuid(context.hostUuid);
310-
file.setVmInstanceUuid(context.vmUuid);
311-
file.setPath(path);
312-
file.setType(type);
313-
file.setCreateDate(now);
314-
file.setLastOpDate(now);
315-
file.setResourceName(String.format("%s file for %s", type, context.vmUuid));
316-
databaseFacade.persist(file);
317-
}
318-
319-
byte[] bytes = Base64.getDecoder().decode(to.getContentBase64());
320-
if (existsContentUuid.contains(file.getUuid())) {
321-
SQL.New(VmHostFileContentVO.class)
322-
.eq(VmHostFileContentVO_.uuid, file.getUuid())
323-
.set(VmHostFileContentVO_.content, bytes)
324-
.set(VmHostFileContentVO_.format, VmHostFileContentFormat.valueOf(to.getFileFormat()))
325-
.set(VmHostFileContentVO_.lastOpDate, now)
326-
.update();
327-
} else {
328-
VmHostFileContentVO content = new VmHostFileContentVO();
329-
content.setUuid(file.getUuid());
330-
content.setContent(bytes);
331-
content.setFormat(VmHostFileContentFormat.valueOf(to.getFileFormat()));
332-
content.setCreateDate(now);
333-
content.setLastOpDate(now);
334-
databaseFacade.persist(content);
335-
}
336-
337-
if (logger.isTraceEnabled()) {
338-
logger.trace(String.format("persist/update VmHostFileContentVO [uuid=%s]", file.getUuid()));
339-
}
340-
}
341-
342-
if (errors.isEmpty()) {
343-
completion.success();
344-
} else {
345-
completion.fail(operr("failed to read file content from host[uuid=%s]", context.hostUuid).withCause(errors));
346-
}
347-
}
348-
349-
@Override
350-
public void fail(ErrorCode errorCode) {
351-
completion.fail(errorCode);
352-
}
353-
});
354-
}
355-
356224
public static class RewriteVmHostFilesContext {
357225
public String hostUuid;
358226
public List<KVMAgentCommands.VmHostFileTO> hostFiles;
@@ -517,29 +385,30 @@ public void run(FlowTrigger trigger, Map data) {
517385
}
518386

519387
context.sameHost = vmHostFile.getHostUuid().equals(context.hostUuid);
520-
SyncVmHostFilesFromHostContext syncContext = new SyncVmHostFilesFromHostContext();
521-
syncContext.hostUuid = vmHostFile.getHostUuid();
522-
syncContext.vmUuid = context.vmUuid;
388+
SyncVmHostFilesFromHostMsg syncMsg = new SyncVmHostFilesFromHostMsg();
389+
syncMsg.setHostUuid(vmHostFile.getHostUuid());
390+
syncMsg.setVmUuid(context.vmUuid);
523391

524392
if (vmHostFile.getType() == VmHostFileType.NvRam) {
525-
context.path = syncContext.nvRamPath = vmHostFile.getPath();
393+
context.path = vmHostFile.getPath();
394+
syncMsg.setNvRamPath(context.path);
526395
} else if (vmHostFile.getType() == VmHostFileType.TpmState) {
527-
context.path = syncContext.tpmStateFolder = vmHostFile.getPath();
396+
context.path = vmHostFile.getPath();
397+
syncMsg.setTpmStateFolder(context.path);
528398
} else {
529399
throw new CloudRuntimeException("unsupported vm host file type: " + vmHostFile.getType());
530400
}
531401

532-
syncVmHostFilesFromHost(syncContext, new Completion(trigger) {
533-
@Override
534-
public void success() {
535-
context.vmHostFile = vmHostFile;
536-
trigger.next();
537-
}
538-
402+
bus.makeLocalServiceId(syncMsg, VmInstanceConstant.SECURE_BOOT_SERVICE_ID);
403+
bus.send(syncMsg, new CloudBusCallBack(trigger) {
539404
@Override
540-
public void fail(ErrorCode errorCode) {
541-
logger.warn(String.format("failed to read vm host file for VM[vmUuid=%s] but still continue: %s",
542-
context.vmUuid, errorCode.getReadableDetails()));
405+
public void run(MessageReply reply) {
406+
if (reply.isSuccess()) {
407+
context.vmHostFile = vmHostFile;
408+
} else {
409+
logger.warn(String.format("failed to read vm host file for VM[vmUuid=%s] but still continue: %s",
410+
context.vmUuid, reply.getError().getReadableDetails()));
411+
}
543412
trigger.next();
544413
}
545414
});
@@ -628,26 +497,25 @@ public boolean skip(Map data) {
628497

629498
@Override
630499
public void run(FlowTrigger trigger, Map data) {
631-
KvmSecureBootExtensions.SyncVmHostFilesFromHostContext syncBackContext =
632-
new KvmSecureBootExtensions.SyncVmHostFilesFromHostContext();
633-
syncBackContext.hostUuid = context.hostUuid;
634-
syncBackContext.vmUuid = context.vmUuid;
500+
SyncVmHostFilesFromHostMsg syncMsg = new SyncVmHostFilesFromHostMsg();
501+
syncMsg.setHostUuid(context.hostUuid);
502+
syncMsg.setVmUuid(context.vmUuid);
635503

636504
if (context.type == VmHostFileType.NvRam) {
637-
syncBackContext.nvRamPath = context.path;
505+
syncMsg.setNvRamPath(context.path);
638506
} else if (context.type == VmHostFileType.TpmState) {
639-
syncBackContext.tpmStateFolder = context.path;
507+
syncMsg.setTpmStateFolder(context.path);
640508
}
641509

642-
syncVmHostFilesFromHost(syncBackContext, new Completion(trigger) {
510+
bus.makeLocalServiceId(syncMsg, VmInstanceConstant.SECURE_BOOT_SERVICE_ID);
511+
bus.send(syncMsg, new CloudBusCallBack(trigger) {
643512
@Override
644-
public void success() {
645-
trigger.next();
646-
}
647-
648-
@Override
649-
public void fail(ErrorCode errorCode) {
650-
trigger.fail(errorCode);
513+
public void run(MessageReply reply) {
514+
if (reply.isSuccess()) {
515+
trigger.next();
516+
} else {
517+
trigger.fail(reply.getError());
518+
}
651519
}
652520
});
653521
}

0 commit comments

Comments
 (0)