Skip to content
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

shpool should support system-wide config #30

Closed
ethanpailes opened this issue Jun 3, 2024 · 7 comments · Fixed by #58
Closed

shpool should support system-wide config #30

ethanpailes opened this issue Jun 3, 2024 · 7 comments · Fixed by #58
Assignees
Labels
enhancement New feature or request

Comments

@ethanpailes
Copy link
Contributor

Currently, we only support config in a user's home directory (~/.config/shpool/config.toml). We should also support a system wide location so that settings can be applied globally on a machine or by an orginization. I think /etc/shpool/config.toml would be a good path for system wide settings.

Any user-level settings should override system-wide settings. To do this we will need to write some merge logic for the config struct.

I see this being the most applicable when it comes to the motd settings. Individual users probably want them off or on dump by default, but organizations which make importaint announcements via the motd may wish to set a different setting.

@Aetf
Copy link
Contributor

Aetf commented Jun 3, 2024

Let me take this one.

IMHO the config paths etc could come from xdg using crates like https://github.com/dirs-dev/directories-rs, and we can use something like https://docs.rs/figment/latest/figment/ or https://github.com/mehcode/config-rs to handle layered configs.

@Aetf Aetf self-assigned this Jun 3, 2024
@ethanpailes
Copy link
Contributor Author

directories-rs does seem pretty useful, but the configuration frameworks seem a bit heavy to me (and I'm worried about compability if we switch to one of them). If we just program directly, there will be a single config merge routine, and each new top level field in the config will require probably a single field: higher.field.or_else(lower.field) line wich is not much maintenance burden. Since we need to vendor deps internally, I'm not sure avoiding that is worth the import toil.

@Aetf
Copy link
Contributor

Aetf commented Jun 7, 2024

That makes sense. Let me just code the merge directly.

@qaqland
Copy link

qaqland commented Jun 15, 2024

And hope it would work as a system service

@ethanpailes
Copy link
Contributor Author

@qaqland do you mean you want it to run as a non-user systemd service?

@qaqland
Copy link

qaqland commented Jun 18, 2024

@qaqland do you mean you want it to run as a non-user systemd service?

yes, i use openrc

@ethanpailes
Copy link
Contributor Author

@qaqland that seems like a different feature request. Currently, shpool can't run as a system wide service because it assumes itself to be running as the user. In order to run as a system service, we would need a mode for the daemon to be running as root and know how to drop privileges. This seems like a major vector for security issues that I would rather avoid thinking about, so for the moment you'll need to run the daemon as your own user via a helper script of some kind. For your particular case, it looks like the command_user OpenRC option will let you write a service that launches the daemon as your normal user.

I made #56 to track work on autodaemonization in order to make life easier for people who don't use systemd.

Aetf added a commit that referenced this issue Jun 19, 2024
- Simple merging logic for `Config`
- Load config from system-wide locations (fixes #30)
- Dynamically pick up changes from newly created config files (fixes #29)
- Use `directories-rs` to find user level config directory path

A new `ConfigWatcher` is introduced, which opportunistically watches the
closest existing parent of target paths and rewatches dynamically accordingly.
This way we can get notifications for new file creations in addition to
modifications.

`ConfigWatcher` also does debounce (100ms by default) to only trigger
one config reload for multiple events in a short time period.

The core idea of the watcher is as follow:

Given a watching target path `/base/sub/config.toml`,
a) readd watches if any segment in the path is created/removed;
b) reload config only if the event is about the full target path.

The actual implementation extends this idea to handle multiple targets.
Please refer to `config_watcher.rs` for details and extensive test cases.

A few design points:

- Notify event handling is done in a separate thread, rather than in
  notify's internal event handler thread, because the code is more
  readable and calling unwatch/watch in that thread may lead to deadlock
  in some cases. (notify-rs/notify#410, notify-rs/notify#463)
- For simplicity, `ConfigWatcher` doesn't  provide infomation about
  which exact config file was changed, assuming a reload would need to
  read all config files anyway.
Aetf added a commit that referenced this issue Jun 24, 2024
- Simple merging logic for `Config`
- Load config from system-wide locations (fixes #30)
- Dynamically pick up changes from newly created config files (fixes #29)
- Use `directories-rs` to find user level config directory path

A new `ConfigWatcher` is introduced, which opportunistically watches the
closest existing parent of target paths and rewatches dynamically accordingly.
This way we can get notifications for new file creations in addition to
modifications.

`ConfigWatcher` also does debounce (100ms by default) to only trigger
one config reload for multiple events in a short time period.

The core idea of the watcher is as follow:

Given a watching target path `/base/sub/config.toml`,
a) readd watches if any segment in the path is created/removed;
b) reload config only if the event is about the full target path.

The actual implementation extends this idea to handle multiple targets.
Please refer to `config_watcher.rs` for details and extensive test cases.

A few design points:

- Notify event handling is done in a separate thread, rather than in
  notify's internal event handler thread, because the code is more
  readable and calling unwatch/watch in that thread may lead to deadlock
  in some cases. (notify-rs/notify#410, notify-rs/notify#463)
- For simplicity, `ConfigWatcher` doesn't  provide infomation about
  which exact config file was changed, assuming a reload would need to
  read all config files anyway.
Aetf added a commit that referenced this issue Jun 24, 2024
- Simple merging logic for `Config`
- Load config from system-wide locations (fixes #30)
- Dynamically pick up changes from newly created config files (fixes #29)
- Use `directories-rs` to find user level config directory path

A new `ConfigWatcher` is introduced, which opportunistically watches the
closest existing parent of target paths and rewatches dynamically accordingly.
This way we can get notifications for new file creations in addition to
modifications.

`ConfigWatcher` also does debounce (100ms by default) to only trigger
one config reload for multiple events in a short time period.

The core idea of the watcher is as follow:

Given a watching target path `/base/sub/config.toml`,
a) readd watches if any segment in the path is created/removed;
b) reload config only if the event is about the full target path.

The actual implementation extends this idea to handle multiple targets.
Please refer to `config_watcher.rs` for details and extensive test cases.

A few design points:

- Notify event handling is done in a separate thread, rather than in
  notify's internal event handler thread, because the code is more
  readable and calling unwatch/watch in that thread may lead to deadlock
  in some cases. (notify-rs/notify#410, notify-rs/notify#463)
- For simplicity, `ConfigWatcher` doesn't  provide infomation about
  which exact config file was changed, assuming a reload would need to
  read all config files anyway.
Aetf added a commit that referenced this issue Jun 24, 2024
- Simple merging logic for `Config`
- Load config from system-wide locations (fixes #30)
- Dynamically pick up changes from newly created config files (fixes #29)
- Use `directories-rs` to find user level config directory path

A new `ConfigWatcher` is introduced, which opportunistically watches the
closest existing parent of target paths and rewatches dynamically accordingly.
This way we can get notifications for new file creations in addition to
modifications.

`ConfigWatcher` also does debounce (100ms by default) to only trigger
one config reload for multiple events in a short time period.

The core idea of the watcher is as follow:

Given a watching target path `/base/sub/config.toml`,
a) readd watches if any segment in the path is created/removed;
b) reload config only if the event is about the full target path.

The actual implementation extends this idea to handle multiple targets.
Please refer to `config_watcher.rs` for details and extensive test cases.

A few design points:

- Notify event handling is done in a separate thread, rather than in
  notify's internal event handler thread, because the code is more
  readable and calling unwatch/watch in that thread may lead to deadlock
  in some cases. (notify-rs/notify#410, notify-rs/notify#463)
- For simplicity, `ConfigWatcher` doesn't  provide infomation about
  which exact config file was changed, assuming a reload would need to
  read all config files anyway.
@ethanpailes ethanpailes added the enhancement New feature or request label Jun 24, 2024
Aetf added a commit that referenced this issue Jun 25, 2024
- Simple merging logic for `Config`
- Load config from system-wide locations (fixes #30)
- Dynamically pick up changes from newly created config files (fixes #29)
- Use `directories-rs` to find user level config directory path

A new `ConfigWatcher` is introduced, which opportunistically watches the
closest existing parent of target paths and rewatches dynamically accordingly.
This way we can get notifications for new file creations in addition to
modifications.

`ConfigWatcher` also does debounce (100ms by default) to only trigger
one config reload for multiple events in a short time period.

The core idea of the watcher is as follow:

Given a watching target path `/base/sub/config.toml`,
a) readd watches if any segment in the path is created/removed;
b) reload config only if the event is about the full target path.

The actual implementation extends this idea to handle multiple targets.
Please refer to `config_watcher.rs` for details and extensive test cases.

A few design points:

- Notify event handling is done in a separate thread, rather than in
  notify's internal event handler thread, because the code is more
  readable and calling unwatch/watch in that thread may lead to deadlock
  in some cases. (notify-rs/notify#410, notify-rs/notify#463)
- For simplicity, `ConfigWatcher` doesn't  provide infomation about
  which exact config file was changed, assuming a reload would need to
  read all config files anyway.
Aetf added a commit that referenced this issue Jun 25, 2024
- Simple merging logic for `Config`
- Load config from system-wide locations (fixes #30)
- Dynamically pick up changes from newly created config files (fixes #29)
- Use `directories-rs` to find user level config directory path

A new `ConfigWatcher` is introduced, which opportunistically watches the
closest existing parent of target paths and rewatches dynamically accordingly.
This way we can get notifications for new file creations in addition to
modifications.

`ConfigWatcher` also does debounce (100ms by default) to only trigger
one config reload for multiple events in a short time period.

The core idea of the watcher is as follow:

Given a watching target path `/base/sub/config.toml`,
a) readd watches if any segment in the path is created/removed;
b) reload config only if the event is about the full target path.

The actual implementation extends this idea to handle multiple targets.
Please refer to `config_watcher.rs` for details and extensive test cases.

A few design points:

- Notify event handling is done in a separate thread, rather than in
  notify's internal event handler thread, because the code is more
  readable and calling unwatch/watch in that thread may lead to deadlock
  in some cases. (notify-rs/notify#410, notify-rs/notify#463)
- For simplicity, `ConfigWatcher` doesn't  provide infomation about
  which exact config file was changed, assuming a reload would need to
  read all config files anyway.
@Aetf Aetf closed this as completed in #58 Jun 25, 2024
Aetf added a commit that referenced this issue Jun 25, 2024
* Gracefully handle missing XDG_RUNTIME_DIR env var in tests

* Configuration loading overhaul

- Simple merging logic for `Config`
- Load config from system-wide locations (fixes #30)
- Dynamically pick up changes from newly created config files (fixes #29)
- Use `directories-rs` to find user level config directory path

A new `ConfigWatcher` is introduced, which opportunistically watches the
closest existing parent of target paths and rewatches dynamically accordingly.
This way we can get notifications for new file creations in addition to
modifications.

`ConfigWatcher` also does debounce (100ms by default) to only trigger
one config reload for multiple events in a short time period.

The core idea of the watcher is as follow:

Given a watching target path `/base/sub/config.toml`,
a) readd watches if any segment in the path is created/removed;
b) reload config only if the event is about the full target path.

The actual implementation extends this idea to handle multiple targets.
Please refer to `config_watcher.rs` for details and extensive test cases.

A few design points:

- Notify event handling is done in a separate thread, rather than in
  notify's internal event handler thread, because the code is more
  readable and calling unwatch/watch in that thread may lead to deadlock
  in some cases. (notify-rs/notify#410, notify-rs/notify#463)
- For simplicity, `ConfigWatcher` doesn't  provide infomation about
  which exact config file was changed, assuming a reload would need to
  read all config files anyway.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants