mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
launchd: Handle deprecated APIs in plistlib (#1554)
Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
parent
620dd7e8da
commit
6c88b69d6f
2 changed files with 43 additions and 7 deletions
2
changelogs/fragments/1552_launchd.yml
Normal file
2
changelogs/fragments/1552_launchd.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
bugfixes:
|
||||||
|
- launchd - handle deprecated APIs like ``readPlist`` and ``writePlist`` in ``plistlib`` (https://github.com/ansible-collections/community.general/issues/1552).
|
|
@ -114,6 +114,7 @@ from abc import ABCMeta, abstractmethod
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils._text import to_native
|
||||||
|
|
||||||
|
|
||||||
class ServiceState:
|
class ServiceState:
|
||||||
|
@ -142,6 +143,9 @@ class Plist:
|
||||||
|
|
||||||
state, pid, dummy, dummy = LaunchCtlList(module, service).run()
|
state, pid, dummy, dummy = LaunchCtlList(module, service).run()
|
||||||
|
|
||||||
|
# Check if readPlist is available or not
|
||||||
|
self.old_plistlib = hasattr(plistlib, 'readPlist')
|
||||||
|
|
||||||
self.__file = self.__find_service_plist(service)
|
self.__file = self.__find_service_plist(service)
|
||||||
if self.__file is None:
|
if self.__file is None:
|
||||||
msg = 'Unable to infer the path of %s service plist file' % service
|
msg = 'Unable to infer the path of %s service plist file' % service
|
||||||
|
@ -150,7 +154,8 @@ class Plist:
|
||||||
module.fail_json(msg=msg)
|
module.fail_json(msg=msg)
|
||||||
self.__update(module)
|
self.__update(module)
|
||||||
|
|
||||||
def __find_service_plist(self, service_name):
|
@staticmethod
|
||||||
|
def __find_service_plist(service_name):
|
||||||
"""Finds the plist file associated with a service"""
|
"""Finds the plist file associated with a service"""
|
||||||
|
|
||||||
launchd_paths = [
|
launchd_paths = [
|
||||||
|
@ -176,9 +181,38 @@ class Plist:
|
||||||
self.__handle_param_enabled(module)
|
self.__handle_param_enabled(module)
|
||||||
self.__handle_param_force_stop(module)
|
self.__handle_param_force_stop(module)
|
||||||
|
|
||||||
|
def __read_plist_file(self, module):
|
||||||
|
service_plist = {}
|
||||||
|
if self.old_plistlib:
|
||||||
|
return plistlib.readPlist(self.__file)
|
||||||
|
|
||||||
|
# readPlist is deprecated in Python 3 and onwards
|
||||||
|
try:
|
||||||
|
with open(self.__file, 'rb') as plist_fp:
|
||||||
|
service_plist = plistlib.load(plist_fp)
|
||||||
|
except Exception as e:
|
||||||
|
module.fail_json(msg="Failed to read plist file "
|
||||||
|
"%s due to %s" % (self.__file, to_native(e)))
|
||||||
|
return service_plist
|
||||||
|
|
||||||
|
def __write_plist_file(self, module, service_plist=None):
|
||||||
|
if not service_plist:
|
||||||
|
service_plist = {}
|
||||||
|
|
||||||
|
if self.old_plistlib:
|
||||||
|
plistlib.writePlist(service_plist, self.__file)
|
||||||
|
return
|
||||||
|
# writePlist is deprecated in Python 3 and onwards
|
||||||
|
try:
|
||||||
|
with open(self.__file, 'wb') as plist_fp:
|
||||||
|
plistlib.dump(service_plist, plist_fp)
|
||||||
|
except Exception as e:
|
||||||
|
module.fail_json(msg="Failed to write to plist file "
|
||||||
|
" %s due to %s" % (self.__file, to_native(e)))
|
||||||
|
|
||||||
def __handle_param_enabled(self, module):
|
def __handle_param_enabled(self, module):
|
||||||
if module.params['enabled'] is not None:
|
if module.params['enabled'] is not None:
|
||||||
service_plist = plistlib.readPlist(self.__file)
|
service_plist = self.__read_plist_file(module)
|
||||||
|
|
||||||
# Enable/disable service startup at boot if requested
|
# Enable/disable service startup at boot if requested
|
||||||
# Launchctl does not expose functionality to set the RunAtLoad
|
# Launchctl does not expose functionality to set the RunAtLoad
|
||||||
|
@ -191,12 +225,12 @@ class Plist:
|
||||||
|
|
||||||
# Update the plist with one of the changes done.
|
# Update the plist with one of the changes done.
|
||||||
if not module.check_mode:
|
if not module.check_mode:
|
||||||
plistlib.writePlist(service_plist, self.__file)
|
self.__write_plist_file(module, service_plist)
|
||||||
self.__changed = True
|
self.__changed = True
|
||||||
|
|
||||||
def __handle_param_force_stop(self, module):
|
def __handle_param_force_stop(self, module):
|
||||||
if module.params['force_stop'] is not None:
|
if module.params['force_stop'] is not None:
|
||||||
service_plist = plistlib.readPlist(self.__file)
|
service_plist = self.__read_plist_file(module)
|
||||||
|
|
||||||
# Set KeepAlive to false in case force_stop is defined to avoid
|
# Set KeepAlive to false in case force_stop is defined to avoid
|
||||||
# that the service gets restarted when stopping was requested.
|
# that the service gets restarted when stopping was requested.
|
||||||
|
@ -207,7 +241,7 @@ class Plist:
|
||||||
|
|
||||||
# Update the plist with one of the changes done.
|
# Update the plist with one of the changes done.
|
||||||
if not module.check_mode:
|
if not module.check_mode:
|
||||||
plistlib.writePlist(service_plist, self.__file)
|
self.__write_plist_file(module, service_plist)
|
||||||
self.__changed = True
|
self.__changed = True
|
||||||
|
|
||||||
def is_changed(self):
|
def is_changed(self):
|
||||||
|
@ -325,7 +359,7 @@ class LaunchCtlStart(LaunchCtlTask):
|
||||||
def runCommand(self):
|
def runCommand(self):
|
||||||
state, dummy, dummy, dummy = self.get_state()
|
state, dummy, dummy, dummy = self.get_state()
|
||||||
|
|
||||||
if state == ServiceState.STOPPED or state == ServiceState.LOADED:
|
if state in (ServiceState.STOPPED, ServiceState.LOADED):
|
||||||
self.reload()
|
self.reload()
|
||||||
self.start()
|
self.start()
|
||||||
elif state == ServiceState.STARTED:
|
elif state == ServiceState.STARTED:
|
||||||
|
@ -361,7 +395,7 @@ class LaunchCtlStop(LaunchCtlTask):
|
||||||
if self._plist.is_changed():
|
if self._plist.is_changed():
|
||||||
self.reload()
|
self.reload()
|
||||||
self.stop()
|
self.stop()
|
||||||
elif state == ServiceState.STARTED or state == ServiceState.LOADED:
|
elif state in (ServiceState.STARTED, ServiceState.LOADED):
|
||||||
if self._plist.is_changed():
|
if self._plist.is_changed():
|
||||||
self.reload()
|
self.reload()
|
||||||
self.stop()
|
self.stop()
|
||||||
|
|
Loading…
Add table
Reference in a new issue