resticprofile
resticprofile copied to clipboard
[Discussion] Regarding systemd units (includes feature requests/ideas)
Hi, I started writing my own restic wrapping for running restic via systemd. After that I found resticprofile
. I am currently in the process of replacing my systemd units with resticprofile ones but ran into some questions. I don't mean this as "hey you should do things differently and my way is the right way" but I do have some suggestions and hope you don't mind.
For my use case: I use 2 restic repos ("s3" and "local") on my machine and backup /
and $HOME
in different intervals. I also do regular restic forget
s and restic prune
s for both repositories.
Legend: I use "job" for "backup", "check", "forget" and "prune". Not sure what it is actually called I am trying to avoid "command".
timers and units
By default a timer called [email protected]
or baz.timer
will activate [email protected]
or baz.service
respectively. You define it explicitly with Unit=
which is not necessary unless you activate a service which has another name. I haven't see this anywhere with resticprofile
, yet.
This also works with instances of templates (see below).
activating/scheduling
Currently there is no --dry-run
option for resticprofile schedule
and resticprofile unschedule
as far as I can tell. And it seems to be impossible to only activate certain jobs (e.g. backup) but not others (check) without adjusting config.
Also I'd like to be able to create the unit files, but not activate them right away (symlinking to timers.target.wants
directory) but only creating the service and timer units. (More of a feature request than a discussion)
systemd templating
I noticed you use the systemd template syntax but you don't utilize it. What I mean by that is that you use template@instance
(for timer or service) but you create a file for each of them.
An example how this could be done with a template (only including important parts, this not an actual unit):
# /etc/systemd/system/[email protected]
[Service]
ExecStart=/usr/local/bin/resticprofile --no-prio --no-ansi --config /etc/resticprofile/profiles.toml --name %i check
This has the benefit of uncoupling the scheduling and activating from resticprofile
. You could still use the resticprofile schedule
but you would only need one template for each job (backup, check, etc.). This also means you can activate jobs for profiles that have no schedule without additional config needed.
timer templating
The same concept works for timers but not as well because there are three things to take into account: profile, job and schedule.
In my version I opted for one timer per job and schedule combination, meaning [email protected]
would run [email protected]
every month (notice different names in the units). If I wanted I could also activate [email protected]
with no additional unit files and it would activate [email protected]
every month.
For resticprofile
you have one file per schedule-job-profile and the naming is a bit different. So I think it is hard to improve with different schedules. You could combine job and schedule, but I don't think it would be very useful. Example:
You'd need a name of a schedule, here monthly
and create a timer for a job, e.g. [email protected]
. You could then activate it [email protected]
to run [email protected]
. If you wanted to change the schedule. You'd need a new timer.
Not sure if possible but ~the~ my dream would be to have something like one timer for each schedule that can then activate a combination of job and profile. Timer: [email protected]
Activate [email protected]
to run [email protected]
every month. There is no nice way to do this.
But if there way a way to call resticprofile in a way that told it profile and job in one sting it would be possible and would even reduce more unit files. The proposal would be as follows:
resticprofile s3.check
(resticprofile <profile>.<job>
) would behave the same as resticprofile --name s3 check
This means the service unit template can look like this:
# /etc/systemd/system/[email protected]
[Service]
ExecStart=/usr/local/bin/resticprofile --no-prio --no-ansi --config /etc/resticprofile/profiles.toml %i
To do the check, start [email protected]
(i.e. resticprofile@<profile>.<job>.service
). For timers you'd still need one unit per unique schedule, e.g. [email protected]
, [email protected]
, etc.
You can then easily activate different schedules for different profiles and times like so:
-
[email protected]
activates[email protected]
-
[email protected]
activates[email protected]
If you totally hate the systemd unit structure I propose here. I still would love to have the feature to use resticprofile <profile>.<job>
. Then I could build the systemd parts on my own.
I saw #27, and wonder what @jkellerer thinks of that ideas above.
By default a timer called
[email protected]
orbaz.timer
will activate[email protected]
orbaz.service
respectively. You define it explicitly withUnit=
which is not necessary unless you activate a service which has another name. I haven't see this anywhere withresticprofile
, yet.
That's true, I forgot about that. Although it doesn't hurt to be precise 😛
Currently there is no
--dry-run
option forresticprofile schedule
andresticprofile unschedule
as far as I can tell. And it seems to be impossible to only activate certain jobs (e.g. backup) but not others (check) without adjusting config.
I suppose we could add a flag for specifying the jobs we want to schedule (defaults to all)
Also I'd like to be able to create the unit files, but not activate them right away (symlinking to
timers.target.wants
directory) but only creating the service and timer units. (More of a feature request than a discussion)
Sure, can do 😄
I noticed you use the systemd template syntax but you don't utilize it. What I mean by that is that you use
template@instance
(for timer or service) but you create a file for each of them.
This is not as easy as it sounds:
- I still need to create one template per config file (it might not be a real case scenario to use more than one config file but I need it for my tests)
- The command line is not static: depending on the target some parameters can be added (
--log
,--lock-wait
or--no-lock
). This is because running a job directly from the command line or from a schedule can be slightly different.
I don't mind changing the unit structure, but we need to find a way to pass more parameters to the command in the service file, if it's possible
I still would love to have the feature to use
resticprofile <profile>.<job>
. Then I could build the systemd parts on my own.
Can do as well. But just for an easy parsing of the command line I might do something more like resticprofile --run <profile>.<job>
if you don't mind
This is not as easy as it sounds:
Yeah, I kinda expected a catch :wink:
- The command line is not static: depending on the target some parameters can be added (
--log
,--lock-wait
or--no-lock
). This is because running a job directly from the command line or from a schedule can be slightly different.
Is that something that needs to be in the ExecStart=
? It sounds like it could be both read from the config file and the overridden by command line arguments if needed. I assume you need read access to the same config file anyways.
Side node: I noticed --no-ansi
but it looks like you already check if you have a tty (tested with | cat
) and remove color (and maybe more). Possibly not necessary – not sure if you clean up restic
output here – or could be added "smartly" unless forced.
- I still need to create one template per config file (it might not be a real case scenario to use more than one config file but I need it for my tests)
I don't use them but user scope units might be another issue as well where you need multiple units.
I don't mind changing the unit structure, but we need to find a way to pass more parameters to the command in the service file, if it's possible
Well, the --run <profile>.<job>
would be a way to pass two arguments via instance but what do you mean exactly?
I see two ways to pass parameters to services at the moment: @instance
and through the config file (and maybe the environment/scope it is run in).
I guess if you wanted you could define config files to be included/imported for different jobs but as you mentioned the amount of real case scenarios might be quite small.
The additional flags specific to a schedule are in the config file indeed, starting with schedule-
so yes, it is technically possible just to put one flag on the command line telling to read the additional flags from the schedule configuration.
So we could potentially have one template per user per config file
FYI: I slapped together a proof of concept for --run
and will try it in the next days and hopefully won't break my backups.
It's just shoddily piggybacking on your code since I can't write golang. (It's just another language. but I can hardly distinguish between =
and :=
).
Cool 👍🏻
You know, that exactly how I started with Go. And now it's my favourite programming language 😄
Works great so far. Trying to figure out how to backup via stdin now.