update from RIFT as of 696b75d2fe9fb046261b08c616f1bcf6c0b54a9b second try
[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, loop, cleanup_interval=60):
55
56 self.store = store
57 self.loop = loop
58
59 assert self.loop is not None
60
61 self.cleaner = CleanupThread(self.store, loop=self.loop, cleanup_interval=cleanup_interval)
62 self.cleaner.start()
63
64 super(StagingApplication, self).__init__([
65 (r"/api/upload/(.*)", handler.UploadStagingHandler, {'store': store}),
66 (r"/api/download/(.*)", tornado.web.StaticFileHandler, {'path': store.root_dir}),
67 ])
68
69
70 class CleanUpStaging(object):
71 def __init__(self, store, log=None):
72 """
73 Args:
74 store : Any store obj from store opackage
75 log : Log handle
76 """
77 self.store = store
78 self.log = log or logging.getLogger()
79 self.log.setLevel(logging.DEBUG)
80
81 def cleanup(self):
82 # Extract package could return multiple packages if
83 # the package is converted
84 for root, dirs, files in os.walk(self.store.root_dir):
85 for staging_id in dirs:
86 try:
87 staging_area = self.store.get_staging_area(staging_id)
88 if staging_area.has_expired:
89 self.store.remove_staging_area(staging_area)
90 except Exception as e:
91 # Ignore the temp directories
92 pass
93
94
95 class CleanupThread(threading.Thread):
96 """Daemon thread that clean up the staging area
97 """
98 def __init__(self, store, loop, log=None, cleanup_interval=60):
99 """
100 Args:
101 store: A compatible store object
102 log (None, optional): Log handle
103 cleanup_interval (int, optional): Cleanup interval in secs
104 loop: Tasklet main loop
105 """
106 super().__init__()
107 self.log = log or logging.getLogger()
108 self.store = store
109 self._cleaner = CleanUpStaging(store, log)
110 self.cleanup_interval = cleanup_interval
111 self.daemon = True
112 self.loop = loop
113
114 assert self.loop is not None
115
116 def run(self):
117 try:
118 while True:
119 self.loop.call_soon_threadsafe(self._cleaner.cleanup, )
120 time.sleep(self.cleanup_interval)
121
122 except Exception as e:
123 self.log.exception(e)
124