satella.os package

Submodules

satella.os.daemon module

satella.os.daemon.daemonize(exit_via=<built-in function exit>, redirect_std_to_devnull=True, uid=None, gid=None)

Make this process into a daemon.

This entails:

  • umask 0

  • forks twice

  • be the child of init

  • becomes session leader

  • changes root directory to /

  • closes stdin, stdout, stderr

  • (option) redirects stdin, stdout, stderr to /dev/null

Refer - “Advanced Programming in the UNIX Environment” 13.3

Parameters:
  • exit_via (Callable) – callable used to terminate process

  • redirect_std_to_devnull (bool) – whether to redirect stdin, stdout and stderr to /dev/null

  • uid (Optional[int]) – User to set (via seteuid). Default - this won’t be done. You can pass either user name as string or UID.

  • gid (Optional[int]) – Same as UID, but for groups. These will be resolved too.

Raises:
  • KeyError – uid/gid was passed as string, but getpwnam() failed

  • OSError – platform is Windows

satella.os.misc module

satella.os.misc.is_running_as_root()

Is this process running as root?

Checks whether effective UID is 0

Returns:

bool

Raises:

OSError – called on Windows!

Return type:

bool

satella.os.misc.safe_listdir(directory)

Return elements of directory.

Returns nothing (an empty iterator) if directory does not exist, or is not a directory.

Parameters:

directory (str) – path to the element to examine.

Return type:

Iterator[str]

satella.os.misc.suicide(kill_entire_pg=True)

Kill self.

Parameters:

kill_entire_pg (bool) – whether to kill entire PG if a session leader. Won’t work on Windows.

Return type:

None

satella.os.misc.whereis(name)

Looking in PATH return a sequence of executable files having provided name.

Additionally, on Windows, it will use PATHEXT.

Note

on Windows name is supposed to be without extension!

Parameters:

name (str) – name of the executable to search for

Returns:

an iterator of absolute paths to given executable

Return type:

Iterator[str]

satella.os.pidlock module

class satella.os.pidlock.PIDFileLock(pid_file, base_dir='/var/run')

Bases: object

Acquire a PID lock file.

Usage:

>>> with PIDFileLock('my_service.pid'):
>>>     ... rest of code ..

Any alternatively

>>> pid_lock = PIDFileLock('my_service.pid')
>>> pid_lock.acquire()
>>> ...
>>> pid_lock.release()

The constructor doesn’t throw, __enter__ or acquire() does, one of:

  • ResourceLocked - lock is already held. This has two attributes - pid (int), the PID of holder,

    and is_alive (bool) - whether the holder is an alive process

Initialize a PID lock file object

Parameters:
  • pid_file – rest of path

  • base_dir – base lock directory

acquire()

Acquire the PID lock

Raises:

ResourceLocked – if lock if held

Return type:

None

file_no
path
release()

Free the lock :raises RuntimeError: lock not acquired

Return type:

None

satella.os.signals module

satella.os.signals.hang_until_sig(extra_signals=None, sleep_interval=2)

Will hang until this process receives SIGTERM or SIGINT. If you pass extra signal IDs (signal.SIG*) with extra_signals, then also on those signals this call will release.

Periodic sleeping with polling was chosen as the approach of choice, as pause() seemed to work a bit shakily multi-platform.

Parameters:
  • extra_signals (Optional[Sequence[int]]) – a list of extra signals to listen to

  • sleep_interval (float) – amount of time to sleep between checking for termination condition.

Return type:

None

Module contents

class satella.os.PIDFileLock(pid_file, base_dir='/var/run')

Bases: object

Acquire a PID lock file.

Usage:

>>> with PIDFileLock('my_service.pid'):
>>>     ... rest of code ..

Any alternatively

>>> pid_lock = PIDFileLock('my_service.pid')
>>> pid_lock.acquire()
>>> ...
>>> pid_lock.release()

The constructor doesn’t throw, __enter__ or acquire() does, one of:

  • ResourceLocked - lock is already held. This has two attributes - pid (int), the PID of holder,

    and is_alive (bool) - whether the holder is an alive process

Initialize a PID lock file object

Parameters:
  • pid_file – rest of path

  • base_dir – base lock directory

acquire()

Acquire the PID lock

Raises:

ResourceLocked – if lock if held

Return type:

None

file_no
path
release()

Free the lock :raises RuntimeError: lock not acquired

Return type:

None

satella.os.daemonize(exit_via=<built-in function exit>, redirect_std_to_devnull=True, uid=None, gid=None)

Make this process into a daemon.

This entails:

  • umask 0

  • forks twice

  • be the child of init

  • becomes session leader

  • changes root directory to /

  • closes stdin, stdout, stderr

  • (option) redirects stdin, stdout, stderr to /dev/null

Refer - “Advanced Programming in the UNIX Environment” 13.3

Parameters:
  • exit_via (Callable) – callable used to terminate process

  • redirect_std_to_devnull (bool) – whether to redirect stdin, stdout and stderr to /dev/null

  • uid (Optional[int]) – User to set (via seteuid). Default - this won’t be done. You can pass either user name as string or UID.

  • gid (Optional[int]) – Same as UID, but for groups. These will be resolved too.

Raises:
  • KeyError – uid/gid was passed as string, but getpwnam() failed

  • OSError – platform is Windows

satella.os.hang_until_sig(extra_signals=None, sleep_interval=2)

Will hang until this process receives SIGTERM or SIGINT. If you pass extra signal IDs (signal.SIG*) with extra_signals, then also on those signals this call will release.

Periodic sleeping with polling was chosen as the approach of choice, as pause() seemed to work a bit shakily multi-platform.

Parameters:
  • extra_signals (Optional[Sequence[int]]) – a list of extra signals to listen to

  • sleep_interval (float) – amount of time to sleep between checking for termination condition.

Return type:

None

satella.os.is_running_as_root()

Is this process running as root?

Checks whether effective UID is 0

Returns:

bool

Raises:

OSError – called on Windows!

Return type:

bool

satella.os.safe_listdir(directory)

Return elements of directory.

Returns nothing (an empty iterator) if directory does not exist, or is not a directory.

Parameters:

directory (str) – path to the element to examine.

Return type:

Iterator[str]

satella.os.suicide(kill_entire_pg=True)

Kill self.

Parameters:

kill_entire_pg (bool) – whether to kill entire PG if a session leader. Won’t work on Windows.

Return type:

None

satella.os.whereis(name)

Looking in PATH return a sequence of executable files having provided name.

Additionally, on Windows, it will use PATHEXT.

Note

on Windows name is supposed to be without extension!

Parameters:

name (str) – name of the executable to search for

Returns:

an iterator of absolute paths to given executable

Return type:

Iterator[str]