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 class PackageStoreError(Exception):
28 class PackageExistsError(PackageStoreError
):
32 class PackageNotFoundError(PackageStoreError
):
36 class PackageFilesystemStore(object):
37 """ This class is able to store/retreive/delete DescriptorPackages on disk
39 To insulate components from having to deal with accessing the filesystem directly
40 to deal with onboarded packages, this class provides a convenient interface for
41 storing, retreiving, deleting packages stored on disk. The interfaces deal directly
42 with DescriptorPackages so clients are abstracted from the actual location on disk.
45 def __init__(self
, log
, root_dir
):
47 self
._root
_dir
= root_dir
48 self
._package
_dirs
= {}
56 def _get_package_dir(self
, package_id
):
57 self
._log
.debug("Package dir {}, {}".format(self
._root
_dir
, package_id
))
58 return os
.path
.join(self
._root
_dir
, package_id
)
60 def _get_package_files(self
, package_id
):
63 package_dir
= self
._get
_package
_dir
(package_id
)
65 for dirpath
, dirnames
, filenames
in os
.walk(package_dir
):
66 for name
in filenames
:
67 file_path
= os
.path
.join(dirpath
, name
)
68 file_rel_path
= os
.path
.relpath(file_path
, package_dir
)
69 package_files
[file_rel_path
] = file_path
74 """ Refresh the package index from disk """
75 if not os
.path
.exists(self
._root
_dir
):
76 self
._package
_dirs
= {}
80 for package_id_dir
in os
.listdir(self
._root
_dir
):
82 package_dir_path
= os
.path
.join(self
._root
_dir
, package_id_dir
)
83 if not os
.path
.isdir(package_dir_path
):
84 self
._log
.warning("Unknown file in package store: %s", package_dir_path
)
87 files
= os
.listdir(package_dir_path
)
89 self
._log
.warning("Package directory %s is empty", package_dir_path
)
92 package_id
= os
.path
.basename(package_id_dir
)
93 package_dirs
[package_id
] = package_id_dir
96 self
._log
.warning("Failed to read packages from %s: %s",
97 package_dir_path
, str(e
))
99 self
._package
_dirs
= package_dirs
101 def get_package(self
, package_id
):
102 """ Get a DescriptorPackage on disk from the package descriptor id
105 package_id - The DescriptorPackage.descriptor_id
108 A DescriptorPackage instance of the correct type
111 PackageStoreError- The package could not be retrieved
113 if package_id
not in self
._package
_dirs
:
114 msg
= "Package %s not found in %s" % (package_id
, self
._root
_dir
)
115 raise PackageNotFoundError(msg
)
117 package_files
= self
._get
_package
_files
(package_id
)
118 package_dir
= self
._get
_package
_dir
(package_id
)
120 def do_open(pkg_file
):
121 pkg_path
= os
.path
.join(package_dir
, pkg_file
)
122 return open(pkg_path
, "rb")
124 pkg
= package
.DescriptorPackage
.from_package_files(self
._log
, do_open
, package_files
)
125 for pkg_file
in package_files
:
126 pkg
.add_file(pkg_file
)
130 def store_package(self
, pkg
):
131 """ Store a DescriptorPackage to disk
134 pkg - A DescriptorPackage
137 PackageStoreError - The package could not be stored
139 if pkg
.descriptor_id
in self
._package
_dirs
:
140 raise PackageExistsError("Package %s already exists", pkg
.descriptor_id
)
142 package_dir
= self
._get
_package
_dir
(pkg
.descriptor_id
)
145 os
.makedirs(package_dir
, exist_ok
=True)
147 raise PackageStoreError("Failed to create package dir: %s", package_dir
) from e
150 self
._log
.debug("Storing package in dir %s", package_dir
)
151 pkg
.extract(package_dir
)
152 self
._log
.debug("Package stored in dir %s", package_dir
)
153 except pkg
.PackageError
as e
:
154 raise PackageStoreError("Failed to extract package to package store") from e
156 self
._package
_dirs
[pkg
.descriptor_id
] = package_dir
158 def delete_package(self
, descriptor_id
):
159 """ Delete a stored DescriptorPackage
162 descriptor_id - The DescriptorPackage.descriptor_id
165 PackageNotFoundError - The package could not be found
166 PackageStoreError - The package could not be deleted
169 if descriptor_id
not in self
._package
_dirs
:
170 raise PackageNotFoundError("Package %s does not exists", descriptor_id
)
172 package_dir
= self
._get
_package
_dir
(descriptor_id
)
174 if os
.path
.exists(package_dir
):
175 self
._log
.debug("Removing stored package directory: %s", package_dir
)
176 shutil
.rmtree(package_dir
)
178 raise PackageStoreError(
179 "Failed to remove stored package directory: %s", package_dir
182 del self
._package
_dirs
[descriptor_id
]
184 def update_package(self
, pkg
):
185 """ Update a stored DescriptorPackage
188 pkg - A DescriptorPackage
191 PackageNotFoundError - The package could not be found
192 PackageStoreError - The package could not be deleted
194 self
.delete_package(pkg
.descriptor_id
)
195 self
.store_package(pkg
)
198 class NsdPackageFilesystemStore(PackageFilesystemStore
):
199 DEFAULT_ROOT_DIR
= os
.path
.join(
200 os
.environ
["RIFT_ARTIFACTS"],
201 "launchpad", "packages", "nsd"
204 def __init__(self
, log
, root_dir
=DEFAULT_ROOT_DIR
):
205 super().__init
__(log
, root_dir
)
208 class VnfdPackageFilesystemStore(PackageFilesystemStore
):
209 DEFAULT_ROOT_DIR
= os
.path
.join(
210 os
.environ
["RIFT_ARTIFACTS"],
211 "launchpad", "packages", "vnfd"
214 def __init__(self
, log
, root_dir
=DEFAULT_ROOT_DIR
):
215 super().__init
__(log
, root_dir
)