rotate-backups: Simple command line interface for backup rotation

https://travis-ci.org/xolox/python-rotate-backups.svg?branch=master https://coveralls.io/repos/xolox/python-rotate-backups/badge.svg?branch=master

Backups are good for you. Most people learn this the hard way (including me). Nowadays my Linux laptop automatically creates a full system snapshot every four hours by pushing changed files to an rsync daemon running on the server in my home network and creating a snapshot afterwards using the cp -al command (the article Easy Automated Snapshot-Style Backups with Linux and Rsync explains the basic technique). The server has a second disk attached which asynchronously copies from the main disk so that a single disk failure doesn’t wipe all of my backups (the “time delayed replication” aspect has also proven to be very useful).

Okay, cool, now I have backups of everything, up to date and going back in time! But I’m running through disk space like crazy... A proper deduplicating filesystem would be awesome but I’m running crappy consumer grade hardware and e.g. ZFS has not been a good experience in the past. So I’m going to have to delete backups...

Deleting backups is never nice, but an easy and proper rotation scheme can help a lot. I wanted to keep things manageable so I wrote a Python script to do it for me. Over the years I actually wrote several variants. Because I kept copy/pasting these scripts around I decided to bring the main features together in a properly documented Python package and upload it to the Python Package Index.

The rotate-backups package is currently tested on cPython 2.6, 2.7, 3.4, 3.5 and PyPy (2.7). It’s tested on Linux and Mac OS X and may work on other unixes but definitely won’t work on Windows right now.

Features

Dry run mode
Use it. I’m serious. If you don’t and rotate-backups eats more backups than intended you have no right to complain ;-)
Flexible rotation
Rotation with any combination of hourly, daily, weekly, monthly and yearly retention periods.
Fuzzy timestamp matching in filenames

The modification times of the files and/or directories are not relevant. If you speak Python regular expressions, here is how the fuzzy matching works:

# Required components.
(?P<year>\d{4}) \D?
(?P<month>\d{2}) \D?
(?P<day>\d{2}) \D?
(
   # Optional components.
   (?P<hour>\d{2}) \D?
   (?P<minute>\d{2}) \D?
   (?P<second>\d{2})?
)?
All actions are logged
Log messages are saved to the system log (e.g. /var/log/syslog) so you can retrace what happened when something seems to have gone wrong.

Installation

The rotate-backups package is available on PyPI which means installation should be as simple as:

$ pip install rotate-backups

There’s actually a multitude of ways to install Python packages (e.g. the per user site-packages directory, virtual environments or just installing system wide) and I have no intention of getting into that discussion here, so if this intimidates you then read up on your options before returning to these instructions ;-).

Usage

There are two ways to use the rotate-backups package: As the command line program rotate-backups and as a Python API. For details about the Python API please refer to the API documentation available on Read the Docs. The command line interface is described below.

Command line

Usage: rotate-backups [OPTIONS] [DIRECTORY, ..]

Easy rotation of backups based on the Python package by the same name.

To use this program you specify a rotation scheme via (a combination of) the --hourly, --daily, --weekly, --monthly and/or --yearly options and the directory (or directories) containing backups to rotate as one or more positional arguments.

You can rotate backups on a remote system over SSH by prefixing a DIRECTORY with an SSH alias and separating the two with a colon (similar to how rsync accepts remote locations).

Instead of specifying directories and a rotation scheme on the command line you can also add them to a configuration file. For more details refer to the online documentation (see also the --config option).

Please use the --dry-run option to test the effect of the specified rotation scheme before letting this program loose on your precious backups! If you don’t test the results using the dry run mode and this program eats more backups than intended you have no right to complain ;-).

Supported options:

Option Description
-M, --minutely=COUNT In a literal sense this option sets the number of “backups per minute” to preserve during rotation. For most use cases that doesn’t make a lot of sense :-) but you can combine the --minutely and --relaxed options to preserve more than one backup per hour. Refer to the usage of the -H, --hourly option for details about COUNT.
-H, --hourly=COUNT

Set the number of hourly backups to preserve during rotation:

  • If COUNT is a number it gives the number of hourly backups to preserve, starting from the most recent hourly backup and counting back in time.
  • Alternatively you can provide an expression that will be evaluated to get a number (e.g. if COUNT is “7 * 2” the result would be 14).
  • You can also pass “always” for COUNT, in this case all hourly backups are preserved.
  • By default no hourly backups are preserved.
-d, --daily=COUNT Set the number of daily backups to preserve during rotation. Refer to the usage of the -H, --hourly option for details about COUNT.
-w, --weekly=COUNT Set the number of weekly backups to preserve during rotation. Refer to the usage of the -H, --hourly option for details about COUNT.
-m, --monthly=COUNT Set the number of monthly backups to preserve during rotation. Refer to the usage of the -H, --hourly option for details about COUNT.
-y, --yearly=COUNT Set the number of yearly backups to preserve during rotation. Refer to the usage of the -H, --hourly option for details about COUNT.
-I, --include=PATTERN Only process backups that match the shell pattern given by PATTERN. This argument can be repeated. Make sure to quote PATTERN so the shell doesn’t expand the pattern before it’s received by rotate-backups.
-x, --exclude=PATTERN Don’t process backups that match the shell pattern given by PATTERN. This argument can be repeated. Make sure to quote PATTERN so the shell doesn’t expand the pattern before it’s received by rotate-backups.
-j, --parallel

Remove backups in parallel, one backup per mount point at a time. The idea behind this approach is that parallel rotation is most useful when the files to be removed are on different disks and so multiple devices can be utilized at the same time.

Because mount points are per system the -j, --parallel option will also parallelize over backups located on multiple remote systems.

-p, --prefer-recent By default the first (oldest) backup in each time slot is preserved. If you’d prefer to keep the most recent backup in each time slot instead then this option is for you.
-r, --relaxed

By default the time window for each rotation scheme is enforced (this is referred to as strict rotation) but the -r, --relaxed option can be used to alter this behavior. The easiest way to explain the difference between strict and relaxed rotation is using an example:

  • When using strict rotation and the number of hourly backups to preserve is three, only backups created in the relevant time window (the hour of the most recent backup and the two hours leading up to that) will match the hourly frequency.
  • When using relaxed rotation the three most recent backups will all match the hourly frequency (and thus be preserved), regardless of the calculated time window.

If the explanation above is not clear enough, here’s a simple way to decide whether you want to customize this behavior or not:

  • If your backups are created at regular intervals and you never miss an interval then strict rotation (the default) is probably the best choice.
  • If your backups are created at irregular intervals then you may want to use the -r, --relaxed option in order to preserve more backups.
-i, --ionice=CLASS Use the “ionice” program to set the I/O scheduling class and priority of the “rm” invocations used to remove backups. CLASS is expected to be one of the values “idle”, “best-effort” or “realtime”. Refer to the man page of the “ionice” program for details about these values.
-c, --config=PATH Load configuration from the pathname given by PATH. If this option isn’t given two default locations are checked: “~/.rotate-backups.ini” and “/etc/rotate-backups.ini”. The first of these two configuration files to exist is loaded. For more details refer to the online documentation.
-u, --use-sudo Enable the use of “sudo” to rotate backups in directories that are not readable and/or writable for the current user (or the user logged in to a remote system over SSH).
-n, --dry-run Don’t make any changes, just print what would be done. This makes it easy to evaluate the impact of a rotation scheme without losing any backups.
-v, --verbose Make more noise (increase logging verbosity). Can be repeated.
-q, --quiet Make less noise (decrease logging verbosity). Can be repeated.
-h, --help Show this message and exit.

Configuration files

Instead of specifying directories and rotation schemes on the command line you can also add them to a configuration file.

By default two locations are checked for a configuration file, these are ~/.rotate-backups.ini and /etc/rotate-backups.ini. The first of these that exists is loaded. You can load a configuration file in a nonstandard location using the command line option --config.

Configuration files use the familiar INI syntax. Each section defines a directory that contains backups to be rotated. The options in each section define the rotation scheme and other options. Here’s an example based on how I use rotate-backups to rotate the backups of the Linux installations that I make regular backups of:

# /etc/rotate-backups.ini:
# Configuration file for the rotate-backups program that specifies
# directories containing backups to be rotated according to specific
# rotation schemes.

[/backups/laptop]
hourly = 24
daily = 7
weekly = 4
monthly = 12
yearly = always
ionice = idle

[/backups/server]
daily = 7 * 2
weekly = 4 * 2
monthly = 12 * 4
yearly = always
ionice = idle

[/backups/mopidy]
daily = 7
weekly = 4
monthly = 2
ionice = idle

[/backups/xbmc]
daily = 7
weekly = 4
monthly = 2
ionice = idle

As you can see in the retention periods of the directory /backups/server in the example above you are allowed to use expressions that evaluate to a number (instead of having to write out the literal number).

Here’s an example of a configuration for two remote directories:

# SSH as a regular user and use `sudo' to elevate privileges.
[server:/backups/laptop]
use-sudo = yes
hourly = 24
daily = 7
weekly = 4
monthly = 12
yearly = always
ionice = idle

# SSH as the root user (avoids sudo passwords).
[server:/backups/server]
ssh-user = root
hourly = 24
daily = 7
weekly = 4
monthly = 12
yearly = always
ionice = idle

As this example shows you have the option to connect as the root user or to connect as a regular user and use sudo to elevate privileges.

Customizing the rotation algorithm

Since publishing rotate-backups I’ve found that the default rotation algorithm is not to everyone’s satisfaction and because the suggested alternatives were just as valid as the choices that I initially made, options were added to expose the alternative behaviors:

Default Alternative
Strict rotation (the time window for each rotation frequency is enforced). Relaxed rotation (time windows are not enforced). Enabled by the -r, --relaxed option.
The oldest backup in each time slot is preserved and newer backups in the time slot are removed. The newest backup in each time slot is preserved and older backups in the time slot are removed. Enabled by the -p, --prefer-recent option.

Contact

The latest version of rotate-backups is available on PyPI and GitHub. The documentation is hosted on Read the Docs. For bug reports please create an issue on GitHub. If you have questions, suggestions, etc. feel free to send me an e-mail at peter@peterodding.com.

License

This software is licensed under the MIT license.

© 2016 Peter Odding.

API documentation

This documentation is based on the source code of version 4.3.1 of the rotate-backups package. The following modules are available:

rotate_backups

Simple to use Python API for rotation of backups.

The rotate_backups module contains the Python API of the rotate-backups package. The core logic of the package is contained in the RotateBackups class.

rotate_backups.GLOBAL_CONFIG_FILE = '/etc/rotate-backups.ini'

The pathname of the system wide configuration file (a string).

rotate_backups.LOCAL_CONFIG_FILE = '~/.rotate-backups.ini'

The pathname of the user specific configuration file (a string).

rotate_backups.ORDERED_FREQUENCIES = (('minutely', relativedelta(minutes=+1)), ('hourly', relativedelta(hours=+1)), ('daily', relativedelta(days=+1)), ('weekly', relativedelta(days=+7)), ('monthly', relativedelta(months=+1)), ('yearly', relativedelta(years=+1)))

A list of tuples with two values each:

  • The name of a rotation frequency (a string like ‘hourly’, ‘daily’, etc.).
  • A relativedelta object.

The tuples are sorted by increasing delta (intentionally).

rotate_backups.SUPPORTED_FREQUENCIES = {'yearly': relativedelta(years=+1), 'hourly': relativedelta(hours=+1), 'monthly': relativedelta(months=+1), 'daily': relativedelta(days=+1), 'minutely': relativedelta(minutes=+1), 'weekly': relativedelta(days=+7)}

A dictionary with rotation frequency names (strings) as keys and relativedelta objects as values. This dictionary is generated based on the tuples in ORDERED_FREQUENCIES.

rotate_backups.TIMESTAMP_PATTERN = <_sre.SRE_Pattern object at 0x2bec7d0>

A compiled regular expression object used to match timestamps encoded in filenames.

rotate_backups.coerce_location(value, **options)[source]

Coerce a string to a Location object.

Parameters:
  • value – The value to coerce (a string or Location object).
  • options – Any keyword arguments are passed on to create_context().
Returns:

A Location object.

rotate_backups.coerce_retention_period(value)[source]

Coerce a retention period to a Python value.

Parameters:value – A string containing the text ‘always’, a number or an expression that can be evaluated to a number.
Returns:A number or the string ‘always’.
Raises:ValueError when the string can’t be coerced.
rotate_backups.load_config_file(configuration_file=None)[source]

Load a configuration file with backup directories and rotation schemes.

Parameters:configuration_file – Override the pathname of the configuration file to load (a string or None).
Returns:A generator of tuples with four values each:
  1. An execution context created using executor.contexts.
  2. The pathname of a directory with backups (a string).
  3. A dictionary with the rotation scheme.
  4. A dictionary with additional options.
Raises:ValueError when configuration_file is given but doesn’t exist or can’t be loaded.

When configuration_file isn’t given LOCAL_CONFIG_FILE and GLOBAL_CONFIG_FILE are checked and the first configuration file that exists is loaded. This function is used by RotateBackups to discover user defined rotation schemes and by rotate_backups.cli to discover directories for which backup rotation is configured.

rotate_backups.rotate_backups(directory, rotation_scheme, **options)[source]

Rotate the backups in a directory according to a flexible rotation scheme.

Note

This function exists to preserve backwards compatibility with older versions of the rotate-backups package where all of the logic was exposed as a single function. Please refer to the documentation of the RotateBackups initializer and the rotate_backups() method for an explanation of this function’s parameters.

class rotate_backups.RotateBackups(rotation_scheme, **options)[source]

Python API for the rotate-backups program.

__init__(rotation_scheme, **options)[source]

Initialize a RotateBackups object.

Parameters:
config_file[source]

The pathname of a configuration file (a string or None).

When this property is set rotate_backups() will use load_config_file() to give the user (operator) a chance to set the rotation scheme and other options via a configuration file.

Note

The config_file property is a mutable_property. You can change the value of this property using normal attribute assignment syntax. To reset it to its default (computed) value you can use del or delattr().

dry_run[source]

True to simulate rotation, False to actually remove backups (defaults to False).

If this is True then rotate_backups() won’t make any actual changes, which provides a ‘preview’ of the effect of the rotation scheme. Right now this is only useful in the command line interface because there’s no return value.

Note

The dry_run property is a mutable_property. You can change the value of this property using normal attribute assignment syntax. To reset it to its default (computed) value you can use del or delattr().

exclude_list[source]

Filename patterns to exclude specific backups (a list of strings).

This is a list of strings with fnmatch patterns. When collect_backups() encounters a backup whose name matches any of the patterns in this list the backup will be ignored, even if it also matches the include list (it’s the only logical way to combine both lists).

See also:include_list

Note

The exclude_list property is a custom_property. You can change the value of this property using normal attribute assignment syntax. This property’s value is computed once (the first time it is accessed) and the result is cached. To clear the cached value you can use del or delattr().

include_list[source]

Filename patterns to select specific backups (a list of strings).

This is a list of strings with fnmatch patterns. When it’s not empty collect_backups() will only collect backups whose name matches a pattern in the list.

See also:exclude_list

Note

The include_list property is a custom_property. You can change the value of this property using normal attribute assignment syntax. This property’s value is computed once (the first time it is accessed) and the result is cached. To clear the cached value you can use del or delattr().

io_scheduling_class[source]

The I/O scheduling class for backup rotation (a string or None).

When this property is set (and have_ionice is True) then ionice will be used to set the I/O scheduling class for backup rotation. This can be useful to reduce the impact of backup rotation on the rest of the system.

The value of this property is expected to be one of the strings ‘idle’, ‘best-effort’ or ‘realtime’.

Note

The io_scheduling_class property is a mutable_property. You can change the value of this property using normal attribute assignment syntax. To reset it to its default (computed) value you can use del or delattr().

prefer_recent[source]

Whether to prefer older or newer backups in each time slot (a boolean).

Defaults to False which means the oldest backup in each time slot (an hour, a day, etc.) is preserved while newer backups in the time slot are removed. You can set this to True if you would like to preserve the newest backup in each time slot instead.

Note

The prefer_recent property is a mutable_property. You can change the value of this property using normal attribute assignment syntax. To reset it to its default (computed) value you can use del or delattr().

rotation_scheme[source]

The rotation scheme to apply to backups (a dictionary).

Each key in this dictionary defines a rotation frequency (one of the strings ‘minutely’, ‘hourly’, ‘daily’, ‘weekly’, ‘monthly’ and ‘yearly’) and each value defines a retention count:

  • An integer value represents the number of backups to preserve in the given rotation frequency, starting from the most recent backup and counting back in time.
  • The string ‘always’ means all backups in the given rotation frequency are preserved (this is intended to be used with the biggest frequency in the rotation scheme, e.g. yearly).

No backups are preserved for rotation frequencies that are not present in the dictionary.

Note

The rotation_scheme property is a required_property. You are required to provide a value for this property by calling the constructor of the class that defines the property with a keyword argument named rotation_scheme (unless a custom constructor is defined, in this case please refer to the documentation of that constructor). You can change the value of this property using normal attribute assignment syntax.

strict[source]

Whether to enforce the time window for each rotation frequency (a boolean, defaults to True).

The easiest way to explain the difference between strict and relaxed rotation is using an example:

  • If strict is True and the number of hourly backups to preserve is three, only backups created in the relevant time window (the hour of the most recent backup and the two hours leading up to that) will match the hourly frequency.
  • If strict is False then the three most recent backups will all match the hourly frequency (and thus be preserved), regardless of the calculated time window.

If the explanation above is not clear enough, here’s a simple way to decide whether you want to customize this behavior:

  • If your backups are created at regular intervals and you never miss an interval then the default (True) is most likely fine.
  • If your backups are created at irregular intervals then you may want to set strict to False to convince RotateBackups to preserve more backups.

Note

The strict property is a mutable_property. You can change the value of this property using normal attribute assignment syntax. To reset it to its default (computed) value you can use del or delattr().

rotate_concurrent(*locations, **kw)[source]

Rotate the backups in the given locations concurrently.

Parameters:

This function uses rotate_backups() to prepare rotation commands for the given locations and then it removes backups in parallel, one backup per mount point at a time.

The idea behind this approach is that parallel rotation is most useful when the files to be removed are on different disks and so multiple devices can be utilized at the same time.

Because mount points are per system rotate_concurrent() will also parallelize over backups located on multiple remote systems.

rotate_backups(location, load_config=True, prepare=False)[source]

Rotate the backups in a directory according to a flexible rotation scheme.

Parameters:
  • location – Any value accepted by coerce_location().
  • load_config – If True (so by default) the rotation scheme and other options can be customized by the user in a configuration file. In this case the caller’s arguments are only used when the configuration file doesn’t define a configuration for the location.
  • prepare – If this is True (not the default) then rotate_backups() will prepare the required rotation commands without running them.
Returns:

A list with the rotation commands (ExternalCommand objects).

Raises:

ValueError when the given location doesn’t exist, isn’t readable or isn’t writable. The third check is only performed when dry run isn’t enabled.

This function binds the main methods of the RotateBackups class together to implement backup rotation with an easy to use Python API. If you’re using rotate-backups as a Python API and the default behavior is not satisfactory, consider writing your own rotate_backups() function based on the underlying collect_backups(), group_backups(), apply_rotation_scheme() and find_preservation_criteria() methods.

load_config_file(location)[source]

Load a rotation scheme and other options from a configuration file.

Parameters:location – Any value accepted by coerce_location().
Returns:The configured or given Location object.
collect_backups(location)[source]

Collect the backups at the given location.

Parameters:location – Any value accepted by coerce_location().
Returns:A sorted list of Backup objects (the backups are sorted by their date).
Raises:ValueError when the given directory doesn’t exist or isn’t readable.
group_backups(backups)[source]

Group backups collected by collect_backups() by rotation frequencies.

Parameters:backups – A set of Backup objects.
Returns:A dict whose keys are the names of rotation frequencies (‘hourly’, ‘daily’, etc.) and whose values are dictionaries. Each nested dictionary contains lists of Backup objects that are grouped together because they belong into the same time unit for the corresponding rotation frequency.
apply_rotation_scheme(backups_by_frequency, most_recent_backup)[source]

Apply the user defined rotation scheme to the result of group_backups().

Parameters:
  • backups_by_frequency – A dict in the format generated by group_backups().
  • most_recent_backup – The datetime of the most recent backup.
Raises:

ValueError when the rotation scheme dictionary is empty (this would cause all backups to be deleted).

Note

This method mutates the given data structure by removing all backups that should be removed to apply the user defined rotation scheme.

find_preservation_criteria(backups_by_frequency)[source]

Collect the criteria used to decide which backups to preserve.

Parameters:backups_by_frequency – A dict in the format generated by group_backups() which has been processed by apply_rotation_scheme().
Returns:A dict with Backup objects as keys and list objects containing strings (rotation frequencies) as values.
class rotate_backups.Location(**kw)[source]

Location objects represent a root directory containing backups.

context[source]

An execution context created using executor.contexts.

Note

The context property is a required_property. You are required to provide a value for this property by calling the constructor of the class that defines the property with a keyword argument named context (unless a custom constructor is defined, in this case please refer to the documentation of that constructor). You can change the value of this property using normal attribute assignment syntax.

directory[source]

The pathname of a directory containing backups (a string).

Note

The directory property is a required_property. You are required to provide a value for this property by calling the constructor of the class that defines the property with a keyword argument named directory (unless a custom constructor is defined, in this case please refer to the documentation of that constructor). You can change the value of this property using normal attribute assignment syntax.

have_ionice[source]

True when ionice is available, False otherwise.

Note

The have_ionice property is a lazy_property. This property’s value is computed once (the first time it is accessed) and the result is cached.

mount_point[source]

The pathname of the mount point of directory (a string or None).

If the stat --format=%m ... command that is used to determine the mount point fails, the value of this property defaults to None. This enables graceful degradation on e.g. Mac OS X whose stat implementation is rather bare bones compared to GNU/Linux.

Note

The mount_point property is a lazy_property. This property’s value is computed once (the first time it is accessed) and the result is cached.

is_remote[source]

True if the location is remote, False otherwise.

Note

The is_remote property is a lazy_property. This property’s value is computed once (the first time it is accessed) and the result is cached.

ssh_alias[source]

The SSH alias of a remote location (a string or None).

Note

The ssh_alias property is a lazy_property. This property’s value is computed once (the first time it is accessed) and the result is cached.

key_properties

A list of strings with the names of the key properties.

Overrides key_properties to customize the ordering of Location objects so that they are ordered first by their ssh_alias and second by their directory.

ensure_exists()[source]

Make sure the location exists.

ensure_readable()[source]

Make sure the location exists and is readable.

ensure_writable()[source]

Make sure the directory exists and is writable.

__str__()[source]

Render a simple human readable representation of a location.

class rotate_backups.Backup(**kw)[source]

Backup objects represent a rotation subject.

In addition to the pathname, timestamp and week properties Backup objects support all of the attributes of datetime objects by deferring attribute access for unknown attributes to timestamp.

key_properties = ('timestamp', 'pathname')

Customize the ordering of Backup objects.

Backup objects are ordered first by their timestamp and second by their pathname. This class variable overrides key_properties.

pathname[source]

The pathname of the backup (a string).

Note

The pathname property is a key_property. You are required to provide a value for this property by calling the constructor of the class that defines the property with a keyword argument named pathname (unless a custom constructor is defined, in this case please refer to the documentation of that constructor). Once this property has been assigned a value you are not allowed to assign a new value to the property.

timestamp[source]

The date and time when the backup was created (a datetime object).

Note

The timestamp property is a key_property. You are required to provide a value for this property by calling the constructor of the class that defines the property with a keyword argument named timestamp (unless a custom constructor is defined, in this case please refer to the documentation of that constructor). Once this property has been assigned a value you are not allowed to assign a new value to the property.

week

The ISO week number of timestamp (a number).

__getattr__(name)[source]

Defer attribute access to timestamp.

rotate_backups.cli

Usage: rotate-backups [OPTIONS] [DIRECTORY, ..]

Easy rotation of backups based on the Python package by the same name.

To use this program you specify a rotation scheme via (a combination of) the --hourly, --daily, --weekly, --monthly and/or --yearly options and the directory (or directories) containing backups to rotate as one or more positional arguments.

You can rotate backups on a remote system over SSH by prefixing a DIRECTORY with an SSH alias and separating the two with a colon (similar to how rsync accepts remote locations).

Instead of specifying directories and a rotation scheme on the command line you can also add them to a configuration file. For more details refer to the online documentation (see also the --config option).

Please use the --dry-run option to test the effect of the specified rotation scheme before letting this program loose on your precious backups! If you don’t test the results using the dry run mode and this program eats more backups than intended you have no right to complain ;-).

Supported options:

Option Description
-M, --minutely=COUNT In a literal sense this option sets the number of “backups per minute” to preserve during rotation. For most use cases that doesn’t make a lot of sense :-) but you can combine the --minutely and --relaxed options to preserve more than one backup per hour. Refer to the usage of the -H, --hourly option for details about COUNT.
-H, --hourly=COUNT

Set the number of hourly backups to preserve during rotation:

  • If COUNT is a number it gives the number of hourly backups to preserve, starting from the most recent hourly backup and counting back in time.
  • Alternatively you can provide an expression that will be evaluated to get a number (e.g. if COUNT is “7 * 2” the result would be 14).
  • You can also pass “always” for COUNT, in this case all hourly backups are preserved.
  • By default no hourly backups are preserved.
-d, --daily=COUNT Set the number of daily backups to preserve during rotation. Refer to the usage of the -H, --hourly option for details about COUNT.
-w, --weekly=COUNT Set the number of weekly backups to preserve during rotation. Refer to the usage of the -H, --hourly option for details about COUNT.
-m, --monthly=COUNT Set the number of monthly backups to preserve during rotation. Refer to the usage of the -H, --hourly option for details about COUNT.
-y, --yearly=COUNT Set the number of yearly backups to preserve during rotation. Refer to the usage of the -H, --hourly option for details about COUNT.
-I, --include=PATTERN Only process backups that match the shell pattern given by PATTERN. This argument can be repeated. Make sure to quote PATTERN so the shell doesn’t expand the pattern before it’s received by rotate-backups.
-x, --exclude=PATTERN Don’t process backups that match the shell pattern given by PATTERN. This argument can be repeated. Make sure to quote PATTERN so the shell doesn’t expand the pattern before it’s received by rotate-backups.
-j, --parallel

Remove backups in parallel, one backup per mount point at a time. The idea behind this approach is that parallel rotation is most useful when the files to be removed are on different disks and so multiple devices can be utilized at the same time.

Because mount points are per system the -j, --parallel option will also parallelize over backups located on multiple remote systems.

-p, --prefer-recent By default the first (oldest) backup in each time slot is preserved. If you’d prefer to keep the most recent backup in each time slot instead then this option is for you.
-r, --relaxed

By default the time window for each rotation scheme is enforced (this is referred to as strict rotation) but the -r, --relaxed option can be used to alter this behavior. The easiest way to explain the difference between strict and relaxed rotation is using an example:

  • When using strict rotation and the number of hourly backups to preserve is three, only backups created in the relevant time window (the hour of the most recent backup and the two hours leading up to that) will match the hourly frequency.
  • When using relaxed rotation the three most recent backups will all match the hourly frequency (and thus be preserved), regardless of the calculated time window.

If the explanation above is not clear enough, here’s a simple way to decide whether you want to customize this behavior or not:

  • If your backups are created at regular intervals and you never miss an interval then strict rotation (the default) is probably the best choice.
  • If your backups are created at irregular intervals then you may want to use the -r, --relaxed option in order to preserve more backups.
-i, --ionice=CLASS Use the “ionice” program to set the I/O scheduling class and priority of the “rm” invocations used to remove backups. CLASS is expected to be one of the values “idle”, “best-effort” or “realtime”. Refer to the man page of the “ionice” program for details about these values.
-c, --config=PATH Load configuration from the pathname given by PATH. If this option isn’t given two default locations are checked: “~/.rotate-backups.ini” and “/etc/rotate-backups.ini”. The first of these two configuration files to exist is loaded. For more details refer to the online documentation.
-u, --use-sudo Enable the use of “sudo” to rotate backups in directories that are not readable and/or writable for the current user (or the user logged in to a remote system over SSH).
-n, --dry-run Don’t make any changes, just print what would be done. This makes it easy to evaluate the impact of a rotation scheme without losing any backups.
-v, --verbose Make more noise (increase logging verbosity). Can be repeated.
-q, --quiet Make less noise (decrease logging verbosity). Can be repeated.
-h, --help Show this message and exit.
rotate_backups.cli.main()[source]

Command line interface for the rotate-backups program.