Skip to content
1 change: 1 addition & 0 deletions commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ func getOwnCommands() []ownCommand {
flags: map[string]string{
"--no-start": "don't start the job after installing (systemd/launch only)",
"--start": "start the job after installing (systemd/launch only)",
"--reload": "force a systemctl daemon-reload after setting up the files (systemd only, available since v0.32.0)",
"--all": "add all scheduled jobs of all profiles and groups",
},
},
Expand Down
5 changes: 5 additions & 0 deletions commands_schedule.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ func createSchedule(_ io.Writer, ctx commandContext) error {
jobs[id].SetFlag("no-start", "")
}
}
if slices.Contains(args, "--reload") {
for id := range jobs {
jobs[id].SetFlag("reload", "")
}
}

allJobs = append(allJobs, profileJobs{schedulerConfig: scheduler, name: profileName, jobs: jobs})
}
Expand Down
2 changes: 1 addition & 1 deletion commands_schedule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ func TestCreateScheduleOverwriteExistingIntegrationUsingCrontab(t *testing.T) {
config: cfg,
global: global,
request: Request{
arguments: []string{"--all"},
arguments: []string{"--all", "--reload", "--no-start"},
},
},
}
Expand Down
14 changes: 7 additions & 7 deletions complete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,15 +271,15 @@ func TestCompleter(t *testing.T) {
{args: []string{"self-update", "-q"}, expected: nil},

// Can completion commands after flags
{args: []string{"--verbose", "schedule", "-"}, expected: []string{"--all", "--no-start", "--start"}},
{args: []string{"--log", "file", "schedule", "-"}, expected: []string{"--all", "--no-start", "--start"}},
{args: []string{"--verbose", "schedule", "-"}, expected: []string{"--all", "--no-start", "--reload", "--start"}},
{args: []string{"--log", "file", "schedule", "-"}, expected: []string{"--all", "--no-start", "--reload", "--start"}},

// Flags are returned only once
{args: []string{"--verb"}, expected: []string{"--verbose"}},
{args: []string{"--verb", "--verb"}, expected: []string{"--verbose"}},
{args: []string{"--verbose", "--verb"}, expected: nil},
{args: []string{"schedule", "-"}, expected: []string{"--all", "--no-start", "--start"}},
{args: []string{"schedule", "--all", "-"}, expected: []string{"--no-start", "--start"}},
{args: []string{"schedule", "-"}, expected: []string{"--all", "--no-start", "--reload", "--start"}},
{args: []string{"schedule", "--all", "-"}, expected: []string{"--no-start", "--reload", "--start"}},

// Exact command match returns nothing (no duplication)
{args: []string{"schedule"}, expected: nil},
Expand All @@ -295,9 +295,9 @@ func TestCompleter(t *testing.T) {
{args: []string{"__POS:2", "--log", "out.log", "--verbose", "schedule", "-"}, expected: []string{RequestFileCompletion}},
{args: []string{"__POS:4", "--log", "out.log", "--verbose", "schedule", "-"}, expected: nil},
{args: []string{"__POS:4", "--log", "out.log", "--verbose", "schedule"}, expected: nil},
{args: []string{"__POS:5", "--log", "out.log", "--verbose", "schedule", "-"}, expected: []string{"--all", "--no-start", "--start"}},
{args: []string{"__POS:5", "--log", "out.log", "--verbose", "schedule"}, expected: []string{"--all", "--no-start", "--start"}},
{args: []string{"__POS:INVALID", "--log", "out.log", "--verbose", "schedule", "-"}, expected: []string{"--all", "--no-start", "--start"}},
{args: []string{"__POS:5", "--log", "out.log", "--verbose", "schedule", "-"}, expected: []string{"--all", "--no-start", "--reload", "--start"}},
{args: []string{"__POS:5", "--log", "out.log", "--verbose", "schedule"}, expected: []string{"--all", "--no-start", "--reload", "--start"}},
{args: []string{"__POS:INVALID", "--log", "out.log", "--verbose", "schedule", "-"}, expected: []string{"--all", "--no-start", "--reload", "--start"}},
{args: []string{"__POS:INVALID", "--log", "out.log", "--verbose", "schedule"}, expected: nil},

// Unknown is delegated to restic
Expand Down
61 changes: 30 additions & 31 deletions docs/content/schedules/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,18 @@ title: "Schedule Commands"
weight: 20
---

resticprofile supports the following commands:
- **schedule**
- **unschedule**
- **status**

resticprofile accepts these commands:
- **schedule**
- **unschedule**
- **status**
These commands apply to the profile or group specified by `--name`, or to all profiles when `--all` is used.

These commands operate on the profile or group selected by `--name`, or on all profiles when `--all` is passed.

{{% notice style="warning" %}}
Before version `0.29.0`, the `--name` flag on a group selected all profiles in the group for scheduling, similar to running the schedule command on each profile individually.

Version `0.29.0` introduced group scheduling: The group schedule works at the group level and runs all profiles one by one when triggered.
{{% /notice %}}
{{% notice style="warning" %}}
In versions prior to `0.29.0`, the `--name` flag for a group scheduled all profiles in the group individually, as if the schedule command was run on each profile.

Starting with version `0.29.0`, group scheduling was introduced. This feature schedules at the group level, executing all profiles sequentially when triggered.
{{% /notice %}}

Examples:
```shell
Expand All @@ -25,52 +23,53 @@ resticprofile --name group schedule
resticprofile schedule --all
```

Schedules are always independent, regardless of whether they are created with `--all` or from a single profile.
Schedules are always independent, whether created with `--all` or a single profile.

### schedule command

Install all schedules defined in the selected profile(s).

Note: On systemd, you need to `start` the timer once to enable it. Otherwise, it will only be enabled on the next reboot. If you don't want to start (and enable) it now, pass the `--no-start` flag to the command.
**Note:** On systemd, you must `start` the timer once to enable it. Otherwise, it will only activate after the next reboot. To skip starting (and enabling) it now, use the `--no-start` flag.

If you use the `--all` flag to schedule all profiles at once, use either `user` mode or `system` mode. Combining both will not schedule tasks properly:
- If the user is not privileged, only `user` tasks will be scheduled.
- If the user is privileged, all schedules will be `system` schedules.
When using the `--all` flag to schedule all profiles at once, choose either `user` mode or `system` mode. Mixing both will cause scheduling issues:
- Non-privileged users can only schedule `user` tasks.
- Privileged users will schedule all tasks as `system` tasks.

Use the `--reload` flag to trigger a `systemctl daemon-reload` after setting up the schedule files. This is helpful if systemd fails to detect manually added dependencies in the service file. The flag is available starting from version 0.32.0.

{{% notice style=tip %}}
Before version `v0.30.0`, resticprofile did not keep a state of the schedule and unschedule commands. If you needed to make many changes to your profiles (e.g., moving, renaming, deleting), it was recommended to unschedule everything using the `--all` flag before making changes. This is no longer necessary since version `v0.30.0`.
Before version `v0.30.0`, resticprofile did not track the state of schedule and unschedule commands. If you needed to make significant changes to profiles (e.g., moving, renaming, deleting), it was recommended to unschedule everything using the `--all` flag first. This is no longer required as of version `v0.30.0`.
{{% /notice %}}

### unschedule command

Remove all schedules defined on the selected profile, or all profiles using the `--all` flag.
Remove all schedules from the selected profile or all profiles using the `--all` flag.

Before version `v0.30.0`, the `--all` flag didn't remove schedules on deleted or renamed profiles.
Before `v0.30.0`, the `--all` flag did not remove schedules for deleted or renamed profiles.

> [!NOTE]
> The behavior of the `unschedule` command changed in version `v0.30.0`:
>
> It now deletes any schedule associated with the profile name, or any profile in the configuration file with `--all` (including deleted profiles).
> [!NOTE]
> Starting with `v0.30.0`, the behavior of the `unschedule` command changed:
> - Without the `--all` flag, it deletes schedules associated with the profile name.
> - With the `--all` flag, it removes all profiles from the configuration file, including deleted and renamed ones.

### status command

Print the status of all installed schedules for the selected profile(s).
Print the status of all installed schedules for the selected profiles.

The `status` command output depends on the OS. Refer to the [examples]({{% relref "/schedules/examples" %}}) for expected output.
The `status` command output varies by OS. See the [examples]({{% relref "/schedules/examples" %}}) for details.

### run-schedule command

This command allows the scheduler to instruct resticprofile to run according to a schedule. It configures the appropriate log output (`schedule-log`) and other schedule-specific flags.

This command is used by the scheduler to tell resticprofile to execute within a schedule. It sets the proper log output (`schedule-log`) and other schedule-specific flags.

If you're scheduling resticprofile manually, use this command. It executes the profile with all `schedule-*` parameters defined in the profile.
If you're manually scheduling resticprofile, use this command. It runs the profile with all `schedule-*` parameters defined in the profile.

This command takes one argument: the command name followed by the profile name, separated by an `@` sign.
The command requires one argument: the command name followed by the profile name, separated by an `@` symbol.

```shell
resticprofile run-schedule backup@profile
```

{{% notice info %}}
For the `run-schedule` command, you cannot specify the profile name using the `--name` flag.
{{% /notice %}}
The `--name` flag cannot be used to specify the profile name with the `run-schedule` command.
{{% /notice %}}
19 changes: 9 additions & 10 deletions docs/content/usage/keyfile.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,23 @@ weight: 10

## Generating random keys

resticprofile has a handy tool to generate cryptographically secure random keys encoded in base64. You can simply put this key into a file and use it as a strong key for restic.
Resticprofile includes a tool to generate cryptographically secure, base64-encoded random keys. Save the key to a file and use it as a strong key for Restic.

- On Linux and FreeBSD, the generator uses `getrandom(2)` if available, `/dev/urandom` otherwise.
- On OpenBSD and macOS, the generator uses `getentropy(2)`.
- On other Unix-like systems, the generator reads from `/dev/urandom`.
- On Windows systems, the generator uses the uses the RtlGenRandom API.
- On JS/Wasm, the generator uses the Web Crypto API.
- On WASIP1/Wasm, the generator uses `random_get` from `wasi_snapshot_preview1`.
- On Linux, FreeBSD, Dragonfly, and Solaris, Reader uses `getrandom(2)`.
- On legacy Linux (< 3.17), it uses `/dev/urandom`.
- On macOS, and OpenBSD Reader, uses `arc4random_buf(3)`.
- On NetBSD, Reader uses the kern.arandom sysctl.
- On Windows, Reader uses the ProcessPrng API.

[Reference from the Go documentation](https://golang.org/pkg/crypto/rand/#pkg-variables)
[Reference from the Go cryto library documentation](https://golang.org/pkg/crypto/rand/#pkg-variables)

```shell
resticprofile generate --random-key
```

generates a 1024 bytes random key (converted into 1368 base64 characters) and displays it on the console
Generates a 1024-byte random key (converted to 1368 Base64 characters) and displays it in the console.

To generate a different size of key, you can specify the bytes length on the command line:
To generate a key of a different size, specify the byte length in the command line.

```shell
resticprofile generate --random-key 2048
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/creativeprojects/resticprofile

go 1.24.3
go 1.24.5

require (
github.com/Masterminds/semver/v3 v3.3.1
Expand Down
Loading
Loading