Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
3b1ab6f
Add source VM name on virt-v2v migration log entries
nvazquez Sep 5, 2025
e194ba9
Improve the feedback by displaying the running importing tasks
nvazquez Sep 7, 2025
83fd30d
Add source VM name prefix on more conversion logs
nvazquez Sep 8, 2025
f9e9466
Improve listing and also list completed tasks
nvazquez Sep 14, 2025
9200dd0
Pass extra parameters to virt-v2v if administrator allows via global …
nvazquez Sep 14, 2025
c3b06da
Add Force converting directly to storage pool option
nvazquez Sep 19, 2025
e9176ee
Refactor based on review comments
nvazquez Sep 19, 2025
2a92813
Add properties for env vars for the instance conversion
nvazquez Sep 20, 2025
2f08049
Add separate component for Import VM Tasks
nvazquez Sep 20, 2025
6493720
applying copilot suggestions from code review
shwstppr Sep 22, 2025
1ba03c0
Merge branch 'main' into 422-vmware-to-kvm-improvements
sureshanaparti Sep 26, 2025
7196e09
Fix importing unmanaged instances due to incorrect internal name
nvazquez Sep 29, 2025
03ed3cf
Add VM prefix on each log operation for conversion
nvazquez Sep 30, 2025
f952e76
Log the original VM name instead of the cloned VM in case of cloning
nvazquez Oct 1, 2025
b981367
Allow searching storage pool by UUID after conversion to support Shar…
nvazquez Oct 2, 2025
b1012d2
Fix search pools logic
nvazquez Oct 3, 2025
63c0eac
Improve UI and add checks for force convert to pool parameter
nvazquez Oct 7, 2025
0638763
Merge branch 'main' into 422-vmware-to-kvm-improvements
nvazquez Oct 8, 2025
2c52bfa
Support Local storage when forceconverttopool is set to true
nvazquez Oct 8, 2025
977f6b6
Merge branch 'main' into 422-vmware-to-kvm-improvements
nvazquez Oct 8, 2025
c506ee8
Merge branch 'main' into 422-vmware-to-kvm-improvements
nvazquez Oct 9, 2025
4c5b87d
Add config key to for allowed extra params and add validation
nvazquez Oct 9, 2025
4f73495
Fix params lists
nvazquez Oct 10, 2025
9431b9d
Fix compile error
nvazquez Oct 10, 2025
83c6585
Remove extra stubbings
nvazquez Oct 10, 2025
d9c0f74
Merge branch 'main' into 422-vmware-to-kvm-improvements
nvazquez Oct 10, 2025
dac73f4
Fix extra params execution
nvazquez Oct 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions agent/conf/agent.properties
Original file line number Diff line number Diff line change
Expand Up @@ -451,3 +451,9 @@ iscsi.session.cleanup.enabled=false

# If set to true, creates VMs as full clones of their templates on KVM hypervisor. Creates as linked clones otherwise.
# create.full.clone=false

# Instance conversion TMPDIR env var
#convert.instance.env.tmpdir=

# Instance conversion VIRT_V2V_TMPDIR env var
#convert.instance.env.virtv2v.tmpdir=
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,20 @@ public Property<Integer> getWorkers() {
*/
public static final Property<Boolean> VIRTV2V_VERBOSE_ENABLED = new Property<>("virtv2v.verbose.enabled", false);

/**
* Set env TMPDIR var for virt-v2v Instance Conversion from VMware to KVM
* Data type: String.<br>
* Default value: <code>null</code>
*/
public static final Property<String> CONVERT_ENV_TMPDIR = new Property<>("convert.instance.env.tmpdir", null, String.class);

/**
* Set env VIRT_V2V_TMPDIR var for virt-v2v Instance Conversion from VMware to KVM
* Data type: String.<br>
* Default value: <code>null</code>
*/
public static final Property<String> CONVERT_ENV_VIRTV2V_TMPDIR = new Property<>("convert.instance.env.virtv2v.tmpdir", null, String.class);

/**
* BGP controll CIDR
* Data type: String.<br>
Expand Down
4 changes: 4 additions & 0 deletions api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ public class ApiConstants {
public static final String EVENT_TYPE = "eventtype";
public static final String EXPIRES = "expires";
public static final String EXTRA_CONFIG = "extraconfig";
public static final String EXTRA_PARAMS = "extraparams";
public static final String EXTRA_DHCP_OPTION = "extradhcpoption";
public static final String EXTRA_DHCP_OPTION_NAME = "extradhcpoptionname";
public static final String EXTRA_DHCP_OPTION_CODE = "extradhcpoptioncode";
Expand All @@ -240,6 +241,8 @@ public class ApiConstants {
public static final String FIRSTNAME = "firstname";
public static final String FORCED = "forced";
public static final String FORCED_DESTROY_LOCAL_STORAGE = "forcedestroylocalstorage";
public static final String FORCE_CONVERT_TO_POOL = "forceconverttopool";

public static final String FORCE_DELETE_HOST = "forcedeletehost";
public static final String FORCE_MS_TO_IMPORT_VM_FILES = "forcemstoimportvmfiles";
public static final String FORCE_UPDATE_OS_TYPE = "forceupdateostype";
Expand Down Expand Up @@ -526,6 +529,7 @@ 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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,18 @@ public class ImportVmCmd extends ImportUnmanagedInstanceCmd {
description = "(only for importing VMs from VMware to KVM) optional - if true, forces MS to export OVF from VMware to temporary storage, else uses KVM Host if ovftool is available, falls back to MS if not.")
private Boolean forceMsToImportVmFiles;

@Parameter(name = ApiConstants.EXTRA_PARAMS,
type = CommandType.STRING,
since = "4.22",
description = "(only for importing VMs from VMware to KVM) optional - extra parameters to be passed on the virt-v2v command, if allowed by the administrator")
private String extraParams;

@Parameter(name = ApiConstants.FORCE_CONVERT_TO_POOL,
type = CommandType.BOOLEAN,
since = "4.22",
description = "(only for importing VMs from VMware to KVM) optional - if true, forces virt-v2v conversions to write directly on the provided storage pool (avoid using temporary conversion pool).")
private Boolean forceConvertToPool;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -248,6 +260,14 @@ public String getEventType() {
return EventTypes.EVENT_VM_IMPORT;
}

public String getExtraParams() {
return extraParams;
}

public boolean getForceConvertToPool() {
return BooleanUtils.toBooleanDefaultIfNull(forceConvertToPool, false);
}

@Override
public String getEventDescription() {
String vmName = getName();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.command.admin.vm;

import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ResponseObject;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.AccountResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.ImportVMTaskResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.vm.ImportVmTasksManager;

import javax.inject.Inject;

@APICommand(name = "listImportVmTasks",
description = "List running import virtual machine tasks from a unmanaged hosts into CloudStack",
responseObject = ImportVMTaskResponse.class,
responseView = ResponseObject.ResponseView.Full,
requestHasSensitiveInfo = false,
authorized = {RoleType.Admin},
since = "4.22")
public class ListImportVMTasksCmd extends BaseListCmd {

@Inject
public ImportVmTasksManager importVmTasksManager;

@Parameter(name = ApiConstants.ZONE_ID,
type = CommandType.UUID,
entityType = ZoneResponse.class,
required = true,
description = "the zone ID")
private Long zoneId;

@Parameter(name = ApiConstants.ACCOUNT_ID,
type = CommandType.UUID,
entityType = AccountResponse.class,
description = "the ID of the Account")
private Long accountId;

@Parameter(name = ApiConstants.VCENTER,
type = CommandType.STRING,
description = "The name/ip of vCenter. Make sure it is IP address or full qualified domain name for host running vCenter server.")
private String vcenter;

@Parameter(name = ApiConstants.CONVERT_INSTANCE_HOST_ID,
type = CommandType.UUID,
entityType = HostResponse.class,
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;
Comment on lines +78 to +82
Copy link
Contributor

Choose a reason for hiding this comment

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

minor - What is the difference between these params, are these tasks associated with different initiator accounts? If not then can we use listall param to list completed tasks

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @shwstppr - by default only running tasks will be listed. Difference should be when showcompleted = true will retrieve only the completed but not the running tasks, but listall = true should list running and completed tasks


public Long getZoneId() {
return zoneId;
}

public Long getAccountId() {
return accountId;
}

public String getVcenter() {
return vcenter;
}

public Long getConvertHostId() {
return convertHostId;
}

public boolean isListAll() {
return listAll;
}

public boolean isShowCompleted() {
return showCompleted;
}

@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
ListResponse<ImportVMTaskResponse> response = importVmTasksManager.listImportVMTasks(this);
response.setResponseName(getCommandName());
setResponseObject(response);
}

@Override
public long getEntityOwnerId() {
Account account = CallContext.current().getCallingAccount();
if (account != null) {
return account.getId();
}
return Account.ACCOUNT_ID_SYSTEM;
}
}
Loading
Loading