diff --git a/.github/workflows/check-and-lint.yaml b/.github/workflows/check-and-lint.yaml index ce68b45..5837976 100644 --- a/.github/workflows/check-and-lint.yaml +++ b/.github/workflows/check-and-lint.yaml @@ -4,12 +4,13 @@ on: - main paths-ignore: - "**/*.md" - - "docs/**" + - "docs/**/*" push: branches: - main paths-ignore: - "**/*.md" + - "docs/**/*" name: Check and Lint # env: diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 337bd18..937a012 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -4,13 +4,14 @@ on: - main paths-ignore: - "**/*.md" - - "docs/**" + - "docs/**/*" push: branches: - main - release/* paths-ignore: - "**/*.md" + - "docs/**/*" name: Build release binaries diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 2948e71..8258792 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -4,12 +4,13 @@ on: - main paths-ignore: - "**/*.md" - - "docs/**" + - "docs/**/*" push: branches: - main paths-ignore: - "**/*.md" + - "docs/**/*" name: Tests diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d1d1e94..954de6f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,263 +4,6 @@ Thank you for your interest in contributing to `rustic`! We appreciate your help in making this project better. -## Table of Contents - -- [Code of Conduct](#code-of-conduct) -- [How to Contribute](#how-to-contribute) - - [Reporting Bugs](#reporting-bugs) - - [Issue and Pull Request Labels](#issue-and-pull-request-labels) - - [Suggesting Enhancements](#suggesting-enhancements) - - [Code Style and Formatting](#code-style-and-formatting) - - [Testing](#testing) - - [Submitting Pull Requests](#submitting-pull-requests) - - [Rebasing and other workflows](#rebasing-and-other-workflows) -- [Development Setup](#development-setup) -- [License](#license) - -## Code of Conduct - -Please review and abide by the general Rust Community -[Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct) when -contributing to this project. In the future, we might create our own Code of -Conduct and supplement it at this location. - -## How to Contribute - -### Reporting Bugs - -If you find a bug, please open an -[issue on GitHub](https://github.com/rustic-rs/rustic/issues/new/choose) and -provide as much detail as possible. Include steps to reproduce the bug and the -expected behavior. - -### Issue and Pull Request labels - -Our Issues and Pull Request labels follow the official Rust style: - -```text -A - Area -C - Category -D - Diagnostic -E - Call for participation -F - Feature -I - Issue e.g. I-crash -M - Meta -O - Operating systems -P - priorities e.g. P-{low, medium, high, critical} -PG - Project Group -perf - Performance -S - Status e.g. S-{blocked, experimental, inactive} -T - Team relevancy -WG - Working group -``` - -### Suggesting Enhancements - -If you have an idea for an enhancement or a new feature, we'd love to hear it! -Open an [issue on GitHub](https://github.com/rustic-rs/rustic/issues/new/choose) -and describe your suggestion in detail. - -### Code Style and Formatting - -We follow the Rust community's best practices for code style and formatting. -Before submitting code changes, please ensure your code adheres to these -guidelines: - -- Use `rustfmt` to format your code. You can run it with the following command: - - ```bash - cargo fmt --all - ``` - -- Use `dprint` to format text in markdown, toml, and json. You can install it - with `cargo install dprint` and run it with the following command in the - repository root: - - ```bash - dprint fmt - ``` - -- Write clear and concise code with meaningful, self-describing variable and - function names. This tells the reader **what** the code does. - -- Write clear and consise comments to tell the reader **why** you chose to - implement it that way and **which** problem it solves. - -### Testing - -We value code quality and maintainability. If you are adding new features or -making changes, please include relevant unit tests. Run the test suite with: - -```bash -cargo test --workspace -``` - -Make sure all tests pass before submitting your changes. - -### Submitting Pull Requests - -To contribute code changes, follow these steps: - -1. **Fork** the repository. - -2. **Create** a new branch with a descriptive name: - - ```bash - git checkout -b feature/your-feature-name - ``` - -3. **Commit** your changes: - - ```bash - git commit -m "Add your meaningful commit message here" - ``` - -4. **Push** your branch to your forked repository: - - ```bash - git push origin feature/your-feature-name - ``` - -5. **Open** a Pull Request (PR) to our repository. Please include a detailed - description of the changes and reference any related issues. - -#### `Release early and often!` also applies to pull requests - -Consider drafting a Pull request early in the development process, so we can -follow your progress and can give early feedback. - -Once your PR is submitted, it will be reviewed by the maintainers. We may -suggest changes or ask for clarifications before merging. - -#### IMPORTANT NOTE - -Please don't force push commits in your branch, in order to keep commit history -and make it easier for us to see changes between reviews. - -Make sure to Allow edits of maintainers (under the text box) in the PR so people -can actually collaborate on things or fix smaller issues themselves. - -#### Rebasing and other workflows - -(taken from: -[openage on rebasing](https://github.com/SFTtech/openage/blob/master/doc/contributing.md#rebasing)) - -**Rebasing** is 'moving' your commits to a different parent commit. - -In other words: *Cut off* your branch from its tree, and *attach it* somewhere -else. - -There's two main applications: - -- If you based your work on a older master (so old that stuff can't be - automatically merged), you can rebase to move your commits to the current - [upstream](https://help.github.com/articles/fork-a-repo/) master: - -```bash -# update the upstream remote to receive new commits -git fetch upstream - -# be on your feature branch (you probably are) -git checkout my-awesome-feature - -# make backup (you never know, you know?) -git branch my-awesome-feature-backup - -# rebase: put your commits on top of upstream's master -git rebase -m upstream/master -``` - -- If you want to fix an older commit of yours, or merge several commits into a - single one (**squash** them), rebase interactively. We ***don't*** want to - have a commit history like this: - - - `add stuff` - - `fix typo in stuff` - - `fix compilation` - - `change stuff a bit` - - and so on... - -##### `rebase` in practice - -`git log --graph --oneline` shows your commit history as graph. To make some -changes in that graph, you do an **interactive rebase**: - -```sh -git rebase -i -m upstream/master -``` - -With this command, your new "base" is `upstream/master` and you can then change -any of your branch's commits. - -`-i` will open an interactive editor where you can choose actions for each -individual commit: - -- re-order commits -- drop commits by deleting their line -- squash/fixup ("meld") your commits -- reword a commit message -- stop rebasing at a commit to edit (`--amend`) it manually - -Just follow the messages on screen. - -##### Changing commits with `amend` and `fixup` - -There's also `git commit --amend` which is a "mini-rebase" that modifies just -the last commit with your current changes by `git add`. It just skips the -creation of a new commit and instead melds the changes into the last one you -made. - -If you want to update a single commit in the range -`[upstream/master, current HEAD]` which is not the last commit: - -- `edit stuff you wanna change in some previous commit` -- `git add changed_stuff` -- `git commit --fixup $hash_of_commit_to_be_fixed` -- `git rebase --autosquash -i -m upstream/master` - -##### Pushing changes - -After you have rebased stuff -(["rewritten history"](https://www.youtube.com/watch?v=9lXuZHkOoH8)) that had -already been pushed, git will not accept your pushes because they're not simple -fast-forwards: - -- The commit contents and the parent commit have changed as you updated the - commit, therefore the commit hash changed, too. - - If somebody used those commits, they will keep a copy and have a hard time - updating to your updated version (because they "use" the old hashes). - - Update your pull request branch with your re-written history! - -- **force push** is the standard way of overwriting your development work with - the fixed and mergeable version of your contribution! - - Why? You changed the commits, so you want the old ones to be deleted! - - You can use any of: - - `git push origin +my-awesome-feature` - - `git push origin -f my-awesome-feature` - - `git push origin --force my-awesome-feature` - -Some extra tutorials on `git rebase`: - -- [Atlassian's Git Tutorial](https://www.atlassian.com/git/tutorials/rewriting-history/) -- [Pro Git book](http://git-scm.com/book) -- `man git-rebase` - -## Development Setup - -If you want to set up a local development environment, follow the steps in the -[development guide](/docs/dev/development_guide.md) file - which is currently -being worked on. - -## License - -By contributing to `rustic` or any crates contained in this repository, you -agree that your contributions will be licensed under: - -- [Apache License, Version 2.0](./LICENSE-APACHE) -- [MIT license](./LICENSE-MIT). - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in the work by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. +Please read the +[contribution guide](https://rustic.cli.rs/docs/contributing-to-rustic.html) to +get started. diff --git a/README.md b/README.md index 854cbff..ec52ff1 100644 --- a/README.md +++ b/README.md @@ -1,69 +1,140 @@ -# rustic - fast, encrypted, deduplicated backups powered by Rust +

+ +

+

fast, encrypted, and deduplicated backups

-[![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] -![Apache2/MIT licensed][license-image] -[![Crates.io Downloads][downloads-image]][crate-link] - -## Contact - -| Contact | Where? | -| ------------- | -------------------------------------------------------------------------------------- | -| Issue Tracker | [GitHub Issues](https://github.com/rustic-rs/rustic/issues) | -| Discord | [![](https://dcbadge.vercel.app/api/server/WRUWENZnzQ)](https://discord.gg/WRUWENZnzQ) | -| Discussions | [GitHub Discussions](https://github.com/rustic-rs/rustic/discussions) | +

+ + + + +

## About -Rustic is a backup tool that provides fast, encrypted, deduplicated backups -written in [Rust](https://www.rust-lang.org/). It reads and writes the -[restic][1] repo format described in the [design document][2] and can be used as -a restic replacement in most cases. +`rustic` is a backup tool that provides fast, encrypted, deduplicated backups. -Rustic supports the major operating systems (Linux, MacOs, *BSD), Windows -support is experimental. +It reads and writes the [restic][1] repo format described in the +[design document][2] and can be used as a *restic* replacement in most cases. -Note that rustic currently is in a beta release and misses regression tests. +It is implemented in [Rust](https://www.rust-lang.org/), a performant, +memory-efficient, and reliable cross-platform systems programming language. -You can ask questions in the [Discussions][3] or have a look at the -[FAQ](docs/FAQ.md). +Hence `rustic` supports all major operating systems (Linux, MacOs, *BSD), with +Windows support still being experimental. + +### Stability + +`rustic` currently is in **beta** state and misses regression tests. It is not +recommended to use it for production backups, yet. + +## `rustic` Libraries + +The `rustic` project is split into multiple crates: + +- [rustic](https://crates.io/crates/rustic-rs) - the main binary +- [rustic-core](https://crates.io/crates/rustic_core) - the core library + + ## Features -- Backup data is deduplicated and encrypted. +- Backup data is **deduplicated** and **encrypted**. - Backup storage can be local or cloud storages, including cold storages. -- Allows multiple clients to concurrently access a backup repository using +- Allows multiple clients to **concurrently** access a backup repository using lock-free operations. - Backups by default are append-only on the repository. -- The operations are robustly designed and can be safely aborted and efficiently - resumed. +- The operations are robustly designed and can be **safely aborted** and + **efficiently resumed**. - Snapshot organization is possible by hostname, backup paths, label and tags. Also a rich set of metadata is saved with each snapshot. -- Retention policies and cleaning of old backups can be highly customized. +- Retention policies and cleaning of old backups can be **highly customized**. - Follow-up backups only process changed files, but still create a complete backup snapshot. - In-place restore only modifies files which are changed. -- Can use config files for easy configuration of all every-day commands, see +- Uses config files for easy configuration of all every-day commands, see [example config files](/config/). -## Quick start +## Contact -![rustic getting started](https://github.com/rustic-rs/rustic/blob/main/docs/screenshots/gettingstarted.gif?raw=true) +You can ask questions in the [Discussions][3] or have a look at the +[FAQ](https://rustic.cli.rs/docs/FAQ.html). -## Are binaries available? +| Contact | Where? | +| ------------- | -------------------------------------------------------------------------------------------------------- | +| Issue Tracker | [GitHub Issues](https://github.com/rustic-rs/rustic/issues) | +| Discord | [![](https://dcbadge.vercel.app/api/server/WRUWENZnzQ?style=flat-square)](https://discord.gg/WRUWENZnzQ) | +| Discussions | [GitHub Discussions](https://github.com/rustic-rs/rustic/discussions) | + +## Getting started + +Please check our +[documentation](https://rustic.cli.rs/docs/getting_started.html) for more +information on how to get started. + +## Installation + +### From binaries + +##### [cargo-binstall](https://crates.io/crates/cargo-binstall) + +```bash +cargo binstall rustic-rs +``` + +#### Windows + +##### [Scoop](https://scoop.sh/) + +```bash +scoop install rustic +``` + +Or you can check out the +[releases](https://github.com/rustic-rs/rustic/releases). -Sure. Check out the [releases](https://github.com/rustic-rs/rustic/releases). Binaries for the latest development version are available [here](https://github.com/rustic-rs/rustic-beta). -## What is the difference between rustic and restic? +### From source -See the [Comparison between rustic and restic](docs/comparison-restic.md). +**Beware**: This installs the latest development version, which might be +unstable. -## Contribution +```bash +cargo install --git https://github.com/rustic-rs/rustic.git rustic-rs +``` + +### crates.io + +```bash +cargo install rustic-rs +``` + +## Differences to `restic`? + +We have collected some improvements of `rustic` over `restic` +[here](https://rustic.cli.rs/docs/comparison-restic.html). + +## Contributing Contributions in form of [issues][4] or PRs are very welcome. -Please make sure, that you read the [contribution guide](./CONTRIBUTING.md). +Please make sure, that you read the +[contribution guide](https://rustic.cli.rs/docs/contributing-to-rustic.html). + +## Minimum Rust version policy + +This crate's minimum supported `rustc` version is `1.67.1`. + +The current policy is that the minimum Rust version required to use this crate +can be increased in minor version updates. For example, if `crate 1.0` requires +Rust 1.20.0, then `crate 1.0.z` for all values of `z` will also require Rust +1.20.0 or newer. However, `crate 1.y` for `y > 0` may require a newer minimum +version of Rust. + +In general, this crate will be conservative with respect to the minimum +supported version of Rust. ## License @@ -75,12 +146,6 @@ Licensed under either of: at your option. [//]: # (badges) -[crate-image]: https://img.shields.io/crates/v/rustic-rs.svg -[crate-link]: https://crates.io/crates/rustic-rs -[docs-image]: https://docs.rs/rustic-rs/badge.svg -[docs-link]: https://docs.rs/rustic-rs/ -[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[downloads-image]: https://img.shields.io/crates/d/rustic-rs.svg [//]: # (general links) [1]: https://github.com/restic/restic [2]: https://github.com/restic/restic/blob/master/doc/design.rst diff --git a/config/README.md b/config/README.md index 8c73e34..a676de7 100644 --- a/config/README.md +++ b/config/README.md @@ -33,7 +33,7 @@ options. Therefore `commandline arguments` have the highest precedence. Configuration files can be placed in the user's local config directory, e.g. `~/.config/rustic/` or in the global config dir, e.g. `/etc/rustic/`. You can -use a different config files, e.g. `myconfig.toml` and use the `-P` option to +use different config files, e.g. `myconfig.toml` and use the `-P` option to specify the profile name, e.g. `rustic -P myconfig`. Examples for different configuration files can be found here in the [/config/](/config) directory. diff --git a/crates/Readme.md b/crates/Readme.md new file mode 100644 index 0000000..bc9973e --- /dev/null +++ b/crates/Readme.md @@ -0,0 +1,73 @@ +# Ecosystem + +**Note**: This is a work in progress. The crates are not yet published. The +descriptions will be updated as soon as the crates are published. We needed to +reserve some crates, because we discovered that another project recently chose +the same name as `rustic`. + +## Crates + +### rustic_core - [Link](https://crates.io/crates/rustic_core) + +Core functionality for the `rustic` ecosystem. Can be found in +[crates/rustic_core](./rustic_core/). + +### rustic_testing (reserved) - [Link](https://crates.io/crates/rustic_testing) + +Testing functionality for the `rustic` ecosystem. Can be found in +[crates/rustic_testing](./rustic_testing/). + +### rustic_ui (reserved) - [Link](https://crates.io/crates/rustic_ui) + +General UI functionality for the `rustic` ecosystem. + +### rustic_gui (reserved) - [Link](https://crates.io/crates/rustic_gui) + +Graphical UI for `rustic`. + +### rustic_tui (reserved) - [Link](https://crates.io/crates/rustic_tui) + +Terminal UI for `rustic`. + +### rustic_cli (reserved) - [Link](https://crates.io/crates/rustic_cli) + +Common used CLI functionality for the `rustic` ecosystem. + +### rustic_web (reserved) - [Link](https://crates.io/crates/rustic_web) + +Possible WASM/WASI functionality for the `rustic` ecosystem. + +### rustic_store (reserved) - [Link](https://crates.io/crates/rustic_store) + +Possible store functionality to support a plugin system for the `rustic` +ecosystem. + +### rustic_plugins (reserved) - [Link](https://crates.io/crates/rustic_plugins) + +Plugin functionality for the `rustic` ecosystem. + +### rustic_scheduler (reserved) - [Link](https://crates.io/crates/rustic_scheduler) + +Scheduling functionality for the `rustic` ecosystem. + +### rustic_daemon (reserved) - [Link](https://crates.io/crates/rustic_daemon) + +A daemon for `rustic` and running it as a service. + +### rustic_backend (reserved) - [Link](https://crates.io/crates/rustic_backend) + +A possible backend implementation for `rustic` to support multi-system backup +management. + +### rustic_server (reserved) - [Link](https://crates.io/crates/rustic_server) + +A possible server implementation for `rustic` to support client-/server +communication (for example for a web GUI or a TUI). + +### rustic_bench (reserved) - [Link](https://crates.io/crates/rustic_bench) + +Benchmarking functionality for the `rustic` ecosystem. + +### rustic_auth (reserved) - [Link](https://crates.io/crates/rustic_auth) + +Authentication functionality for the `rustic` ecosystem. diff --git a/crates/rustic_core/README.md b/crates/rustic_core/README.md index 75f278e..7f466eb 100644 --- a/crates/rustic_core/README.md +++ b/crates/rustic_core/README.md @@ -1,6 +1,190 @@ -# rustic_core +

+ +

-Library powering rustic-rs +

+ + + + +

+ +# *`rustic_core`* + +### **Library for fast, encrypted, and deduplicated backups** + +## About + +This library is powering [rustic-rs](https://crates.io/crates/rustic-rs). A +backup tool that provides fast, encrypted, deduplicated backups. It reads and +writes the `restic` repository format, which is described in their design +document. + +## Contact + +You can ask questions in the +[Discussions](https://github.com/rustic-rs/rustic/discussions) or have a look at +the [FAQ](https://rustic.cli.rs/docs/FAQ.html). + +| Contact | Where? | +| ------------- | -------------------------------------------------------------------------------------------------------- | +| Issue Tracker | [GitHub Issues](https://github.com/rustic-rs/rustic/issues) | +| Discord | [![](https://dcbadge.vercel.app/api/server/WRUWENZnzQ?style=flat-square)](https://discord.gg/WRUWENZnzQ) | +| Discussions | [GitHub Discussions](https://github.com/rustic-rs/rustic/discussions) | + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +rustic_core = "0.6" +``` + +## Crate features + +This crate exposes a few features for controlling dependency usage: + +- **cli** - Enables support for CLI features by enabling `merge` and `clap` + features. *This feature is disabled by default*. +- **merge** - Enables support for merging multiple values into one, which + enables the `merge` dependency. This is needed for parsing commandline + arguments and merging them into one (e.g. `config`). *This feature is disabled + by default*. +- **clap** - Enables a dependency on the `clap` and `clap_complete` crate and + enables parsing from the commandline. *This feature is disabled by default*. + +## Examples + +### Example: Initializing a new repository + +```rust +use rustic_core::{ConfigOptions, KeyOptions, Repository, RepositoryOptions}; +use simplelog::{Config, LevelFilter, SimpleLogger}; +use std::error::Error; + +fn main() -> Result<(), Box> { + // Display info logs + let _ = SimpleLogger::init(LevelFilter::Info, Config::default()); + + // Init repository + let repo_opts = RepositoryOptions::default() + .repository("/tmp/repo") + .password("test"); + let key_opts = KeyOptions::default(); + let config_opts = ConfigOptions::default(); + let _repo = Repository::new(&repo_opts)?.init(&key_opts, &config_opts)?; + + // -> use _repo for any operation on an open repository + Ok(()) +} +``` + +### Example: Creating a new snapshot + +```rust +use rustic_core::{BackupOptions, PathList, Repository, RepositoryOptions, SnapshotOptions}; +use simplelog::{Config, LevelFilter, SimpleLogger}; +use std::error::Error; + +fn main() -> Result<(), Box> { + // Display info logs + let _ = SimpleLogger::init(LevelFilter::Info, Config::default()); + + // Open repository + let repo_opts = RepositoryOptions::default() + .repository("/tmp/repo") + .password("test"); + let repo = Repository::new(&repo_opts)?.open()?.to_indexed_ids()?; + + let backup_opts = BackupOptions::default(); + let source = PathList::from_string(".")?.sanitize()?; + let snap = SnapshotOptions::default() + .add_tags("tag1,tag2")? + .to_snapshot()?; + + // Create snapshot + let snap = repo.backup(&backup_opts, source, snap)?; + + println!("successfully created snapshot:\n{snap:#?}"); + Ok(()) +} +``` + +### Example: Restoring a snapshot + +```rust +use rustic_core::{LocalDestination, LsOptions, Repository, RepositoryOptions, RestoreOptions}; +use simplelog::{Config, LevelFilter, SimpleLogger}; +use std::error::Error; + +fn main() -> Result<(), Box> { + // Display info logs + let _ = SimpleLogger::init(LevelFilter::Info, Config::default()); + + // Open repository + let repo_opts = RepositoryOptions::default() + .repository("/tmp/repo") + .password("test"); + let repo = Repository::new(&repo_opts)?.open()?.to_indexed()?; + + // use latest snapshot without filtering snapshots + let node = repo.node_from_snapshot_path("latest", |_| true)?; + + // use list of the snapshot contents using no additional filtering + let streamer_opts = LsOptions::default(); + let ls = repo.ls(&node, &streamer_opts)?; + + let destination = "./restore/"; // restore to this destination dir + let create = true; // create destination dir, if it doesn't exist + let dest = LocalDestination::new(destination, create, !node.is_dir())?; + + let opts = RestoreOptions::default(); + let dry_run = false; + // create restore infos. Note: this also already creates needed dirs in the destination + let restore_infos = repo.prepare_restore(&opts, ls.clone(), &dest, dry_run)?; + + repo.restore(restore_infos, &opts, ls, &dest)?; + Ok(()) +} +``` + +### Example: Checking a repository + +```rust +use rustic_core::{CheckOptions, Repository, RepositoryOptions}; +use simplelog::{Config, LevelFilter, SimpleLogger}; +use std::error::Error; + +fn main() -> Result<(), Box> { + // Display info logs + let _ = SimpleLogger::init(LevelFilter::Info, Config::default()); + + // Open repository + let repo_opts = RepositoryOptions::default() + .repository("/tmp/repo") + .password("test"); + let repo = Repository::new(&repo_opts)?.open()?; + + // Check respository with standard options but omitting cache checks + let opts = CheckOptions::default().trust_cache(true); + repo.check(opts)?; + Ok(()) +} +``` + +## Minimum Rust version policy + +This crate's minimum supported `rustc` version is `1.66.1`. + +The current policy is that the minimum Rust version required to use this crate +can be increased in minor version updates. For example, if `crate 1.0` requires +Rust 1.20.0, then `crate 1.0.z` for all values of `z` will also require Rust +1.20.0 or newer. However, `crate 1.y` for `y > 0` may require a newer minimum +version of Rust. + +In general, this crate will be conservative with respect to the minimum +supported version of Rust. ## License diff --git a/docs/FAQ.md b/docs/FAQ.md deleted file mode 100644 index d0825fd..0000000 --- a/docs/FAQ.md +++ /dev/null @@ -1,96 +0,0 @@ -# Frequently asked questions - -## What are the differences between rustic and restic? - -- Written in Rust instead of golang -- Optimized for small resource usage (in particular memory usage, but also - overall CPU usage) -- Philosophy of development (release new features early) -- New features (e.g. hot/cold repositories, lock-free pruning) -- Some commands or options act a bit different or have slightly different syntax - -## Why is rustic written in Rust - -Rust is a powerful language designed to build reliable and efficient software. -This is a very good fit for a backup tool. - -## How does rustic work with cold storages like AWS Glacier? - -If you want to use cold storage, make sure you always specify an extra -repository `--repo-hot` which contains the hot data. This repository acts like a -cache for all metadata, i.e. config/key/snapshot/index files and tree packs. As -all commands except `restore` only need to access the metadata, they are fully -functional but only need the cold storage to list files while everything else is -read from the "hot repo". Note that the "hot repo" on its own is not a valid -rustic repository. The "cold repo", however, contains all files and is nothing -but a standard rustic repository. - -If you additionally use a cache, you effectively have a first level cache on -your local disc and a second level cache with the "hot repo". Note that the "hot -repo" can be also a remote repo, so hot/cold repositories also work for multiple -rustic clients backing up to the same repository. - -## How does the lock-free prune work? - -Like the prune within restic, rustic decides for each pack whether to keep it, -remove it or repack it. Instead of removing packs, it however only marks the -packs to remove in a separate index structure. Packs which are marked for -removal are checked if they are really not needed and have been marked long -enough ago. Depending on these checks they are either finally removed, recovered -or kept in the state of being marked for removal. - -This two-phase deletion is needed for rustic to work lock-free: If a `backup` -runs parallel to a `prune` run (or `forget --prune`), it could be that prune -decides that some blobs can be removed, but the parallel backup uses these blobs -for the newly generated snapshot. - -The time to hold marked packs should be long enough to guarantee that a possibly -parallel backup run has finished in between. It can be set by the -`--keep-delete` option and defaults to 23 hours. In any case, packs will be kept -marked and only deleted by the next prune run. - -Note that there is the option `--instant-delete` which circumvents this -two-phase deletion. Only use this option, if you **REALLY KNOW** that there is -no parallel access to your repo, else you risk losing data! - -## You said "rustic uses less resources than restic" but I'm observing the opposite - -In general rustic uses less resources, but there may be some exceptions. For -instance the crypto libraries of Rust and golang both have optimizations for -some CPUs. But it might be that your CPU benefits from a golang optimization -which is not present in the Rust implementation. If you observe some unexpected -resource usage, please don't hesitate to submit an issue. - -## How to install shell completions - -All completion files are generated by invoking `rustic completions` command. So -run: - -### Bash - -```sh -rustic completions bash > /etc/bash_completion.d/rustic.bash -``` - -### Fish - -```sh -rustic completions fish > $HOME/.config/fish/completions/rustic.fish -``` - -### Zsh - -ZSH completions are commonly stored in any directory listed in your `$fpath` -variable. To use these completions, write completions script (`_rustic`) to one -of those directories, or add your own to this list. - -This list includes, for example, these directories: - -- `/usr/local/share/zsh/site-functions` -- `/usr/share/zsh/site-functions` - -So you can run: - -```sh -rustic completions zsh > /usr/local/share/zsh/site-functions/_rustic -``` diff --git a/docs/Readme.md b/docs/Readme.md new file mode 100644 index 0000000..ab0c724 --- /dev/null +++ b/docs/Readme.md @@ -0,0 +1,3 @@ +# Documentation + +Our documentation can be found at: diff --git a/docs/comparison-restic.md b/docs/comparison-restic.md deleted file mode 100644 index a06f003..0000000 --- a/docs/comparison-restic.md +++ /dev/null @@ -1,31 +0,0 @@ -# Comparison rustic vs. restic - -Improvements implemented in rustic: - -- Allows using cold storage (e.g. AWS Glacier) repos which are only read in the - `restore` command + supports warm-up -- All operations are completely lock-free as rustic supports two-phase-pruning - (prune option `instant-delete` is available) -- Supports configuration in a config file - ([example config files](https://github.com/rustic-rs/rustic/tree/main/config)) -- Huge decrease in memory requirement -- Already faster than restic for most operations (but not yet fully speed - optimized) -- Cleaner concept of logging output; possibility to write logs to a log file -- `rustic repair` command allows to repair some kinds of broken repositories -- `backup` command can use `.gitignore` files -- `restore` uses existing files; also option `--delete` available -- Snapshots save much more information, available in `snapshots` command -- Integrates the [Rhai](https://rhai.rs/) script language for snapshot filtering -- Allows to save repository options in the repository config file via the - command `config` -- New command `merge` -- New command `repo-info` -- `check` command checks and uses cache; option `--trust-cache` is available -- Option `prune --fast-repack` for faster repacking -- Syntax `[:PATH]` is available for many commands - -## Missing points - -- [ ] tests and benchmarks -- [ ] missing commands: find, mount diff --git a/docs/dev/development_guide.md b/docs/dev/development_guide.md deleted file mode 100644 index 6ab37fa..0000000 --- a/docs/dev/development_guide.md +++ /dev/null @@ -1,3 +0,0 @@ -# Development guide - -Work in progress ... diff --git a/justfile b/justfile index f65a0b0..28daeef 100644 --- a/justfile +++ b/justfile @@ -63,6 +63,10 @@ doc *ARGS: format: @cargo +nightly fmt --all +# Runs the formatter on md, json, and toml files. +format-mjt: + dprint fmt + # Runs the linter. lint: check cargo clippy --no-default-features @@ -106,6 +110,9 @@ natest *ARGS: # # updating the public API files for each platform works # by setting the environment variable `UPDATE_EXPECT=1` +# +# Run on Windows: `$env:UPDATE_EXPECT=1; cargo test --test public_api -p rustic_core -- --ignored` +# Run on Linux: `export UPDATE_EXPECT=1; cargo test --test public_api -p rustic_core -- --ignored` tpa: cargo test --test public_api -p rustic_core -- --ignored @@ -119,3 +126,6 @@ coverage: # as in which feature enables a given crate inv-ft *ARGS: cargo tree -e features -i {{ARGS}} + +# Prepare a Contribution/Pull request and run necessary checks and lints +pre-commit: format format-mjt test lint