Offline Media
=============

A medium stores mirrored repositories and subscription information for use by offline Proxmox
systems. It can be an external storage device, such as a USB flash drive, or a local network share.

Setting Up a Medium
-------------------

Either run the ``setup`` wizard again, or use the ``config media add`` command.
For example, to define a new medium containing the
`proxmox-ve-bookworm-no-subscription` and `debian-bookworm` mirrors, run the
following command:

.. code-block:: console

  proxmox-offline-mirror config media add \
   --id pve-bookworm \
   --mirrors proxmox-ve-bookworm-no-subscription \
   --mirrors debian-bookworm \
   --sync true \
   --verify-mode size \
   --mountpoint /path/where/medium/is/mounted

.. _sync_medium:

Syncing a Medium
----------------

To sync the local mirrors to a medium, the following command can be used:

.. code-block:: console

  proxmox-offline-mirror medium sync pve-bookworm

This command will sync all mirrors linked with this medium to the medium's mount point.
Additionally, it will sync all offline keys for further processing by
``proxmox-offline-mirror-helper`` on the target system.

The medium's ``verify-mode`` controls checks of files already stored on it. ``none`` checks only
that they exist, ``size`` compares their sizes with the corresponding source files in the mirror,
and ``full`` verifies their checksums. A file that fails the selected check is copied again. In
``size`` and ``full`` mode, checksums are also verified during copying. If a source file fails this
check, synchronization fails rather than copying damaged content into the medium's pool.

While copying a mirror, synchronization holds the same per-mirror lock as snapshot creation. This
prevents the snapshots from changing during the copy. If another operation holds the lock,
synchronization waits up to five seconds, then fails if the mirror is still busy. Retry once the
conflicting operation has finished.

Using a Medium
--------------

After syncing a medium you can make it accessible on the (offline) target system by either:

* unmounting it from the mirror host, plugging it into the target and mounting it there
* exposing it either directly (from the mirror host) or indirectly (from another host) via the local
  network (NFS, CIFS/SMB or HTTP)

After that you can upgrade the host as usual, either using the console or the web interface, as
described in the respective project's documentation.

Once an upgrade is done you should disable, or remove, the snippet to avoid apt errors from
automatic refresh. Note that you can disable and re-enable repositories simply via the web interface
of Proxmox VE, Proxmox Backup Server or Proxmox Mail Gateway.

Example: Local Mount Point
^^^^^^^^^^^^^^^^^^^^^^^^^^

Either option below assumes that you already mounted the medium on the target host.

Guided Setup
++++++++++++

For a guided setup run ``proxmox-offline-mirror-helper setup``. It will let you select the mirrors
and snapshots and can then generate a `sources.list.d` snippet. This snippet can be saved to the
``/etc/apt/sources.list.d`` directory. The default file name is ``offline-mirror.list``.

Manual Setup
++++++++++++

To use a snapshot directly with APT, create a repository entry in a ``.list`` file under
``/etc/apt/sources.list.d/``. For example:

.. code-block:: sources.list

  deb [check-valid-until=false] file:///mnt/mirror-path/<mirror-name>/<snapshot-timestamp> <suite> <components>

Replace ``<suite>`` with the suite from the mirror's repository line, such as ``bookworm`` or
``bookworm-security``. Replace ``<components>`` with one or more of that repository's components,
such as ``main``, ``pve-enterprise``, or ``pbstest``. Use the mirror name and snapshot timestamp for
``<mirror-name>`` and ``<snapshot-timestamp>``.

You can then upgrade the system as usual. After upgrading, disable the repository entry until the
medium is needed again.

.. _example-local-http-server:

Example: Local HTTP Server
^^^^^^^^^^^^^^^^^^^^^^^^^^

You can also configure an HTTP server to provide the snapshots in your internal network.
A minimal sample configuration for `nginx`:

  .. literalinclude:: examples/nginx-conf

Create a ``.list`` file under ``/etc/apt/sources.list.d/`` with a repository entry pointing to the
HTTP server:

.. code-block:: sources.list

  deb [ check-valid-until=false ] http://proxmox-offline-mirror.domain.example/<mirror-name>/<snapshot-timestamp> <suite> <components>

Replace the placeholders as described in `Manual Setup`_ above. You can then upgrade the system as
usual. After upgrading, disable the repository entry until the mirror is needed again.

Activating a Subscription Key
------------------------------

To activate or update a subscription key offline, either use ``proxmox-offline-mirror-helper
offline-key`` directly or follow the respective step when doing the guided setup via the
``proxmox-offline-mirror-helper setup`` command.

The ``offline-key`` command supports both local mountpoints and HTTP URLs. When using an HTTP
server (as described in the :ref:`example-local-http-server` section), you can activate subscription keys
directly from the HTTP URL without needing to mount the medium locally:

.. code-block:: console

  proxmox-offline-mirror-helper offline-key --source http://proxmox-offline-mirror.domain.example/

This is particularly useful when the mirror is served over HTTP and you only need to activate
subscription keys. Other operations like the ``status`` command and repository configuration
still require a local mountpoint.
