Darwin: function service.running cannot detect 'postgres'
noelmcloughlin opened this issue · 11 comments
On Darwin, salt function service.running returns False despite pillar "postgres.service: postgres" having the correct value.
OS: Darwin 15.6.0
Version: saltstack: stable 2017.7.1 (bottled), HEAD
This is the code:
postgresql-running:
service.running:
- name: {{ postgres.service }}
- enable: True
- reload: True
- watch:
- file: postgresql-pg_hba
But salt-state returns false.
[ERROR ] The named service postgres is not available
...
ID: postgresql-running
Function: service.running
Name: postgres
Result: False
Comment: The named service postgres is not available
Started: 01:40:37.545185
Duration: 1.969 ms
Changes:
The postgres services (daemon, chk, wal, wri, avac,stats) are definitely running.
$ pgrep postgres | wc -l
6
Based on salt.grains.core.py (if grains['kernel'] == Darwin THEN grains['os'] = "MacOS"). So we could update osmap.yaml with 'MacOS' stanza if needed.
Testing with #164 suggests problem resides within salt.state unless 'services' needs some special value. The service is running but salt.state insists otherwise.
Wrong value "service: postgres"
ID: postgresql-running
Function: service.running
Name: postgres
Result: False
Comment: An exception occurred in this state: Traceback (most recent call last):
File "/usr/local/Cellar/saltstack/2017.7.1/libexec/lib/python2.7/site-packages/salt/state.py", line 1837, in call
**cdata['kwargs'])
File "/usr/local/Cellar/saltstack/2017.7.1/libexec/lib/python2.7/site-packages/salt/loader.py", line 1794, in wrapper
return f(*args, **kwargs)
File "/usr/local/Cellar/saltstack/2017.7.1/libexec/lib/python2.7/site-packages/salt/states/service.py", line 887, in mod_watch
__salt__['service.stop'](name)
File "/usr/local/Cellar/saltstack/2017.7.1/libexec/lib/python2.7/site-packages/salt/modules/mac_service.py", line 358, in stop
service = _get_service(name)
File "/usr/local/Cellar/saltstack/2017.7.1/libexec/lib/python2.7/site-packages/salt/modules/mac_service.py", line 147, in _get_service
raise CommandExecutionError('Service not found: {0}'.format(name))
CommandExecutionError: Service not found: postgres
Started: 23:33:06.348267
Duration: 10.496 ms
Changes:
Correct value: "service: postgresql"
ID: postgresql-running
Function: service.running
Name: postgresql
Result: False
Comment: The named service postgresql is not available
Started: 23:38:26.602316
Duration: 2.935 ms
Changes:
Could be environmental problem. Something is not correct but configuration looks correct.
Darwin:
$ brew services start postgresql
==> Successfully started `postgresql` (label: homebrew.mxcl.postgresql)
# ls /Users/danny/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
/Users/danny/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
$ sudo brew services start postgresql
==> Successfully started `postgresql` (label: homebrew.mxcl.postgresql)
$ ls /Library/LaunchDaemons/homebrew.mxcl.postgresql.plist
/Library/LaunchDaemons/homebrew.mxcl.postgresql.plist
service state:
----------
ID: postgresql-running
Function: service.running
Name: postgresql
Result: False
Comment: The named service postgresql is not available
Started: 12:21:18.370843
Duration: 2.087 ms
Changes:
Duration: 2.087 ms
$ brew services list | grep postgre
postgresql started root /Library/LaunchDaemons/homebrew.mxcl.postgresql.plist
$ sudo brew services stop postgresql
Stopping `postgresql`... (might take a while)
==> Successfully stopped `postgresql` (label: homebrew.mxcl.postgresql)
$ ls /Library/LaunchDaemons/homebrew.mxcl.postgresql.plist
ls: /Library/LaunchDaemons/homebrew.mxcl.postgresql.plist: No such file or directory
$ brew services stop postgresql
Stopping `postgresql`... (might take a while)
==> Successfully stopped `postgresql` (label: homebrew.mxcl.postgresql)
$ ls ~/Library/LaunchAgents/homebrew.mxcl.postgresql*
ls: /Users/danny/Library/LaunchAgents/homebrew.mxcl.postgresql*: No such file or directory
$ brew services list | grep postgresql
postgresql stopped
$ ls /usr/local/Cellar/postgresql/9.6.5/homebrew.mxcl.postgresql.plist
/usr/local/Cellar/postgresql/9.6.5/homebrew.mxcl.postgresql.plist
Salt:
$more /usr/local/Cellar/saltstack/2017.7.1/libexec/lib/python2.7/site-packages/salt/modules/mac_service.py
..
def _launchd_paths():
'''
Paths where launchd services can be found
'''
return [
'/Library/LaunchAgents',
'/Library/LaunchDaemons',
'/System/Library/LaunchAgents',
'/System/Library/LaunchDaemons',
]
Formula os mapping:
MacOS:
service: postgresql
pkg: postgresql
pkg_client:
pkg_libpq_dev:
conf_dir: /usr/local/var/postgres
user: _postgres
group: _postgres
prepare_cluster:
command: initdb -D /usr/local/var/postgres/
test: test -f /usr/local/var/postgres/PG_VERSION
user: _postgres
group: _postgres
Have you tried setting the service to homebrew.mxcl.postgresql ?
Yes, but it threw python exception. I also tried adding '/usr/local/Cellar/postgresql/9.6.5/' path to launchd_paths() list since the plist file persists there regardless of service status but no luck either. I think its something silly but cannot see what.
Salt code searches _launchd_paths()
paths listed above for the plist file.
def _available_services():
'''
Return a dictionary of all available services on the system
'''
available_services = dict()
for launch_dir in _launchd_paths():
for root, dirs, files in os.walk(launch_dir):
for file_name in files:
# Must be a plist file
if not file_name.endswith('.plist'):
continue
...
I noticed that too. It also tries to resolve symlinks correctly and discards broken ones, so no problems arise in case of removed packages. I'm thinking maybe this should be enriched (the service detection part) with direct launchctl access. Working with files is one way to do it, but if it's not reliable, salt might benefit from some service manager interaction. I haven't looked at the sources for the windows service management code, but I imagine it's not doing registry or file based discovery there either.
Problem: Brew installs Kegs in the Cellar (/usr/local/Cellar
) but salt does not look there.
Solution: Update salt.modules.mac_services._launchd_path()
adding Cellar.
def _launchd_paths():
'''
Paths where launchd services can be found
'''
return [
'/Library/LaunchAgents',
'/Library/LaunchDaemons',
'/System/Library/LaunchAgents',
'/System/Library/LaunchDaemons',
'/usr/local/Cellar', ##### This is the Keg Cellar
]
Now available_states
dict includes Brew(ed) services:
'homebrew.mxcl.postgresql': {'file_name': 'homebrew.mxcl.postgresql.plist', 'file_path': '/usr/local/Cellar/postgresql/9.6.5/homebrew.mxcl.postgresql.plist', 'plist': {'
RunAtLoad': True, 'WorkingDirectory': '/usr/local', 'Label': 'homebrew.mxcl.postgresql', 'ProgramArguments': ['/usr/local/opt/postgresql/bin/postgres', '-D', '/usr/local/var/postgres'], 'KeepAlive': True, 'StandardErrorPath': '/usr/local/var/log/postgres.log'}},
This dict clearly suggest (''homebrew.mxcl.[salt-formula-service-name]' is the correct salt-formula value for all homebrew(ed) software, apparently @mxcl is the designer behind homebrew. This fixes one issue with mac_services.py module. New issue is exception from salt.service module:
An exception occurred in this state: Traceback (most recent call last):
<<CUT>>
File "/usr/local/Cellar/saltstack/2017.7.1_1/libexec/lib/python2.7/site-packages/salt/states/service.py", line 155, in _enable before_toggle_enable_status = __salt__['service.enabled'](name, **kwargs)
TypeError: enabled() got an unexpected keyword argument 'reload'
Code in service.py
def _enable(name, started, result=True, **kwargs):
<<CUT>>
# Service can be enabled
before_toggle_enable_status = __salt__['service.enabled'](name, **kwargs)
Debugging shows
__salt__['service.enabled']('homebrew.mxcl.postgresql', {'reload': 'True'})
Tomcat works on Darwin (see saltstack-formulas/tomcat-formula/issues/70). Need to port solution to Postgres.
Added support for PostgresAPP upstream package on MacOS: #178
TODO: Homebrew installation of postgres
Homebrew #179