← Back to context

Comment by xerxes901

21 hours ago

> As a trivial example, you can dynamically depend on other services depending on system configuration (as PostgreSQL does)

Depending on what you want to do, a generator might be appropriate:

> Their main purpose is to convert configuration and execution context parameters that are not native to the service manager into dynamically generated unit files, symlinks or unit file drop-ins

Well, here are the relevant parts of the service file:

  get_config() {
      [ -f "${PGDATA%/}/postgresql.conf" ] || return 1
  
      eval echo $(sed -e 's:#.*::' "${PGDATA%/}/postgresql.conf" \
          | awk '$1 == "'$1'" { print ($2 == "=" ? $3 : $2) }')
  }
  
  depend() {
      use net
      provide postgresql
  
      if [ "$(get_config log_destination)" = "syslog" ]; then
          use logger
      fi
  }

If PostgreSQL has been configured, this reads its config file, looks to see if it's configured to use 'syslog' as its log destination, and -if so- adds a dependency on the 'logger' "meta-service". [0]

What would this look like with a systemd service file generator?

[0] What's a "meta-service"? 'provide postgresql' makes the service started by this service file provide the 'postgresql' "meta-service". This is useful for PostgreSQL because you can install multiple versions of the software simultaneously... so the service files are named like postgresql-17, and postgresql-18. The 'logger' "meta-service" is useful because who cares which syslog software you have installed... you only care that it speaks syslog.

  • Yeah parsing config files with regular expressions that may or may not properly handle quoting or line continuations etc is… not a great idea in my opinion.

    But of course in this particular case, because systemd makes the /dev/log journal/syslog socket a dependency of every unit by default, there is no need to encode this dependency at all.

    Anyway if you really wanted to you could write this script as a generator and have it put a drop-in in /run/systemd/system/postgres.service.d. But… why?

    • Okay, I'll rephrase the question a bit and ask it again.

      Imagine that you have a service that has a configuration-dependent dependency on rsyslog. For whatever reason, journald's not an option... maybe it's simply not installed, or this service depends on rsyslog-specific behaviors that journald simply doesn't replicate. It doesn't matter why this configuration-dependent dependency exists, it simply exists and there's no workaround.

      Assuming that the rsyslog service is named 'rsyslog', the service with the dependency is named 'stupid-service', the configuration file is named '/etc/stupid-service/stupid-service.conf', and the configuration option to search that config file for is 'logging = syslog', what would the systemd service file generator look like to make 'stupid-service' depend on 'rsyslog' if and only if that config file contains 'logging = syslog'?

      You appear to have worked with these service file generators, which is why I'm asking. I expect you'd know what the generator to accomplish this trivial task would look like, or if it was even possible with generators.

      Also:

      > Yeah parsing config files with regular expressions that may or may not properly handle quoting or line continuations

      Nah, this is substring matching and column-cutting. The only use of regexes ("#.*") is to remove comments. Go check out the format docs for the PostgreSQL config file. [0] It's pretty basic and straightforward.

      [0] <https://www.postgresql.org/docs/17/config-setting.html#CONFI...>

      2 replies →