# Creating and rotating snapshots of Hetzner cloud servers
This script can perform the following tasks for selected servers of a [Hetzner cloud project](https://www.hetzner.com/cloud/):
- Creating a new snapshot
- Shutting down the server before taking a snapshot and restarting it afterwards
- Rotating snapshots, retaining a limited number of quarter-hourly, hourly, daily, weekly, monthly, quarterly and
yearly snapshots
- Generating names of new and rotated snapshots from templates
These tasks can be configured independently per server in a [JSON configuration file](#creating-the-configuration-file).
Additional features:
- The secret API token can be read from the configuration file, from an environment variable or from `stdin`
- Log messages are sent to the console or to syslog
## Content
- [Generating an API token](#generating-an-api-token)
- [Installing this script](#installing-this-script)
- [Creating the configuration file](#creating-the-configuration-file)
- [Taking snapshots](#taking-snapshots)
- [Rotating snapshots](#rotating-snapshots)
- [Snapshot name templates](#snapshot-name-templates)
- [Running the script natively](#running-the-script-natively)
- [Command line options](#command-line-options)
- [Passing the API token](#passing-the-api-token)
- [Creating and rotating snapshots in a cron job](#creating-and-rotating-snapshots-in-a-cron-job)
- [Running the script in a container](#running-the-script-in-a-container)
- [Passing the configuration file to the container](#passing-the-configuration-file-to-the-container)
- [Environment variables](#environment-variables)
- [Examples](#examples)
- [Licenses](#licenses)
## Generating an API token
[This document](https://docs.hetzner.com/cloud/api/getting-started/generating-api-token/) describes in detail
how to generate an API token for your Hetzner cloud project. This script requires a token with "Read & Write"
permission.
Guard your API token well since it provides unlimited read/write/delete access to all servers, snapshots, backups etc.
of your Hetzner cloud project!
## Installing this script
This script is available as a [PyPI project](https://pypi.org/project/hetzner-snap-and-rotate/). It can be installed by:
```shell
python3 -m pip install hetzner-snap-and-rotate
```
## Creating the configuration file
The configuration file is expected to be a JSON document in UTF-8 encoding with the following structure:
```
{
"api-token": "...", // optional, can also be passed via the command line;
// see section "Command line options" below
"defaults": { // optional defaults, can be overriden per server
"create-snapshot": // create a new snapshot whenever the script is invoked
true,
"snapshot-timeout": // timeout (in s) after which snapshot creation is considered to have failed
120,
"snapshot-name": // template for the snapshot name; see section "Snapshot name templates" below
"{server}-{label[VERSION]}_{period_type}#{period_number}_{timestamp:%Y-%m-%d_%H:%M:%S}_by_{env[USER]}",
"shutdown-and-restart": // shut down the server before taking a snapshot
true, // and restart it afterwards
"shutdown-timeout": // timeout (in s) after which graceful shutdown is considered to have failed
15,
"allow-poweroff": // power off the server if it cannot be shut down gracefully
false,
"rotate": // rotate the existing snapshots and the new one, if any
true,
"quarter-hourly": // number of quarter-hourly snapshots to retain (intended for testing)
0,
"hourly": // number of hourly snapshots to retain
2,
"daily": // number of daily snapshots to retain
3,
"weekly": // number of weekly snapshots to retain
4,
"monthly": // number of monthly snapshots to retain
3,
"quarter-yearly": // number of quarter-yearly snapshots to retain
2,
"yearly": // number of yearly snapshots to retain
1
},
"servers": { // one entry per server
"server-1": { // Hetzner cloud server name
// uses only "defaults" settings
},
"server-2": { // another server; override a few defaults
"snapshot-name": "snapshot_{timestamp:%Y-%m-%d_%H:%M:%S}",
"snapshot-timeout": 300,
"shutdown-timeout": 30,
"allow-poweroff": true,
"hourly": 0,
"daily": 0,
"monthly": 6,
"quarter-yearly": 0,
"yearly": 0
}
}
}
```
Omitted `defaults` default to `0`, `false` or `''` except for:
- `snapshot-timeout`: defaults to `300`
- `shutdown-timeout`: defaults to `30`
Please note that this is not valid JSON due to the comments.
File [resources/config-example.json](https://raw.githubusercontent.com/undecaf/hetzner-snap-and-rotate/refs/heads/main/resources/config-example.json) contains the same example
as a valid JSON file without comments.
### Taking snapshots
This script takes a snapshot of every `server` in the configuration file
for which `create-snapshot` is `true`. Each of these snapshots also stores a copy
of the current server labels.
If taking the snapshot takes longer than `snapshot-timeout` then that operation
is considered to have failed.
If `shutdown-and-restart` is `true` and the server is running
then the script attempts to shut down the server gracefully before taking the snapshot.
If the server cannot be shut down gracefully within the `shutdown-timeout` then it
will be powered down instead if `allow-poweroff` is `true`, or else the snapshot operation will fail.
If the server was running before taking the snapshot then it is restarted afterwards.
### Rotating snapshots
This script rotates the snapshots of every `server` in the configuration file
for which `rotate-snapshots` is `true`.
"Rotating" means that existing snapshots will be renamed
according to `snapshot-name`, or will be deleted if they
are no longer contained in any of the configured `quarter-hourly`, `hourly`, ... `yearly`
periods. Those settings determine for how many such periods the snapshots will be retained.
New snapshots that are _not yet_ contained in any rotation period will be renamed but not deleted.
Snapshots that have been protected are neither renamed nor deleted during rotation.
Nevertheless, they are taken into account in the rotation process.
Rotating snapshots is controlled by the following rules:
- Rotation period types (`quarter-hourly`, `hourly`, ... `yearly`) that were set to zero are ignored.
- Periods are counted backwards from the present into the past.
- The first period is the shortest period immediately preceding the instant of rotation.
- Other periods immediately precede the next shorter periods without gaps.
- If a period contains multiple snapshots then only the oldest one will be retained for that period.
- New and rotated snapshots are (re)named according to the template `snapshot-name`. This allows the server name and
labels, the period, the snapshot timestamp and environment variables to become part of the snapshot name.
See section [Snapshot name templates](#snapshot-name-templates) below for details.
### Snapshot name templates
`snapshot-name` must be a string and may contain [Python format strings](https://docs.python.org/3/library/string.html#format-string-syntax).
Snapshot names should be unique but this is not a requirement.
The following field names are available for formatting:
| Field name | Type | Rendered as |
|-----------------|:------------------------------------------------------------------------:|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `server` | `str` | Server name, same as `server` in the [configuration file](#creating-the-configuration-file) |
| `timestamp` | [`datetime.datetime`](https://docs.python.org/3.8/library/datetime.html) | _Creation_ instant of the snapshot (_not changed by rotation_), expressed in the timezone of the system running this script. [`datetime`-specific formatting](https://docs.python.org/3.10/library/datetime.html#strftime-and-strptime-format-codes) may be used for this field. |
| `label` | `dict[str]` | Value of a server label at the _creation_ instant of the snapshot (_not changed by rotation_), may be referred to as e.g. `label[VERSION]` |
| `period_type` | `str` | Type of period: `quarter-hourly`, `hourly`, ... `yearly`, or `latest` for new snapshots that have not been rotated yet |
| `period_number` | `int` | Rotation number of the period: `1` = latest, `2` = next to latest and so on; also applies to `latest` snapshots |
| `env` | `dict[str]` | Value of an environment variable at the creation or rotation instant of the snapshot, may be referred to as e.g. `env[USER]` |
## Running the script natively
```shell
python3 -m hetzner_snap_and_rotate [options ...]
```
### Command line options
| Option | Description |
|------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| <code>--config <u>config_file</u></code><br><code>-c <u>config_file</u></code> | Read the configuration from <code><u>config_file</u></code>. Default: `config.json` |
| <code>--api-token-from <u>env_var</u></code><br><code>-t <u>env_var</u></code> | Read the API token from environment variable <code><u>env_var</u></code>, or read it from `stdin` if `'-'` is specified. Default: get the API token from <code><u>config_file</u></code>. |
| <code>--facility <u>syslog_facility</u></code><br><code>-f <u>syslog_facility</u></code> | Send the log messages to <code><u>syslog_facility</u></code> (`SYSLOG`, `USER`, `DAEMON`, `CRON`, etc.). Default: send log messages to `stdout`. |
| <code>--priority <u>pri</u></code><br><code>-p <u>pri</u></code> | Log only messages up to syslog priority <code><u>pri</u></code> (`ERR`, `WARNING`, `NOTICE`, `INFO`, `DEBUG`, or `OFF` to disable logging). Default: `NOTICE`. |
| `--dry-run`<br>`-n` | Perform a trial run with no changes made. This requires only an [API token](#generating-an-api-token) with "Read" permission. |
| `--version`<br>`-v` | Display the version number and exit. |
| `--help`<br>`-h` | Display a help message and exit. |
### Passing the API token
The API token provides complete control over your Hetzner cloud project, therefore it must be protected against
unauthorized access. The following methods are available for passing the API token to the script:
- Inlcuding it as `api-token` in the configuration file. The configuration file then must be protected adequately.
- Passing it via an environent variable and specifying the variable name on the command line as `api-token-from`.
- Piping it to the script through `stdin` and specifying `api-token-from -` on the command line.
### Creating and rotating snapshots in a cron job
As a cron job, this script should run once per the shortest period for which snapshots are to be retained.
If, for example, the shortest retention period has been set to `daily` then the script should run daily.
If the script is run more frequently then several `latest` snapshots will be preserved.
## Running the script in a container
[This image on Docker Hub](https://hub.docker.com/r/undecaf/hetzner-snap-and-rotate) runs the script
in a [Docker](https://www.docker.com/) or [Podman](https://podman.io/) container
(for Podman, substitute `podman` for `docker` in the following commands):
```shell
docker run [Docker options] undecaf/hetzner-snap-and-rotate:latest [script command line options]
```
The same [command line options](#command-line-options) are available as for the native script.
### Passing the configuration file to the container
[The configuration file](#creating-the-configuration-file) needs to be prepared on the host.
It can be passed to the container in various ways:
- As a [bind mount](https://docs.docker.com/storage/bind-mounts/), e.g.
```shell
docker run --mount type=bind,source=/path/to/your/config.json,target=/config.json [other Docker options] undecaf/hetzner-snap-and-rotate:latest [script command line options]
```
- As a [secret](https://docs.docker.com/engine/swarm/secrets/); this requires [Podman](https://podman.io/) or
[Docker swarm](https://docs.docker.com/engine/swarm/).
First, your configuration file needs to be saved as a secret (e.g. called `config_json`):
```shell
docker secret create config_json /path/to/your/config.json
```
That secret becomes part of your Docker/Podman configuration and then can be passed to the container:
```shell
docker run --secret=config_json,target=/config.json [other Docker options] undecaf/hetzner-snap-and-rotate:latest [script command line options]
```
### Environment variables
Environment variables referenced in your [snapshot name templates](#snapshot-name-templates) must be
passed to the container as `--env` options, e.g.
```shell
docker run --env USER=your_username [other Docker options] undecaf/hetzner-snap-and-rotate:latest [script command line options]
```
### Examples
Display the script version and exit:
```shell
# does not require a configuration file
docker run --rm undecaf/hetzner-snap-and-rotate:latest --version
```
Dry run with the API token in the configuration file, log priority `DEBUG`:
```shell
# option --tty/-t displays log output in real time
docker run \
--rm \
--tty \
--mount type=bind,source=/path/to/your/config.json,target=/config.json \
undecaf/hetzner-snap-and-rotate:latest --dry-run --priority DEBUG
```
Live run with the API token in the configuration file:
```shell
# option --tty/-t displays log output in real time
docker run \
--rm \
--tty \
--mount type=bind,source=/path/to/your/config.json,target=/config.json \
undecaf/hetzner-snap-and-rotate:latest
```
Passing the API token through `stdin`:
```shell
# requires option --interactive/-i, adding --tty/-t would display the API token :-(
cat /your/api/token/file | docker run \
--rm \
--interactive \
--mount type=bind,source=/path/to/your/config.json,target=/config.json \
undecaf/hetzner-snap-and-rotate:latest --api-token-from -
```
## Licenses
Software: [MIT](https://opensource.org/license/mit)
Documentation: [CC-BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)
Raw data
{
"_id": null,
"home_page": null,
"name": "hetzner-snap-and-rotate",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "Backup rotation, Cloud, Hetzner, Snapshot rotation",
"author": null,
"author_email": "\"F. Kasper\" <fkasper@modus-operandi.at>",
"download_url": "https://files.pythonhosted.org/packages/21/0a/1eab17d91444829e2284c1e3bbb7600b069e2b8e5b41cb3352ee2104ad8f/hetzner_snap_and_rotate-1.1.2.tar.gz",
"platform": null,
"description": "# Creating and rotating snapshots of Hetzner cloud servers\n\nThis script can perform the following tasks for selected servers of a [Hetzner cloud project](https://www.hetzner.com/cloud/):\n\n- Creating a new snapshot\n- Shutting down the server before taking a snapshot and restarting it afterwards\n- Rotating snapshots, retaining a limited number of quarter-hourly, hourly, daily, weekly, monthly, quarterly and\n yearly snapshots\n- Generating names of new and rotated snapshots from templates\n\nThese tasks can be configured independently per server in a [JSON configuration file](#creating-the-configuration-file).\n\nAdditional features:\n\n- The secret API token can be read from the configuration file, from an environment variable or from `stdin`\n- Log messages are sent to the console or to syslog\n\n\n## Content\n\n- [Generating an API token](#generating-an-api-token)\n- [Installing this script](#installing-this-script)\n- [Creating the configuration file](#creating-the-configuration-file)\n - [Taking snapshots](#taking-snapshots)\n - [Rotating snapshots](#rotating-snapshots)\n - [Snapshot name templates](#snapshot-name-templates)\n- [Running the script natively](#running-the-script-natively)\n - [Command line options](#command-line-options)\n - [Passing the API token](#passing-the-api-token)\n - [Creating and rotating snapshots in a cron job](#creating-and-rotating-snapshots-in-a-cron-job)\n- [Running the script in a container](#running-the-script-in-a-container)\n - [Passing the configuration file to the container](#passing-the-configuration-file-to-the-container)\n - [Environment variables](#environment-variables)\n - [Examples](#examples)\n- [Licenses](#licenses)\n\n\n## Generating an API token\n\n[This document](https://docs.hetzner.com/cloud/api/getting-started/generating-api-token/) describes in detail\nhow to generate an API token for your Hetzner cloud project. This script requires a token with \"Read & Write\"\npermission.\n\nGuard your API token well since it provides unlimited read/write/delete access to all servers, snapshots, backups etc. \nof your Hetzner cloud project!\n\n\n## Installing this script\n\nThis script is available as a [PyPI project](https://pypi.org/project/hetzner-snap-and-rotate/). It can be installed by:\n\n```shell\npython3 -m pip install hetzner-snap-and-rotate\n```\n\n\n## Creating the configuration file\n\nThe configuration file is expected to be a JSON document in UTF-8 encoding with the following structure:\n\n```\n{\n \"api-token\": \"...\", // optional, can also be passed via the command line;\n // see section \"Command line options\" below\n\n \"defaults\": { // optional defaults, can be overriden per server\n \"create-snapshot\": // create a new snapshot whenever the script is invoked\n true,\n \"snapshot-timeout\": // timeout (in s) after which snapshot creation is considered to have failed\n 120,\n \"snapshot-name\": // template for the snapshot name; see section \"Snapshot name templates\" below\n \"{server}-{label[VERSION]}_{period_type}#{period_number}_{timestamp:%Y-%m-%d_%H:%M:%S}_by_{env[USER]}\",\n \"shutdown-and-restart\": // shut down the server before taking a snapshot\n true, // and restart it afterwards\n \"shutdown-timeout\": // timeout (in s) after which graceful shutdown is considered to have failed\n 15,\n \"allow-poweroff\": // power off the server if it cannot be shut down gracefully\n false,\n \"rotate\": // rotate the existing snapshots and the new one, if any \n true,\n \"quarter-hourly\": // number of quarter-hourly snapshots to retain (intended for testing)\n 0,\n \"hourly\": // number of hourly snapshots to retain\n 2,\n \"daily\": // number of daily snapshots to retain\n 3,\n \"weekly\": // number of weekly snapshots to retain\n 4,\n \"monthly\": // number of monthly snapshots to retain\n 3,\n \"quarter-yearly\": // number of quarter-yearly snapshots to retain\n 2,\n \"yearly\": // number of yearly snapshots to retain\n 1\n },\n\n \"servers\": { // one entry per server\n \"server-1\": { // Hetzner cloud server name\n // uses only \"defaults\" settings\n },\n\n \"server-2\": { // another server; override a few defaults\n \"snapshot-name\": \"snapshot_{timestamp:%Y-%m-%d_%H:%M:%S}\",\n \"snapshot-timeout\": 300,\n \"shutdown-timeout\": 30,\n \"allow-poweroff\": true,\n\n \"hourly\": 0,\n \"daily\": 0,\n \"monthly\": 6,\n \"quarter-yearly\": 0,\n \"yearly\": 0\n }\n }\n}\n```\n\nOmitted `defaults` default to `0`, `false` or `''` except for:\n\n- `snapshot-timeout`: defaults to `300`\n- `shutdown-timeout`: defaults to `30`\n\nPlease note that this is not valid JSON due to the comments.\nFile [resources/config-example.json](https://raw.githubusercontent.com/undecaf/hetzner-snap-and-rotate/refs/heads/main/resources/config-example.json) contains the same example\nas a valid JSON file without comments.\n\n\n### Taking snapshots\n\nThis script takes a snapshot of every `server` in the configuration file\nfor which `create-snapshot` is `true`. Each of these snapshots also stores a copy\nof the current server labels.\n\nIf taking the snapshot takes longer than `snapshot-timeout` then that operation\nis considered to have failed.\n\nIf `shutdown-and-restart` is `true` and the server is running\nthen the script attempts to shut down the server gracefully before taking the snapshot.\nIf the server cannot be shut down gracefully within the `shutdown-timeout` then it\nwill be powered down instead if `allow-poweroff` is `true`, or else the snapshot operation will fail.\nIf the server was running before taking the snapshot then it is restarted afterwards.\n\n\n### Rotating snapshots\n\nThis script rotates the snapshots of every `server` in the configuration file\nfor which `rotate-snapshots` is `true`.\n\n\"Rotating\" means that existing snapshots will be renamed\naccording to `snapshot-name`, or will be deleted if they\nare no longer contained in any of the configured `quarter-hourly`, `hourly`, ... `yearly`\nperiods. Those settings determine for how many such periods the snapshots will be retained.\n\nNew snapshots that are _not yet_ contained in any rotation period will be renamed but not deleted.\n\nSnapshots that have been protected are neither renamed nor deleted during rotation.\nNevertheless, they are taken into account in the rotation process.\n\nRotating snapshots is controlled by the following rules:\n\n- Rotation period types (`quarter-hourly`, `hourly`, ... `yearly`) that were set to zero are ignored.\n- Periods are counted backwards from the present into the past.\n- The first period is the shortest period immediately preceding the instant of rotation.\n- Other periods immediately precede the next shorter periods without gaps.\n- If a period contains multiple snapshots then only the oldest one will be retained for that period.\n- New and rotated snapshots are (re)named according to the template `snapshot-name`. This allows the server name and \n labels, the period, the snapshot timestamp and environment variables to become part of the snapshot name. \nSee section [Snapshot name templates](#snapshot-name-templates) below for details.\n\n\n### Snapshot name templates\n\n`snapshot-name` must be a string and may contain [Python format strings](https://docs.python.org/3/library/string.html#format-string-syntax).\nSnapshot names should be unique but this is not a requirement.\nThe following field names are available for formatting:\n\n| Field name | Type | Rendered as |\n|-----------------|:------------------------------------------------------------------------:|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `server` | `str` | Server name, same as `server` in the [configuration file](#creating-the-configuration-file) |\n| `timestamp` | [`datetime.datetime`](https://docs.python.org/3.8/library/datetime.html) | _Creation_ instant of the snapshot (_not changed by rotation_), expressed in the timezone of the system running this script. [`datetime`-specific formatting](https://docs.python.org/3.10/library/datetime.html#strftime-and-strptime-format-codes) may be used for this field. |\n| `label` | `dict[str]` | Value of a server label at the _creation_ instant of the snapshot (_not changed by rotation_), may be referred to as e.g. `label[VERSION]` |\n| `period_type` | `str` | Type of period: `quarter-hourly`, `hourly`, ... `yearly`, or `latest` for new snapshots that have not been rotated yet |\n| `period_number` | `int` | Rotation number of the period: `1` = latest, `2` = next to latest and so on; also applies to `latest` snapshots |\n| `env` | `dict[str]` | Value of an environment variable at the creation or rotation instant of the snapshot, may be referred to as e.g. `env[USER]` |\n\n\n\n## Running the script natively\n\n```shell\npython3 -m hetzner_snap_and_rotate [options ...]\n```\n\n\n### Command line options\n\n| Option | Description |\n|------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| <code>--config <u>config_file</u></code><br><code>-c <u>config_file</u></code> | Read the configuration from <code><u>config_file</u></code>. Default: `config.json` |\n| <code>--api-token-from <u>env_var</u></code><br><code>-t <u>env_var</u></code> | Read the API token from environment variable <code><u>env_var</u></code>, or read it from `stdin` if `'-'` is specified. Default: get the API token from <code><u>config_file</u></code>. |\n| <code>--facility <u>syslog_facility</u></code><br><code>-f <u>syslog_facility</u></code> | Send the log messages to <code><u>syslog_facility</u></code> (`SYSLOG`, `USER`, `DAEMON`, `CRON`, etc.). Default: send log messages to `stdout`. |\n| <code>--priority <u>pri</u></code><br><code>-p <u>pri</u></code> | Log only messages up to syslog priority <code><u>pri</u></code> (`ERR`, `WARNING`, `NOTICE`, `INFO`, `DEBUG`, or `OFF` to disable logging). Default: `NOTICE`. |\n| `--dry-run`<br>`-n` | Perform a trial run with no changes made. This requires only an [API token](#generating-an-api-token) with \"Read\" permission. |\n| `--version`<br>`-v` | Display the version number and exit. | \n| `--help`<br>`-h` | Display a help message and exit. |\n\n\n### Passing the API token\n\nThe API token provides complete control over your Hetzner cloud project, therefore it must be protected against\nunauthorized access. The following methods are available for passing the API token to the script:\n\n- Inlcuding it as `api-token` in the configuration file. The configuration file then must be protected adequately.\n- Passing it via an environent variable and specifying the variable name on the command line as `api-token-from`.\n- Piping it to the script through `stdin` and specifying `api-token-from -` on the command line.\n\n\n### Creating and rotating snapshots in a cron job\n\nAs a cron job, this script should run once per the shortest period for which snapshots are to be retained. \nIf, for example, the shortest retention period has been set to `daily` then the script should run daily.\n\nIf the script is run more frequently then several `latest` snapshots will be preserved. \n\n\n## Running the script in a container\n\n[This image on Docker Hub](https://hub.docker.com/r/undecaf/hetzner-snap-and-rotate) runs the script\nin a [Docker](https://www.docker.com/) or [Podman](https://podman.io/) container\n(for Podman, substitute `podman` for `docker` in the following commands):\n\n```shell\ndocker run [Docker options] undecaf/hetzner-snap-and-rotate:latest [script command line options]\n```\n\nThe same [command line options](#command-line-options) are available as for the native script.\n\n\n### Passing the configuration file to the container\n\n[The configuration file](#creating-the-configuration-file) needs to be prepared on the host.\nIt can be passed to the container in various ways:\n\n- As a [bind mount](https://docs.docker.com/storage/bind-mounts/), e.g.\n\n ```shell\n docker run --mount type=bind,source=/path/to/your/config.json,target=/config.json [other Docker options] undecaf/hetzner-snap-and-rotate:latest [script command line options]\n ```\n \n- As a [secret](https://docs.docker.com/engine/swarm/secrets/); this requires [Podman](https://podman.io/) or \n[Docker swarm](https://docs.docker.com/engine/swarm/). \n First, your configuration file needs to be saved as a secret (e.g. called `config_json`):\n\n ```shell\n docker secret create config_json /path/to/your/config.json\n ```\n \n That secret becomes part of your Docker/Podman configuration and then can be passed to the container:\n\n ```shell\n docker run --secret=config_json,target=/config.json [other Docker options] undecaf/hetzner-snap-and-rotate:latest [script command line options]\n ```\n\n\n### Environment variables\n\nEnvironment variables referenced in your [snapshot name templates](#snapshot-name-templates) must be\npassed to the container as `--env` options, e.g.\n\n```shell\ndocker run --env USER=your_username [other Docker options] undecaf/hetzner-snap-and-rotate:latest [script command line options]\n```\n\n\n### Examples\n\nDisplay the script version and exit:\n\n```shell\n# does not require a configuration file\ndocker run --rm undecaf/hetzner-snap-and-rotate:latest --version\n```\n\nDry run with the API token in the configuration file, log priority `DEBUG`:\n\n```shell\n# option --tty/-t displays log output in real time\ndocker run \\\n --rm \\\n --tty \\\n --mount type=bind,source=/path/to/your/config.json,target=/config.json \\\n undecaf/hetzner-snap-and-rotate:latest --dry-run --priority DEBUG\n```\n\nLive run with the API token in the configuration file:\n\n```shell\n# option --tty/-t displays log output in real time\ndocker run \\\n --rm \\\n --tty \\\n --mount type=bind,source=/path/to/your/config.json,target=/config.json \\\n undecaf/hetzner-snap-and-rotate:latest\n```\n\nPassing the API token through `stdin`:\n\n```shell\n# requires option --interactive/-i, adding --tty/-t would display the API token :-(\ncat /your/api/token/file | docker run \\\n --rm \\\n --interactive \\\n --mount type=bind,source=/path/to/your/config.json,target=/config.json \\\n undecaf/hetzner-snap-and-rotate:latest --api-token-from -\n```\n\n\n## Licenses\n\nSoftware: [MIT](https://opensource.org/license/mit)\n\nDocumentation: [CC-BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)\n",
"bugtrack_url": null,
"license": null,
"summary": "Creates and rotates snapshots of Hetzner cloud servers",
"version": "1.1.2",
"project_urls": {
"Homepage": "https://github.com/undecaf/hetzner-snap-and-rotate",
"Issues": "https://github.com/undecaf/hetzner-snap-and-rotate/issues"
},
"split_keywords": [
"backup rotation",
" cloud",
" hetzner",
" snapshot rotation"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "84452377a4c49318f456a86e2dfa2a834b5b5e3a46f42fe481fc5df97337ac28",
"md5": "f6de6911b293c965829b8b6e43eb0c26",
"sha256": "dd083bf3531d7c02a9dfeba38cf60d6c91bfd0103c8d5e31c2df1148e9662ef2"
},
"downloads": -1,
"filename": "hetzner_snap_and_rotate-1.1.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "f6de6911b293c965829b8b6e43eb0c26",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 17246,
"upload_time": "2024-11-23T08:40:56",
"upload_time_iso_8601": "2024-11-23T08:40:56.818985Z",
"url": "https://files.pythonhosted.org/packages/84/45/2377a4c49318f456a86e2dfa2a834b5b5e3a46f42fe481fc5df97337ac28/hetzner_snap_and_rotate-1.1.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "210a1eab17d91444829e2284c1e3bbb7600b069e2b8e5b41cb3352ee2104ad8f",
"md5": "83552e36bd688c0a266421609f467e39",
"sha256": "c0775f7128bef34989cd6080a73c2816ef959ea50b9da11ef9133eea213fd235"
},
"downloads": -1,
"filename": "hetzner_snap_and_rotate-1.1.2.tar.gz",
"has_sig": false,
"md5_digest": "83552e36bd688c0a266421609f467e39",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 19994,
"upload_time": "2024-11-23T08:40:58",
"upload_time_iso_8601": "2024-11-23T08:40:58.951019Z",
"url": "https://files.pythonhosted.org/packages/21/0a/1eab17d91444829e2284c1e3bbb7600b069e2b8e5b41cb3352ee2104ad8f/hetzner_snap_and_rotate-1.1.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-23 08:40:58",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "undecaf",
"github_project": "hetzner-snap-and-rotate",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "hetzner-snap-and-rotate"
}