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 ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils._text import to_native
|
||||
|
||||
|
||||
class ServiceState:
|
||||
|
@ -142,6 +143,9 @@ class Plist:
|
|||
|
||||
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)
|
||||
if self.__file is None:
|
||||
msg = 'Unable to infer the path of %s service plist file' % service
|
||||
|
@ -150,7 +154,8 @@ class Plist:
|
|||
module.fail_json(msg=msg)
|
||||
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"""
|
||||
|
||||
launchd_paths = [
|
||||
|
@ -176,9 +181,38 @@ class Plist:
|
|||
self.__handle_param_enabled(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):
|
||||
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
|
||||
# Launchctl does not expose functionality to set the RunAtLoad
|
||||
|
@ -191,12 +225,12 @@ class Plist:
|
|||
|
||||
# Update the plist with one of the changes done.
|
||||
if not module.check_mode:
|
||||
plistlib.writePlist(service_plist, self.__file)
|
||||
self.__write_plist_file(module, service_plist)
|
||||
self.__changed = True
|
||||
|
||||
def __handle_param_force_stop(self, module):
|
||||
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
|
||||
# that the service gets restarted when stopping was requested.
|
||||
|
@ -207,7 +241,7 @@ class Plist:
|
|||
|
||||
# Update the plist with one of the changes done.
|
||||
if not module.check_mode:
|
||||
plistlib.writePlist(service_plist, self.__file)
|
||||
self.__write_plist_file(module, service_plist)
|
||||
self.__changed = True
|
||||
|
||||
def is_changed(self):
|
||||
|
@ -325,7 +359,7 @@ class LaunchCtlStart(LaunchCtlTask):
|
|||
def runCommand(self):
|
||||
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.start()
|
||||
elif state == ServiceState.STARTED:
|
||||
|
@ -361,7 +395,7 @@ class LaunchCtlStop(LaunchCtlTask):
|
|||
if self._plist.is_changed():
|
||||
self.reload()
|
||||
self.stop()
|
||||
elif state == ServiceState.STARTED or state == ServiceState.LOADED:
|
||||
elif state in (ServiceState.STARTED, ServiceState.LOADED):
|
||||
if self._plist.is_changed():
|
||||
self.reload()
|
||||
self.stop()
|
||||
|
|
Loading…
Reference in a new issue