41bbc59d8ece6543f8e16657a9c6946fece128f0
[osm/SO.git] / rwlaunchpad / plugins / rwstagingmgr / rift / tasklets / rwstagingmgr / server / app.py
1
2 #
3 # Copyright 2016 RIFT.IO Inc
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 #
17
18 import logging
19 import os
20 import threading
21 import time
22
23 import requests
24 # disable unsigned certificate warning
25 from requests.packages.urllib3.exceptions import InsecureRequestWarning
26 requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
27
28 import tornado
29 import tornado.escape
30 import tornado.httpclient
31 import tornado.httputil
32 import tornado.ioloop
33 import tornado.web
34
35 import gi
36 gi.require_version('RwStagingMgmtYang', '1.0')
37 from gi.repository import (
38 RwStagingMgmtYang,
39 )
40
41 from . import handler
42
43
44 MB = 1024 * 1024
45 GB = 1024 * MB
46 MAX_STREAMED_SIZE = 5 * GB
47
48
49 class StagingApplication(tornado.web.Application):
50 MAX_BUFFER_SIZE = 1 * MB # Max. size loaded into memory!
51 MAX_BODY_SIZE = 1 * MB # Max. size loaded into memory!
52 PORT = 4568
53
54 def __init__(self, store, cleanup_interval=60):
55
56 self.store = store
57
58 self.cleaner = CleanupThread(self.store, cleanup_interval=cleanup_interval)
59 self.cleaner.start()
60
61 super(StagingApplication, self).__init__([
62 (r"/api/upload/(.*)", handler.UploadStagingHandler, {'store': store}),
63 (r"/api/download/(.*)", tornado.web.StaticFileHandler, {'path': store.root_dir}),
64 ])
65
66
67 class CleanUpStaging(object):
68 def __init__(self, store, log=None):
69 """
70 Args:
71 store : Any store obj from store opackage
72 log : Log handle
73 """
74 self.store = store
75 self.log = log or logging.getLogger()
76 self.log.setLevel(logging.DEBUG)
77
78 def cleanup(self):
79 # Extract package could return multiple packages if
80 # the package is converted
81 for root, dirs, files in os.walk(self.store.root_dir):
82 for staging_id in dirs:
83 try:
84 staging_area = self.store.get_staging_area(staging_id)
85 if staging_area.has_expired:
86 self.store.remove_staging_area(staging_area)
87 except Exception as e:
88 # Ignore the temp directories
89 pass
90
91
92 class CleanupThread(threading.Thread):
93 """Daemon thread that clean up the staging area
94 """
95 def __init__(self, store, log=None, cleanup_interval=60):
96 """
97 Args:
98 store : A compatible store object
99 log (None, optional): Log handle
100 cleanup_interval (int, optional): Cleanup interval in secs
101 """
102 super().__init__()
103 self.log = log or logging.getLogger()
104 self.store = store
105 self._cleaner = CleanUpStaging(store, log)
106 self.cleanup_interval = cleanup_interval
107 self.daemon = True
108
109 def run(self):
110 try:
111 while True:
112 self._cleaner.cleanup()
113 time.sleep(self.cleanup_interval)
114
115 except Exception as e:
116 self.log.exception(e)
117