Bits, Bytes, & Radio Waves

A quiet journey through discovery and understanding.

VMware Cloud Foundation (VCF) Bundle Transfer Utility (v 5.2) and Offline Depot with RHEL 9 (Archived)


Archived Post

This article has been archived and is no longer maintained.
A consolidated and up-to-date version of this content is available here → https://www.aaronrombaut.com/offline-depot-management-for-vmware-cloud-foundation-vcf-legacy-and-current-tooling/


Overview

If the SDDC Manager appliance is not connected to an online or offline depot, you can use the Bundle Transfer Utility to download the bundles to a different computer and then upload them to the SDDC Manager appliance.

Moreover, in cases where an organization comprises numerous VMware Cloud Foundation (VCF) instances or operates within air-gapped networks, the implementation of an offline depot may be advisable. The utilization of an offline depot enhances the experience for air-gapped customers by minimizing the number of steps required to distribute artifacts across multiple VCF instances repeatedly.


RTFM

VCF authenticated downloads configuration update instructions

“Got Http error[403] while downloading bundle”, OBTU tool fails to download bundles from the online repositories

“ASYNC_PATCH_INPUT_SPEC_DOWNLOAD_FAILED – Ensure the depot credentials provided are correct” AP tool patch enablement fails while trying to connect to online repositories

VCF Offline Depot deployment

Offline Download of VMware Cloud Foundation 5.2.x Upgrade Bundles

Download Bundles to an Offline Depot

Connect SDDC Manager to a Software Depot for Downloading Bundles

VMware Cloud Foundation Offline Depot Introduction


Warnings and Assumptions

First, the warning. This whole procedure is not for the faint of heart. If you are comfortable on the command line, you will likely succeed. Hopefully, in the future, this process will be streamlined and we can laugh about this absurd process someday.

Now, on to the assumptions.

  • know what VMware Cloud Foundation (VCF) is and what it does
  • understand basic virtualization concepts
  • working SDDC Manager
  • generated your download token with Broadcom support (link)
  • understand how to edit files on the command line

I also hope you have a good heartbeat and a greater sense of humor!


Build an Offline Depot

To get started with an offline depot, we need a virtual machine to host the upgrade bundles.

Deploy and Configure a Virtual Machine

I am going to use a minimal RHEL image for the virtual machine to build the Offline Depot.

Complete the marked items.

Enter the correct credentials or use an appropriate Activation Key to connect to the Red Hat servers.

My plan is to install the operating system to the smaller hard drive (/dev/sda in the example) and then use the second hard drive (/dev/sdb) for package storage.

I only need a Basic Web Server and Guest Agents since I am running on a VMware infrastructure.

Add a root password and confirmation.

While not required at this point, the Network Configuration is configured with static IP address information and a hostname.

The Ethernet toggle may need to toggled off and back on to activate the connection.

Once all the tasks are completed, the Begin Installation button activates.

Wait until the installation completes to reboot.


Permit root Login for SSH

By default, SSH does not allow root login. However, to make it easier to copy and paste commands during setup, I’ll temporarily enable root access via SSH. I’ll disable it again when I’m done.

Start by opening a console window and logging in as root. Then, let’s add a temporary file in the sshd_config.d directory to make the changes.

vi /etc/ssh/sshd_config.d/70-allow-root-ssh.conf

Add the following line to the file.

PermitRootLogin yes

Save the configuration file.

<Esc>
:wq

Restart the sshd.service service and check the status.

systemctl restart sshd.service
systemctl status sshd.service

Update the Virtual Machine

Now that we can log in with SSH, we can update the virtual machine. Log in as root to the virtual machine with SSH.

Update the virtual machine.

dnf update

Reboot the virtual machine.

reboot

Optional – Use Additional Storage Device

Since the size of the offline bundles can vary, I would like to use an additional storage device to store the bundles.

Start out listing the available storage devices.

lsblk

From the listing, I can see that I have an additional disk (sdb) available to use.

I need to add a partition to make the disk usable so I will use gdisk.

gdisk /dev/sdb

You can use the letter ? for help.

Use the letter n to add a new partition. I am also going to use the default partition number of 1 and the other defaults.

Command (? for help): n
Partition number (1-128, default 1): 1
First sector (34-1048575966, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-1048575966, default = 1048575966) or {+-}size{KMGTP}:
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): 8300
Changed type of partition to 'Linux filesystem'

When returned back to Command (? for help): use the letter w to write the changes.

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/sdb.
The operation has completed successfully.

Now, when viewing the available block devices, there should be a new partition available.

lsblk

Now that I know my disk is partitioned, I need to format it with a file system.

mkfs.ext4 /dev/sdb1

I can check that the filesystem was created using the -f switch.

lsblk -f

Notice the UUID in the output? That’s the device UUID, not the partition UUID. We will need the partition UUID to update the fstab file so that our disk automounts. The device UUID can be helpful if there are many disks and partitions listed.

blkid

Open the fstab file and add the following line to the end of the file. Shift + G to get to the end of the file, little o to enter Insert Mode on the next line.

vi /etc/fstab
PARTUUID=<UUID>  /var/www/html  ext4  defaults  0  0

Save and close the file.

<esc>
:wq

Make sure there are no files currently in the /var/www/html directory. If there are, move them to somewhere else. Mount all the devices using the fstab file to test.

mount -a

Verify the file systems and mount points.

lsblk -f

Restore the file context label since we added the new volume.

restorecon -Rv /var/www/html

Now, when the install bundles are downloaded to /var/www/html, the files will be on the new disk. This will help to prevent the OS disk from filling up and causing trouble in the future.


Apache HTTP Server

Check if Apache is installed.

systemctl status httpd.service

Install Apache

Install the Apache Web server if it wasn’t installed from the initial installation.

dnf install httpd

Certificates

Create a temporary directory to prepare the certificate.

mkdir /root/http-certificates

Change to the new directory.

cd /root/http-certificates

Generate a private key.

openssl genpkey -out /root/http-certificates/server.key -algorithm RSA -pkeyopt rsa_keygen_bits:2048

Make a configuration file containing Subject Alternative Name (SAN) information. Modern browsers will not trust the certificate otherwise.

vi offline-depot.cnf
[req]
distinguished_name = req_distinguished_name
req_extensions = req_ext
prompt = no

[req_distinguished_name]
C = <country>
ST = <state>
L = <locality>
O = <organization>
OU = <organizational unit>
CN = <fully-qualified domain name>

[req_ext]
subjectAltName = @alt_names

[alt_names]
IP.1 = <ip address>
DNS.1 = <fully-qualified domain name>
DNS.2 = <short name>

Generate the Certificate Signing Request (CSR) using the private key and the configuration file.

openssl req -new -key /root/http-certificates/server.key -out /root/http-certificates/request.csr -config /root/http-certificates/offline-depot.cnf

Have the Certificate Signing Request (CSR) signed by your Certificate Authority (CA). This will depend on your organization’s policy. Once the certificate request is signed, upload the machine (machine.crt), intermediate (if applicable), and root certificates, in PEM format and encoded in Base64, to the /root/http-certificates directory.

Combine the files, top-to-bottom, starting with the <machine certificate>, <intermediate certificate>, then <root certificate> into a file called server.crt. In my lab, I do not have an intermediate signing authority, so I will skip that.

cat machine.crt >> server.crt
cat intermediate.crt >> server.crt
cat root.crt >> server.crt

Open the file, remove any spaces between the certificates if necessary, and then save it. Move the server key and certificate to the /etc/httpd/conf directory.

mv /root/http-certificates/server.* /etc/pki/tls/certs/

Fix the permissions on the key.

chmod 0400 /etc/pki/tls/certs/server.key && chown root:root /etc/pki/tls/certs/server.key

Restore the context of the files added.

restorecon -Rv /etc/pki/tls/certs

Configure Apache HTTP Server

Edit the /etc/httpd/conf/httpd.conf file, setting the ServerName and ServerAdmin directives accordingly.

vi /etc/httpd/conf/httpd.conf

Show line numbers or use the line-number,character reference mapping natively in vi.

:set number

ServerAdmin is near line 91 and ServerName is near line 100.

Save and close the file.

<esc>
:wq

Open up the ssl.conf file.

vi /etc/httpd/conf.d/ssl.conf 

On about line 85, comment out the original SSLCertificateFile and add the following on the next line.

SSLCertificateFile /etc/pki/tls/certs/server.crt

On about line 93, comment out the original SSLCertificateKeyFile and add the following on the next line.

SSLCertificateKeyFile /etc/pki/tls/certs/server.key

Optionally, if you did not include the full chain in the SSLCertificateFile, add the following on about line 102.

SSLCertificateChainFile /etc/pki/tls/certs/root.crt

Add <Directory> Directives

Continuing to edit the /etc/httpd/conf.d/ssl.conf file.

vi /etc/httpd/conf.d/ssl.conf

Go to the end of the file.

<shift> + g

Insert the following lines after the </VirtualHost> (on about line 203) directive (use :set number in vi to view line numbers).

<Directory /var/www/html/<token id>/PROD/COMP/SDDC_MANAGER_VCF>
# Basic Auth (VCF 4.x and 5.0)
    AuthType Basic
    AuthName "Basic Authentication"
    AuthUserFile /etc/httpd/conf/.htpasswd
    require valid-user
</Directory>
<Directory "/var/www/html/<token id>/PROD/COMP/SDDC_MANAGER_VCF/Compatibility/VxrailCompatibilityData.json">
# VxRail VVS Cookie Validation (VCF 5.0)
    <If "%{HTTP:Cookie} == 'ngssosession=ngsso-token' ">
        Require all granted
    </If>
</Directory>
<Directory /var/www/html/<token id>/PROD/vsan/hcl>
    <If "%{HTTP:X-vmw-esp-clientid} == 'offline-depot-hcl-vcf' ">
        Require all granted
    </If>
</Directory>

# These Alias statements are needed only for VCF 5.1.0.0.
Alias /products/v1/bundles/lastupdatedtime /var/www/html/<token id>/PROD/vsan/hcl/lastupdatedtime.json
Alias /products/v1/bundles/all /var/www/html/<token id>/PROD/vsan/hcl/all.json

Notice you will need to replace the <token id> in the snippet above with your unique token generated from the Broadcom Support portal for this. There are five locations highlighted in bold to change. If you are using vi or vim, you can do the replacement with one line.

:%s#<token id>#<your actual token id>#g

Save and close the file.

<esc>
:wq

Configure Basic Authentication

Generate a user and password for use with the offline depot. If more than one user will be created, remove the -c after the initial file creation.

htpasswd -c /etc/httpd/conf/.htpasswd <username>

Protect the file by modifying the file’s permissions.

chown apache /etc/httpd/conf/.htpasswd
chmod 0400 /etc/httpd/conf/.htpasswd

Change the SELinux File Context

Run the following commands to restore the file context on the files that were created or modified, if necessary.

restorecon -Rv /etc/httpd/conf
restorecon -Rv /etc/pki/tls/certs
restorecon -Rv /var/www/html

Start and Enable Apache HTTP Server

After making modifications to configuration files, it’s a good idea to test them. If Apache is already running, stop the service.

systemctl stop httpd.service

Test the configuration.

apachectl configtest

or

httpd -t

Assuming that the everything is good, start the server.

systemctl start httpd.service

Check the status of the server, ensuring the the service is active (running).

systemctl status httpd.service

Now, enable the service so that it runs at startup.

systemctl enable httpd.service

Configure firewalld

To allow web traffic to the server, add an ALLOW rule to firewalld and save it.

firewall-cmd --add-service=https --permanent

Check that the rule is configured as expected.

firewall-cmd --list-all

Note: If you don’t see the https service in the list of services, try to reload the firewall configuration.

firewall-cmd --reload

Open a web browser and navigate to the offline depot URL or IP address.

https://offline-depot.domain.com

or

https://<ip address>

Clean Up Tasks

Remove the directory used to generate the certificates.

rm -rf /root/http-certificates

Comment out all the lines in the welcome.conf file. Note: Do not delete the file! It will be replaced during an upgrade.

vi /etc/httpd/conf.d/welcome.conf
:g/^[^#]/s/^/# /

Restart the httpd service after commenting out the file.

systemctl restart httpd

If PermitRootLogin was used for SSH, it is best to remove the file.

rm -f /etc/ssh/sshd_config.d/70-allow-root-ssh.conf

Offline Depot Bundles Download

For this section, I am going to use the same virtual machine that was just configured above. In an air-gapped network, an additional virtual machine may be required. The offline bundles must be downloaded from an internet connected computer and then transferred over to the air-gapped offline depot virtual machine. In my case, I am cutting out the additional virtual machine and just using the one. The steps will be the same up until the file transfer.

Download the Bundle Transfer Utility

Download the bundle transfer utility (lcm-tools-prod.tar.gz) from support.broadcom.com and transfer it to the offline depot virtual machine to /opt/vmware/vcf/lcm/lcm-tools.

mkdir -p /opt/vmware/vcf/lcm/lcm-tools
cd /opt/vmware/vcf/lcm/lcm-tools

Extract the file.

tar -xvf lcm-tools-prod.tar.gz

Change into the bin directory.

cd bin

Make the lcm-bundle-transfer-util file executable.

chmod u+x lcm-bundle-transfer-util

Test that the tool will work.

./lcm-bundle-transfer-util --help

Edit the application-prod.properties file

Prerequisite step required here. Ensure you have already generated your unique token and have it available (VCF Authenticated Downloads). The next few steps are going to require editing the application-prod.properties file.

Open the application-prod.properties file to begin editing.

vi /opt/vmware/vcf/lcm/lcm-tools/conf/application-prod.properties

Let’s get some line numbers to make this easier.

:set number

Lines 25, 26, 27, 39, and 43 need to be edited. I will include the original text as well as updated sample text. If desired, make a backup of the entire file before editing.

Line 25

lcm.depot.adapter.host=depot.vmware.com
lcm.depot.adapter.host=dl.broadcom.com

or

:%s#depot.vmware.com#dl.broadcom.com#g

Line 26

lcm.depot.adapter.remote.rootDir=/PROD2

Replace <downloadToken> with the token you received from the Broadcom Support portal.

lcm.depot.adapter.remote.rootDir=/<downloadToken>/PROD

Line 27

lcm.depot.adapter.remote.repoDir=/evo/vmw
lcm.depot.adapter.remote.repoDir=/COMP/SDDC_MANAGER_VCF

Line 39

lcm.depot.adapter.remote.lcmManifestDir=/evo/vmw/lcm/manifest
lcm.depot.adapter.remote.lcmManifestDir=/COMP/SDDC_MANAGER_VCF/lcm/manifest

Line 43

lcm.depot.adapter.remote.bundletransferconfig.repoDir:/evo/vmw/obtu
lcm.depot.adapter.remote.bundletransferconfig.repoDir:/COMP/SDDC_MANAGER_VCF/obtu

Save the file.

<esc>
:wq

Set up the Offline Depot

Create a plain text password file and make it readable to only the user running the bundle transfer utility. (yes, this is real)

vi ~/obtu-user-password
chmod 400 ~/obtu-user-password

Prepare to download the bundles required to upgrade VMware Cloud Foundation.

cd /opt/vmware/vcf/lcm/lcm-tools/bin

Here is the syntax.

./lcm-bundle-transfer-util --setUpOfflineDepot -sv vcf-source-version --offlineDepotRootDir offline-depot-root-dir --offlineDepotUrl url:port --depotUser user-name --depotUserPasswordFile path-to-password-file

Here is an example.

./lcm-bundle-transfer-util --setUpOfflineDepot -sv 5.2.0.0 --offlineDepotRootDir /var/www/html --offlineDepotUrl https://offline-depot.aaronrombaut.com:443 --depotUser [email protected] --depotUserPasswordFile ~/obtu-user-password

Here is a documentation example. One thing to note is that the --sourceVersion or -sv parameter is supposed to define the version that will be downloaded. However, while I am trying to download patches for 5.2.1.0, the tool will report back that there are no new bundles. If I specify the version as 5.2.0.0, I will get back the updates I am looking for.

./lcm-bundle-transfer-util --setUpOfflineDepot -sv 5.0.0.0 --offlineDepotRootDir /var/www/html --offlineDepotUrl https://10.123.456.78:8282 --depotUser [email protected] --depotUserPasswordFile ../vmw-depot 

Here is a sample list of bundles that will be downloaded when you specify the source version as 5.2.0.0. Take note of the bundle names—although the product version is listed as 5.2.1.0, the list also includes patches for SDDC Manager 5.2.1.1 and 5.2.1.2.

This can be a bit confusing. I initially tried using 5.2.1.2 as the value for the -sv (source version) parameter, but that consistently returned no results. Using 5.2.0.0 instead resolved the issue and returned the expected bundles.


-------------------------------------------------------------------------------------------------------------------------------------------------
Bundle                               | Product Version  |      Bundle Size | Bundle Component                                   | Bundle Type    
-------------------------------------------------------------------------------------------------------------------------------------------------
bundle-133762                        | 5.2.1.0          |         606.4 MB | ESX_HOST-8.0.3-24280767                            | PATCH          
bundle-133763                        | 5.2.1.0          |        8895.2 MB | NSX_T_MANAGER-4.2.1.0.0-24304122                   | PATCH          
bundle-202281                        | 5.2.1.0          |        2364.8 MB | SDDC_MANAGER_VCF-5.2.1.1-24397777                  | PATCH          
bundle-214558                        | 5.2.1.0          |        2375.9 MB | SDDC_MANAGER_VCF-5.2.1.2-24690695                  | PATCH          
bundle-133760                        | 5.2.1.0          |        2364.8 MB | SDDC_MANAGER_VCF-5.2.1.0-24307856                  | PATCH          
bundle-133761                        | 5.2.1.0          |           0.0 MB | SDDC_MANAGER_VCF-5.2.1.0-24307856                  | PATCH (Drift)  
bundle-133765                        | 5.2.1.0          |       18817.0 MB | VCENTER-8.0.3.00300-24305161                       | PATCH          
bundle-130870                        | 5.2.1.0          |        4238.5 MB | NSX_ALB-22.1.7-24190832                            | INSTALL        
bundle-133764                        | 5.2.1.0          |       11636.7 MB | NSX_T_MANAGER-4.2.1.0.0-24304122                   | INSTALL        
bundle-133766                        | 5.2.1.0          |       11832.3 MB | VCENTER-8.0.3.00300-24305161                       | INSTALL        
-------------------------------------------------------------------------------------------------------------------------------------------------

Once the downloads complete, copy the files to the document root or if they were downloaded directly, view the directory.

ls -la /var/www/html/

Notice your directory will use your token id where I have highlighted the <download token>.

root@offline-depot [ /opt/vmware/vcf/lcm/lcm-tools/bin ]# tree /var/www/html
/var/www/html
└── <download token>
    └── PROD
        ├── COMP
        │   └── SDDC_MANAGER_VCF
        │       ├── bundles
        │       │   ├── bundle-130870.tar
        │       │   ├── bundle-133760.tar
        │       │   ├── bundle-133761.tar
        │       │   ├── bundle-133762.tar
        │       │   ├── bundle-133763.tar
        │       │   ├── bundle-133764.tar
        │       │   ├── bundle-133765.tar
        │       │   ├── bundle-133766.tar
        │       │   ├── bundle-202281.tar
        │       │   └── bundle-214558.tar
        │       ├── Compatibility
        │       │   └── VmwareCompatibilityData.json
        │       ├── deltaFileDownloaded
        │       ├── deltaFileDownloaded.md5
        │       ├── index.v3
        │       ├── lcm
        │       │   └── manifest
        │       │       └── v1
        │       │           └── lcmManifest.json
        │       ├── manifests
        │       │   ├── bundle-130870.manifest
        │       │   ├── bundle-130870.manifest.sig
        │       │   ├── bundle-133760.manifest
        │       │   ├── bundle-133760.manifest.sig
        │       │   ├── bundle-133761.manifest
        │       │   ├── bundle-133761.manifest.sig
        │       │   ├── bundle-133762.manifest
        │       │   ├── bundle-133762.manifest.sig
        │       │   ├── bundle-133763.manifest
        │       │   ├── bundle-133763.manifest.sig
        │       │   ├── bundle-133764.manifest
        │       │   ├── bundle-133764.manifest.sig
        │       │   ├── bundle-133765.manifest
        │       │   ├── bundle-133765.manifest.sig
        │       │   ├── bundle-133766.manifest
        │       │   ├── bundle-133766.manifest.sig
        │       │   ├── bundle-202281.manifest
        │       │   ├── bundle-202281.manifest.sig
        │       │   ├── bundle-214558.manifest
        │       │   └── bundle-214558.manifest.sig
        │       └── tmp
        │           ├── index.v3
        │           └── lcmManifest.json
        └── vsan
            └── hcl
                ├── all.json
                └── lastupdatedtime.json

13 directories, 39 files

Set the correct file permissions to the directories and files or if a cron job was set, this will likely already have taken place.

chown apache:apache -R /var/www/html
find /var/www/html/ -type d -exec chmod 0755 {} \;
find /var/www/html/ -type f -exec chmod 0644 {} \;

The httpd service may need to be restarted for the changes to take effect.

systemctl restart httpd.service

Try to navigate to https://<ip address>/<Token ID>/PROD/COMP/SDDC_MANAGER_VCF and verify the site prompts for a log in. Use the log in that was created and added to the .htaccess file to verify the credentials.


SDDC Manager Edits and Connecting to Offline Depot

Edit the application-prod.properties file

After Broadcom changed to VCF authenticated downloads, even using an Offline Depot still requires the SDDC Manager application-prod.properties file to be edited to look at the correct directories.

vi /opt/vmware/vcf/lcm/lcm-app/conf/application-prod.properties
:set number

Line 66

lcm.depot.adapter.host=depot.vmware.com
lcm.depot.adapter.host=dl.broadcom.com

Line 68

lcm.depot.adapter.remote.rootDir=/PROD2
lcm.depot.adapter.remote.rootDir=/<downloadToken>/PROD

Line 69

lcm.depot.adapter.remote.repoDir=/evo/vmw
lcm.depot.adapter.remote.repoDir=/COMP/SDDC_MANAGER_VCF

Line 79

lcm.depot.adapter.remote.lcmManifestDir=/evo/vmw/lcm/manifest
lcm.depot.adapter.remote.lcmManifestDir=/COMP/SDDC_MANAGER_VCF/lcm/manifest

Line 60

lcm.depot.adapter.remote.lcmProductVersionCatalogDir=/evo/vmw/lcm/productVersionCatalog
lcm.depot.adapter.remote.lcmProductVersionCatalogDir=/COMP/SDDC_MANAGER_VCF/lcm/productVersionCatalog

Save the file, making sure you add the ! to the command to overwrite the read-only file.

<esc>
:wq!

Restart the LCM service.

systemctl restart lcm

Connect SDDC Manager to Offline Depot

Note: Make sure the TLS certifcates are configured for both the Offline Depot and the SDDC Manager. Otherwise, it is likely a Secure protocol communication error will be logged. You can tail the lcm-debug.log on SDDC Manager for more details if there are issues connecting to the depot. In the UI, I received the message, “Failed to connect to VMware depot with the provided user credentials. Cause: {0}.” Turns out the credentials are correct, the lack of trust between the two servers is actually the cause.

tail -f /var/log/vmware/vcf/lcm/lcm-debug.log

In the navigation pane, click Administration > Depot Settings.

Connect SDDC Manager to the Offline Depot by clicking the Set Up button.

Enter the appropriate details for the offline depot.

You can view the lcm-debug.log to view what’s going on in the background since the Tasks won’t populate. Be patient here as the Bundle Management populates.


Conclusion

By following this guide, you’ve successfully set up an Offline Depot for VMware Cloud Foundation (VCF), enabling patch and bundle management in air-gapped or restricted environments. This configuration allows SDDC Manager to pull upgrade bundles from a secure, local source without requiring internet access, ensuring compliance, control, and operational continuity across isolated VCF deployments.

While the setup process is intricate and requires command-line proficiency, the end result significantly streamlines bundle distribution, especially in environments with multiple VCF instances. With the Offline Depot in place, your organization is now better positioned to manage VCF updates reliably and securely—even in the most disconnected networks.