mirror of https://github.com/CIRCL/lookyloo
				
				
				
			chg: Make the website start a normal start script
							parent
							
								
									8918b11a7f
								
							
						
					
					
						commit
						85e43fc677
					
				| 
						 | 
					@ -1,43 +1,40 @@
 | 
				
			||||||
#!/usr/bin/env python3
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
# -*- coding: utf-8 -*-
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import time
 | 
					import logging
 | 
				
			||||||
import signal
 | 
					
 | 
				
			||||||
from subprocess import Popen
 | 
					from subprocess import Popen
 | 
				
			||||||
from lookyloo.helpers import get_homedir, shutdown_requested, set_running, unset_running, get_config
 | 
					
 | 
				
			||||||
 | 
					from lookyloo.abstractmanager import AbstractManager
 | 
				
			||||||
 | 
					from lookyloo.helpers import get_homedir, get_config, set_running
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					logging.basicConfig(format='%(asctime)s %(name)s %(levelname)s:%(message)s',
 | 
				
			||||||
 | 
					                    level=logging.INFO, datefmt='%I:%M:%S')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Website(AbstractManager):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, loglevel: int=logging.INFO):
 | 
				
			||||||
 | 
					        super().__init__(loglevel)
 | 
				
			||||||
 | 
					        self.script_name = 'website'
 | 
				
			||||||
 | 
					        self.process = self._launch_website()
 | 
				
			||||||
 | 
					        set_running(self.script_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _launch_website(self):
 | 
				
			||||||
 | 
					        website_dir = get_homedir() / 'website'
 | 
				
			||||||
 | 
					        ip = get_config('generic', 'website_listen_ip')
 | 
				
			||||||
 | 
					        port = get_config('generic', 'website_listen_port')
 | 
				
			||||||
 | 
					        return Popen(['gunicorn', '-w', '10',
 | 
				
			||||||
 | 
					                      '--graceful-timeout', '2', '--timeout', '300',
 | 
				
			||||||
 | 
					                      '-b', f'{ip}:{port}',
 | 
				
			||||||
 | 
					                      '--log-level', 'info',
 | 
				
			||||||
 | 
					                      'web:app'],
 | 
				
			||||||
 | 
					                     cwd=website_dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def main():
 | 
					def main():
 | 
				
			||||||
    website_dir = get_homedir() / 'website'
 | 
					    w = Website()
 | 
				
			||||||
    ip = get_config('generic', 'website_listen_ip')
 | 
					    w.run(sleep_in_sec=10)
 | 
				
			||||||
    port = get_config('generic', 'website_listen_port')
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        p = Popen(['gunicorn', '-w', '10',
 | 
					 | 
				
			||||||
                   '--graceful-timeout', '2', '--timeout', '300',
 | 
					 | 
				
			||||||
                   '-b', f'{ip}:{port}',
 | 
					 | 
				
			||||||
                   '--log-level', 'info',
 | 
					 | 
				
			||||||
                   'web:app'],
 | 
					 | 
				
			||||||
                  cwd=website_dir)
 | 
					 | 
				
			||||||
        set_running('website')
 | 
					 | 
				
			||||||
        while True:
 | 
					 | 
				
			||||||
            if p.poll() is not None:
 | 
					 | 
				
			||||||
                print('gunicorn stopped itself.')
 | 
					 | 
				
			||||||
                break
 | 
					 | 
				
			||||||
            if shutdown_requested():
 | 
					 | 
				
			||||||
                print('"shutdown" key present in the cache database.')
 | 
					 | 
				
			||||||
                break
 | 
					 | 
				
			||||||
            time.sleep(1)
 | 
					 | 
				
			||||||
    except KeyboardInterrupt:
 | 
					 | 
				
			||||||
        print('Website killed by user.')
 | 
					 | 
				
			||||||
    finally:
 | 
					 | 
				
			||||||
        print('Shutting down website.')
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            # Killing everything if possible.
 | 
					 | 
				
			||||||
            p.send_signal(signal.SIGWINCH)
 | 
					 | 
				
			||||||
            p.send_signal(signal.SIGTERM)
 | 
					 | 
				
			||||||
        except Exception:
 | 
					 | 
				
			||||||
            pass
 | 
					 | 
				
			||||||
        unset_running('website')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from abc import ABC
 | 
					from abc import ABC
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
 | 
					import signal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .helpers import long_sleep, shutdown_requested, set_running, unset_running
 | 
					from .helpers import long_sleep, shutdown_requested, set_running, unset_running
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +17,7 @@ class AbstractManager(ABC):
 | 
				
			||||||
        self.logger = logging.getLogger(f'{self.__class__.__name__}')
 | 
					        self.logger = logging.getLogger(f'{self.__class__.__name__}')
 | 
				
			||||||
        self.logger.setLevel(loglevel)
 | 
					        self.logger.setLevel(loglevel)
 | 
				
			||||||
        self.logger.info(f'Initializing {self.__class__.__name__}')
 | 
					        self.logger.info(f'Initializing {self.__class__.__name__}')
 | 
				
			||||||
 | 
					        self.process = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def _to_run_forever_async(self) -> None:
 | 
					    async def _to_run_forever_async(self) -> None:
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
| 
						 | 
					@ -25,16 +27,36 @@ class AbstractManager(ABC):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def run(self, sleep_in_sec: int) -> None:
 | 
					    def run(self, sleep_in_sec: int) -> None:
 | 
				
			||||||
        self.logger.info(f'Launching {self.__class__.__name__}')
 | 
					        self.logger.info(f'Launching {self.__class__.__name__}')
 | 
				
			||||||
        while True:
 | 
					        try:
 | 
				
			||||||
            if shutdown_requested():
 | 
					            while True:
 | 
				
			||||||
                break
 | 
					                if shutdown_requested():
 | 
				
			||||||
            try:
 | 
					                    break
 | 
				
			||||||
                set_running(self.script_name)
 | 
					                try:
 | 
				
			||||||
                self._to_run_forever()
 | 
					                    if self.process:
 | 
				
			||||||
            except Exception:
 | 
					                        if self.process.poll() is not None:
 | 
				
			||||||
                self.logger.exception(f'Something went terribly wrong in {self.__class__.__name__}.')
 | 
					                            self.logger.critical(f'Unable to start {self.script_name}.')
 | 
				
			||||||
            finally:
 | 
					                            break
 | 
				
			||||||
                unset_running(self.script_name)
 | 
					                    else:
 | 
				
			||||||
            if not long_sleep(sleep_in_sec):
 | 
					                        set_running(self.script_name)
 | 
				
			||||||
                break
 | 
					                        self._to_run_forever()
 | 
				
			||||||
        self.logger.info(f'Shutting down {self.__class__.__name__}')
 | 
					                except Exception:
 | 
				
			||||||
 | 
					                    self.logger.exception(f'Something went terribly wrong in {self.__class__.__name__}.')
 | 
				
			||||||
 | 
					                finally:
 | 
				
			||||||
 | 
					                    if not self.process:
 | 
				
			||||||
 | 
					                        # self.process means we run an external script, all the time,
 | 
				
			||||||
 | 
					                        # do not unset between sleep.
 | 
				
			||||||
 | 
					                        unset_running(self.script_name)
 | 
				
			||||||
 | 
					                if not long_sleep(sleep_in_sec):
 | 
				
			||||||
 | 
					                    break
 | 
				
			||||||
 | 
					        except KeyboardInterrupt:
 | 
				
			||||||
 | 
					            self.logger.warning(f'{self.script_name} killed by user.')
 | 
				
			||||||
 | 
					        finally:
 | 
				
			||||||
 | 
					            if self.process:
 | 
				
			||||||
 | 
					                try:
 | 
				
			||||||
 | 
					                    # Killing everything if possible.
 | 
				
			||||||
 | 
					                    self.process.send_signal(signal.SIGWINCH)
 | 
				
			||||||
 | 
					                    self.process.send_signal(signal.SIGTERM)
 | 
				
			||||||
 | 
					                except Exception:
 | 
				
			||||||
 | 
					                    pass
 | 
				
			||||||
 | 
					            unset_running(self.script_name)
 | 
				
			||||||
 | 
					            self.logger.info(f'Shutting down {self.__class__.__name__}')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue