diff --git a/.cargo/config.toml b/.cargo/config.toml index 37fecab..a5bfa9c 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,3 +1,3 @@ [alias] runs = "run -- --config data/config --backup data/backups --world data/worlds --layers 2min,2,4,4;3min,3,2,2" -runrs = "run --release -- paper 1.19.4-545 --config data/config --backup data/backups --world data/worlds --jar data/paper-1.19.4-525.jar" +runrs = "run --release -- --config data/config --backup data/backups --world data/worlds --layers 2min,2,4,4;3min,3,2,2" diff --git a/CHANGELOG.md b/CHANGELOG.md index c6009a6..7a3fc13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 same full backup * "backups to keep" has been replaced by "chains to keep" * Server type & version is now stored as metadata in the metadata file +* Backup layers + * Store multiple chains of backups in parallel, configuring each with + different parameters (son-father-grandfather principle) ### Changed diff --git a/README.md b/README.md index 4e00b78..dc96623 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,24 @@ Alex is a wrapper around a typical Minecraft server process. It acts as the parent process, and sits in between the user's input and the server's stdin. -This allows Alex to support additional commands that execute Rust code. +This allows Alex to support additional commands that execute Rust code, notably +creating periodic backups. + +## Installation + +Alex is distributed as statically compiled binaries for Linux amd64 and arm64. +These can be found +[here](https://git.rustybever.be/Chewing_Bever/alex/packages). + +### Dockerfiles + +You can easily install alex in your Docker images by letting Docker download it +for you. Add the following to your Dockerfile (replace with your required +version & architecture): + +```dockerfile +ADD "https://git.rustybever.be/api/packages/Chewing_Bever/generic/alex/0.2.2/alex-linux-amd64" /bin/alex +``` ## Why @@ -19,8 +36,86 @@ Afterwards, saving is enabled again with `save-on`. * Properly configures the process (working directory, optimisation flags) * Configure everything as CLI arguments or environment variables -## Installation +## Configuration -Alex is distributed as statically compiled binaries for Linux amd64 and arm64. -These can be found -[here](https://git.rustybever.be/Chewing_Bever/alex/packages). +Most information can be retrieved easily by looking at the help command: + +``` +Wrapper around Minecraft server processes, designed to complement Docker image installations. + +Usage: alex [OPTIONS] + +Commands: + run Run the server + backup Interact with the backup system without starting a server + help Print this message or the help of the given subcommand(s) + +Options: + --config + Directory where configs are stored, and where the server will run [env: ALEX_CONFIG_DIR=] [default: .] + --world + Directory where world files will be saved [env: ALEX_WORLD_DIR=] [default: ../worlds] + --backup + Directory where backups will be stored [env: ALEX_BACKUP_DIR=] [default: ../backups] + --layers + What backup layers to employ, provided as a list of tuples name,frequency,chains,chain_len delimited by semicolons (;) [env: ALEX_LAYERS=] + --server + Type of server [env: ALEX_SERVER=] [default: unknown] [possible values: unknown, paper, forge, vanilla] + --server-version + Version string for the server, e.g. 1.19.4-545 [env: ALEX_SERVER_VERSION=] [default: ] + -h, --help + Print help + -V, --version + Print version + +``` + +### Choosing layer parameters + +One part of the configuration that does require some clarification is the layer +system. Alex can manage an arbitrary number of backup layers, each having its +own configuration. These layers can either use incremental or full backups, +depending on how they're configured. + +These layers mostly correspond to the grandfather-father-son backup rotation +scheme. For example, one could have a layer that creates incremental backups +every 30 minutes, which are stored for 24 hours. This gives you 24 hours of +granular rollback in case your server suffers a crash. A second layer might +create a full backup every 24 hours, with backups being stored for 7 days. This +gives you 7 days worth of backups with the granularity of 24 hours. This +approach allows for greater versatility, while not having to store a large +amount of data. Thanks to incremental backups, frequent backups don't have to +take long at all. + +A layer consists of 4 pieces of metadata: + +* A name, which will be used in the file system and the in-game notifications +* The frequency, which describes in minutes how frequently a backup should be + created +* How many chains should be kept at all times +* How long each chain should be + +These last two require some clarification. In Alex, a "chain" describes an +initial full backup and zero or more incremental backups that are created from +that initial full backup. This concept exists because an incremental backup has +no real meaning if its ancestors are not known. To restore one of these chains, +all backups in the chain need to be restored in-order. Note that a chain length +of 1 disables incremental backups entirely. + +How many backups to keep is defined by how many chains should be stored. +Because an incremental backup needs to have its ancestors in order to be +restored, we can't simply "keep the last n backups", as this would break these +chains. Therefore, you configure how many backups to store using these chains. + +For example, if you configure a layer to store 5 chains of length 4, you will +have 20 archive files on disk, namely 5 full backups and 15 incremental +backups. Note that Alex applies these rules to *full* chains. An in-progress +chain does not count towards this total. Therefore, you can have up to `n-1` +additional archive files, with `n` being the chain length, on disk. + +To look at it from another perspective, say we wish to have a granularity of 30 +minutes for a timespan of 24 hours. Then we could configure the layer to only +save a single chain, with a chain length of 48. If we prefer to have a few full +backups instead of a long chain of incremental backups, we could instead use a +chain length of 12 and store 4 chains. Either way, the total comes out to 48, +which spans 24 hours if we make a backup every 30 minutes.