-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Configuration File #16
Comments
This is a proposal for a configuration file for restic, in TOML (see https://github.com/toml-lang/toml#example for an example). The configuration file can be used to define global default values and aliases to repositories, which apply configuration values. [global]
[global.backup]
exclude = [ "*.swp" ]
[gibson]
location = "sftp://gibson.domain.tld//data/backup/restic-repo"
[gibson.backup]
exclude = [ "/home/user/work", "*.go" ]
target = [ "/home/user" ]
[mainframe]
location = "sftp://mainframe.internal//home/user/repo"
[mainframe.backup]
exclude = [ "/tmp", "/proc", "/sys" ] This leads to the following behaviour:
So if I have a good config file, creating a backup is a matter of running |
Have you considered using JSON as the format for your configuration files? After all you are already reading and writing JSON for the repository itself. Tools that want to interact with restic will already need to understand JSON etc. The biggest downside to JSON is that it does not make it easy to add comments to the configuration files |
Yes, I've considered and discarded JSON for the config file, writing JSON by hand is tiresome and very error-prone (at least in my experience). I'll probably use HCL by Hashicorp or a custom format for the config file. HCL supports comments and is machine-readable. |
I think TOML is well suited for this situation because it is easy to read and write for humans and easy to parse (compared to YAML). |
+1 for the config but then please add btw is the intent to have each restic cmd have it's own sub section, or can we combine them all in one? as long as the flags (now keywords) do not overlap between the cmds, that should work, no? [global]
exclude = [ "*.swp" ]
forget_daily = 7
forget_weekly= 4
forget_monthly = 36
forget_yearly = 99
[gibson]
location = "sftp://gibson.domain.tld//data/backup/restic-repo"
exclude = [ "/home/user/work", "*.go" ]
target = [ "/home/user" ]
[mainframe]
location = "sftp://mainframe.internal//home/user/repo"
exclude = [ "/tmp", "/proc", "/sys" ] Ok, you prob don't like that :) Lets just keep the forget_xxx's [Edit] Oh, nasty. How do I remove a global setting? Say I do need swapfiles in mainframe. Something like |
Like fwilhe (and for the very same reasons), I think TOML is well suited for this. I also think that this issue is important: Since obnam was retired a couple of weeks ago, many obnam users either switch to borg or restic. I am one of those, currently making the transition fro obnam to restic and the support for a configuration file is what I'm missing most. Thank you for your work! |
Is there any progress in this area? Gentoo just masked obnam for removal and this is the No. 1 missing feature to choose restic as replacement. |
No progress yet, sorry. |
Sample implementation for config file support: Dislcaimer: This is my first time touching Go, so there might be dragons. https://github.com/leak/restic/tree/config-file Quick facts: Concerns: Proposal: I wanted to continue and enhance this experience, thus my proposal: A single config file per repository paired with default config search behavior, enabling the following scenarios: Single repository:
Multi repository:
The |
Hm, nice idea, let me think about it. What I had in mind for the config file would be to be able to configure multip repositories, with a name for each repo. So you could have a repo config I'm still busy with #1494, but I'll think about it. :) |
I must admit I don't like the context-awareness of the multi-repo proposal. Tools like Git have this feature, but there you are actually inside the repo when it loads the repo-specific configuration parts, not inside a folder that (maybe) refers to a repo, but is not by design the single-point-of-entry to that repo. I think I like @fd0's idea with |
That's easy to solve: The name may not start with a |
Nah,
|
I like the git client analogy a lot. You can just drop into a folder and use commands without specifying the same parameters over and over again, or alternatively, scroll back and edit your previously issued commands so you can avoid retyping the same things again. To me this is very user unfriendly. Btw. this feature only requires for restic to look for a "restic.toml" in the current working dir, nothing more or less, it could perfectly live side-by-side with all other proposed options. As for the Maybe a new flag could be called |
Let's talk about that when we get there. |
I just want to drop some lines about my usecase here:
As config format is toml preferrable. YAML is too complicated for many users and toml feels more natural (looks like ini). |
So it's been a while already. Meanwhile I'm using restic in more and more places across multiple OS without any problems, which is very pleasant. The only thing that keeps coming up is the lack of a configuration file that would remove the need for shell scripts and whatnot. I got a bit spare time on my hands. I could turn my sample implementation above into a pull request. I believe my implementation could already cover a lot of use cases and the advanced features could be handled/discussed in a new github issue. Would that potential pull request have a chance? |
Thank you very much for the offer (and for asking before spending more time on it)! I think I'd like to try this myself, using HCL instead of TOML and avoiding viper. I've looked at it and I think it has way more features than what we want. |
I have all my secrets in a non-checked in secrets file, in JSON format. So I wrote a simple wrapper to pull those out and export it, keeping all my secrets in one place. Lightweight setting wrapper to set the environment variables via a JSON file config file using Dependency:
EDIT: This didn't work as a wrapper, when used in a pipe. Suggestions for fixing this are welcome... |
I understand that now there is no RFC/feedback needed labels, but if you think of the restic as a "low-level" backup program, then configuration should be done either in some higher-level language. I tried to design restic configuration in toml, but it's kinda hard because nested mappings in toml is too much verbose IMO. But yaml is nice both to write and read, I think: repos:
host:
path: /backups/host
password-file: /mnt/host-password.txt
global:
repo: host
ignore:
caches: true
jobs:
etc: /etc
home:
path: /home
exclude: .local/share/Steam
postgres:
cmd: sudo -u postgres pg_dumpall
save-as: pgdumpall.bin But I see that there are people who don't like yaml. Then, maybe, we should look at interpretable languages, like Python? from resticrc.models import Repository, Job, FileRunner
repo = Repository(name="host", path="/backups/host")
job = Job(
repo=repo,
tag="gitea",
runner=FileRunner(paths=["/home/git", "/var/lib/gitea"]),
exclude={"logs": True}
)
job.run() |
So, I came here, too, looking for configuration file supports… Well, it isn’t ready yet, too bad. But I want this to be very clear: yes, that is perfectly fair, for this is Open Source. I haven't yet put a single ounce of effort or money in developing this great software, so please: no guilt anyone. Now, I have just gone through this thread several times, as well as several others threads related to it and to restic development in general. I have also looked at most propositions and many existing wrappers. And I think it might be helpful to share some insights I gained from this exercise. First, the existence of all these wrappers clearly demonstrates that strictly speaking, restic does not need native support for configuration files. Of course, this appears to be desirable, but if there are so many wrappers providing support for configuration files over restic, it is indeed because it is reasonably easy to do so. In comparison, compression can’t be implemented outside of restic’s core, and purge’s performance can’t be improved by an external command. But configuration files support can. Therefore, in term of development priority, it is not unreasonable for configuration files support to be in the backlog. Second, most propositions I have seen differ essentially by their configuration languages, and most existing wrappers differ mainly by their programming languages and by their implementers. But aside from these minor differences, I think most suggestions and existing wrappers are essentially equivalent from a functional point of view (that is, with the notable exception of schedic and replica, which both store configuration files in the cloud and internally handle scheduling of backup execution). Then why isn’t everyone converging to a unique configuration wrapper? That’s a broad question, indeed, but I personally think that it is in large part because there is no clear winner, and therefore, no payback to convert existing configurations and scripts that are working. Everybody is waiting for an “official” solution to move on… A solution that has received agreement from restic’s core developers, and that will be maintained in future restic development. On the opposite side, there are also use cases for which configuration files as those envisioned for restic will simply never be fit… That is notably the case of schedic and replica, but there will certainly be many others. For these use cases, providing parameters through environment variables and/or command line arguments is just fine. Now, from the discussion in this thread, it appears that @fd0 has some reasonable ideas of how he would like the configuration language to be designed. I must admit that, personally, I am not a huge fan of the HCL syntax, but my opinion on this matter doesn’t count, and it is true that HCL would indeed make restic’s configuration much more powerful. But in the end, what really matter is that 1) community efforts should be put on converging toward a unique configuration language, 2) that this configuration language must have support from @fd0 and other core developers, and 3) that a usable prototype of that configuration language be developed. There is however nothing that require that the configuration language should be designed by @fd0 himself or any of the other core developers (they have other, more important things to do, whatever they are, and we must respect that). Core developers certainly must be in the loop, because obtaining their agreement is critical, but they should not be the ones doing the hard work on that. Also, the prototype for that configuration language can very well be implemented as a wrapper over restic, rather than being implemented in restic’s source code. Tens of wrappers have already proven that this is possible, so why not do it for a prototype of the official configuration file support if that means we can get a working implementation much sooner, with very little effort from the core developers? Obviously, it would be highly desirable for that prototype to be constructed on the same technologies as restic itself (so that this wrapper can actually be used by anyone who would be using restic, without any supplementary requirement), but the code can be written by distinct, capable developers, without involving reviews by restic’s core developers. Once this is done, this ticket can finally be closed, and everyone will be invited to start using the new “official” configuration file support, based on the “official” wrapper, instead of those numerous work around and third-party wrappers. All of this can be done even while restic’s code is in flux, since this is a distinct, external code base. Then, eventually, once restic’s code and the configuration language have both stabilized, and free time flows in (ok, maybe I’m exaggerating a little bit on that one…), well, at that time, restic’s core developers shall take decisions on how to best integrate both softwares. Maybe they will choose to rebundle the configuration-file aware cli as a module to be import from restic’s core… Or maybe the opposite: the wrapper could be promoted to become the actual restic binary, importing the restic’s core module… For sure, there will be several reasonable options at that time. And what could be the worst case? Well, if the prototype’s source code isn’t clean enough, it can all be rewritten from scratch, at that time… That would still be a win compared to have no solution at all until then. So this was my two cents. @fd0, I think this has to be your decision. Does that all make sense to you? Do you feel comfortable with what I propose? There are certainly a few details I might have missed… After all, I have known this project for only a few days yet, so I’ll stay very humble if there are factors I have not considered… But I truly believe that it would be in everyone’s interest if we can get this ticket to move on without involving you more than necessary. James Watkins-Harvey |
Maybe also, instead of coming up with a solution to all problems at once and at the same time, how about dividing the problem into its components and tackling one at a time? I.e. we could do
|
I was looking at spf13/viper the other day. The best thing about it is that it can load all sort of configuration file formats out of the box. So the user would be able to choose his favourite format. I'm quite tempted to rewrite resticprofile in go using viper. Mostly for the fun of it (and also to learn a bit more of go) but also because maybe it makes sense to keep the tool and the configuration separated after all. |
I decided, just for good measure, to write my own super simple configuration wrapper, crestic :-) |
Another solution is here: autorestic It seems crestic may be the simplest approach - not needing updates every time the restic api moves forward... |
In case it can help, I have published a few notes I had on an HCL configuration language for restic. I used HCL because I was hoping that we could finally all agree on a syntax that would get @fd0's official support… But I don't know if he agrees on this direction… https://gist.github.com/mjameswh/9e9f7ddfdcdc2e5f30c4547ad72b402e |
For such a simple prototype I must say I am really happy with the way crestic works, and I am using it daily now. It's an almost-one-click install with no dependencies, does not try to be too clever, speaks a language you already know (the restic CLI parameters become keys in an INI file), and parameters are easily overrideable when you need to. |
If you have the time please create a post on the forum to introduce your project. |
I really like @nils-werner's approach with Also, I can't wait to get this as a native |
I like However, it does not allow the |
@lucmos |
@nettnikl thanks for the heads up! Do you mean in crestic? Because I am not finding anything relative to that |
@lucmos Yes, in crestic. Was talking to the dev about this exact issue and later i found you asking for the exact same feature. It's not yet megred, but i invite you to join the discussion, a working branch can also be found there! |
Are you sure? I don't think that should be the case. Can you please open an issue in https://github.com/nils-werner/crestic to help me reproduce this?
There is a dedicated issue and branch for this. |
Update the Dockerfile to run the container as a non-root user Co-authored-by: bmason <briab@gabey.com> Co-authored-by: John Mears <jmears@netapp.com>
One possible current restic configuration option is to simply use bash scripting. For example, using pass to fetch secrets, put this into your _config-restic () {
local _pass_file="${1}"
local _pass_contents="$(pass ${_pass_file})"
export AWS_ACCESS_KEY_ID=$(echo ${_pass_contents} | sed -e '/^aws_access_key_id:/s/aws_access_key_id:[[:space:]]*//p' -e d)
export AWS_SECRET_ACCESS_KEY=$(echo ${_pass_contents} | sed -e '/^aws_secret_access_key:/s/aws_secret_access_key:[[:space:]]*//p' -e d)
export RESTIC_REPOSITORY=$(echo ${_pass_contents} | sed -e "/^${2}:/s/${2}:[[:space:]]*//p" -e d)
export RESTIC_PASSWORD=$(echo ${_pass_contents} | head -1)
}
unconfig-restic () {
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
unset RESTIC_REPOSITORY
unset RESTIC_PASSWORD
}
_mount-restic () {
_config-restic ${@}
local _temp_dir="$(mktemp -d --tmpdir restic.XXX)"
echo "Backup will be mounted in ${_temp_dir}"
restic mount ${_temp_dir}
rmdir ${_temp_dir}
unconfig-restic
}
# Configuration aliases
alias -- config-restic-desktop='_config-restic Restic desktop_repository'
alias -- config-restic-server='_config-restic Restic server_repository'
# Mount aliases
alias -- mount-restic-desktop='_mount-restic Restic desktop_repository'
alias -- mount-restic-server='_mount-restic Restic server_repository' The repository_password
---
aws_access_key_id: key_id
aws_secret_access_key: secret
desktop_repository: s3:https://server:port/bucket
server_repository: s3:https://other/bucket
sftp_repository: sftp:server:/path/to/repo As you can see you can even use different repository backends since restic simply ignores environment variables that it does not need. Moreover, this is extensible to as many environment variables as needed. Then to use it, simply run: $ config-restic-desktop
$ restic snapshots # or any restic command
$ unconfig-restic # if you want to clear environment variables (optional) Or for fast mount (after umount or Ctrl-c the tempdir is deleted 😉): $ mount-restic-desktop
Backup will be mounted in /tmp/restic.o0o
repository bebecafe00 opened (version 2, compression level auto)
[0:00] 100.00% 666 / 666 index files loaded
Now serving the repository at /tmp/restic.o0o
Use another terminal or tool to browse the contents of this folder.
When finished, quit with Ctrl-c here or umount the mountpoint. Another option that can also be used (pure bash script and without pass) is a small script that I have created for Arch Linux but that can be used in any Linux distribution, see here for full info. |
Configuration File to store the default settings. Just run "restic" to create next snapshot based on settings in config file.
Connect #288
The text was updated successfully, but these errors were encountered: