From e7a55a766c557ee1d8a32ddf4ceb257847d3710a Mon Sep 17 00:00:00 2001 From: Nicolas Vazquez Date: Thu, 16 Oct 2025 10:26:41 -0300 Subject: [PATCH] Fixes for Import VM Tasks listing (#11841) * Fix import VM tasks pagination * Fix UI for pagination and proper listing * Fixes and improvements * Polish UI * Restore config.json * Fix state on parameter description --- .../apache/cloudstack/api/ApiConstants.java | 2 +- .../admin/vm/ListImportVMTasksCmd.java | 15 +- .../api/response/ImportVMTaskResponse.java | 12 ++ .../apache/cloudstack/vm/ImportVmTask.java | 15 +- .../cloudstack/vm/ImportVmTasksManager.java | 2 +- .../java/com/cloud/vm/ImportVMTaskVO.java | 11 ++ .../com/cloud/vm/dao/ImportVMTaskDao.java | 6 +- .../com/cloud/vm/dao/ImportVMTaskDaoImpl.java | 13 +- .../META-INF/db/schema-42100to42200.sql | 3 +- .../vm/ImportVmTasksManagerImpl.java | 62 ++++-- .../vm/UnmanagedVMsManagerImpl.java | 2 +- .../vm/UnmanagedVMsManagerImplTest.java | 1 - ui/public/locales/en.json | 7 + ui/src/views/tools/ImportVmTasks.vue | 179 ++++++++++++------ ui/src/views/tools/ManageInstances.vue | 39 +++- 15 files changed, 256 insertions(+), 113 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index cab545f9228..8fca652518f 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -535,7 +535,6 @@ public class ApiConstants { public static final String SHOW_CAPACITIES = "showcapacities"; public static final String SHOW_REMOVED = "showremoved"; public static final String SHOW_RESOURCE_ICON = "showicon"; - public static final String SHOW_COMPLETED = "showcompleted"; public static final String SHOW_INACTIVE = "showinactive"; public static final String SHOW_UNIQUE = "showunique"; public static final String SIGNATURE = "signature"; @@ -585,6 +584,7 @@ public class ApiConstants { public static final String SUITABLE_FOR_VM = "suitableforvirtualmachine"; public static final String SUPPORTS_STORAGE_SNAPSHOT = "supportsstoragesnapshot"; public static final String TARGET_IQN = "targetiqn"; + public static final String TASKS_FILTER = "tasksfilter"; public static final String TEMPLATE_FILTER = "templatefilter"; public static final String TEMPLATE_ID = "templateid"; public static final String TEMPLATE_IDS = "templateids"; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ListImportVMTasksCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ListImportVMTasksCmd.java index a0c8cb57ee6..94b547ff426 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ListImportVMTasksCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ListImportVMTasksCmd.java @@ -75,11 +75,8 @@ public class ListImportVMTasksCmd extends BaseListCmd { description = "Conversion host of the importing task") private Long convertHostId; - @Parameter(name = ApiConstants.LIST_ALL, type = CommandType.BOOLEAN, description = "Whether to list all import tasks.") - private boolean listAll = false; - - @Parameter(name = ApiConstants.SHOW_COMPLETED, type = CommandType.BOOLEAN, description = "Whether to list completed tasks.") - private boolean showCompleted = false; + @Parameter(name = ApiConstants.TASKS_FILTER, type = CommandType.STRING, description = "Filter tasks by state, valid options are: All, Running, Completed, Failed") + private String tasksFilter; public Long getZoneId() { return zoneId; @@ -97,12 +94,8 @@ public class ListImportVMTasksCmd extends BaseListCmd { return convertHostId; } - public boolean isListAll() { - return listAll; - } - - public boolean isShowCompleted() { - return showCompleted; + public String getTasksFilter() { + return tasksFilter; } @Override diff --git a/api/src/main/java/org/apache/cloudstack/api/response/ImportVMTaskResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ImportVMTaskResponse.java index dd49127f1bd..aa85554f567 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/ImportVMTaskResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/ImportVMTaskResponse.java @@ -55,6 +55,10 @@ public class ImportVMTaskResponse extends BaseResponse { @Param(description = "the display name of the importing VM") private String displayName; + @SerializedName(ApiConstants.STATE) + @Param(description = "the state of the importing VM task") + private String state; + @SerializedName(ApiConstants.VCENTER) @Param(description = "the vcenter name of the importing VM task") private String vcenter; @@ -242,4 +246,12 @@ public class ImportVMTaskResponse extends BaseResponse { public void setLastUpdated(Date lastUpdated) { this.lastUpdated = lastUpdated; } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } } diff --git a/api/src/main/java/org/apache/cloudstack/vm/ImportVmTask.java b/api/src/main/java/org/apache/cloudstack/vm/ImportVmTask.java index 96d7cd346f3..5bb51dfcbcb 100644 --- a/api/src/main/java/org/apache/cloudstack/vm/ImportVmTask.java +++ b/api/src/main/java/org/apache/cloudstack/vm/ImportVmTask.java @@ -23,6 +23,19 @@ import org.apache.cloudstack.api.InternalIdentity; public interface ImportVmTask extends Identity, InternalIdentity { enum Step { - Prepare, CloningInstance, ConvertingInstance, Importing, Cleaning, Completed + Prepare, CloningInstance, ConvertingInstance, Importing, Completed + } + + enum TaskState { + Running, Completed, Failed; + + public static TaskState getValue(String state) { + for (TaskState s : TaskState.values()) { + if (s.name().equalsIgnoreCase(state)) { + return s; + } + } + throw new IllegalArgumentException("Invalid task state: " + state); + } } } diff --git a/api/src/main/java/org/apache/cloudstack/vm/ImportVmTasksManager.java b/api/src/main/java/org/apache/cloudstack/vm/ImportVmTasksManager.java index 44eed8c531a..233511fbce8 100644 --- a/api/src/main/java/org/apache/cloudstack/vm/ImportVmTasksManager.java +++ b/api/src/main/java/org/apache/cloudstack/vm/ImportVmTasksManager.java @@ -34,5 +34,5 @@ public interface ImportVmTasksManager { void updateImportVMTaskStep(ImportVmTask importVMTaskVO, DataCenter zone, Account owner, Host convertHost, Host importHost, Long vmId, ImportVmTask.Step step); - boolean removeImportVMTask(long taskId); + void updateImportVMTaskErrorState(ImportVmTask importVMTaskVO, ImportVmTask.TaskState state, String errorMsg); } diff --git a/engine/schema/src/main/java/com/cloud/vm/ImportVMTaskVO.java b/engine/schema/src/main/java/com/cloud/vm/ImportVMTaskVO.java index e472b56460a..9a8a769f0a5 100644 --- a/engine/schema/src/main/java/com/cloud/vm/ImportVMTaskVO.java +++ b/engine/schema/src/main/java/com/cloud/vm/ImportVMTaskVO.java @@ -93,6 +93,9 @@ public class ImportVMTaskVO implements ImportVmTask { @Column(name = "step") private Step step; + @Column(name = "state") + private TaskState state; + @Column(name = "description") private String description; @@ -217,6 +220,14 @@ public class ImportVMTaskVO implements ImportVmTask { this.step = step; } + public TaskState getState() { + return state; + } + + public void setState(TaskState state) { + this.state = state; + } + public String getDescription() { return description; } diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/ImportVMTaskDao.java b/engine/schema/src/main/java/com/cloud/vm/dao/ImportVMTaskDao.java index 990dacb33fb..a4f0a155da4 100644 --- a/engine/schema/src/main/java/com/cloud/vm/dao/ImportVMTaskDao.java +++ b/engine/schema/src/main/java/com/cloud/vm/dao/ImportVMTaskDao.java @@ -18,12 +18,14 @@ // package com.cloud.vm.dao; +import com.cloud.utils.Pair; import com.cloud.utils.db.GenericDao; import com.cloud.vm.ImportVMTaskVO; - +import org.apache.cloudstack.vm.ImportVmTask; import java.util.List; public interface ImportVMTaskDao extends GenericDao { - List listImportVMTasks(Long zoneId, Long accountId, String vcenter, Long convertHostId, boolean showCompleted); + Pair, Integer> listImportVMTasks(Long zoneId, Long accountId, String vcenter, Long convertHostId, + ImportVmTask.TaskState state, Long startIndex, Long pageSizeVal); } diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/ImportVMTaskDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/ImportVMTaskDaoImpl.java index 8bdae2e456a..da9c391af9d 100644 --- a/engine/schema/src/main/java/com/cloud/vm/dao/ImportVMTaskDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/vm/dao/ImportVMTaskDaoImpl.java @@ -16,10 +16,13 @@ // under the License. package com.cloud.vm.dao; +import com.cloud.utils.Pair; +import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.vm.ImportVMTaskVO; +import org.apache.cloudstack.vm.ImportVmTask; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; @@ -41,12 +44,14 @@ public class ImportVMTaskDaoImpl extends GenericDaoBase im AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), SearchCriteria.Op.EQ); AllFieldsSearch.and("vcenter", AllFieldsSearch.entity().getVcenter(), SearchCriteria.Op.EQ); AllFieldsSearch.and("convertHostId", AllFieldsSearch.entity().getConvertHostId(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), SearchCriteria.Op.EQ); AllFieldsSearch.done(); } @Override - public List listImportVMTasks(Long zoneId, Long accountId, String vcenter, Long convertHostId, boolean showCompleted) { + public Pair, Integer> listImportVMTasks(Long zoneId, Long accountId, String vcenter, Long convertHostId, + ImportVmTask.TaskState state, Long startIndex, Long pageSizeVal) { SearchCriteria sc = AllFieldsSearch.create(); if (zoneId != null) { sc.setParameters("zoneId", zoneId); @@ -60,6 +65,10 @@ public class ImportVMTaskDaoImpl extends GenericDaoBase im if (convertHostId != null) { sc.setParameters("convertHostId", convertHostId); } - return showCompleted ? listIncludingRemovedBy(sc) : listBy(sc); + if (state != null) { + sc.setParameters("state", state); + } + Filter filter = new Filter(ImportVMTaskVO.class, "created", false, startIndex, pageSizeVal); + return searchAndCount(sc, filter); } } diff --git a/engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql b/engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql index da111e354d4..b523016aa3d 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-42100to42200.sql @@ -65,7 +65,8 @@ CREATE TABLE IF NOT EXISTS `cloud`.`import_vm_task`( `source_vm_name` varchar(255) COMMENT 'Source VM name on vCenter', `convert_host_id` bigint unsigned COMMENT 'Convert Host ID', `import_host_id` bigint unsigned COMMENT 'Import Host ID', - `step` varchar(20) NOT NULL COMMENT 'Importing VM Task Step', + `step` varchar(20) COMMENT 'Importing VM Task Step', + `state` varchar(20) COMMENT 'Importing VM Task State', `description` varchar(255) COMMENT 'Importing VM Task Description', `duration` bigint unsigned COMMENT 'Duration in milliseconds for the completed tasks', `created` datetime NOT NULL COMMENT 'date created', diff --git a/server/src/main/java/org/apache/cloudstack/vm/ImportVmTasksManagerImpl.java b/server/src/main/java/org/apache/cloudstack/vm/ImportVmTasksManagerImpl.java index fa36627e864..88b8f0f425d 100644 --- a/server/src/main/java/org/apache/cloudstack/vm/ImportVmTasksManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/vm/ImportVmTasksManagerImpl.java @@ -25,13 +25,17 @@ import com.cloud.host.dao.HostDao; import com.cloud.user.Account; import com.cloud.user.AccountService; import com.cloud.utils.DateUtil; +import com.cloud.utils.Pair; import com.cloud.vm.ImportVMTaskVO; import com.cloud.vm.UserVmVO; import com.cloud.vm.dao.ImportVMTaskDao; import com.cloud.vm.dao.UserVmDao; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.command.admin.vm.ListImportVMTasksCmd; import org.apache.cloudstack.api.response.ImportVMTaskResponse; import org.apache.cloudstack.api.response.ListResponse; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -72,25 +76,33 @@ public class ImportVmTasksManagerImpl implements ImportVmTasksManager { Long accountId = cmd.getAccountId(); String vcenter = cmd.getVcenter(); Long convertHostId = cmd.getConvertHostId(); - boolean listAll = cmd.isListAll(); - boolean showCompleted = cmd.isShowCompleted(); + Long startIndex = cmd.getStartIndex(); + Long pageSizeVal = cmd.getPageSizeVal(); - List tasks; - if (listAll) { - tasks = importVMTaskDao.listAll(); - } else { - tasks = importVMTaskDao.listImportVMTasks(zoneId, accountId, vcenter, convertHostId, showCompleted); - } + ImportVmTask.TaskState state = getStateFromFilter(cmd.getTasksFilter()); + Pair, Integer> result = importVMTaskDao.listImportVMTasks(zoneId, accountId, vcenter, convertHostId, state, startIndex, pageSizeVal); + List tasks = result.first(); List responses = new ArrayList<>(); for (ImportVMTaskVO task : tasks) { responses.add(createImportVMTaskResponse(task)); } ListResponse listResponses = new ListResponse<>(); - listResponses.setResponses(responses, responses.size()); + listResponses.setResponses(responses, result.second()); return listResponses; } + private ImportVmTask.TaskState getStateFromFilter(String tasksFilter) { + if (StringUtils.isBlank(tasksFilter) || tasksFilter.equalsIgnoreCase("all")) { + return null; + } + try { + return ImportVmTask.TaskState.getValue(tasksFilter); + } catch (IllegalArgumentException e) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, String.format("Invalid value for task state: %s", tasksFilter)); + } + } + @Override public ImportVmTask createImportVMTaskRecord(DataCenter zone, Account owner, long userId, String displayName, String vcenter, String datacenterName, String sourceVMName, Host convertHost, Host importHost) { logger.debug("Creating import VM task entry for VM: {} for account {} on zone {} " + @@ -98,6 +110,7 @@ public class ImportVmTasksManagerImpl implements ImportVmTasksManager { sourceVMName, owner.getAccountName(), zone.getName(), displayName, vcenter, datacenterName); ImportVMTaskVO importVMTaskVO = new ImportVMTaskVO(zone.getId(), owner.getAccountId(), userId, displayName, vcenter, datacenterName, sourceVMName, convertHost.getId(), importHost.getId()); + importVMTaskVO.setState(ImportVmTask.TaskState.Running); return importVMTaskDao.persist(importVMTaskVO); } @@ -111,7 +124,6 @@ public class ImportVmTasksManagerImpl implements ImportVmTasksManager { if (Completed == step) { stringBuilder.append("Completed at ").append(DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), updatedDate)); } else { - stringBuilder.append(String.format("[%s] ", DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), updatedDate))); if (CloningInstance == step) { stringBuilder.append(String.format("Cloning source instance: %s on vCenter: %s / datacenter: %s", sourceVMName, vcenter, datacenter)); } else if (ConvertingInstance == step) { @@ -142,13 +154,19 @@ public class ImportVmTasksManagerImpl implements ImportVmTasksManager { Duration duration = Duration.between(importVMTaskVO.getCreated().toInstant(), updatedDate.toInstant()); importVMTaskVO.setDuration(duration.toMillis()); importVMTaskVO.setVmId(vmId); + importVMTaskVO.setState(ImportVmTask.TaskState.Completed); } importVMTaskDao.update(importVMTaskVO.getId(), importVMTaskVO); } @Override - public boolean removeImportVMTask(long taskId) { - return importVMTaskDao.remove(taskId); + public void updateImportVMTaskErrorState(ImportVmTask importVMTask, ImportVmTask.TaskState state, String errorMsg) { + ImportVMTaskVO importVMTaskVO = (ImportVMTaskVO) importVMTask; + Date updatedDate = DateUtil.now(); + importVMTaskVO.setUpdated(updatedDate); + importVMTaskVO.setState(state); + importVMTaskVO.setDescription(errorMsg); + importVMTaskDao.update(importVMTaskVO.getId(), importVMTaskVO); } private ImportVMTaskResponse createImportVMTaskResponse(ImportVMTaskVO task) { @@ -169,19 +187,21 @@ public class ImportVmTasksManagerImpl implements ImportVmTasksManager { response.setDisplayName(task.getDisplayName()); response.setStep(getStepDisplayField(task.getStep())); response.setDescription(task.getDescription()); + response.setState(task.getState().name()); Date updated = task.getUpdated(); Date currentDate = new Date(); - if (updated != null && Completed != task.getStep()) { - Duration stepDuration = Duration.between(updated.toInstant(), currentDate.toInstant()); - response.setStepDuration(getDurationDisplay(stepDuration.toMillis())); - } - if (Completed == task.getStep()) { - response.setStepDuration(getDurationDisplay(task.getDuration())); - } else { - Duration totalDuration = Duration.between(task.getCreated().toInstant(), currentDate.toInstant()); - response.setDuration(getDurationDisplay(totalDuration.toMillis())); + + if (updated != null) { + if (ImportVmTask.TaskState.Running == task.getState()) { + Duration stepDuration = Duration.between(updated.toInstant(), currentDate.toInstant()); + response.setStepDuration(getDurationDisplay(stepDuration.toMillis())); + } else { + Duration totalDuration = Duration.between(task.getCreated().toInstant(), updated.toInstant()); + response.setDuration(getDurationDisplay(totalDuration.toMillis())); + } } + HostVO host = hostDao.findById(task.getConvertHostId()); if (host != null) { response.setConvertInstanceHostId(host.getUuid()); diff --git a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java index 7e8370257a7..14e038487cd 100644 --- a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java @@ -1776,10 +1776,10 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager { logger.debug(String.format("VMware VM %s imported successfully to CloudStack instance %s (%s), Time taken: %d secs, OVF files imported from %s, Source VMware VM details - OS: %s, PowerState: %s, Disks: %s, NICs: %s", sourceVMName, displayName, displayName, timeElapsedInSecs, (ovfTemplateOnConvertLocation != null)? "MS" : "KVM Host", sourceVMwareInstance.getOperatingSystem(), sourceVMwareInstance.getPowerState(), sourceVMwareInstance.getDisks(), sourceVMwareInstance.getNics())); importVmTasksManager.updateImportVMTaskStep(importVMTask, zone, owner, convertHost, importHost, userVm.getId(), Completed); - importVmTasksManager.removeImportVMTask(importVMTask.getId()); return userVm; } catch (CloudRuntimeException e) { logger.error(String.format("Error importing VM: %s", e.getMessage()), e); + importVmTasksManager.updateImportVMTaskErrorState(importVMTask, ImportVmTask.TaskState.Failed, e.getMessage()); ActionEventUtils.onCompletedActionEvent(userId, owner.getId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_VM_IMPORT, cmd.getEventDescription(), null, null, 0); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage()); diff --git a/server/src/test/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImplTest.java b/server/src/test/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImplTest.java index 465cea3c74a..60ce662b4f3 100644 --- a/server/src/test/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImplTest.java +++ b/server/src/test/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImplTest.java @@ -782,7 +782,6 @@ public class UnmanagedVMsManagerImplTest { when(agentManager.send(Mockito.eq(convertHostId), Mockito.any(CheckConvertInstanceCommand.class))).thenReturn(checkConvertInstanceAnswer); } - when(importVMTaskVO.getId()).thenReturn(1L); when(importVmTasksManager.createImportVMTaskRecord(any(DataCenter.class), any(Account.class), anyLong(), anyString(), anyString(), anyString(), anyString(), any(Host.class), any(Host.class))).thenReturn(importVMTaskVO); when(volumeApiService.doesStoragePoolSupportDiskOffering(any(StoragePool.class), any(DiskOffering.class))).thenReturn(true); diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 3a2af9e6e15..4f450e940fc 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -635,6 +635,7 @@ "label.continue": "Continue", "label.continue.install": "Continue with installation", "label.controlnodes": "Control nodes", +"label.conversionhost": "Conversion Host", "label.copied.clipboard": "Copied to clipboard", "label.copy": "Copy", "label.copy.clipboard": "Copy to clipboard", @@ -700,6 +701,8 @@ "label.csienabled": "CSI Enabled", "label.currency": "Currency", "label.current": "Current", +"label.currentstep": "Current step", +"label.currentstep.duration": "Current step duration", "label.current.storage": "Current storage", "label.currentpassword": "Current password", "label.custom": "Custom", @@ -1246,6 +1249,7 @@ "label.import.instance": "Import Instance", "label.import.offering": "Import Offering", "label.import.role": "Import Role", +"label.import.vm.tasks": "Import VM Tasks", "label.import.volume": "Import Volume", "label.inactive": "Inactive", "label.inbuilt": "Inbuilt", @@ -2314,6 +2318,7 @@ "label.sourcenattype": "Supported source NAT type", "label.sourceport": "Source port", "label.sourcetype": "Source type", +"label.sourcevmname": "Source VM Name", "label.specifyasnumber": "Specify AS Number", "label.specifyipranges": "Specify IP ranges", "label.specifyvlan": "Specify VLAN", @@ -2881,6 +2886,7 @@ "label.leaseexpiryaction": "Lease expiry action", "label.remainingdays": "Lease", "label.leased": "Leased", +"label.totalduration": "Total duration", "label.usestoragereplication": "Use primary storage replication", "message.acquire.ip.failed": "Failed to acquire IP.", "message.action.acquire.ip": "Please confirm that you want to acquire new IP.", @@ -3524,6 +3530,7 @@ "message.host.dedication.released": "Host dedication released.", "message.host.external.datadisk": "Usage of data disks for the selected template is not applicable", "message.import.running.instance.warning": "The selected VM is powered-on on the VMware Datacenter. The recommended state to convert a VMware VM into KVM is powered-off after a graceful shutdown of the guest OS.", +"message.import.vm.tasks": "Import from VMware to KVM tasks", "message.import.volume": "Please specify the domain, account or project name.
If not set, the volume will be imported for the caller.", "message.info.cloudian.console": "Cloudian Management Console should open in another window.", "message.installwizard.cloudstack.helptext.website": " * Project website:\t ", diff --git a/ui/src/views/tools/ImportVmTasks.vue b/ui/src/views/tools/ImportVmTasks.vue index 51741f18e69..37725337947 100644 --- a/ui/src/views/tools/ImportVmTasks.vue +++ b/ui/src/views/tools/ImportVmTasks.vue @@ -16,56 +16,83 @@ // under the License.