From 9d98c523db3ac35e1e0f2bc94d0ec390858ae4f1 Mon Sep 17 00:00:00 2001 From: Cody Hiar Date: Tue, 14 Feb 2017 09:06:37 -0700 Subject: Updates --- build/Dockerfile | 8 +++--- daemon_example.py | 84 ++++++++++++++++++++++++++++++++++++++++++------------ long_task.py | 6 ++++ unix_doublefork.py | 8 ------ 4 files changed, 75 insertions(+), 31 deletions(-) create mode 100644 long_task.py diff --git a/build/Dockerfile b/build/Dockerfile index f9e25a8..a23b6da 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -7,11 +7,11 @@ ENV TERM xterm-256color # Update and install RUN apt-get update && apt-get install -y \ htop \ - python-dev \ - python-pip + python3-dev \ + python3-pip -# Add the project requirements -ADD requirements.txt /opt/requirements.txt +# # Add the project requirements +# ADD requirements.txt /opt/requirements.txt # The code should be symlinked to this directory WORKDIR /app diff --git a/daemon_example.py b/daemon_example.py index 0eb3a7f..1ab9376 100755 --- a/daemon_example.py +++ b/daemon_example.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- """Example on how to create a daemon. @@ -7,9 +7,11 @@ from the tests. https://pagure.io/python-daemon/blob/master/f/test/test_runner.py """ +import os +import sys from logging import FileHandler, Formatter, getLogger, info -from os import fork, setsid, getpid -from sys import exit +from os.path import isfile +from signal import SIGINT, SIGTERM, signal from time import sleep @@ -18,46 +20,90 @@ class MyDaemon(object): def __init__(self): """Initialize the paths and the pidfile of the daemon.""" - self.stdin_path = '/dev/null' - self.stdout_path = '/dev/null' - self.stderr_path = '/dev/null' + # Setup logging + log = getLogger() + handler = FileHandler('/var/log/python_daemon.log') + formatter = Formatter('%(asctime)s %(levelname)s %(message)s') + handler.setFormatter(formatter) + log.addHandler(handler) + log.setLevel('INFO') self.pidfile_path = '/var/run/python_daemon.pid' + # Register handlers to exit when we get a kill signal + signal(SIGINT, self.exit_gracefully) + signal(SIGTERM, self.exit_gracefully) + + def exit_gracefully(self, signum, frame): + """Exit Gracefully.""" + info('I died') + self.remove_pidfile() + exit() def create_pidfile(self): + """Create a pidfile for the daemon.""" + info('Creating pid file') with open(self.pidfile_path, mode='w', encoding='utf-8') as a_file: a_file.write(str('{}\n'.format(self.pid))) + def remove_pidfile(self): + """Remove the pidfile.""" + info('Removing pidfile: {}'.format(self.pidfile_path)) + os.remove(self.pidfile_path) + def detach_process(self): """Simple method for daemonizing process.""" - newpid = fork() + newpid = os.fork() if newpid > 0: exit() else: - setsid() - newpid = fork() + os.setsid() + newpid = os.fork() if newpid > 0: exit() else: - self.pid = getpid() - self.create_pidfile() + self.pid = os.getpid() return def run(self): """Entrypoint for the daemon.""" + if isfile(self.pidfile_path): + print('Pidfile already exists, Daemon already running') + exit() + info('Starting up the python daemon.') self.detach_process() - # Setup logging - log = getLogger() - handler = FileHandler('/var/log/python_daemon.log') - formatter = Formatter('%(asctime)s %(levelname)s %(message)s') - handler.setFormatter(formatter) - log.addHandler(handler) - log.setLevel('INFO') + # redirect stdin, stdout and stderr to devnull + f = open(os.devnull, 'w') + sys.stdin = f + sys.stdout = f + sys.stderr = f + # Create the pid file + self.create_pidfile() while True: info('I am alive') sleep(1) + def stop(self): + """Stop a currently running process.""" + try: + with open(self.pidfile_path, encoding='utf-8') as a_file: + pid = a_file.readline() + pid = pid.strip() # Remove whitespace + os.kill(int(pid), SIGTERM) + exit() + except FileNotFoundError: + print('no pidfile found, is the daemon running?') + exit() + # run the daemon if __name__ == '__main__': daemon = MyDaemon() - daemon.run() + if len(sys.argv) <= 1: + print('Usage: ./daemon_example.py \'start|stop\'') + exit() + if sys.argv[1] == 'start': + daemon.run() + exit() + if sys.argv[1] == 'stop': + daemon.stop() + exit() + print('Error: I dont know that command') diff --git a/long_task.py b/long_task.py new file mode 100644 index 0000000..eba74f8 --- /dev/null +++ b/long_task.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +"""A long running task.""" +import time + +time.sleep(2) +print('hi') diff --git a/unix_doublefork.py b/unix_doublefork.py index fc94a42..a98dfbf 100644 --- a/unix_doublefork.py +++ b/unix_doublefork.py @@ -27,11 +27,3 @@ else: else: print_process_info('Child') sys.exit() - -# # POP QUIZ!!!! Why won't this work -# print_process_info('Parent') -# os.setsid() -# print_process_info('Parent') -# newpid = os.fork() -# if newpid == 0: -# print_process_info('Child') -- cgit v1.2.3