creativeprojects / resticprofile

Configuration profiles manager and scheduler for restic backup
https://creativeprojects.github.io/resticprofile/
GNU General Public License v3.0
604 stars 29 forks source link

Profile names in config file partially behave case-sensitive #368

Open ThelloD opened 1 month ago

ThelloD commented 1 month ago

The groups section in profiles.yaml seems to be somewhat case sensitive and behaves inconsistently when profile names with upper case letters are used. Although parts of the specified profile are loaded, some parts aren't, and therefore resticprofile runs unexpectedly. Only tested with version 2 of the profile, so I don't know if version 1 is affected, too. Steps to reproduce are below.

Exemplary config file:

# yaml-language-server: $schema=https://creativeprojects.github.io/resticprofile/jsonschema/config-2.json
version: "2"

global:
  restic-binary: /path/to/restic

groups:
  default:
    profiles:
      - TestProfile

profiles:
  TestProfile:
    password-file: "test.key"
    base-dir: {{ .ConfigDir }}
    use:
      - this-mixin-does-not-exist
    repository: rest:https://user:pass@example.com

    backup:
      check-after: true
      files-from:
        - {{ .ConfigDir }}/include.ini

Things to note:

  1. TestProfile is written with the identical upper and lower case letters.
  2. The profile uses the mixin named this-mixin-does-not-exist which does not exist.

Expectation: Resticprofile should load TestProfile but execution should fail because an undefined mixin is used.

$ /path/to/resticprofile --dry-run -v backup
2024/06/15 12:37:03 resticprofile 0.26.0 compiled with go1.21.7
2024/06/15 12:37:03 using configuration file: profiles.yaml
2024/06/15 12:37:03 loading: profiles.yaml
2024/06/15 12:37:03 memory available: 22261MB
2024/06/15 12:37:03 using restic 0.16.4
2024/06/15 12:37:03 [1/1] starting profile 'TestProfile' from group 'default'
2024/06/15 12:37:03 profile 'TestProfile': starting 'backup'
2024/06/15 12:37:03 unfiltered extra flags:
2024/06/15 12:37:03 unfiltered command: backup --files-from=/path/config/test/include.ini --host=example.com --password-file=test.key --repo=rest:https://user:×××@example.com --verbose=1
2024/06/15 12:37:03 starting command: /path/to/restic backup --files-from=/path/config/test/include.ini --host=example.com --password-file=test.key --repo=rest:https://user:×××@example.com --verbose=1
2024/06/15 12:37:03 dry-run: /path/to/restic backup --files-from=/path/config/test/include.ini --host=example.com --password-file=test.key --repo=rest:https://user:×××@example.com --verbose=1
2024/06/15 12:37:03 profile 'TestProfile': finished 'backup'
2024/06/15 12:37:03 profile 'TestProfile': checking repository consistency
...

Contrary to the expected behavior, resticprofile runs the profile but ignores some declarations, such as the use: directive.

Let's take a look at a slightly modified profile:

# yaml-language-server: $schema=https://creativeprojects.github.io/resticprofile/jsonschema/config-2.json
version: "2"

global:
  restic-binary: /path/to/restic

groups:
  default:
    profiles:
      - testprofile

profiles:
  TestProfile:
    password-file: "test.key"
    base-dir: {{ .ConfigDir }}
    use:
      - this-mixin-does-not-exist
    repository: rest:https://user:pass@example.com

    backup:
      check-after: true
      files-from:
        - {{ .ConfigDir }}/include.ini

Here, the profile name in the groups section has been changed to lowercase (testprofile). Everything else stayed unchanged, so the the profile name is still TestProfile.

$ /path/to/resticprofile --dry-run -v backup
2024/06/15 12:36:45 resticprofile 0.26.0 compiled with go1.21.7
2024/06/15 12:36:45 using configuration file: profiles.yaml
2024/06/15 12:36:45 loading: profiles.yaml
2024/06/15 12:36:45 memory available: 22258MB
2024/06/15 12:36:45 using restic 0.16.4
2024/06/15 12:36:45 [1/1] starting profile 'testprofile' from group 'default'
2024/06/15 12:36:45 cannot load profile 'testprofile': failed applying profiles.testprofile.use: undefined mixin "this-mixin-does-not-exist"

Now resticprofile also interprets the use: part and, as expected, an error message is shown that mixin this-mixin-does-not-exist could not be loaded.

jkellerer commented 1 month ago

Thanks a lot for the report. We’re using a config parser that is not case sensitive and it changes the case to lowercase names. However values like profile lists in groups are kept as they are.

Since mixins operate on the object structure of the parsed config file, they apply only when the case matches correctly.

Other parts are less tricky and may still work correctly. With other words this requires fixing to be truly case insensitive.

jkellerer commented 1 month ago

As a workaround, at the moment all names should be kept lowercase to avoid the problem until it is fixed.