3 # Copyright 2016 RIFT.IO Inc
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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.
24 import tornado
.httputil
26 import rift
.package
.package
27 import rift
.package
.convert
28 import rift
.package
.image
29 import rift
.package
.checksums
31 from .convert_pkg
import ConvertPackage
34 class ExtractError(Exception):
38 class UnreadableHeadersError(ExtractError
):
42 class MissingTerminalBoundary(ExtractError
):
46 class UnreadableDescriptorError(ExtractError
):
50 class UnreadablePackageError(ExtractError
):
54 class PackageImage(object):
55 def __init__(self
, log
, image_name
, image_hdl
, checksum
=None):
56 self
.name
= image_name
57 self
.image_hdl
= image_hdl
60 log
.debug("Image %s checksum not provided, calculating checksum...")
61 checksum
= rift
.package
.checksums
.checksum(self
.image_hdl
)
62 log
.debug("Image %s checksum: %s", self
.name
, checksum
)
64 self
.checksum
= checksum
67 class UploadPackageExtractor(object):
68 def __init__(self
, log
):
71 def create_packages_from_upload(self
, uploaded_file
, extracted_pkgfile
):
72 def create_package_from_descriptor_file(desc_hdl
):
73 # Uploaded package was a plain descriptor file
74 bytes_hdl
= io
.BytesIO(desc_hdl
.read())
75 bytes_hdl
.name
= uploaded_file
77 package
= rift
.package
.package
.DescriptorPackage
.from_descriptor_file_hdl(
80 except rift
.package
.package
.PackageError
as e
:
81 msg
= "Could not create descriptor package from descriptor: %s" % str(e
)
83 raise UnreadableDescriptorError(msg
) from e
87 def create_package_from_tar_file(tar_hdl
):
88 # Uploaded package was in a .tar.gz format
89 tar_archive
= rift
.package
.package
.TarPackageArchive(
93 package
= tar_archive
.create_package()
94 except rift
.package
.package
.PackageError
as e
:
95 msg
= "Could not create package from tar archive: %s" % str(e
)
97 raise UnreadablePackageError(msg
) from e
101 self
._log
.info("creating package from uploaded descriptor file/package")
105 # This file handle will be passed to TemporaryPackage to be closed
106 # and the underlying file removed.
107 upload_hdl
= open(extracted_pkgfile
, "r+b")
109 # Process the package archive
110 if tarfile
.is_tarfile(extracted_pkgfile
):
111 package
= create_package_from_tar_file(upload_hdl
)
112 tmp_pkgs
.append(rift
.package
.package
.TemporaryPackage(self
._log
,
116 # Check if this is just a descriptor file
117 elif rift
.package
.convert
.ProtoMessageSerializer
.is_supported_file(uploaded_file
):
118 package
= create_package_from_descriptor_file(upload_hdl
)
119 tmp_pkgs
.append(rift
.package
.package
.TemporaryPackage(self
._log
,
124 # See if the package can be converted
125 files
= ConvertPackage(self
._log
,
127 extracted_pkgfile
).convert(delete
=True)
129 if files
is None or not len(files
):
130 # Not converted successfully
131 msg
= "Uploaded file was neither a tar.gz or descriptor file"
133 raise UnreadablePackageError(msg
)
135 # Close the open file handle as this file is not used anymore
139 self
._log
.debug("Upload converted file: {}".format(f
))
140 upload_hdl
= open(f
, "r+b")
141 package
= create_package_from_tar_file(upload_hdl
)
142 if package
.descriptor_id
:
143 tmp_pkgs
.append(rift
.package
.package
.TemporaryPackage(self
._log
,
147 except Exception as e
:
148 # Cleanup any TemporaryPackage instances created
152 # Close the handle if not already closed
154 if upload_hdl
is not None:
157 self
._log
.warning("Failed to close file handle: %s", str(e
))
160 self
._log
.debug("Removing extracted package file: %s", extracted_pkgfile
)
161 os
.remove(extracted_pkgfile
)
163 self
._log
.warning("Failed to remove extracted package dir: %s", str(e
))