Suspect some of those line breaks in the xml might cause some
problems. Have attached separately. Hopefully that will work.
Cheers,
Jay
On Jan 18, 2007, at 2:06 PM, Jay wrote:
Hi James,
Thanks as always! Disabling <background/> did the trick!
Here's a first draft of the write up. I'm sure I've taken something
for granted. Please let me know your thoughts and I'll polish it up
as desired.
Cheers,
Jay
======================================================================
======
launchd is considered to be the recommended method for launching
and managing processes on OS X since 10.4. launchd can launch a
process automatically startup, when a file is modified, when the
contents of a folder are modified, at any given date and time and
more.
=================================================
CONFIGURING YOUR LAUNCHD JOB
=================================================
In my case, I wanted PyMSNt to launch only if and when the jabberd
(iChat Server) process was active. This was possible by setting
launchd to monitor jabberd's run directory, which contains .pid
files when jabberd is active, and is empty otherwise. Ideally, I
wanted to have PyMSNt shut down when the jabberd service stopped,
but this does not seem possible. So, nonetheless, I created a
launchd property list (plist) file named net.cjb.delx.pymsnt.plist
and stored it in the root Library of my server's drive in /Library/
LaunchDaemons/
The contents of this file are as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>net.cjb.delx.pymsnt</string>
<key>OnDemand</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/python</string>
<string>/var/jabber/modules/pymsnt/PyMSNt.py</string>
</array>
<key>UserName</key>
<string>jabber</string>
<key>QueueDirectories</key>
<array>
<string>/var/jabber/run/</string>
</array>
</dict>
</plist>
While these options are all detailed with "man launchd.plist",
let's go through the options chosen and why:
1. Label
This must be unique across any other launchd plist files used in
your system. Apple has preinstalled plenty of these already (see /
System/Library/LaunchDaemons for examples). Apple seems to
recommend reverse domain name style naming conventions, which I've
followed. (James, is that the best label, or should I recommend
org.jabber.pymsnt.plist or something else?)
2. OnDemand
This indicates that the process should not launch at startup, but
rather based on another event. This is because I've chosen to
activate PyMSNt based on the activeness of jabberd. I'll give
another plist example below of how you can rather simply set PyMSNt
to be running at startup continuously instead.
3. Program Arguments
This is an array of the process you are calling along with any
arguments needed. You can't have spaces in these, so when you need
a space, just add another <string></string>. For example, if you
wanted to run a launchd job to delete a directory, this key's array
would look as such:
<key>ProgramArguments</key>
<array>
<string>/bin/rm</string>
<string>-rf</string>
<string>/what/ever/directory/you/choose</string>
</array>
4. UserName
By default in OS X Server, jabberd and all its directories are
owned and used by the user, jabber. When I installed PyMSNt, I
placed it in the existing directory structure in what I felt was a
logical location (/var/jabber/modules/pymsnt/), and chown'd the
contents to the jabber user. So, in my case and probably yours, you
want PyMSNt to be owned by the jabber user for access to the same
directory structure (for storage of spool files, etc.)
5. QueueDirectories
This is the directive that relates to the OnDemand key. Defined in
the man page as, "this key will watch the paths for modifications.
The job will only be started if the path is a directory and the
directory is not empty." When jabberd is not running, this
directory is empty and when it is running, two files are present
(jabber.pid and proxy65.pid), and this then triggers the launch of
PyMSNT.
=================================================
IMPORTANT CHANGE TO PYMSNT CONFIG.XML REQUIRED
=================================================
There is a stipulation in the launchd manual that states:
" daemon or agent launched by launchd MUST NOT do the following in
the process directly launched by launchd: * fork(2) and have the
parent process exit(3) or _exit(2)"
By default, PyMSNt is configured to fork. This can be seen in the
config.xml file in the directive:
<!-- If set, the transport will background itself when run -->
<background/>
You need to comment our or delete <background/> as such:
<!-- If set, the transport will background itself when run -->
<!-- <background/> -->
Otherwise, you will notice the following type of errors in your
system.log when we load the job:
Jan 18 13:38:02 imac launchd: net.cjb.delx.pymsnt: exited with exit
code: 1
Jan 18 13:38:02 imac launchd: net.cjb.delx.pymsnt: 9 more failures
without living at least 60 seconds will cause job removal
Interestingly, when this happens, PyMSNt is still launched and
working, but launchd isn't going to monitor it for you and isn't
going to be able to unload it for you when desired.
=================================================
LOADING YOUR LAUNCHD JOB
=================================================
Finally, we need to load the launchd job. This will automatically
happen at startup or can manually be done with the following command:
sudo launchctl load /Library/LaunchDaemons/net.cjb.delx.pymsnt.plist
At this point, if there are any contents in /var/jabber/run/,
PyMSNt will start up right away. I personally use this line to
check if it is running:
ps -auxx | grep python
If you see something like this in the response, PyMSNt is running:
jabber 8390 0.0 0.8 37156 8388 ?? Ss 1:39PM
0:00.83 /usr/bin/python /var/jabber/modules/pymsnt/PyMSNt.py
If there are no contents in /var/jabber/run (jabberd is obviously
not running), start the iChat Server with:
sudo serveradmin start jabber
At this point, issue another "ps -auxx | grep python" and you
should see PyMSNt is now running. Unfortunately, as mentioned,
stopping the iChat Server is not enough to stop PyMSNt, but issuing
an unload command to launchd will gently stop it:
sudo launchctl unload /Library/LaunchDaemons/net.cjb.delx.pymsnt.plist
Note that even if you have unloaded the job, the next time you
restart, the launchd job will be reactivated. If you would like to
disable the launchd job and PyMSNt until further notice, you can
issue an unload command with the -w flag:
sudo launchctl unload -w /Library/LaunchDaemons/
net.cjb.delx.pymsnt.plist
All this does in actuality is add the following key to your plist:
<key>Disabled</key>
<true/>
This means the job will NOT be loaded at startup. Reloading it with
the -w flag removes that directive:
sudo launchctl load -w /Library/LaunchDaemons/
net.cjb.delx.pymsnt.plist
Of course, you can always do this edit manually.
=================================================
CONFIGURING AN ALTERNATIVE LAUNCHD JOB
=================================================
Alternatively, as mentioned, you can instead use launchd to simply
launch PyMSNt at startup so it's ready and waiting for the jabber
server. The plist file would be different as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>net.cjb.delx.pymsnt</string>
<key>OnDemand</key>
<false/>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/python</string>
<string>/var/jabber/modules/pymsnt/PyMSNt.py</string>
</array>
<key>UserName</key>
<string>jabber</string>
</dict>
</plist>
The differences are minimal. OnDemans is set to false, and
QueueDirectories is no longer needed. Choose your method as desired!
======================================================================
======
On Jan 18, 2007, at 1:05 PM, James Bunton wrote:
On 17/01/2007, at 5:00 PM, Jay wrote:
Hi All,
I've been using PyMSNt with OS X Server's jabber server
implementation for over a year now quite successfully, with full
file transfer and avatar support. Many thanks to James and
everyone else!
I've been looking at ways to get it to start automatically and/or
synchronized with the start and stopping of jabberd, and the
"recommended" method for accomplishing anything like this on OS X
is with the use of something called launchd, which has been
proposed to replace the following components in Apple's unixy OS
X: init, mach_init, xinetd, RC, SystemStarter, watchdog, and cron.
Basically, you setup a launchd job to launch PyMSNt.py based on
any parameters (e.g. at startup, by watching a dir, etc.).
However, my launchd job is failing, and I think it might have
something to do with launchd's expectations of PyMSNt.py. Would
someone be kind enough to let me know if PyMSNt.py matches those
as described:
====================================================================
=
EXPECTATIONS
Daemons or agents managed by launchd are expected to behave
certain ways.
A daemon or agent launched by launchd MUST NOT do the
following in the
process directly launched by launchd:
o fork(2) and have the parent process exit(3) or
_exit(2).
o Call daemon(3)
A daemon or agent launched by launchd SHOULD NOT do the
following as a
part of their startup initialization:
o Setup the user ID or group ID.
o Setup the working directory.
o chroot(2)
o setsid(2)
o Close "stray" file descriptors.
o Change stdio(3) to /dev/null.
o Setup resource limits with setrusage(2).
o Setup priority with setpriority(2).
o Ignore the SIGTERM signal.
A daemon or agent launched by launchd SHOULD:
o Launch on demand given criteria specified in the
XML property
list. More information can be found in launch(3).
o Catch the SIGTERM signal.
====================================================================
=
I'm 99% sure PyMSNt does properly catch the SIGTERM signal, but
unfortunately, that's the extent of my knowledge with regard to
these expectations.
FWIW, my launchd job is simply configured to launch PyMSNt.py at
startup as the jabber user using the following command:
/usr/bin/python /var/jabber/modules/pymsnt/PyMSNt.py
It does successfully start it, but is incapable of monitoring it
(which would be ideal, as it could alter stop it based on other
events)
Any insight would be gratefully appreciated and shared within the
OS X Server community.
Kind regards and thanks,
Jay
I'd double check that you don't have the <background/> option set
in config.xml, because that causes the transport to fork when run.
The transport does set up the working directory, but that is
necessary. I don't know why launchd would forbid that.
It doesn't chroot, or change uid/gid or anything like that, and it
definitely obeys SIGTERM. When it receives SIGTERM it quits, as
expected.
If you figure out how to get all this working it'd be much
appreciated if you could write a little howto and I'll integrate
it with the docs.
Good luck!
---
James
_______________________________________________
py-transports mailing list
[email protected]
http://www.modevia.com/cgi-bin/mailman/listinfo/py-transports
_______________________________________________
py-transports mailing list
[email protected]
http://www.modevia.com/cgi-bin/mailman/listinfo/py-transports
launchd is considered to be the recommended method for launching and managing
processes on OS X since 10.4. launchd can launch a process automatically
startup, when a file is modified, when the contents of a folder are modified,
at any given date and time and more.
=================================================
CONFIGURING YOUR LAUNCHD JOB
=================================================
In my case, I wanted PyMSNt to launch only if and when the jabberd (iChat
Server) process was active. This was possible by setting launchd to monitor
jabberd's run directory, which contains .pid files when jabberd is active, and
is empty otherwise. Ideally, I wanted to have PyMSNt shut down when the jabberd
service stopped, but this does not seem possible. So, nonetheless, I created a
launchd property list (plist) file named net.cjb.delx.pymsnt.plist and stored
it in the root Library of my server's drive in /Library/LaunchDaemons/
The contents of this file are as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>net.cjb.delx.pymsnt</string>
<key>OnDemand</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/python</string>
<string>/var/jabber/modules/pymsnt/PyMSNt.py</string>
</array>
<key>UserName</key>
<string>jabber</string>
<key>QueueDirectories</key>
<array>
<string>/var/jabber/run/</string>
</array>
</dict>
</plist>
While these options are all detailed with "man launchd.plist", let's go through
the options chosen and why:
1. Label
This must be unique across any other launchd plist files used in your system.
Apple has preinstalled plenty of these already (see
/System/Library/LaunchDaemons for examples). Apple seems to recommend reverse
domain name style naming conventions, which I've followed. (James, is that the
best label, or should I recommend org.jabber.pymsnt.plist or something else?)
2. OnDemand
This indicates that the process should not launch at startup, but rather based
on another event. This is because I've chosen to activate PyMSNt based on the
activeness of jabberd. I'll give another plist example below of how you can
rather simply set PyMSNt to be running at startup continuously instead.
3. Program Arguments
This is an array of the process you are calling along with any arguments
needed. You can't have spaces in these, so when you need a space, just add
another <string></string>. For example, if you wanted to run a launchd job to
delete a directory, this key's array would look as such:
<key>ProgramArguments</key>
<array>
<string>/bin/rm</string>
<string>-rf</string>
<string>/what/ever/directory/you/choose</string>
</array>
4. UserName
By default in OS X Server, jabberd and all its directories are owned and used
by the user, jabber. When I installed PyMSNt, I placed it in the existing
directory structure in what I felt was a logical location
(/var/jabber/modules/pymsnt/), and chown'd the contents to the jabber user. So,
in my case and probably yours, you want PyMSNt to be owned by the jabber user
for access to the same directory structure (for storage of spool files, etc.)
5. QueueDirectories
This is the directive that relates to the OnDemand key. Defined in the man page
as, "this key will watch the paths for modifications. The job will only be
started if the path is a directory and the directory is not empty." When
jabberd is not running, this directory is empty and when it is running, two
files are present (jabber.pid and proxy65.pid), and this then triggers the
launch of PyMSNT.
=================================================
IMPORTANT CHANGE TO PYMSNT CONFIG.XML REQUIRED
=================================================
There is a stipulation in the launchd manual that states:
" daemon or agent launched by launchd MUST NOT do the following in the process
directly launched by launchd: * fork(2) and have the parent process exit(3) or
_exit(2)"
By default, PyMSNt is configured to fork. This can be seen in the config.xml
file in the directive:
<!-- If set, the transport will background itself when run -->
<background/>
You need to comment our or delete <background/> as such:
<!-- If set, the transport will background itself when run -->
<!-- <background/> -->
Otherwise, you will notice the following type of errors in your system.log when
we load the job:
Jan 18 13:38:02 imac launchd: net.cjb.delx.pymsnt: exited with exit code: 1
Jan 18 13:38:02 imac launchd: net.cjb.delx.pymsnt: 9 more failures without
living at least 60 seconds will cause job removal
Interestingly, when this happens, PyMSNt is still launched and working, but
launchd isn't going to monitor it for you and isn't going to be able to unload
it for you when desired.
=================================================
LOADING YOUR LAUNCHD JOB
=================================================
Finally, we need to load the launchd job. This will automatically happen at
startup or can manually be done with the following command:
sudo launchctl load /Library/LaunchDaemons/net.cjb.delx.pymsnt.plist
At this point, if there are any contents in /var/jabber/run/, PyMSNt will start
up right away. I personally use this line to check if it is running:
ps -auxx | grep python
If you see something like this in the response, PyMSNt is running:
jabber 8390 0.0 0.8 37156 8388 ?? Ss 1:39PM 0:00.83
/usr/bin/python /var/jabber/modules/pymsnt/PyMSNt.py
If there are no contents in /var/jabber/run (jabberd is obviously not running),
start the iChat Server with:
sudo serveradmin start jabber
At this point, issue another "ps -auxx | grep python" and you should see PyMSNt
is now running. Unfortunately, as mentioned, stopping the iChat Server is not
enough to stop PyMSNt, but issuing an unload command to launchd will gently
stop it:
sudo launchctl unload /Library/LaunchDaemons/net.cjb.delx.pymsnt.plist
Note that even if you have unloaded the job, the next time you restart, the
launchd job will be reactivated. If you would like to disable the launchd job
and PyMSNt until further notice, you can issue an unload command with the -w
flag:
sudo launchctl unload -w /Library/LaunchDaemons/net.cjb.delx.pymsnt.plist
All this does in actuality is add the following key to your plist:
<key>Disabled</key>
<true/>
This means the job will NOT be loaded at startup. Reloading it with the -w flag
removes that directive:
sudo launchctl load -w /Library/LaunchDaemons/net.cjb.delx.pymsnt.plist
Of course, you can always do this edit manually.
=================================================
CONFIGURING AN ALTERNATIVE LAUNCHD JOB
=================================================
Alternatively, as mentioned, you can instead use launchd to simply launch
PyMSNt at startup so it's ready and waiting for the jabber server. The plist
file would be different as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>net.cjb.delx.pymsnt</string>
<key>OnDemand</key>
<false/>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/python</string>
<string>/var/jabber/modules/pymsnt/PyMSNt.py</string>
</array>
<key>UserName</key>
<string>jabber</string>
</dict>
</plist>
The differences are minimal. OnDemans is set to false, and QueueDirectories is
no longer needed. Choose your method as desired!
============================================================================
_______________________________________________
py-transports mailing list
[email protected]
http://www.modevia.com/cgi-bin/mailman/listinfo/py-transports