Skip to content

Commit 780afb6

Browse files
committed
Fix directory structure of valm for new download and script in README.md for fix on already downloaded repo
1 parent 0d6cf54 commit 780afb6

3 files changed

Lines changed: 82 additions & 9 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "DSvClient"
3-
version = "0.7.0"
3+
version = "0.8.0"
44
edition = "2021"
55
description = "VMware vCenter and ESXi patch downloading tool with checksum verification"
66
authors = ["Michael Ryom"]

README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,68 @@
22

33
Check out [https://michaelryom.dk/dsvclient-new-patch-downloading-tool-for-vcenter](https://michaelryom.dk/dsvclient-new-patch-downloading-tool-for-vcenter)
44

5+
## 📁 Version 0.8.0
6+
**Released:** April 11, 2026
7+
8+
### On-Disk Layout Now Mirrors the Broadcom CDN (VCSA)
9+
Previous releases downloaded every VCSA patch file (RPMs, container image
10+
blobs, container manifests, patch-scripts zips, root metadata) into a single
11+
flat directory at `valm/<version>/`. That worked for local inspection and for
12+
ISO repackaging, but it did **not** match the layout the appliance expects: the
13+
real Broadcom CDN, a real VCSA patch ISO, and `software-packages stage --url`
14+
all put everything except the top-level manifests under `package-pool/`.
15+
16+
As a result, the downloaded tree could not be served over HTTP as a drop-in
17+
replacement for the CDN, and the ISO-building helper had to reconstruct
18+
`package-pool/` by hand — which broke in 0.7.0 once blobs, `.manifest`
19+
container files, and the two `*-patch-scripts.zip` script bundles entered the
20+
picture (they ended up at the ISO root instead of in `package-pool/`, causing
21+
`software-packages stage --iso` to fail with *"Staging failed. Retry to resume
22+
from the current state."*).
23+
24+
**What changed in 0.8.0:**
25+
- **`get_vcsa_file_path` preserves the relative path from each package's
26+
`<location>` / `relativepath` entry** instead of stripping it to the
27+
basename. Files whose location has a `package-pool/` prefix now land at
28+
`valm/<version>/package-pool/<file>`; bare root metadata files
29+
(`manifest-latest.xml`, `rpm-manifest.json`, and their `.sha256` / `.sign`
30+
sidecars) still land at `valm/<version>/<file>`.
31+
- **`..` and `.` path segments are stripped defensively** so a hostile
32+
manifest can't write outside the version directory.
33+
- **`download_file` already creates missing parent directories**, so the
34+
`package-pool/` subdir is created on demand — no schema migration needed
35+
inside DSvClient itself.
36+
37+
**Result:** a freshly-downloaded `valm/<version>/` tree can be:
38+
1. Served directly over HTTP as a local mirror of the Broadcom CDN for
39+
`software-packages stage --url http://host/valm/<version>/`.
40+
2. Turned into a VCSA patch ISO by straight recursive copy — no need to
41+
partition files between root and `package-pool/` at ISO-build time.
42+
3. Inspected locally the same way as before — only the layout has changed.
43+
44+
**Migrating an existing flat repo (no re-download):**
45+
```sh
46+
cd /path/to/VMware-repo/valm/<version>
47+
mkdir -p package-pool
48+
for f in *; do
49+
case "$f" in
50+
package-pool|manifest-latest.xml|manifest-latest.xml.sha256|manifest-latest.xml.sign|\
51+
rpm-manifest.json|rpm-manifest.json.sha256|rpm-manifest.json.sign) ;;
52+
*) mv -- "$f" package-pool/ ;;
53+
esac
54+
done
55+
```
56+
PowerShell equivalent:
57+
```powershell
58+
$src = 'C:\VMware-repo\valm\8.0.3.00800'
59+
$keep = @('manifest-latest.xml','manifest-latest.xml.sha256','manifest-latest.xml.sign',
60+
'rpm-manifest.json','rpm-manifest.json.sha256','rpm-manifest.json.sign')
61+
New-Item -ItemType Directory -Path (Join-Path $src 'package-pool') -Force | Out-Null
62+
Get-ChildItem -Path $src -File |
63+
Where-Object { $keep -notcontains $_.Name } |
64+
Move-Item -Destination (Join-Path $src 'package-pool')
65+
```
66+
567
## 📦 Version 0.7.0
668
**Released:** April 11, 2026
769

src/downloader.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,14 +1489,25 @@ impl Downloader {
14891489
}
14901490

14911491
fn get_vcsa_file_path(&self, version: &str, file: &str) -> PathBuf {
1492-
// Extract filename from path (after last /)
1493-
let filename = file.split('/').last().unwrap_or(file);
1494-
1495-
// Create path: base_path/valm/version/filename
1496-
self.base_path
1497-
.join("valm")
1498-
.join(version)
1499-
.join(filename)
1492+
// Mirror the CDN URL layout on disk: a file downloaded from
1493+
// `<base>/<version>/package-pool/foo.rpm` is saved at
1494+
// `<base_path>/valm/<version>/package-pool/foo.rpm`, and a bare
1495+
// root file like `manifest-latest.xml` lands at
1496+
// `<base_path>/valm/<version>/manifest-latest.xml`.
1497+
//
1498+
// Preserving the `package-pool/` prefix lets the downloaded repo be
1499+
// served directly over HTTP as a drop-in replacement for the Broadcom
1500+
// CDN (for `software-packages stage --url ...`), and it lets the VCSA
1501+
// patch ISO be built via a straight recursive copy instead of having
1502+
// to reconstruct `package-pool/` from a flat pile of files.
1503+
//
1504+
// `..` and `.` segments are stripped defensively so a hostile manifest
1505+
// can't write outside the version directory.
1506+
let mut path = self.base_path.join("valm").join(version);
1507+
for segment in file.split('/').filter(|s| !s.is_empty() && *s != ".." && *s != ".") {
1508+
path = path.join(segment);
1509+
}
1510+
path
15001511
}
15011512

15021513
async fn process_vcsa_manifest(&self, content: &str, version: &str, base_url: &str) -> Result<()> {

0 commit comments

Comments
 (0)