0

I know that it is possible to restrict systemd units to a specific host by using the ConditionHost condition in the unit file. This ConditionHost is tested against the result of calling hostname.

What I have not been able to find (but I'm hoping this is possible) is a way to do the same based on a DNS alias. So I'm hoping for a way to start systemd units on hosts where the DNS alias specified in the unit file resolves to the current host.

Background: At the moment we have a series of applications/services, started as systemd services, and grouped into systemd targets. Each service unit file contains a ConditionHost specifying on which host this service should run. The unit files are distributed via RPMs, and all unit files are installed on all hosts. One can now start the same systemd target on all these hosts and systemd will take care of starting the correct services on the correct hosts, based on the hostname. The services are typically accessed by clients using a DNS alias, and not using the hostname directly.

If one of the above hosts breaks, one could easily use a spare with the same configuration, and update the DNS alias accordingly. The inconvenience is, however, that the systemd unit files now also have to be updated to reflect the ConditionHost specification for the affected services.

The idea was that if systemd would be able to use the DNS alias instead of the hostname, it would be enough to 1) update the DNS alias, and 2) restart the systemd target on the replacement machine.

  • 1
    I just wanted to point out that this is usually an anti-pattern, starting services based on external configuration such as DNS aliases, since there are too many things that can go wrong (e.g. temporary network outages while machine is booting, or even as simple as network is still not fully up when you start your service.) If you're looking for a high-availability solution, maybe look at software made for it (such as "heartbeat".) Otherwise, would you care to explain what it is exactly that you're trying to solve/implement? – filbranden Oct 16 '18 at 21:45
0

You could write a wrapper script which executes the service only if your DNS alias check passes. The value to check against can be passed as environmental variable.

Service file:

[Service]
Environment=CONDITION_DNSALIAS=abc
Exec=/path/to/dnsaliascheck-wrapper exec args
...

Wrapper script:

#!/bin/sh
check_dns_alias() {
    # Your logic to check DNS alias here, return 0 for success and 1 otherwise.
    return 0
}

if [ -z "$@" ]; then
    echo "No arguments!"
    return 1
fi

# If CONDITION_DNSALIAS is empty, the check should pass
if [ -z "$CONDITION_DNSALIAS" ] || check_dns_alias ; then
    unset CONDITION_DNSALIAS
    exec "$@"
fi

echo "DNS alias condition not met"
exit 0

You need to write the actual check in check_dns_alias, using CONDITION_DNSALIAS variable to compare against.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.