2 # Copyright 2016 RIFT.IO Inc
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
16 # Author(s): Varun Prasad
17 # Creation Date: 09/25/2016
23 import rift
.package
.store
as store
24 import rift
.package
.package
25 import rift
.package
.icon
as icon
26 import rift
.package
.checksums
as checksums
28 from .base
import AbstractPackageManagerProxy
29 from rift
.tasklets
.rwlaunchpad
import image
31 class UnknownPackageType(Exception):
35 class FileSystemProxy(AbstractPackageManagerProxy
):
36 """Proxy for Filesystem based store.
38 PACKAGE_TYPE_MAP
= {"vnfd": store
.VnfdPackageFilesystemStore
,
39 "nsd": store
.NsdPackageFilesystemStore
}
41 # Refer: https://confluence.riftio.com/display/ATG/Launchpad+package+formats
43 "nsd": ["icons", "ns_config", "scripts", "vnf_config"],
44 "vnfd": ["charms", "cloud_init", "icons", "images", "scripts", "readme", "test", "doc"]
47 SCHEMA_TO_PERMS
= {'scripts': 0o777}
49 def __init__(self
, loop
, log
, dts
):
54 self
.uploader
= image
.ImageUploader(self
.log
, self
.loop
, self
.dts
)
56 def _get_store(self
, package_type
, project_name
= None):
57 store_cls
= self
.PACKAGE_TYPE_MAP
[package_type
]
58 self
.store_cache
[package_type
] = store_cls(self
.log
, project
=project_name
)
59 store
= self
.store_cache
[package_type
]
64 def endpoint(self
, package_type
, package_id
, project_name
=None):
65 package_type
= package_type
.lower()
66 if package_type
not in self
.PACKAGE_TYPE_MAP
:
67 raise UnknownPackageType()
69 store
= self
._get
_store
(package_type
, project_name
)
71 package
= store
._get
_package
_dir
(package_id
)
72 rel_path
= os
.path
.relpath(package
, start
=os
.path
.dirname(store
.root_dir
))
74 url
= "https://127.0.0.1:8008/mano/api/package/{}/{}".format(package_type
, rel_path
)
79 def schema(self
, package_type
):
80 package_type
= package_type
.lower()
81 if package_type
not in self
.PACKAGE_TYPE_MAP
:
82 raise UnknownPackageType()
84 return self
.SCHEMA
[package_type
]
86 def package_file_add(self
, new_file
, package_type
, package_id
, package_path
, package_file_type
, project_name
):
87 # Get the schema from thr package path
88 # the first part will always be the vnfd/nsd name
91 # for files other than README, create the package path from the asset type, e.g. icons/icon1.png
92 # for README files, strip off any leading '/'
93 file_name
= package_path
94 package_path
= package_file_type
+ "/" + package_path \
95 if package_file_type
!= "readme" else package_path
.strip('/')
97 components
= package_path
.split("/")
98 if len(components
) > 2:
99 schema
= components
[1]
100 mode
= self
.SCHEMA_TO_PERMS
.get(schema
, mode
)
102 # Fetch the package object
103 package_type
= package_type
.lower()
104 store
= self
._get
_store
(package_type
, project_name
)
105 package
= store
.get_package(package_id
)
107 # Construct abs path of the destination obj
108 path
= store
._get
_package
_dir
(package_id
)
109 dest_file
= os
.path
.join(path
, package
.prefix
, package_path
)
111 # Insert (by copy) the file in the package location. For icons,
112 # insert also in UI location for UI to pickup
114 self
.log
.debug("Inserting file {} in the destination {} - {} ".format(dest_file
, package_path
, dest_file
))
115 package
.insert_file(new_file
, dest_file
, package_path
, mode
=mode
)
117 if package_file_type
== 'icons':
118 icon_extract
= icon
.PackageIconExtractor(self
.log
)
119 icon_extract
.extract_icons(package
)
121 if package_file_type
== 'images':
122 image_hdl
= package
.open(package_path
)
123 image_checksum
= checksums
.checksum(image_hdl
)
126 self
.uploader
.upload_image(file_name
, image_checksum
, image_hdl
, {})
127 self
.uploader
.upload_image_to_cloud_accounts(file_name
, image_checksum
, project_name
)
129 _
= image_hdl
.close()
130 except rift
.package
.package
.PackageAppendError
as e
:
131 self
.log
.exception(e
)
134 self
.log
.debug("File insertion complete at {}".format(dest_file
))
137 def package_file_delete(self
, package_type
, package_id
, package_path
, package_file_type
, project_name
):
138 package_type
= package_type
.lower()
139 store
= self
._get
_store
(package_type
, project_name
)
140 package
= store
.get_package(package_id
)
142 # for files other than README, create the relative package path from the asset type
143 package_path_rel
= package_file_type
+ "/" + package_path \
144 if package_file_type
!= "readme" else package_path
146 # package_path has to be relative, so strip off the starting slash if
147 # provided incorrectly.
148 if package_path_rel
[0] == "/":
149 package_path_rel
= package_path_rel
[1:]
151 # Construct abs path of the destination obj
152 path
= store
._get
_package
_dir
(package_id
)
153 dest_file
= os
.path
.join(path
, package
.prefix
, package_path_rel
)
156 package
.delete_file(dest_file
, package_path_rel
)
158 if package_file_type
== 'icons':
159 ui_icon_path
= os
.path
.join(
160 icon
.PackageIconExtractor
.DEFAULT_INSTALL_DIR
,
163 if os
.path
.exists(ui_icon_path
):
164 icon_file
= os
.path
.join(ui_icon_path
, package_path
)
165 self
.log
.debug("Deleting UI icon file path {}".format(icon_file
))
168 except rift
.package
.package
.PackageAppendError
as e
:
169 self
.log
.exception(e
)