Portsnap is a alternative system for securely distributing and updating the FreeBSD ports tree, which is easier to use than CVSup. Portsnap was first included in FreeBSD 6.0. Like CVSup, Portsnap uses a pull model of updating: The packaged and signed ports trees are placed on a web server which waits passively for clients to request files by either run portsnap manually by users or set up a cron job to download updates automatically on a regular basis.

On older FreeBSD systems, Portsnap is not automatically included, but it can be installed from sysutils/portsnap port by using command:

# pkg_add -r portsnap

Portsnap first fetch and update compresses snapshots of the FreeBSD ports tree stored in /var/db/portsnap/ (in /usr/local/portsnap/ if Portsnap is installed from FreeBSD Ports Collection) by default, and then only extract and update the uncompressed live ports tree at /usr/ports.

The behavior and operation of Portsnap is controlled by configuration file portsnap.conf located in /etc (in /usr/local/etc/ if Portsnap is installed from the FreeBSD Ports Collection, and the configuration file is not automatically generated when freshly installed, instead you’ll found portsnap.conf.sample, just copy it as portsnap.conf). Generally, default configuration file will does its jobs.

At command line, the following options are supported, although most of the time it no need to be used, some can be configured in configuration file itself:

-d workdir : Store working files (e.g. downloaded updates) in workdir. (default: /var/db/portsnap, or as given in the configuration file)

-f conffile : Read the configuration from from conffile. (default: /etc/portsnap.conf)

-I : For the update command, update INDEX files, but not the rest of the ports tree.

-k KEY : Expect a public key with given SHA256 hash. (default: read value from configuration file)

-p portsdir : When extracting or updating an uncompressed snapshot, operate on the directory portsdir. (default: /usr/ports/, or as given in the configuration file.)

-s server : Fetch files from the specified server or server pool. (default: portsnap.FreeBSD.org , or as given in the configuration file.)

path : For extract command only, operate only on parts of the ports tree starting with path. (e.g. portsnap sysutils/port would extract sysutils/portsman, sysutils/portsnap, sysutils/portupgrade, etc.)

The Synopsis for the Portsnap command line is:

portsnap [-I] [-d workdir] [-f conffile] [-k KEY] [-p portsdir] [-s server] command … [path]

Usage of Portsnap

  1. Create an empty directory /usr/ports if it does not exists.
    # mkdir /usr/ports
  2. Fetch and download a compressed snapshot of the Ports Collection into /var/db/portsnap (or any other location specified in configuration file). Internet connection needed at this stage) and update the existing snapshot.
    # portsnap fetch
  3. If you are running Portsnap for the first time (even if a ports tree has already been created or populated, to let Portsnap establishes a baseline from which portsnap can determine which parts of the ports tree need to be updated) or /usr/ports hasn’t been populated, extract the snapshot and replaces the existing files and directories, and establishes Portsnap-maintained ports tree into /usr/ports:
    # portsnap extract

    This step can be skipped if you’re only updating the ports tree.

  4. If you already have a populated /usr/ports and you are just updating, run the following command instead:
    # portsnap update

Note: For updating of FreeBSD Ports Tree, step 1 and 3 can be combined into single command: portsnap fetch update (not support in older version of Portsnap).

Running Portsnap as Cron Job

portsnap fetch will not be able to execute from a cron job to avoid burden of sudden surge of downloading request to Portsnap servers. Instead, a special portsnap cron command exists, which waits and sleeps for a random duration up to 3600 seconds before fetching updates, as if the fetch command is specified.

To run portsnap automatically with cron job, just add the line into /etc/crontab (the line set the time to 3 AM everyday, you can choose your own timing):

0 3 * * * root /usr/sbin/portsnap cron

This will ensure that the FreeBSD snapshot of ports collection is always up-to-date and can be quickly extracted into /usr/ports.

Note: Running portsnap update from cron is not recommended as it may cause problem if installing or updating of a port happens at the time the cron job runs. Portsnap will updates or removes files which are being used by the port build. However, running portsnap -I update to update the ports Index files is possible, and can be used together with portversion to identify installed software which is out of date.

To update ports compressed snapshot and the INDEX files in /usr/ports/, and send an email if any installed ports are out of date, use the following line in /etc/crontab:

0 3 * * * root portsnap -I cron update && pkg_version -vIL=

Note: Older version of portsnap does not support listing multiple commands (e.g., cron update) in the same invocation of portsnap. If the line above fails, try replacing portsnap -I cron update with portsnap cron && portsnap -I update.