Skip to content

fix: percent-encode vCenter datacenter/cluster/host names in virt-v2v URIs - #13932

Open
waterWang wants to merge 1 commit into
apache:mainfrom
waterWang:fix/cloudstack-13920-vmware-uri-encoding
Open

waterWang wants to merge 1 commit into
apache:mainfrom
waterWang:fix/cloudstack-13920-vmware-uri-encoding

Conversation

@waterWang

Copy link
Copy Markdown

Fixes #13920

Summary

LibvirtConvertInstanceCommandWrapper builds vpx:// and vi:// connection URIs for virt-v2v by concatenating vCenter datacenter/cluster/host names without percent-encoding them. A datacenter (or cluster/host) name containing a space — valid in vSphere — produces an invalid URI, and VM import from VMware fails.

Changes

  • encodePathSegment — percent-encodes a single URI path segment using %20 for spaces (not +)
  • encodePathSegments — splits on / and encodes each sub-segment individually, preserving literal / separators for folder-nested names (e.g. MyFolder/MyDC)
  • buildVpxUrl — now calls encodePathSegments on datacenter and cluster, encodePathSegment on host
  • getExportOVAUrlFromRemoteInstance — now calls encodePathSegments on datacenter and path, encodePathSegment on vm
  • encodeUsername — fixed to use explicit UTF-8 charset and %20 instead of + for spaces (libvirt only decodes %20 in URI authority segments)

Testing

Manual test: with a datacenter named QA Lab, the vpx:// URL now correctly becomes:

vpx://Administrator%40vsphere.local@203.0.113.10/QA%20Lab/cluster-a/203.0.113.20?no_verify=1

@DaanHoogland

Copy link
Copy Markdown
Contributor

@waterWang you are adding a lot of PRs, thanks. Very welcome. You are basing all your PRs of main, though the reports/issues are on 4.22 for the most time. Do you think you can rebase them?

@DaanHoogland DaanHoogland left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@waterWang, assess if this is applicable to branch 4.20 as well, and rebase to either that branch or to 4.22.

@DaanHoogland DaanHoogland moved this from Backlog to conflict/waiting in CloudStack Testing Sep 1, 2026
@sudo87
sudo87 requested a lite review from Copilot November 5, 2026 05:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Approval is blocked by an unhandled whitespace-only inventory/path value that can remain unencoded in the URI, along with missing regression tests for spaces, nested paths, and reserved characters.

2 open issues
What changed in this PR

This pull request fixes VMware import failures by percent-encoding vCenter inventory names in virt-v2v and ovftool URIs.

Changes:

  • Adds UTF-8 percent-encoding for URI components, using %20 for spaces.
  • Preserves / separators in nested datacenter, cluster, and inventory paths.
  • Applies encoding to vpx:// and vi:// URL construction and usernames.

This pull request requires changes.

File Review findings
plugins/​hypervisors/​kvm/​src/​main/​java/​com/​cloud/​hypervisor/​kvm/​resource/​wrapper/​LibvirtConvertInstanceCommandWrapper.java Moderate (2 votes): StringUtils.isBlank leaves whitespace-only inventory names or path segments unencoded; use null/empty checks so they reach URLEncoder.

Nit (4 votes): Add regression tests covering spaces, nested slash-preserving paths, reserved characters, and generated vi:// paths.

Review effort: Lite

Comment on lines +302 to +311
private String encodePathSegment(String value) {
if (StringUtils.isBlank(value)) {
return value;
}
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}

private String encodePathSegments(String value) {
if (StringUtils.isBlank(value)) {
return value;
Comment on lines +302 to +320
private String encodePathSegment(String value) {
if (StringUtils.isBlank(value)) {
return value;
}
return URLEncoder.encode(value, StandardCharsets.UTF_8).replace("+", "%20");
}

private String encodePathSegments(String value) {
if (StringUtils.isBlank(value)) {
return value;
}
StringBuilder encoded = new StringBuilder();
for (String seg : value.split("/", -1)) {
if (encoded.length() > 0) {
encoded.append("/");
}
encoded.append(encodePathSegment(seg));
}
return encoded.toString();

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: conflict/waiting

Development

Successfully merging this pull request may close these issues.

VMware import (importVm) fails when datacenter/cluster/host name contains a space

3 participants