summaryrefslogtreecommitdiffstats
path: root/module/obmc/wsgi
diff options
context:
space:
mode:
Diffstat (limited to 'module/obmc/wsgi')
-rw-r--r--module/obmc/wsgi/apps/rest_dbus.py62
1 files changed, 57 insertions, 5 deletions
diff --git a/module/obmc/wsgi/apps/rest_dbus.py b/module/obmc/wsgi/apps/rest_dbus.py
index 03a039d..93cd4de 100644
--- a/module/obmc/wsgi/apps/rest_dbus.py
+++ b/module/obmc/wsgi/apps/rest_dbus.py
@@ -50,6 +50,7 @@ DBUS_UNKNOWN_METHOD = 'org.freedesktop.DBus.Error.UnknownMethod'
DBUS_INVALID_ARGS = 'org.freedesktop.DBus.Error.InvalidArgs'
DBUS_TYPE_ERROR = 'org.freedesktop.DBus.Python.TypeError'
DELETE_IFACE = 'xyz.openbmc_project.Object.Delete'
+SOFTWARE_PATH = '/xyz/openbmc_project/software'
_4034_msg = "The specified %s cannot be %s: '%s'"
@@ -716,11 +717,38 @@ class ImageUploadUtils:
file_loc = '/tmp/images'
file_prefix = 'img'
file_suffix = ''
+ signal = None
@classmethod
def do_upload(cls, filename=''):
+ def cleanup():
+ os.close(handle)
+ if cls.signal:
+ cls.signal.remove()
+ cls.signal = None
+
+ def signal_callback(path, a, **kw):
+ # Just interested on the first Version interface created which is
+ # triggered when the file is uploaded. This helps avoid getting the
+ # wrong information for multiple upload requests in a row.
+ if "xyz.openbmc_project.Software.Version" in a and \
+ "xyz.openbmc_project.Software.Activation" not in a:
+ paths.append(path)
+
+ while cls.signal:
+ # Serialize uploads by waiting for the signal to be cleared.
+ # This makes it easier to ensure that the version information
+ # is the right one instead of the data from another upload request.
+ gevent.sleep(1)
if not os.path.exists(cls.file_loc):
abort(500, "Error Directory not found")
+ paths = []
+ bus = dbus.SystemBus()
+ cls.signal = bus.add_signal_receiver(
+ signal_callback,
+ dbus_interface=dbus.BUS_DAEMON_IFACE + '.ObjectManager',
+ signal_name='InterfacesAdded',
+ path=SOFTWARE_PATH)
if not filename:
handle, filename = tempfile.mkstemp(cls.file_suffix,
cls.file_prefix, cls.file_loc)
@@ -731,12 +759,36 @@ class ImageUploadUtils:
file_contents = request.body.read()
request.body.close()
os.write(handle, file_contents)
+ # Close file after writing, the image manager process watches for
+ # the close event to know the upload is complete.
+ os.close(handle)
except (IOError, ValueError) as e:
+ cleanup()
abort(400, str(e))
- except:
+ except Exception:
+ cleanup()
abort(400, "Unexpected Error")
- finally:
- os.close(handle)
+ loop = gobject.MainLoop()
+ gcontext = loop.get_context()
+ count = 0
+ version_id = ''
+ while loop is not None:
+ try:
+ if gcontext.pending():
+ gcontext.iteration()
+ if not paths:
+ gevent.sleep(1)
+ else:
+ version_id = os.path.basename(paths.pop())
+ break
+ count += 1
+ if count == 10:
+ break
+ except Exception:
+ break
+ cls.signal.remove()
+ cls.signal = None
+ return version_id
class ImagePostHandler(RouteHandler):
@@ -751,7 +803,7 @@ class ImagePostHandler(RouteHandler):
app, bus, self.verbs, self.rules, self.content_type)
def do_post(self, filename=''):
- ImageUploadUtils.do_upload()
+ return ImageUploadUtils.do_upload()
def find(self, **kw):
pass
@@ -873,7 +925,7 @@ class ImagePutHandler(RouteHandler):
app, bus, self.verbs, self.rules, self.content_type)
def do_put(self, filename=''):
- ImageUploadUtils.do_upload(filename)
+ return ImageUploadUtils.do_upload(filename)
def find(self, **kw):
pass
OpenPOWER on IntegriCloud