prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Docker container's /tmp doesn't get automatically cleaned
  ## Problem Definition
  
  PyInstaller extracts the files in /tmp every time the backend starts
  In the docker container /tmp is never cleaned which results in an ever-increasing size on every application restart
  
  ## TODO
  
  - [ ] Add /tmp cleanup on start
  
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `packaging/docker/entrypoint.py`
  Content:
  ```
  1 #!/usr/bin/python3
  2 import json
  3 import logging
  4 import os
  5 import subprocess
  6 import time
  7 from pathlib import Path
  8 from typing import Dict, Optional, Any, List
  9 
  10 logger = logging.getLogger('monitor')
  11 logging.basicConfig(level=logging.DEBUG)
  12 
  13 DEFAULT_LOG_LEVEL = 'critical'
  14 
  15 
  16 def load_config_from_file() -> Optional[Dict[str, Any]]:
  17     config_file = Path('/config/rotki_config.json')
  18     if not config_file.exists():
  19         logger.info('no config file provided')
  20         return None
  21 
  22     with open(config_file) as file:
  23         try:
  24             data = json.load(file)
  25             return data
  26         except json.JSONDecodeError as e:
  27             logger.error(e)
  28             return None
  29 
  30 
  31 def load_config_from_env() -> Dict[str, Any]:
  32     loglevel = os.environ.get('LOGLEVEL')
  33     logfromothermodules = os.environ.get('LOGFROMOTHERMODDULES')
  34     sleep_secs = os.environ.get('SLEEP_SECS')
  35     max_size_in_mb_all_logs = os.environ.get('MAX_SIZE_IN_MB_ALL_LOGS')
  36     max_logfiles_num = os.environ.get('MAX_LOGFILES_NUM')
  37 
  38     return {
  39         'loglevel': loglevel,
  40         'logfromothermodules': logfromothermodules,
  41         'sleep_secs': sleep_secs,
  42         'max_logfiles_num': max_logfiles_num,
  43         'max_size_in_mb_all_logs': max_size_in_mb_all_logs,
  44     }
  45 
  46 
  47 def load_config() -> List[str]:
  48     env_config = load_config_from_env()
  49     file_config = load_config_from_file()
  50 
  51     logger.info('loading config from env')
  52 
  53     loglevel = env_config.get('loglevel')
  54     log_from_other_modules = env_config.get('logfromothermodules')
  55     sleep_secs = env_config.get('sleep_secs')
  56     max_logfiles_num = env_config.get('max_logfiles_num')
  57     max_size_in_mb_all_logs = env_config.get('max_size_in_mb_all_logs')
  58 
  59     if file_config is not None:
  60         logger.info('loading config from file')
  61 
  62         if file_config.get('loglevel') is not None:
  63             loglevel = file_config.get('loglevel')
  64 
  65         if file_config.get('logfromothermodules') is not None:
  66             log_from_other_modules = file_config.get('logfromothermodules')
  67 
  68         if file_config.get('sleep-secs') is not None:
  69             sleep_secs = file_config.get('sleep-secs')
  70 
  71         if file_config.get('max_logfiles_num') is not None:
  72             max_logfiles_num = file_config.get('max_logfiles_num')
  73 
  74         if file_config.get('max_size_in_mb_all_logs') is not None:
  75             max_size_in_mb_all_logs = file_config.get('max_size_in_mb_all_logs')
  76 
  77     args = [
  78         '--data-dir',
  79         '/data',
  80         '--logfile',
  81         '/logs/rotki.log',
  82         '--loglevel',
  83         loglevel if loglevel is not None else DEFAULT_LOG_LEVEL,
  84     ]
  85 
  86     if log_from_other_modules is True:
  87         args.append('--logfromothermodules')
  88 
  89     if sleep_secs is not None:
  90         args.append('--sleep-secs')
  91         args.append(str(sleep_secs))
  92 
  93     if max_logfiles_num is not None:
  94         args.append('--max-logfiles-num')
  95         args.append(str(max_logfiles_num))
  96 
  97     if max_size_in_mb_all_logs is not None:
  98         args.append('--max-size-in-mb-all-logs')
  99         args.append(str(max_size_in_mb_all_logs))
  100 
  101     return args
  102 
  103 
  104 base_args = [
  105     '/usr/sbin/rotki',
  106     '--rest-api-port',
  107     '4242',
  108     '--websockets-api-port',
  109     '4243',
  110     '--api-cors',
  111     'http://localhost:*/*,app://.',
  112     '--api-host',
  113     '0.0.0.0',
  114 ]
  115 
  116 config_args = load_config()
  117 cmd = base_args + config_args
  118 
  119 logger.info('starting rotki backend')
  120 
  121 rotki = subprocess.Popen(cmd)
  122 
  123 if rotki.returncode == 1:
  124     logger.error('Failed to start rotki')
  125     exit(1)
  126 
  127 logger.info('starting nginx')
  128 
  129 nginx = subprocess.Popen('nginx -g "daemon off;"', shell=True)
  130 
  131 if nginx.returncode == 1:
  132     logger.error('Failed to start nginx')
  133     exit(1)
  134 
  135 while True:
  136     time.sleep(60)
  137 
  138     if rotki.poll() is not None:
  139         logger.error('rotki has terminated exiting')
  140         exit(1)
  141 
  142     if nginx.poll() is not None:
  143         logger.error('nginx was not running')
  144         exit(1)
  145 
  146     logger.info('OK: processes still running')
  147
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/packaging/docker/entrypoint.py b/packaging/docker/entrypoint.py
  --- a/packaging/docker/entrypoint.py
  +++ b/packaging/docker/entrypoint.py
  @@ -2,10 +2,12 @@
   import json
   import logging
   import os
  +import shutil
   import subprocess
   import time
  +from datetime import datetime, timedelta
   from pathlib import Path
  -from typing import Dict, Optional, Any, List
  +from typing import Any, Dict, List, Optional
   
   logger = logging.getLogger('monitor')
   logging.basicConfig(level=logging.DEBUG)
  @@ -13,6 +15,41 @@
   DEFAULT_LOG_LEVEL = 'critical'
   
   
  +def can_delete(file: Path, cutoff: int) -> bool:
  +    return int(os.stat(file).st_mtime) <= cutoff or file.name.startswith('_MEI')
  +
  +
  +def cleanup_tmp() -> None:
  +    logger.info('Preparing to cleanup tmp directory')
  +    tmp_dir = Path('/tmp/').glob('*')
  +    cache_cutoff = datetime.today() - timedelta(hours=6)
  +    cutoff_epoch = int(cache_cutoff.strftime("%s"))
  +    to_delete = filter(lambda x: can_delete(x, cutoff_epoch), tmp_dir)
  +
  +    deleted = 0
  +    skipped = 0
  +
  +    for item in to_delete:
  +        path = Path(item)
  +        if path.is_file():
  +            try:
  +                path.unlink()
  +                deleted += 1
  +                continue
  +            except PermissionError:
  +                skipped += 1
  +                continue
  +
  +        try:
  +            shutil.rmtree(item)
  +            deleted += 1
  +        except OSError:
  +            skipped += 1
  +            continue
  +
  +    logger.info(f'Deleted {deleted} files or directories, skipped {skipped} from /tmp')
  +
  +
   def load_config_from_file() -> Optional[Dict[str, Any]]:
       config_file = Path('/config/rotki_config.json')
       if not config_file.exists():
  @@ -101,6 +138,8 @@
       return args
   
   
  +cleanup_tmp()
  +
   base_args = [
       '/usr/sbin/rotki',
       '--rest-api-port',
  
verification_info: {"golden_diff": "diff --git a/packaging/docker/entrypoint.py b/packaging/docker/entrypoint.py\n--- a/packaging/docker/entrypoint.py\n+++ b/packaging/docker/entrypoint.py\n@@ -2,10 +2,12 @@\n import json\n import logging\n import os\n+import shutil\n import subprocess\n import time\n+from datetime import datetime, timedelta\n from pathlib import Path\n-from typing import Dict, Optional, Any, List\n+from typing import Any, Dict, List, Optional\n \n logger = logging.getLogger('monitor')\n logging.basicConfig(level=logging.DEBUG)\n@@ -13,6 +15,41 @@\n DEFAULT_LOG_LEVEL = 'critical'\n \n \n+def can_delete(file: Path, cutoff: int) -> bool:\n+    return int(os.stat(file).st_mtime) <= cutoff or file.name.startswith('_MEI')\n+\n+\n+def cleanup_tmp() -> None:\n+    logger.info('Preparing to cleanup tmp directory')\n+    tmp_dir = Path('/tmp/').glob('*')\n+    cache_cutoff = datetime.today() - timedelta(hours=6)\n+    cutoff_epoch = int(cache_cutoff.strftime(\"%s\"))\n+    to_delete = filter(lambda x: can_delete(x, cutoff_epoch), tmp_dir)\n+\n+    deleted = 0\n+    skipped = 0\n+\n+    for item in to_delete:\n+        path = Path(item)\n+        if path.is_file():\n+            try:\n+                path.unlink()\n+                deleted += 1\n+                continue\n+            except PermissionError:\n+                skipped += 1\n+                continue\n+\n+        try:\n+            shutil.rmtree(item)\n+            deleted += 1\n+        except OSError:\n+            skipped += 1\n+            continue\n+\n+    logger.info(f'Deleted {deleted} files or directories, skipped {skipped} from /tmp')\n+\n+\n def load_config_from_file() -> Optional[Dict[str, Any]]:\n     config_file = Path('/config/rotki_config.json')\n     if not config_file.exists():\n@@ -101,6 +138,8 @@\n     return args\n \n \n+cleanup_tmp()\n+\n base_args = [\n     '/usr/sbin/rotki',\n     '--rest-api-port',\n", "issue": "Docker container's /tmp doesn't get automatically cleaned\n## Problem Definition\r\n\r\nPyInstaller extracts the files in /tmp every time the backend starts\r\nIn the docker container /tmp is never cleaned which results in an ever-increasing size on every application restart\r\n\r\n## TODO\r\n\r\n- [ ] Add /tmp cleanup on start\r\n\r\n\n", "before_files": [{"content": "#!/usr/bin/python3\nimport json\nimport logging\nimport os\nimport subprocess\nimport time\nfrom pathlib import Path\nfrom typing import Dict, Optional, Any, List\n\nlogger = logging.getLogger('monitor')\nlogging.basicConfig(level=logging.DEBUG)\n\nDEFAULT_LOG_LEVEL = 'critical'\n\n\ndef load_config_from_file() -> Optional[Dict[str, Any]]:\n    config_file = Path('/config/rotki_config.json')\n    if not config_file.exists():\n        logger.info('no config file provided')\n        return None\n\n    with open(config_file) as file:\n        try:\n            data = json.load(file)\n            return data\n        except json.JSONDecodeError as e:\n            logger.error(e)\n            return None\n\n\ndef load_config_from_env() -> Dict[str, Any]:\n    loglevel = os.environ.get('LOGLEVEL')\n    logfromothermodules = os.environ.get('LOGFROMOTHERMODDULES')\n    sleep_secs = os.environ.get('SLEEP_SECS')\n    max_size_in_mb_all_logs = os.environ.get('MAX_SIZE_IN_MB_ALL_LOGS')\n    max_logfiles_num = os.environ.get('MAX_LOGFILES_NUM')\n\n    return {\n        'loglevel': loglevel,\n        'logfromothermodules': logfromothermodules,\n        'sleep_secs': sleep_secs,\n        'max_logfiles_num': max_logfiles_num,\n        'max_size_in_mb_all_logs': max_size_in_mb_all_logs,\n    }\n\n\ndef load_config() -> List[str]:\n    env_config = load_config_from_env()\n    file_config = load_config_from_file()\n\n    logger.info('loading config from env')\n\n    loglevel = env_config.get('loglevel')\n    log_from_other_modules = env_config.get('logfromothermodules')\n    sleep_secs = env_config.get('sleep_secs')\n    max_logfiles_num = env_config.get('max_logfiles_num')\n    max_size_in_mb_all_logs = env_config.get('max_size_in_mb_all_logs')\n\n    if file_config is not None:\n        logger.info('loading config from file')\n\n        if file_config.get('loglevel') is not None:\n            loglevel = file_config.get('loglevel')\n\n        if file_config.get('logfromothermodules') is not None:\n            log_from_other_modules = file_config.get('logfromothermodules')\n\n        if file_config.get('sleep-secs') is not None:\n            sleep_secs = file_config.get('sleep-secs')\n\n        if file_config.get('max_logfiles_num') is not None:\n            max_logfiles_num = file_config.get('max_logfiles_num')\n\n        if file_config.get('max_size_in_mb_all_logs') is not None:\n            max_size_in_mb_all_logs = file_config.get('max_size_in_mb_all_logs')\n\n    args = [\n        '--data-dir',\n        '/data',\n        '--logfile',\n        '/logs/rotki.log',\n        '--loglevel',\n        loglevel if loglevel is not None else DEFAULT_LOG_LEVEL,\n    ]\n\n    if log_from_other_modules is True:\n        args.append('--logfromothermodules')\n\n    if sleep_secs is not None:\n        args.append('--sleep-secs')\n        args.append(str(sleep_secs))\n\n    if max_logfiles_num is not None:\n        args.append('--max-logfiles-num')\n        args.append(str(max_logfiles_num))\n\n    if max_size_in_mb_all_logs is not None:\n        args.append('--max-size-in-mb-all-logs')\n        args.append(str(max_size_in_mb_all_logs))\n\n    return args\n\n\nbase_args = [\n    '/usr/sbin/rotki',\n    '--rest-api-port',\n    '4242',\n    '--websockets-api-port',\n    '4243',\n    '--api-cors',\n    'http://localhost:*/*,app://.',\n    '--api-host',\n    '0.0.0.0',\n]\n\nconfig_args = load_config()\ncmd = base_args + config_args\n\nlogger.info('starting rotki backend')\n\nrotki = subprocess.Popen(cmd)\n\nif rotki.returncode == 1:\n    logger.error('Failed to start rotki')\n    exit(1)\n\nlogger.info('starting nginx')\n\nnginx = subprocess.Popen('nginx -g \"daemon off;\"', shell=True)\n\nif nginx.returncode == 1:\n    logger.error('Failed to start nginx')\n    exit(1)\n\nwhile True:\n    time.sleep(60)\n\n    if rotki.poll() is not None:\n        logger.error('rotki has terminated exiting')\n        exit(1)\n\n    if nginx.poll() is not None:\n        logger.error('nginx was not running')\n        exit(1)\n\n    logger.info('OK: processes still running')\n", "path": "packaging/docker/entrypoint.py"}], "after_files": [{"content": "#!/usr/bin/python3\nimport json\nimport logging\nimport os\nimport shutil\nimport subprocess\nimport time\nfrom datetime import datetime, timedelta\nfrom pathlib import Path\nfrom typing import Any, Dict, List, Optional\n\nlogger = logging.getLogger('monitor')\nlogging.basicConfig(level=logging.DEBUG)\n\nDEFAULT_LOG_LEVEL = 'critical'\n\n\ndef can_delete(file: Path, cutoff: int) -> bool:\n    return int(os.stat(file).st_mtime) <= cutoff or file.name.startswith('_MEI')\n\n\ndef cleanup_tmp() -> None:\n    logger.info('Preparing to cleanup tmp directory')\n    tmp_dir = Path('/tmp/').glob('*')\n    cache_cutoff = datetime.today() - timedelta(hours=6)\n    cutoff_epoch = int(cache_cutoff.strftime(\"%s\"))\n    to_delete = filter(lambda x: can_delete(x, cutoff_epoch), tmp_dir)\n\n    deleted = 0\n    skipped = 0\n\n    for item in to_delete:\n        path = Path(item)\n        if path.is_file():\n            try:\n                path.unlink()\n                deleted += 1\n                continue\n            except PermissionError:\n                skipped += 1\n                continue\n\n        try:\n            shutil.rmtree(item)\n            deleted += 1\n        except OSError:\n            skipped += 1\n            continue\n\n    logger.info(f'Deleted {deleted} files or directories, skipped {skipped} from /tmp')\n\n\ndef load_config_from_file() -> Optional[Dict[str, Any]]:\n    config_file = Path('/config/rotki_config.json')\n    if not config_file.exists():\n        logger.info('no config file provided')\n        return None\n\n    with open(config_file) as file:\n        try:\n            data = json.load(file)\n            return data\n        except json.JSONDecodeError as e:\n            logger.error(e)\n            return None\n\n\ndef load_config_from_env() -> Dict[str, Any]:\n    loglevel = os.environ.get('LOGLEVEL')\n    logfromothermodules = os.environ.get('LOGFROMOTHERMODDULES')\n    sleep_secs = os.environ.get('SLEEP_SECS')\n    max_size_in_mb_all_logs = os.environ.get('MAX_SIZE_IN_MB_ALL_LOGS')\n    max_logfiles_num = os.environ.get('MAX_LOGFILES_NUM')\n\n    return {\n        'loglevel': loglevel,\n        'logfromothermodules': logfromothermodules,\n        'sleep_secs': sleep_secs,\n        'max_logfiles_num': max_logfiles_num,\n        'max_size_in_mb_all_logs': max_size_in_mb_all_logs,\n    }\n\n\ndef load_config() -> List[str]:\n    env_config = load_config_from_env()\n    file_config = load_config_from_file()\n\n    logger.info('loading config from env')\n\n    loglevel = env_config.get('loglevel')\n    log_from_other_modules = env_config.get('logfromothermodules')\n    sleep_secs = env_config.get('sleep_secs')\n    max_logfiles_num = env_config.get('max_logfiles_num')\n    max_size_in_mb_all_logs = env_config.get('max_size_in_mb_all_logs')\n\n    if file_config is not None:\n        logger.info('loading config from file')\n\n        if file_config.get('loglevel') is not None:\n            loglevel = file_config.get('loglevel')\n\n        if file_config.get('logfromothermodules') is not None:\n            log_from_other_modules = file_config.get('logfromothermodules')\n\n        if file_config.get('sleep-secs') is not None:\n            sleep_secs = file_config.get('sleep-secs')\n\n        if file_config.get('max_logfiles_num') is not None:\n            max_logfiles_num = file_config.get('max_logfiles_num')\n\n        if file_config.get('max_size_in_mb_all_logs') is not None:\n            max_size_in_mb_all_logs = file_config.get('max_size_in_mb_all_logs')\n\n    args = [\n        '--data-dir',\n        '/data',\n        '--logfile',\n        '/logs/rotki.log',\n        '--loglevel',\n        loglevel if loglevel is not None else DEFAULT_LOG_LEVEL,\n    ]\n\n    if log_from_other_modules is True:\n        args.append('--logfromothermodules')\n\n    if sleep_secs is not None:\n        args.append('--sleep-secs')\n        args.append(str(sleep_secs))\n\n    if max_logfiles_num is not None:\n        args.append('--max-logfiles-num')\n        args.append(str(max_logfiles_num))\n\n    if max_size_in_mb_all_logs is not None:\n        args.append('--max-size-in-mb-all-logs')\n        args.append(str(max_size_in_mb_all_logs))\n\n    return args\n\n\ncleanup_tmp()\n\nbase_args = [\n    '/usr/sbin/rotki',\n    '--rest-api-port',\n    '4242',\n    '--websockets-api-port',\n    '4243',\n    '--api-cors',\n    'http://localhost:*/*,app://.',\n    '--api-host',\n    '0.0.0.0',\n]\n\nconfig_args = load_config()\ncmd = base_args + config_args\n\nlogger.info('starting rotki backend')\n\nrotki = subprocess.Popen(cmd)\n\nif rotki.returncode == 1:\n    logger.error('Failed to start rotki')\n    exit(1)\n\nlogger.info('starting nginx')\n\nnginx = subprocess.Popen('nginx -g \"daemon off;\"', shell=True)\n\nif nginx.returncode == 1:\n    logger.error('Failed to start nginx')\n    exit(1)\n\nwhile True:\n    time.sleep(60)\n\n    if rotki.poll() is not None:\n        logger.error('rotki has terminated exiting')\n        exit(1)\n\n    if nginx.poll() is not None:\n        logger.error('nginx was not running')\n        exit(1)\n\n    logger.info('OK: processes still running')\n", "path": "packaging/docker/entrypoint.py"}]}