DSvClient 0.8.0 - VCSA Patch Layout Fix and On-Disk CDN Mirror
A few critical bugs have been fixed in the DSvClient to make it work when patching vCenter, some blobs where missing and layout didnt align with vCenters expectations when used for an online repo. This make it ready to use with the up coming patch module for vCenter, very useful in airgapped environments.
Here's what changed and why.
Why This Release Exists
Previous DSvClient versions downloaded every VCSA patch file — RPMs, container image blobs, `.manifest` files, script zips, and root metadata — into a single flat directory at `valm/<version>/`. That worked for local inspection, but it didn't match how the Broadcom CDN actually serves those files.
On the CDN, the layout looks like this:valm/8.0.3.00800/ manifest-latest.xml manifest-latest.xml.sha256 manifest-latest.xml.sign rpm-manifest.json rpm-manifest.json.sha256 rpm-manifest.json.sign package-pool/ *.rpm *.blob *.manifest patch-metadata-scripts.zip target-patch-scripts.zip
Only the six metadata files live at the root. Everything else — the hundreds of RPMs, the container image blobs, the `.manifest` container descriptors, and the two `*-patch-scripts.zip` script bundles — lives under `package-pool/`.
What Changed in 0.8.0
The `get_vcsa_file_path` function in `downloader.rs` now preserves the `package-pool/` prefix from each package's `<location>` or `relativepath` entry, instead of stripping it to the basename:
fn get_vcsa_file_path(&self, version: &str, file: &str) -> PathBuf {
let mut path = self.base_path.join("valm").join(version);
for segment in file.split('/')
.filter(|s| !s.is_empty() && *s != ".." && *s != ".")
{
path = path.join(segment);
}
path
}
The `..` and `.` segments are stripped defensively so a hostile manifest can't write outside the version directory. The `download_file` function already creates missing parent directories via `create_dir_all`, so the `package-pool/` subdirectory is created on demand.
Why This Matters
With the on-disk layout now matching the CDN, a freshly-downloaded `valm/<version>/` tree can be:
1. **Served directly over HTTP** as a local mirror of the Broadcom CDN for `software-packages stage --url http://host/valm/<version>/`
2. **Turned into a VCSA patch ISO** via the DSvRepoImport PowerShell module
3. **Inspected locally** the same way as before — only the directory structure changed
Migrating an Existing Flat Repo
If you already downloaded a repo with DSvClient 0.6 or earlier and don't want to re-download ~8 GB, a quick shell one-liner reshuffles the files:
cd /path/to/VMware-repo/valm/8.0.3.00800
mkdir -p package-pool
for f in *; do
case "$f" in
package-pool|manifest-latest.xml|manifest-latest.xml.sha256|\
manifest-latest.xml.sign|rpm-manifest.json|\
rpm-manifest.json.sha256|rpm-manifest.json.sign) ;;
*) mv -- "$f" package-pool/ ;;
esac
donePowerShell equivalent:
$src = 'C:\path\to\VMware-repo\valm\8.0.3.00800'
$keep = @('manifest-latest.xml','manifest-latest.xml.sha256',
'manifest-latest.xml.sign','rpm-manifest.json',
'rpm-manifest.json.sha256','rpm-manifest.json.sign')
New-Item -ItemType Directory -Path (Join-Path $src 'package-pool') -Force | Out-Null
Get-ChildItem -Path $src -File |
Where-Object { $keep -notcontains $_.Name } |
Move-Item -Destination (Join-Path $src 'package-pool')After migration, running DSvClient 0.8.0 again will verify all checksums and skip already-valid files — no re-download.
Also in This Release
- **Version 0.7.0** (bundled in this release) added `parse_vcsa_rpm_manifest_json` to download `.blob` and `.manifest` files referenced by `rpm-manifest.json` that weren't previously being fetched. Without these 24+ container image blobs and 2 container manifests, VCSA patching fails silently during the staging phase.
DSvClient is open source and available on GitHub.
Grab the latest release binary or build from source with `cargo build --release`. 🚀