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
= {}
57 def _get_package_dir(self
, 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
115 if package_id
not in self
._package
_dirs
:
116 msg
= "Package %s not found in %s" % (package_id
, self
._root
_dir
)
117 raise PackageNotFoundError(msg
)
119 package_files
= self
._get
_package
_files
(package_id
)
120 package_dir
= self
._get
_package
_dir
(package_id
)
122 def do_open(pkg_file
):
123 pkg_path
= os
.path
.join(package_dir
, pkg_file
)
124 return open(pkg_path
, "rb")
126 pkg
= package
.DescriptorPackage
.from_package_files(self
._log
, do_open
, package_files
)
127 for pkg_file
in package_files
:
128 pkg
.add_file(pkg_file
)
132 def store_package(self
, pkg
):
133 """ Store a DescriptorPackage to disk
136 pkg - A DescriptorPackage
139 PackageStoreError - The package could not be stored
141 if pkg
.descriptor_id
in self
._package
_dirs
:
142 raise PackageExistsError("Package %s already exists", pkg
.descriptor_id
)
144 package_dir
= self
._get
_package
_dir
(pkg
.descriptor_id
)
147 os
.makedirs(package_dir
, exist_ok
=True)
149 raise PackageStoreError("Failed to create package dir: %s", package_dir
) from e
152 self
._log
.debug("Storing package in dir %s", package_dir
)
153 pkg
.extract(package_dir
)
154 self
._log
.debug("Package stored in dir %s", package_dir
)
155 except pkg
.PackageError
as e
:
156 raise PackageStoreError("Failed to extract package to package store") from e
158 self
._package
_dirs
[pkg
.descriptor_id
] = package_dir
160 def delete_package(self
, descriptor_id
):
161 """ Delete a stored DescriptorPackage
164 descriptor_id - The DescriptorPackage.descriptor_id
167 PackageNotFoundError - The package could not be found
168 PackageStoreError - The package could not be deleted
171 if descriptor_id
not in self
._package
_dirs
:
172 raise PackageNotFoundError("Package %s does not exists", descriptor_id
)
174 package_dir
= self
._get
_package
_dir
(descriptor_id
)
176 if os
.path
.exists(package_dir
):
177 self
._log
.debug("Removing stored package directory: %s", package_dir
)
178 shutil
.rmtree(package_dir
)
180 raise PackageStoreError(
181 "Failed to remove stored package directory: %s", package_dir
184 del self
._package
_dirs
[descriptor_id
]
186 def update_package(self
, pkg
):
187 """ Update a stored DescriptorPackage
190 pkg - A DescriptorPackage
193 PackageNotFoundError - The package could not be found
194 PackageStoreError - The package could not be deleted
196 self
.delete_package(pkg
.descriptor_id
)
197 self
.store_package(pkg
)
200 class NsdPackageFilesystemStore(PackageFilesystemStore
):
201 DEFAULT_ROOT_DIR
= os
.path
.join(
202 os
.environ
["RIFT_ARTIFACTS"],
203 "launchpad", "packages", "nsd"
206 def __init__(self
, log
, root_dir
=DEFAULT_ROOT_DIR
):
207 super().__init
__(log
, root_dir
)
210 class VnfdPackageFilesystemStore(PackageFilesystemStore
):
211 DEFAULT_ROOT_DIR
= os
.path
.join(
212 os
.environ
["RIFT_ARTIFACTS"],
213 "launchpad", "packages", "vnfd"
216 def __init__(self
, log
, root_dir
=DEFAULT_ROOT_DIR
):
217 super().__init
__(log
, root_dir
)