diff --git a/build/pom.xml b/build/pom.xml index bcea34d5d14..1edc891b7df 100755 --- a/build/pom.xml +++ b/build/pom.xml @@ -523,6 +523,11 @@ zce-x-plugin ${project.version} + + org.zstack + zmigrate-plugin + ${project.version} + org.zstack zsv diff --git a/conf/errorCodes/SoftwarePackagePlugin.xml b/conf/errorCodes/SoftwarePackagePlugin.xml index 012c252d148..16e628a618a 100644 --- a/conf/errorCodes/SoftwarePackagePlugin.xml +++ b/conf/errorCodes/SoftwarePackagePlugin.xml @@ -2,7 +2,7 @@ SoftwarePackage - 2000 + 1000 Failed to upload software package diff --git a/conf/errorCodes/ZMigratePlugin.xml b/conf/errorCodes/ZMigratePlugin.xml new file mode 100644 index 00000000000..e6a15bcc3a3 --- /dev/null +++ b/conf/errorCodes/ZMigratePlugin.xml @@ -0,0 +1,63 @@ + + ZMigrate + + + 1000 + ZMigrate generic error + + + + 1001 + Failed to create account in ZMigrate + + + + 1002 + Failed to verify platform connection + + + + 1003 + Failed to verify gateway connection + + + + 1004 + Failed to register ZSV to ZMigrate + + + + 1005 + Failed to register gateway to ZMigrate + + + + 1006 + Failed to get licenses from ZMigrate + + + + 1007 + Failed to get platform information + + + + 1008 + Failed to get migration jobs + + + + 1009 + Failed to get ZMigrate management server information + + + + 1010 + Failed to get gateway server information + + + + 1011 + Failed to get encrypt key + + diff --git a/header/src/main/java/org/zstack/header/storage/backup/CancelDownloadFileOnBackupStorageHostMsg.java b/header/src/main/java/org/zstack/header/storage/backup/CancelDownloadFileOnBackupStorageHostMsg.java new file mode 100644 index 00000000000..5d4e79d4f6e --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/CancelDownloadFileOnBackupStorageHostMsg.java @@ -0,0 +1,25 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.CancelMessage; + +public class CancelDownloadFileOnBackupStorageHostMsg extends CancelMessage implements BackupStorageMessage { + private String backupStorageUuid; + private String backupStorageHostUuid; + + @Override + public String getBackupStorageUuid() { + return backupStorageUuid; + } + + public void setBackupStorageUuid(String backupStorageUuid) { + this.backupStorageUuid = backupStorageUuid; + } + + public String getBackupStorageHostUuid() { + return backupStorageHostUuid; + } + + public void setBackupStorageHostUuid(String backupStorageHostUuid) { + this.backupStorageHostUuid = backupStorageHostUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/CancelDownloadFileOnBackupStorageHostReply.java b/header/src/main/java/org/zstack/header/storage/backup/CancelDownloadFileOnBackupStorageHostReply.java new file mode 100644 index 00000000000..53f1c07b543 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/CancelDownloadFileOnBackupStorageHostReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.MessageReply; + +public class CancelDownloadFileOnBackupStorageHostReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/DeleteFilesOnBackupStorageHostMsg.java b/header/src/main/java/org/zstack/header/storage/backup/DeleteFilesOnBackupStorageHostMsg.java new file mode 100644 index 00000000000..23e27c047e8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/DeleteFilesOnBackupStorageHostMsg.java @@ -0,0 +1,37 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.NeedReplyMessage; + +import java.util.ArrayList; +import java.util.List; + +public class DeleteFilesOnBackupStorageHostMsg extends NeedReplyMessage implements BackupStorageMessage { + private String backupStorageUuid; + private String backupStorageHostUuid; + private List filesPath = new ArrayList<>(); + + @Override + public String getBackupStorageUuid() { + return backupStorageUuid; + } + + public void setBackupStorageUuid(String backupStorageUuid) { + this.backupStorageUuid = backupStorageUuid; + } + + public String getBackupStorageHostUuid() { + return backupStorageHostUuid; + } + + public void setBackupStorageHostUuid(String backupStorageHostUuid) { + this.backupStorageHostUuid = backupStorageHostUuid; + } + + public List getFilesPath() { + return filesPath; + } + + public void setFilesPath(List filesPath) { + this.filesPath = filesPath; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/DeleteFilesOnBackupStorageHostReply.java b/header/src/main/java/org/zstack/header/storage/backup/DeleteFilesOnBackupStorageHostReply.java new file mode 100644 index 00000000000..fc79c452951 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/DeleteFilesOnBackupStorageHostReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.MessageReply; + +public class DeleteFilesOnBackupStorageHostReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressFromBackupStorageHostMsg.java b/header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressFromBackupStorageHostMsg.java new file mode 100644 index 00000000000..46ae4ae4c13 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressFromBackupStorageHostMsg.java @@ -0,0 +1,43 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.NeedReplyMessage; + +public class GetFileDownloadProgressFromBackupStorageHostMsg extends NeedReplyMessage implements BackupStorageMessage { + private String backupStorageUuid; + private String backupStorageHostUuid; + private String taskUuid; + private String hostname; + + @Override + public String getBackupStorageUuid() { + return backupStorageUuid; + } + + public void setBackupStorageUuid(String backupStorageUuid) { + this.backupStorageUuid = backupStorageUuid; + } + + public String getBackupStorageHostUuid() { + return backupStorageHostUuid; + } + + public void setBackupStorageHostUuid(String backupStorageHostUuid) { + this.backupStorageHostUuid = backupStorageHostUuid; + } + + public String getTaskUuid() { + return taskUuid; + } + + public void setTaskUuid(String taskUuid) { + this.taskUuid = taskUuid; + } + + public String getHostname() { + return hostname; + } + + public void setHostname(String hostname) { + this.hostname = hostname; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressFromBackupStorageHostReply.java b/header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressFromBackupStorageHostReply.java new file mode 100644 index 00000000000..da4b1a11807 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/GetFileDownloadProgressFromBackupStorageHostReply.java @@ -0,0 +1,118 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.MessageReply; + +import java.util.Map; + +public class GetFileDownloadProgressFromBackupStorageHostReply extends MessageReply { + private boolean completed; + private int progress; + + private long size; + private long actualSize; + private long downloadSize; + private String installPath; + private long lastOpTime; + private boolean supportSuspend; + private String md5sum; + private String format; + + private String unzipInstallPath; + private Map filesSize; + + public boolean isCompleted() { + return completed; + } + + public void setCompleted(boolean completed) { + this.completed = completed; + } + + public int getProgress() { + return progress; + } + + public void setProgress(int progress) { + this.progress = progress; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public long getActualSize() { + return actualSize; + } + + public void setActualSize(long actualSize) { + this.actualSize = actualSize; + } + + public String getInstallPath() { + return installPath; + } + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public long getLastOpTime() { + return lastOpTime; + } + + public void setLastOpTime(long lastOpTime) { + this.lastOpTime = lastOpTime; + } + + public long getDownloadSize() { + return downloadSize; + } + + public void setDownloadSize(long downloadSize) { + this.downloadSize = downloadSize; + } + + public boolean isSupportSuspend() { + return supportSuspend; + } + + public void setSupportSuspend(boolean supportSuspend) { + this.supportSuspend = supportSuspend; + } + + public String getMd5sum() { + return md5sum; + } + + public void setMd5sum(String md5sum) { + this.md5sum = md5sum; + } + + public String getUnzipInstallPath() { + return unzipInstallPath; + } + + public void setUnzipInstallPath(String unzipInstallPath) { + this.unzipInstallPath = unzipInstallPath; + } + + public Map getFilesSize() { + return filesSize; + } + + public void setFilesSize(Map filesSize) { + this.filesSize = filesSize; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/SoftwareUpgradePackageDeployMsg.java b/header/src/main/java/org/zstack/header/storage/backup/SoftwareUpgradePackageDeployMsg.java new file mode 100644 index 00000000000..62419f636e3 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/SoftwareUpgradePackageDeployMsg.java @@ -0,0 +1,90 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.NeedReplyMessage; + +public class SoftwareUpgradePackageDeployMsg extends NeedReplyMessage implements BackupStorageMessage { + private String backupStorageUuid; + private String backupStorageHostUuid; + private String upgradePackagePath; + private String upgradePackageTargetPath; + private int targetHostSshPort; + private String targetHostSshUsername; + @NoLogging + private String targetHostSshPassword; + private String targetHostIp; + private String upgradeScriptPath; + + @Override + public String getBackupStorageUuid() { + return backupStorageUuid; + } + + public void setBackupStorageUuid(String backupStorageUuid) { + this.backupStorageUuid = backupStorageUuid; + } + + public String getBackupStorageHostUuid() { + return backupStorageHostUuid; + } + + public void setBackupStorageHostUuid(String backupStorageHostUuid) { + this.backupStorageHostUuid = backupStorageHostUuid; + } + + public String getUpgradePackageTargetPath() { + return upgradePackageTargetPath; + } + + public void setUpgradePackageTargetPath(String upgradePackageTargetPath) { + this.upgradePackageTargetPath = upgradePackageTargetPath; + } + + public String getUpgradePackagePath() { + return upgradePackagePath; + } + + public void setUpgradePackagePath(String upgradePackagePath) { + this.upgradePackagePath = upgradePackagePath; + } + + public int getTargetHostSshPort() { + return targetHostSshPort; + } + + public void setTargetHostSshPort(int targetHostSshPort) { + this.targetHostSshPort = targetHostSshPort; + } + + public String getTargetHostSshUsername() { + return targetHostSshUsername; + } + + public void setTargetHostSshUsername(String targetHostSshUsername) { + this.targetHostSshUsername = targetHostSshUsername; + } + + public String getTargetHostSshPassword() { + return targetHostSshPassword; + } + + public void setTargetHostSshPassword(String targetHostSshPassword) { + this.targetHostSshPassword = targetHostSshPassword; + } + + public String getTargetHostIp() { + return targetHostIp; + } + + public void setTargetHostIp(String targetHostIp) { + this.targetHostIp = targetHostIp; + } + + public String getUpgradeScriptPath() { + return upgradeScriptPath; + } + + public void setUpgradeScriptPath(String upgradeScriptPath) { + this.upgradeScriptPath = upgradeScriptPath; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/SoftwareUpgradePackageDeployReply.java b/header/src/main/java/org/zstack/header/storage/backup/SoftwareUpgradePackageDeployReply.java new file mode 100644 index 00000000000..49a6a129ec8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/SoftwareUpgradePackageDeployReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.MessageReply; + +public class SoftwareUpgradePackageDeployReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/UploadFileToBackupStorageHostMsg.java b/header/src/main/java/org/zstack/header/storage/backup/UploadFileToBackupStorageHostMsg.java new file mode 100644 index 00000000000..4f2d2b173c4 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/UploadFileToBackupStorageHostMsg.java @@ -0,0 +1,45 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.NeedReplyMessage; + +public class UploadFileToBackupStorageHostMsg extends NeedReplyMessage implements BackupStorageMessage { + private String backupStorageUuid; + private String taskUuid; + @NoLogging(type = NoLogging.Type.Uri) + private String url; + private String installPath; + + @Override + public String getBackupStorageUuid() { + return backupStorageUuid; + } + + public void setBackupStorageUuid(String backupStorageUuid) { + this.backupStorageUuid = backupStorageUuid; + } + + public String getTaskUuid() { + return taskUuid; + } + + public void setTaskUuid(String taskUuid) { + this.taskUuid = taskUuid; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getInstallPath() { + return installPath; + } + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/UploadFileToBackupStorageHostReply.java b/header/src/main/java/org/zstack/header/storage/backup/UploadFileToBackupStorageHostReply.java new file mode 100644 index 00000000000..7f56d9679b8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/UploadFileToBackupStorageHostReply.java @@ -0,0 +1,64 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.MessageReply; + +import java.util.Map; + +public class UploadFileToBackupStorageHostReply extends MessageReply { + private String md5sum; + private long size; + @NoLogging(type = NoLogging.Type.Uri) + private String directUploadUrl; + private String unzipInstallPath; + private Map filesSize; + private String backupStorageHostUuid; + + public String getMd5sum() { + return md5sum; + } + + public void setMd5sum(String md5sum) { + this.md5sum = md5sum; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public String getDirectUploadUrl() { + return directUploadUrl; + } + + public void setDirectUploadUrl(String directUploadUrl) { + this.directUploadUrl = directUploadUrl; + } + + public String getUnzipInstallPath() { + return unzipInstallPath; + } + + public void setUnzipInstallPath(String unzipInstallPath) { + this.unzipInstallPath = unzipInstallPath; + } + + public Map getFilesSize() { + return filesSize; + } + + public void setFilesSize(Map filesSize) { + this.filesSize = filesSize; + } + + public String getBackupStorageHostUuid() { + return backupStorageHostUuid; + } + + public void setBackupStorageHostUuid(String backupStorageHostUuid) { + this.backupStorageHostUuid = backupStorageHostUuid; + } +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java index e24fdc21e11..8cf8525e0c3 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java @@ -19,6 +19,7 @@ import org.zstack.core.thread.ChainTask; import org.zstack.core.thread.SyncTaskChain; import org.zstack.core.thread.SyncThread; +import org.zstack.core.timeout.ApiTimeoutManager; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; import org.zstack.header.Constants; @@ -51,6 +52,7 @@ import javax.persistence.Tuple; import javax.persistence.TypedQuery; import java.io.Serializable; +import java.net.URI; import java.net.URISyntaxException; import java.util.*; import java.util.concurrent.TimeUnit; @@ -91,6 +93,8 @@ void unlock() { protected RESTFacade restf; @Autowired protected CephBackupStorageMetaDataMaker metaDataMaker; + @Autowired + private ApiTimeoutManager timeoutManager; public enum PingOperationFailure { UnableToCreateFile, @@ -659,6 +663,78 @@ public void setCancellationApiId(String cancellationApiId) { } } + public static class DownloadFileCmd extends AgentCommand implements HasThreadContext, Serializable { + public String taskUuid; + public String installPath; + @NoLogging(type = NoLogging.Type.Uri) + public String url; + @NoLogging(type = NoLogging.Type.Uri) + public String urlScheme; + public long timeout; + @NoLogging(type = NoLogging.Type.Uri) + public String sendCommandUrl; + } + + public static class DownloadFileResponse extends AgentResponse { + public String md5sum; + public long size; + public String unzipInstallPath; + public Map filesSize; + } + + public static class DeleteFilesCmd extends AgentCommand implements HasThreadContext, Serializable { + public List filesPath; + } + + public static class DeleteFilesResponse extends AgentResponse { + } + + public static class UploadFileCmd extends AgentCommand implements HasThreadContext, Serializable { + public String taskUuid; + public String installPath; + @NoLogging(type = NoLogging.Type.Uri) + public String url; + public long timeout; + } + + public static class UploadFileResponse extends AgentResponse { + public String directUploadUrl; + } + + public static class GetDownloadFileProgressCmd extends AgentCommand { + public String taskUuid; + } + + public static class GetDownloadFileProgressResponse extends AgentResponse { + public boolean completed; + public int progress; + public long size; + public long actualSize; + public String installPath; + public String format; + public long lastOpTime; + public long downloadSize; + public String md5sum; + public boolean supportSuspend; + public String unzipInstallPath; + public Map filesSize; + } + + public static class SoftwareUpgradePackageCmd extends AgentCommand implements Serializable { + public String upgradePackagePath; + public String upgradePackageTargetPath; + public String upgradeScriptPath; + public int targetHostSshPort; + public String targetHostSshUsername; + @NoLogging + public String targetHostSshPassword; + public String targetHostIp; + + } + + public static class SoftwareUpgradePackageResponse extends AgentResponse { + } + // common response of storage migration public static class StorageMigrationRsp extends AgentResponse { } @@ -680,6 +756,12 @@ public static class StorageMigrationRsp extends AgentResponse { public static final String GET_LOCAL_FILE_SIZE = "/ceph/backupstorage/getlocalfilesize"; public static final String CEPH_TO_CEPH_MIGRATE_IMAGE_PATH = "/ceph/backupstorage/image/migrate"; + public static final String FILE_DOWNLOAD_PATH = "/ceph/file/download"; + public static final String FILE_UPLOAD_PATH = "/ceph/file/upload"; + public static final String FILE_UPLOAD_PROGRESS_PATH = "/ceph/file/progress"; + public static final String DELETE_FILE_PATH = "/ceph/file/delete"; + public static final String SOFTWARE_UPGRADE_PACKAGE_DEPLOY_PATH = "/ceph/upgrade/deploy"; + protected String makeImageInstallPath(String imageUuid) { return String.format("ceph://%s/%s", getSelf().getPoolName(), imageUuid); } @@ -2021,4 +2103,281 @@ protected void handle(CalculateImageHashOnBackupStorageMsg msg) { private void doRestoreImagesBackupStorageMetadataToDatabase(RestoreImagesBackupStorageMetadataToDatabaseMsg msg) { metaDataMaker.restoreImagesBackupStorageMetadataToDatabase(msg.getImagesMetadata(), msg.getBackupStorageUuid()); } + + @Override + protected void handle(final UploadFileToBackupStorageHostMsg msg) { + UploadFileToBackupStorageHostReply reply = new UploadFileToBackupStorageHostReply(); + + if (msg.getUrl().startsWith("upload://")) { + UploadFileCmd cmd = new UploadFileCmd(); + cmd.url = msg.getUrl(); + cmd.installPath = msg.getInstallPath(); + cmd.timeout = timeoutManager.getTimeout(); + cmd.taskUuid = msg.getTaskUuid(); + httpCall(FILE_UPLOAD_PATH, cmd, UploadFileResponse.class, new ReturnValueCompletion(msg) { + @Override + public void fail(ErrorCode err) { + reply.setError(err); + bus.reply(msg, reply); + } + + @Override + public void success(UploadFileResponse rsp) { + reply.setDirectUploadUrl(rsp.directUploadUrl); + reply.setBackupStorageHostUuid(rsp.handleMon.getMonUuid()); + bus.reply(msg, reply); + } + }); + return; + } + + DownloadFileCmd cmd = new DownloadFileCmd(); + cmd.url = msg.getUrl(); + cmd.installPath = msg.getInstallPath(); + cmd.timeout = timeoutManager.getTimeout(); + cmd.taskUuid = msg.getTaskUuid(); + cmd.sendCommandUrl = restf.getSendCommandUrl(); + + String scheme; + try { + URI uri = new URI(msg.getUrl()); + scheme = uri.getScheme(); + } catch (URISyntaxException e) { + reply.setError(operr("failed to parse upload URL [%s]: %s", msg.getUrl(), e.getMessage())); + bus.reply(msg, reply); + return; + } + if (scheme == null || scheme.isEmpty()) { + reply.setError(operr("upload URL [%s] is missing a protocol prefix", msg.getUrl())); + bus.reply(msg, reply); + return; + } + cmd.urlScheme = scheme; + + httpCall(FILE_DOWNLOAD_PATH, cmd, DownloadFileResponse.class, new ReturnValueCompletion(msg) { + @Override + public void fail(ErrorCode err) { + reply.setError(err); + bus.reply(msg, reply); + } + + @Override + public void success(DownloadFileResponse rsp) { + reply.setMd5sum(rsp.md5sum); + reply.setSize(rsp.size); + reply.setUnzipInstallPath(rsp.unzipInstallPath); + reply.setFilesSize(rsp.filesSize); + reply.setBackupStorageHostUuid(rsp.handleMon.getMonUuid()); + bus.reply(msg, reply); + } + }); + } + + @Override + protected void handle(final DeleteFilesOnBackupStorageHostMsg msg) { + DeleteFilesOnBackupStorageHostReply reply = new DeleteFilesOnBackupStorageHostReply(); + + if (msg.getBackupStorageHostUuid()==null) { + reply.setError(operr("backup storage host uuid is null")); + bus.reply(msg, reply); + return; + } + + Set mons = getSelf().getMons(); + if (mons == null || mons.isEmpty()) { + reply.setError(operr("backup storage [%s] has no mon", getSelf().getName())); + bus.reply(msg, reply); + return; + } + CephBackupStorageMonVO mon = mons.stream() + .filter(m -> m.getUuid().equals(msg.getBackupStorageHostUuid())).findAny().orElse(null); + if (mon == null) { + reply.setError(operr("failed to find mon with uuid [%s]", msg.getBackupStorageHostUuid())); + bus.reply(msg, reply); + return; + } + + if (CoreGlobalProperty.UNIT_TEST_ON) { + bus.reply(msg, reply); + return; + } + + DeleteFilesCmd cmd = new DeleteFilesCmd(); + cmd.filesPath = msg.getFilesPath(); + + CephBackupStorageMonBase monBase = new CephBackupStorageMonBase(mon); + monBase.httpCall(DELETE_FILE_PATH, cmd, DeleteFilesResponse.class, new ReturnValueCompletion(msg) { + @Override + public void fail(ErrorCode err) { + reply.setError(err); + bus.reply(msg, reply); + } + + @Override + public void success(DeleteFilesResponse rsp) { + bus.reply(msg, reply); + } + }); + } + + @Override + protected void handle(GetFileDownloadProgressFromBackupStorageHostMsg msg) { + GetFileDownloadProgressFromBackupStorageHostReply reply = new GetFileDownloadProgressFromBackupStorageHostReply(); + + + if (msg.getBackupStorageHostUuid()==null) { + reply.setError(operr("backup storage host uuid is null")); + bus.reply(msg, reply); + return; + } + + Set mons = getSelf().getMons(); + if (mons == null || mons.isEmpty()) { + reply.setError(operr("backup storage [%s] has no mon", getSelf().getName())); + bus.reply(msg, reply); + return; + } + CephBackupStorageMonVO mon = mons.stream() + .filter(m -> m.getUuid().equals(msg.getBackupStorageHostUuid())).findAny().orElse(null); + if (mon == null) { + reply.setError(operr("failed to find mon with uuid [%s]", msg.getBackupStorageHostUuid())); + bus.reply(msg, reply); + return; + } + + if (CoreGlobalProperty.UNIT_TEST_ON) { + bus.reply(msg, reply); + return; + } + + GetDownloadFileProgressCmd cmd = new GetDownloadFileProgressCmd(); + cmd.taskUuid = msg.getTaskUuid(); + + CephBackupStorageMonBase monBase = new CephBackupStorageMonBase(mon); + monBase.httpCall(FILE_UPLOAD_PROGRESS_PATH, cmd, GetDownloadFileProgressResponse.class, new ReturnValueCompletion(msg) { + @Override + public void fail(ErrorCode err) { + reply.setError(err); + bus.reply(msg, reply); + } + + @Override + public void success(GetDownloadFileProgressResponse rsp) { + reply.setCompleted(rsp.completed); + reply.setProgress(rsp.progress); + reply.setActualSize(rsp.actualSize); + reply.setSize(rsp.size); + reply.setInstallPath(rsp.installPath); + reply.setDownloadSize(rsp.downloadSize); + reply.setLastOpTime(rsp.lastOpTime); + reply.setMd5sum(rsp.md5sum); + reply.setSupportSuspend(rsp.supportSuspend); + reply.setUnzipInstallPath(rsp.unzipInstallPath); + reply.setFilesSize(rsp.filesSize); + bus.reply(msg, reply); + } + }); + } + + @Override + protected void handle(SoftwareUpgradePackageDeployMsg msg) { + SoftwareUpgradePackageDeployReply reply = new SoftwareUpgradePackageDeployReply(); + + + if (msg.getBackupStorageHostUuid()==null) { + reply.setError(operr("backup storage host uuid is null")); + bus.reply(msg, reply); + return; + } + + Set mons = getSelf().getMons(); + if (mons == null || mons.isEmpty()) { + reply.setError(operr("backup storage [%s] has no mon", getSelf().getName())); + bus.reply(msg, reply); + return; + } + CephBackupStorageMonVO mon = mons.stream() + .filter(m -> m.getUuid().equals(msg.getBackupStorageHostUuid())).findAny().orElse(null); + if (mon == null) { + reply.setError(operr("failed to find mon with uuid [%s]", msg.getBackupStorageHostUuid())); + bus.reply(msg, reply); + return; + } + + if (CoreGlobalProperty.UNIT_TEST_ON) { + bus.reply(msg, reply); + return; + } + + SoftwareUpgradePackageCmd cmd = new SoftwareUpgradePackageCmd(); + cmd.upgradePackagePath = msg.getUpgradePackagePath(); + cmd.upgradePackageTargetPath = msg.getUpgradePackageTargetPath(); + cmd.upgradeScriptPath = msg.getUpgradeScriptPath(); + cmd.targetHostSshPort = msg.getTargetHostSshPort(); + cmd.targetHostSshUsername = msg.getTargetHostSshUsername(); + cmd.targetHostSshPassword = msg.getTargetHostSshPassword(); + cmd.targetHostIp = msg.getTargetHostIp(); + + CephBackupStorageMonBase monBase = new CephBackupStorageMonBase(mon); + monBase.httpCall(SOFTWARE_UPGRADE_PACKAGE_DEPLOY_PATH, cmd, SoftwareUpgradePackageResponse.class, new ReturnValueCompletion(msg) { + @Override + public void fail(ErrorCode err) { + reply.setError(err); + bus.reply(msg, reply); + } + + @Override + public void success(SoftwareUpgradePackageResponse rsp) { + bus.reply(msg, reply); + } + }); + } + + @Override + protected void handle(CancelDownloadFileOnBackupStorageHostMsg msg) { + CancelDownloadFileOnBackupStorageHostReply reply = new CancelDownloadFileOnBackupStorageHostReply(); + + + if (msg.getBackupStorageHostUuid()==null) { + reply.setError(operr("backup storage host uuid is null")); + bus.reply(msg, reply); + return; + } + + Set mons = getSelf().getMons(); + if (mons == null || mons.isEmpty()) { + reply.setError(operr("backup storage [%s] has no mon", getSelf().getName())); + bus.reply(msg, reply); + return; + } + CephBackupStorageMonVO mon = mons.stream() + .filter(m -> m.getUuid().equals(msg.getBackupStorageHostUuid())).findAny().orElse(null); + if (mon == null) { + reply.setError(operr("failed to find mon with uuid [%s]", msg.getBackupStorageHostUuid())); + bus.reply(msg, reply); + return; + } + + if (CoreGlobalProperty.UNIT_TEST_ON) { + bus.reply(msg, reply); + return; + } + + CancelCommand cmd = new CancelCommand(); + cmd.setCancellationApiId(msg.getCancellationApiId()); + + CephBackupStorageMonBase monBase = new CephBackupStorageMonBase(mon); + monBase.httpCall(AgentConstant.CANCEL_JOB, cmd, AgentResponse.class, new ReturnValueCompletion(msg) { + @Override + public void fail(ErrorCode err) { + reply.setError(err); + bus.reply(msg, reply); + } + + @Override + public void success(AgentResponse rsp) { + bus.reply(msg, reply); + } + }); + } } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java index 92e76ede2c5..5f480e2ed94 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java @@ -4458,7 +4458,7 @@ public static class UploadFileCmd extends AgentCommand implements HasThreadConte } public static class UploadFileResponse extends AgentResponse { - public String directUploadPath; + public String directUploadUrl; } public static class GetDownloadFileProgressCmd extends AgentCommand { diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java index 23d7b1cfe47..441f1828327 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java @@ -7213,7 +7213,7 @@ public void success(UploadFileResponse rsp) { return; } - reply.setDirectUploadUrl(rsp.directUploadPath); + reply.setDirectUploadUrl(rsp.directUploadUrl); bus.reply(msg, reply); completion.done(); } diff --git a/sdk/src/main/java/org/zstack/sdk/AdditionalLicenseType.java b/sdk/src/main/java/org/zstack/sdk/AdditionalLicenseType.java index 6121f538d79..2c35a09e98a 100644 --- a/sdk/src/main/java/org/zstack/sdk/AdditionalLicenseType.java +++ b/sdk/src/main/java/org/zstack/sdk/AdditionalLicenseType.java @@ -5,4 +5,5 @@ public enum AdditionalLicenseType { zstone, zcex, zsv, + zmigrate, } diff --git a/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/CleanUpgradeSoftwarePackageAction.java b/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/CleanUpgradeSoftwarePackageAction.java new file mode 100644 index 00000000000..587fa3614ff --- /dev/null +++ b/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/CleanUpgradeSoftwarePackageAction.java @@ -0,0 +1,104 @@ +package org.zstack.sdk.softwarePackage.header; + +import java.util.HashMap; +import java.util.Map; +import org.zstack.sdk.*; + +public class CleanUpgradeSoftwarePackageAction 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.softwarePackage.header.CleanUpgradeSoftwarePackageResult value; + + public Result throwExceptionIfError() { + if (error != null) { + throw new ApiException( + String.format("error[code: %s, description: %s, details: %s]", error.code, error.description, error.details) + ); + } + + return this; + } + } + + @Param(required = true, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.lang.String uuid; + + @Param(required = false) + public java.lang.String deleteMode = "Permissive"; + + @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.softwarePackage.header.CleanUpgradeSoftwarePackageResult value = res.getResult(org.zstack.sdk.softwarePackage.header.CleanUpgradeSoftwarePackageResult.class); + ret.value = value == null ? new org.zstack.sdk.softwarePackage.header.CleanUpgradeSoftwarePackageResult() : 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 = "DELETE"; + info.path = "/software-package/upgrade/packages/{uuid}"; + info.needSession = true; + info.needPoll = true; + info.parameterName = ""; + return info; + } + +} diff --git a/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/CleanUpgradeSoftwarePackageResult.java b/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/CleanUpgradeSoftwarePackageResult.java new file mode 100644 index 00000000000..b087b70f048 --- /dev/null +++ b/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/CleanUpgradeSoftwarePackageResult.java @@ -0,0 +1,7 @@ +package org.zstack.sdk.softwarePackage.header; + + + +public class CleanUpgradeSoftwarePackageResult { + +} diff --git a/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/UploadAndExecuteSoftwareUpgradePackageAction.java b/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/UploadAndExecuteSoftwareUpgradePackageAction.java new file mode 100644 index 00000000000..208e03328c9 --- /dev/null +++ b/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/UploadAndExecuteSoftwareUpgradePackageAction.java @@ -0,0 +1,113 @@ +package org.zstack.sdk.softwarePackage.header; + +import java.util.HashMap; +import java.util.Map; +import org.zstack.sdk.*; + +public class UploadAndExecuteSoftwareUpgradePackageAction 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.softwarePackage.header.UploadAndExecuteSoftwareUpgradePackageResult value; + + public Result throwExceptionIfError() { + if (error != null) { + throw new ApiException( + String.format("error[code: %s, description: %s, details: %s]", error.code, error.description, error.details) + ); + } + + return this; + } + } + + @Param(required = true, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.lang.String uuid; + + @Param(required = false, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.lang.String backupStorageUuid; + + @Param(required = false, maxLength = 1024, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.lang.String url; + + @Param(required = true, maxLength = 1024, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.lang.String installPath; + + @Param(required = false, validValues = {"Normal","Reexecute"}, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.lang.String upgradeType = "Normal"; + + @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.softwarePackage.header.UploadAndExecuteSoftwareUpgradePackageResult value = res.getResult(org.zstack.sdk.softwarePackage.header.UploadAndExecuteSoftwareUpgradePackageResult.class); + ret.value = value == null ? new org.zstack.sdk.softwarePackage.header.UploadAndExecuteSoftwareUpgradePackageResult() : 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 = "POST"; + info.path = "/software-packages/backup-storage/{uuid}/upgrade"; + info.needSession = true; + info.needPoll = true; + info.parameterName = "params"; + return info; + } + +} diff --git a/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/UploadAndExecuteSoftwareUpgradePackageResult.java b/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/UploadAndExecuteSoftwareUpgradePackageResult.java new file mode 100644 index 00000000000..543e556d740 --- /dev/null +++ b/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/UploadAndExecuteSoftwareUpgradePackageResult.java @@ -0,0 +1,14 @@ +package org.zstack.sdk.softwarePackage.header; + +import org.zstack.sdk.softwarePackage.header.SoftwarePackageInventory; + +public class UploadAndExecuteSoftwareUpgradePackageResult { + public SoftwarePackageInventory inventory; + public void setInventory(SoftwarePackageInventory inventory) { + this.inventory = inventory; + } + public SoftwarePackageInventory getInventory() { + return this.inventory; + } + +} diff --git a/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/UploadSoftwarePackageToBackupStorageAction.java b/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/UploadSoftwarePackageToBackupStorageAction.java new file mode 100644 index 00000000000..301061c70b6 --- /dev/null +++ b/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/UploadSoftwarePackageToBackupStorageAction.java @@ -0,0 +1,119 @@ +package org.zstack.sdk.softwarePackage.header; + +import java.util.HashMap; +import java.util.Map; +import org.zstack.sdk.*; + +public class UploadSoftwarePackageToBackupStorageAction 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.softwarePackage.header.UploadSoftwarePackageToBackupStorageResult value; + + public Result throwExceptionIfError() { + if (error != null) { + throw new ApiException( + String.format("error[code: %s, description: %s, details: %s]", error.code, error.description, error.details) + ); + } + + return this; + } + } + + @Param(required = true, maxLength = 255, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.lang.String name; + + @Param(required = true, maxLength = 255, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.lang.String type; + + @Param(required = false, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.lang.String backupStorageUuid; + + @Param(required = true, maxLength = 1024, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.lang.String url; + + @Param(required = true, maxLength = 1024, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.lang.String installPath; + + @Param(required = false) + public java.lang.String resourceUuid; + + @Param(required = false, nonempty = false, nullElements = false, emptyString = true, noTrim = false) + public java.util.List tagUuids; + + @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.softwarePackage.header.UploadSoftwarePackageToBackupStorageResult value = res.getResult(org.zstack.sdk.softwarePackage.header.UploadSoftwarePackageToBackupStorageResult.class); + ret.value = value == null ? new org.zstack.sdk.softwarePackage.header.UploadSoftwarePackageToBackupStorageResult() : 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 = "POST"; + info.path = "/software-packages/backup-storage/upload"; + info.needSession = true; + info.needPoll = true; + info.parameterName = "params"; + return info; + } + +} diff --git a/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/UploadSoftwarePackageToBackupStorageResult.java b/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/UploadSoftwarePackageToBackupStorageResult.java new file mode 100644 index 00000000000..89829806437 --- /dev/null +++ b/sdk/src/main/java/org/zstack/sdk/softwarePackage/header/UploadSoftwarePackageToBackupStorageResult.java @@ -0,0 +1,14 @@ +package org.zstack.sdk.softwarePackage.header; + +import org.zstack.sdk.softwarePackage.header.SoftwarePackageInventory; + +public class UploadSoftwarePackageToBackupStorageResult { + public SoftwarePackageInventory inventory; + public void setInventory(SoftwarePackageInventory inventory) { + this.inventory = inventory; + } + public SoftwarePackageInventory getInventory() { + return this.inventory; + } + +} diff --git a/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateGatewayVmInstancesAction.java b/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateGatewayVmInstancesAction.java new file mode 100644 index 00000000000..4d9fdef8f37 --- /dev/null +++ b/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateGatewayVmInstancesAction.java @@ -0,0 +1,92 @@ +package org.zstack.sdk.zmigrate.api; + +import java.util.HashMap; +import java.util.Map; +import org.zstack.sdk.*; + +public class GetZMigrateGatewayVmInstancesAction 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.zmigrate.api.GetZMigrateGatewayVmInstancesResult value; + + public Result throwExceptionIfError() { + if (error != null) { + throw new ApiException( + String.format("error[code: %s, description: %s, details: %s]", error.code, error.description, error.details) + ); + } + + return this; + } + } + + @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; + + + private Result makeResult(ApiResult res) { + Result ret = new Result(); + if (res.error != null) { + ret.error = res.error; + return ret; + } + + org.zstack.sdk.zmigrate.api.GetZMigrateGatewayVmInstancesResult value = res.getResult(org.zstack.sdk.zmigrate.api.GetZMigrateGatewayVmInstancesResult.class); + ret.value = value == null ? new org.zstack.sdk.zmigrate.api.GetZMigrateGatewayVmInstancesResult() : 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 = "/zmigrate/vm-instances"; + info.needSession = true; + info.needPoll = false; + info.parameterName = ""; + return info; + } + +} diff --git a/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateGatewayVmInstancesResult.java b/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateGatewayVmInstancesResult.java new file mode 100644 index 00000000000..853c8f9417d --- /dev/null +++ b/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateGatewayVmInstancesResult.java @@ -0,0 +1,22 @@ +package org.zstack.sdk.zmigrate.api; + + + +public class GetZMigrateGatewayVmInstancesResult { + public java.lang.String managementVmInstanceUuid; + public void setManagementVmInstanceUuid(java.lang.String managementVmInstanceUuid) { + this.managementVmInstanceUuid = managementVmInstanceUuid; + } + public java.lang.String getManagementVmInstanceUuid() { + return this.managementVmInstanceUuid; + } + + public java.util.List gatewayVmInstances; + public void setGatewayVmInstances(java.util.List gatewayVmInstances) { + this.gatewayVmInstances = gatewayVmInstances; + } + public java.util.List getGatewayVmInstances() { + return this.gatewayVmInstances; + } + +} diff --git a/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateImagesAction.java b/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateImagesAction.java new file mode 100644 index 00000000000..89d3060d7f8 --- /dev/null +++ b/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateImagesAction.java @@ -0,0 +1,92 @@ +package org.zstack.sdk.zmigrate.api; + +import java.util.HashMap; +import java.util.Map; +import org.zstack.sdk.*; + +public class GetZMigrateImagesAction 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.zmigrate.api.GetZMigrateImagesResult value; + + public Result throwExceptionIfError() { + if (error != null) { + throw new ApiException( + String.format("error[code: %s, description: %s, details: %s]", error.code, error.description, error.details) + ); + } + + return this; + } + } + + @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; + + + private Result makeResult(ApiResult res) { + Result ret = new Result(); + if (res.error != null) { + ret.error = res.error; + return ret; + } + + org.zstack.sdk.zmigrate.api.GetZMigrateImagesResult value = res.getResult(org.zstack.sdk.zmigrate.api.GetZMigrateImagesResult.class); + ret.value = value == null ? new org.zstack.sdk.zmigrate.api.GetZMigrateImagesResult() : 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 = "/zmigrate/images"; + info.needSession = true; + info.needPoll = false; + info.parameterName = ""; + return info; + } + +} diff --git a/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateImagesResult.java b/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateImagesResult.java new file mode 100644 index 00000000000..0e84b8cf33b --- /dev/null +++ b/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateImagesResult.java @@ -0,0 +1,14 @@ +package org.zstack.sdk.zmigrate.api; + + + +public class GetZMigrateImagesResult { + public java.util.Map images; + public void setImages(java.util.Map images) { + this.images = images; + } + public java.util.Map getImages() { + return this.images; + } + +} diff --git a/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateInfosAction.java b/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateInfosAction.java new file mode 100644 index 00000000000..52efd803ef3 --- /dev/null +++ b/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateInfosAction.java @@ -0,0 +1,92 @@ +package org.zstack.sdk.zmigrate.api; + +import java.util.HashMap; +import java.util.Map; +import org.zstack.sdk.*; + +public class GetZMigrateInfosAction 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.zmigrate.api.GetZMigrateInfosResult value; + + public Result throwExceptionIfError() { + if (error != null) { + throw new ApiException( + String.format("error[code: %s, description: %s, details: %s]", error.code, error.description, error.details) + ); + } + + return this; + } + } + + @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; + + + private Result makeResult(ApiResult res) { + Result ret = new Result(); + if (res.error != null) { + ret.error = res.error; + return ret; + } + + org.zstack.sdk.zmigrate.api.GetZMigrateInfosResult value = res.getResult(org.zstack.sdk.zmigrate.api.GetZMigrateInfosResult.class); + ret.value = value == null ? new org.zstack.sdk.zmigrate.api.GetZMigrateInfosResult() : 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 = "/zmigrate/management/infos"; + info.needSession = true; + info.needPoll = false; + info.parameterName = ""; + return info; + } + +} diff --git a/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateInfosResult.java b/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateInfosResult.java new file mode 100644 index 00000000000..6c20ec599c3 --- /dev/null +++ b/sdk/src/main/java/org/zstack/sdk/zmigrate/api/GetZMigrateInfosResult.java @@ -0,0 +1,54 @@ +package org.zstack.sdk.zmigrate.api; + + + +public class GetZMigrateInfosResult { + public java.lang.String zMigrateVmInstanceStatus; + public void setZMigrateVmInstanceStatus(java.lang.String zMigrateVmInstanceStatus) { + this.zMigrateVmInstanceStatus = zMigrateVmInstanceStatus; + } + public java.lang.String getZMigrateVmInstanceStatus() { + return this.zMigrateVmInstanceStatus; + } + + public java.lang.String version; + public void setVersion(java.lang.String version) { + this.version = version; + } + public java.lang.String getVersion() { + return this.version; + } + + public long platforms; + public void setPlatforms(long platforms) { + this.platforms = platforms; + } + public long getPlatforms() { + return this.platforms; + } + + public long gateways; + public void setGateways(long gateways) { + this.gateways = gateways; + } + public long getGateways() { + return this.gateways; + } + + public long migrateJobs; + public void setMigrateJobs(long migrateJobs) { + this.migrateJobs = migrateJobs; + } + public long getMigrateJobs() { + return this.migrateJobs; + } + + public long zMigrateStartTime; + public void setZMigrateStartTime(long zMigrateStartTime) { + this.zMigrateStartTime = zMigrateStartTime; + } + public long getZMigrateStartTime() { + return this.zMigrateStartTime; + } + +} diff --git a/storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java b/storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java index 7ff0eeda833..a7920a52673 100755 --- a/storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java +++ b/storage/src/main/java/org/zstack/storage/backup/BackupStorageBase.java @@ -123,6 +123,26 @@ protected void handle(GetBackupStorageManagerHostnameMsg msg) { bus.dealWithUnknownMessage(msg); } + protected void handle(UploadFileToBackupStorageHostMsg msg) { + bus.dealWithUnknownMessage(msg); + } + + protected void handle(DeleteFilesOnBackupStorageHostMsg msg) { + bus.dealWithUnknownMessage(msg); + } + + protected void handle(GetFileDownloadProgressFromBackupStorageHostMsg msg) { + bus.dealWithUnknownMessage(msg); + } + + protected void handle(SoftwareUpgradePackageDeployMsg msg) { + bus.dealWithUnknownMessage(msg); + } + + protected void handle(CancelDownloadFileOnBackupStorageHostMsg msg) { + bus.dealWithUnknownMessage(msg); + } + public BackupStorageBase(BackupStorageVO self) { this.self = self; this.id = BackupStorage.buildId(self.getUuid()); @@ -274,8 +294,18 @@ protected void handleLocalMessage(Message msg) throws URISyntaxException { handle((RestoreImagesBackupStorageMetadataToDatabaseMsg) msg); } else if (msg instanceof CalculateImageHashOnBackupStorageMsg) { handle((CalculateImageHashOnBackupStorageMsg) msg); + } else if (msg instanceof UploadFileToBackupStorageHostMsg) { + handle((UploadFileToBackupStorageHostMsg) msg); + } else if (msg instanceof DeleteFilesOnBackupStorageHostMsg) { + handle((DeleteFilesOnBackupStorageHostMsg) msg); } else if (msg instanceof GetBackupStorageManagerHostnameMsg) { handle((GetBackupStorageManagerHostnameMsg) msg); + } else if (msg instanceof GetFileDownloadProgressFromBackupStorageHostMsg) { + handle((GetFileDownloadProgressFromBackupStorageHostMsg) msg); + } else if (msg instanceof SoftwareUpgradePackageDeployMsg) { + handle((SoftwareUpgradePackageDeployMsg) msg); + } else if (msg instanceof CancelDownloadFileOnBackupStorageHostMsg) { + handle((CancelDownloadFileOnBackupStorageHostMsg) msg); } else { bus.dealWithUnknownMessage(msg); } diff --git a/testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy b/testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy index 07c05b73b9e..1ee7b82fc01 100644 --- a/testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy +++ b/testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy @@ -38614,6 +38614,33 @@ abstract class ApiHelper { } + def cleanUpgradeSoftwarePackage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.softwarePackage.header.CleanUpgradeSoftwarePackageAction.class) Closure c) { + def a = new org.zstack.sdk.softwarePackage.header.CleanUpgradeSoftwarePackageAction() + 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 getDirectoryUsage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.softwarePackage.header.GetDirectoryUsageAction.class) Closure c) { def a = new org.zstack.sdk.softwarePackage.header.GetDirectoryUsageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -38745,6 +38772,33 @@ abstract class ApiHelper { } + def uploadAndExecuteSoftwareUpgradePackage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.softwarePackage.header.UploadAndExecuteSoftwareUpgradePackageAction.class) Closure c) { + def a = new org.zstack.sdk.softwarePackage.header.UploadAndExecuteSoftwareUpgradePackageAction() + 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 uploadSoftwarePackage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.softwarePackage.header.UploadSoftwarePackageAction.class) Closure c) { def a = new org.zstack.sdk.softwarePackage.header.UploadSoftwarePackageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -38771,6 +38825,33 @@ abstract class ApiHelper { } + def uploadSoftwarePackageToBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.softwarePackage.header.UploadSoftwarePackageToBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.softwarePackage.header.UploadSoftwarePackageToBackupStorageAction() + 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 addZceX(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zcex.api.AddZceXAction.class) Closure c) { def a = new org.zstack.sdk.zcex.api.AddZceXAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -39018,6 +39099,87 @@ abstract class ApiHelper { } + def getZMigrateGatewayVmInstances(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zmigrate.api.GetZMigrateGatewayVmInstancesAction.class) Closure c) { + def a = new org.zstack.sdk.zmigrate.api.GetZMigrateGatewayVmInstancesAction() + 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 getZMigrateImages(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zmigrate.api.GetZMigrateImagesAction.class) Closure c) { + def a = new org.zstack.sdk.zmigrate.api.GetZMigrateImagesAction() + 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 getZMigrateInfos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zmigrate.api.GetZMigrateInfosAction.class) Closure c) { + def a = new org.zstack.sdk.zmigrate.api.GetZMigrateInfosAction() + 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 addZStone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zstone.api.AddZStoneAction.class) Closure c) { def a = new org.zstack.sdk.zstone.api.AddZStoneAction() a.sessionId = Test.currentEnvSpec?.session?.uuid diff --git a/testlib/src/main/java/org/zstack/testlib/CephBackupStorageSpec.groovy b/testlib/src/main/java/org/zstack/testlib/CephBackupStorageSpec.groovy index bc2d88a5e0e..a41e2b3985d 100755 --- a/testlib/src/main/java/org/zstack/testlib/CephBackupStorageSpec.groovy +++ b/testlib/src/main/java/org/zstack/testlib/CephBackupStorageSpec.groovy @@ -11,7 +11,6 @@ import org.zstack.storage.ceph.backup.CephBackupStorageBase import org.zstack.storage.ceph.backup.CephBackupStorageMonBase import org.zstack.storage.ceph.backup.CephBackupStorageMonVO import org.zstack.storage.ceph.backup.CephBackupStorageMonVO_ -import org.zstack.storage.ceph.primary.CephPrimaryStorageBase import org.zstack.testlib.vfs.VFS import org.zstack.utils.gson.JSONObjectUtil @@ -230,6 +229,36 @@ class CephBackupStorageSpec extends BackupStorageSpec { simulator(CephBackupStorageBase.CEPH_TO_CEPH_MIGRATE_IMAGE_PATH) { HttpEntity entity -> return new CephBackupStorageBase.StorageMigrationRsp() } + + simulator(CephBackupStorageBase.FILE_DOWNLOAD_PATH) { HttpEntity entity -> + def rsp = new CephBackupStorageBase.DownloadFileResponse() + rsp.md5sum = "1234567890" + rsp.size = 3L * 1024 * 1024 * 1024 + rsp.unzipInstallPath = "/root/zstone-software-package/unzipInstallPath" + rsp.filesSize = [:] + rsp.filesSize.put("/root/zstone-software-package/unzipInstallPath/Gateway_Linux_Server_(Treker).zmigrate.fast.10.1.106.qcow2", 1024L * 1024 * 1024) + rsp.filesSize.put("/root/zstone-software-package/unzipInstallPath/BootImage_for_Linux_(TrekerLite)_10.1.106.qcow2", 1024L * 1024 * 1024) + rsp.filesSize.put("/root/zstone-software-package/unzipInstallPath/BootImage_for_Windows_(TrekerLite)_10.1.106.qcow2", 1024L * 1024 * 1024) + rsp.filesSize.put("/root/zstone-software-package/unzipInstallPath/TrekerInstallation.tar.gz", 1024) + return rsp + } + + simulator(CephBackupStorageBase.FILE_UPLOAD_PATH) { HttpEntity entity -> + def rsp = new CephBackupStorageBase.AgentResponse() + return rsp + } + simulator(CephBackupStorageBase.FILE_UPLOAD_PROGRESS_PATH) { HttpEntity entity -> + def rsp = new CephBackupStorageBase.AgentResponse() + return rsp + } + simulator(CephBackupStorageBase.DELETE_FILE_PATH) { HttpEntity entity -> + def rsp = new CephBackupStorageBase.AgentResponse() + return rsp + } + simulator(CephBackupStorageBase.SOFTWARE_UPGRADE_PACKAGE_DEPLOY_PATH) { HttpEntity entity -> + def rsp = new CephBackupStorageBase.AgentResponse() + return rsp + } } } diff --git a/testlib/src/main/java/org/zstack/testlib/KVMSimulator.groovy b/testlib/src/main/java/org/zstack/testlib/KVMSimulator.groovy index 94fc178245d..e48a96a2b4c 100755 --- a/testlib/src/main/java/org/zstack/testlib/KVMSimulator.groovy +++ b/testlib/src/main/java/org/zstack/testlib/KVMSimulator.groovy @@ -664,7 +664,7 @@ class KVMSimulator implements Simulator { spec.simulator(KVMConstant.KVM_HOST_FILE_UPLOAD_PATH) { UploadFileResponse rsp = new UploadFileResponse() - rsp.directUploadPath = "http://172.1.1.1:7070/host/file/direct-upload" + rsp.directUploadUrl = "http://172.1.1.1:7070/host/file/direct-upload" return rsp }