I tried running crankd.py from the development head today and ran into
an exception dealing with sleep and wake events. I have a one line
patch that appears to resolve the issue, but it appears to be far from
ideal.
I'm using the example "monster" config generated in:
examples/crankd/sample-of-events
I ran crankd in the debugger like so:
/usr/bin/python2.5 -m pdb ~/src/pymacadmin/bin/crankd.py
--config=crankd-config.plist
I then put my Mac 10.6.5 system to sleep
and the traceback is:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pdb.py",
line 1213, in main
pdb._runscript(mainpyfile)
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/pdb.py",
line 1138, in _runscript
self.run(statement, globals=globals_, locals=locals_)
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/bdb.py",
line 366, in run
exec cmd in globals, locals
File "<string>", line 1, in <module>
File "/usr/local/sbin/crankd.py", line 597, in <module>
main()
File "/usr/local/sbin/crankd.py", line 523, in main
AppHelper.runConsoleEventLoop(installInterrupt=True)
File "/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python/PyObjCTools/AppHelper.py",
line 178, in runConsoleEventLoop
File "/usr/local/sbin/crankd.py", line 110, in onNotification_
self.callable(user_info=user_info) # pylint: disable-msg=E1101
File "/usr/local/sbin/crankd.py", line 558, in do_shell
for k, v in kwargs['user_info'].items():
AttributeError: 'NoneType' object has no attribute 'items'
Uncaught exception. Entering post mortem debugging
I just added "if kwargs['user_info']:" at line 558 and everything
seems fine now, but I doubt this is the best way to look before you
leap into a Hash in Python. Any suggestions to improve the patch?
diff -r a1321a52a2cf bin/crankd.py
--- a/bin/crankd.py Mon Oct 18 11:38:30 2010 -0700
+++ b/bin/crankd.py Mon Jan 03 20:05:52 2011 -0800
@@ -555,8 +555,9 @@
child_env['CRANKD_%s' % k.upper()] = str(kwargs[k])
if 'user_info' in kwargs:
- for k, v in kwargs['user_info'].items():
- child_env[create_env_name(k)] = str(v)
+ if kwargs['user_info']:
+ for k, v in kwargs['user_info'].items():
+ child_env[create_env_name(k)] = str(v)
try:
rc = call(command, shell=True, env=child_env)
user_info = kwargs.get("user_info", None)
if hasattr(user_info, items):
…
Which would suggest at the very least that we might want something
like an "elif user_info is not None" clause to log or abort if it ever
receives something which is not a dictionary.