2 Mostly utility functions Salmon uses internally that don't
3 really belong anywhere else in the modules. This module
4 is kind of a dumping ground, so if you find something that
5 can be improved feel free to work up a patch.
13 from lockfile
import pidlockfile
16 from salmon
import routing
, server
21 def import_settings(boot_also
, boot_module
="config.boot"):
22 """Returns the current settings module, there is no harm in calling it
25 The location of the settings module can be control via
26 ``SALMON_SETTINGS_MODULE``"""
30 settings_module
= os
.getenv("SALMON_SETTINGS_MODULE", "config.settings")
31 settings
= importlib
.import_module(settings_module
)
34 importlib
.import_module(boot_module
)
39 def daemonize(pid
, chdir
, chroot
, umask
, files_preserve
=None, do_open
=True):
41 Uses python-daemonize to do all the junk needed to make a
42 server a server. It supports all the features daemonize
43 has, except that chroot probably won't work at all without
44 some serious configuration on the system.
46 logs_dir
= os
.path
.join(chdir
, "logs")
47 pid_dir
= os
.path
.join(chdir
, os
.path
.dirname(pid
) or ".")
49 logs_dir
= os
.path
.join(chroot
, logs_dir
)
50 pid_dir
= os
.path
.join(chroot
, pid_dir
)
51 if not os
.path
.exists(logs_dir
):
53 if not os
.path
.exists(pid_dir
):
56 context
= daemon
.DaemonContext()
57 context
.pidfile
= pidlockfile
.PIDLockFile(pid
)
58 context
.stdout
= open(os
.path
.join(logs_dir
, "salmon.out"), "a+")
59 context
.stderr
= open(os
.path
.join(logs_dir
, "salmon.err"), "a+")
60 context
.files_preserve
= files_preserve
or []
61 context
.working_directory
= os
.path
.expanduser(chdir
)
64 context
.chroot_directory
= os
.path
.expanduser(chroot
)
74 def drop_priv(uid
, gid
):
76 Changes the uid/gid to the two given, you should give utils.daemonize
77 0,0 for the uid,gid so that it becomes root, which will allow you to then
80 logging
.debug("Dropping to uid=%d, gid=%d", uid
, gid
)
81 daemon
.daemon
.change_process_owner(uid
, gid
)
82 logging
.debug("Now running as uid=%d, gid=%d", os
.getgid(), os
.getuid())
85 def make_fake_settings(host
, port
):
87 When running as a logging server we need a fake settings module to work with
88 since the logging server can be run in any directory, so there may not be
89 a settings module to import.
94 logging
.basicConfig(filename
="logs/logger.log", level
=logging
.DEBUG
)
95 routing
.Router
.load(['salmon.handlers.log', 'salmon.handlers.queue'])
96 settings
= imp
.new_module('settings')
97 settings
.receiver
= server
.SMTPReceiver(host
, port
)
99 logging
.info("Logging mode enabled, will not send email to anyone, just log.")
104 def check_for_pid(pid
, force
):
105 """Checks if a pid file is there, and if it is sys.exit. If force given
106 then it will remove the file and not exit if it's there."""
107 if os
.path
.exists(pid
):
109 print("PID file %s exists, so assuming Salmon is running. Give --force to force it to start." % pid
)
115 def start_server(pid
, force
, chroot
, chdir
, uid
, gid
, umask
, settings_loader
, debug
, daemon_proc
):
117 Starts the server by doing a daemonize and then dropping priv
118 accordingly. It will only drop to the uid/gid given if both are given.
120 check_for_pid(pid
, force
)
122 if not debug
and daemon_proc
:
123 daemonize(pid
, chdir
, chroot
, umask
, files_preserve
=[])
125 sys
.path
.append(os
.getcwd())
127 settings
= settings_loader()
132 logging
.warning("You probably meant to give a uid and gid, but you gave: uid=%r, gid=%r. "
133 "Will not change to any user.", uid
, gid
)
135 settings
.receiver
.start()
138 print("Salmon started in debug mode. ctrl-c to quit...")
143 except KeyboardInterrupt:
144 # hard quit, since receiver starts a new thread. dirty but works