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
= {}
52 def _get_package_dir(self
, package_id
):
53 return os
.path
.join(self
._root
_dir
, package_id
)
55 def _get_package_files(self
, package_id
):
58 package_dir
= self
._get
_package
_dir
(package_id
)
60 for dirpath
, dirnames
, filenames
in os
.walk(package_dir
):
61 for name
in filenames
:
62 file_path
= os
.path
.join(dirpath
, name
)
63 file_rel_path
= os
.path
.relpath(file_path
, package_dir
)
64 package_files
[file_rel_path
] = file_path
69 """ Refresh the package index from disk """
70 if not os
.path
.exists(self
._root
_dir
):
71 self
._package
_dirs
= {}
75 for package_id_dir
in os
.listdir(self
._root
_dir
):
77 package_dir_path
= os
.path
.join(self
._root
_dir
, package_id_dir
)
78 if not os
.path
.isdir(package_dir_path
):
79 self
._log
.warning("Unknown file in package store: %s", package_dir_path
)
82 files
= os
.listdir(package_dir_path
)
84 self
._log
.warning("Package directory %s is empty", package_dir_path
)
87 package_id
= os
.path
.basename(package_id_dir
)
88 package_dirs
[package_id
] = package_id_dir
91 self
._log
.warning("Failed to read packages from %s: %s",
92 package_dir_path
, str(e
))
94 self
._package
_dirs
= package_dirs
96 def get_package(self
, package_id
):
97 """ Get a DescriptorPackage on disk from the package descriptor id
100 package_id - The DescriptorPackage.descriptor_id
103 A DescriptorPackage instance of the correct type
106 PackageStoreError- The package could not be retrieved
108 if package_id
not in self
._package
_dirs
:
109 msg
= "Package %s not found in %s" % (package_id
, self
._root
_dir
)
110 raise PackageNotFoundError(msg
)
112 package_files
= self
._get
_package
_files
(package_id
)
113 package_dir
= self
._get
_package
_dir
(package_id
)
115 def do_open(pkg_file
):
116 pkg_path
= os
.path
.join(package_dir
, pkg_file
)
117 return open(pkg_path
, "rb")
119 pkg
= package
.DescriptorPackage
.from_package_files(self
._log
, do_open
, package_files
)
120 for pkg_file
in package_files
:
121 pkg
.add_file(pkg_file
)
125 def store_package(self
, pkg
):
126 """ Store a DescriptorPackage to disk
129 pkg - A DescriptorPackage
132 PackageStoreError - The package could not be stored
134 if pkg
.descriptor_id
in self
._package
_dirs
:
135 raise PackageExistsError("Package %s already exists", pkg
.descriptor_id
)
137 package_dir
= self
._get
_package
_dir
(pkg
.descriptor_id
)
140 os
.makedirs(package_dir
, exist_ok
=True)
142 raise PackageStoreError("Failed to create package dir: %s", package_dir
) from e
145 self
._log
.debug("Storing package in dir %s", package_dir
)
146 pkg
.extract(package_dir
)
147 self
._log
.debug("Package stored in dir %s", package_dir
)
148 except pkg
.PackageError
as e
:
149 raise PackageStoreError("Failed to extract package to package store") from e
151 self
._package
_dirs
[pkg
.descriptor_id
] = package_dir
153 def delete_package(self
, descriptor_id
):
154 """ Delete a stored DescriptorPackage
157 descriptor_id - The DescriptorPackage.descriptor_id
160 PackageNotFoundError - The package could not be found
161 PackageStoreError - The package could not be deleted
164 if descriptor_id
not in self
._package
_dirs
:
165 raise PackageNotFoundError("Package %s does not exists", descriptor_id
)
167 package_dir
= self
._get
_package
_dir
(descriptor_id
)
169 if os
.path
.exists(package_dir
):
170 self
._log
.debug("Removing stored package directory: %s", package_dir
)
171 shutil
.rmtree(package_dir
)
173 raise PackageStoreError(
174 "Failed to remove stored package directory: %s", package_dir
177 del self
._package
_dirs
[descriptor_id
]
179 def update_package(self
, pkg
):
180 """ Update a stored DescriptorPackage
183 pkg - A DescriptorPackage
186 PackageNotFoundError - The package could not be found
187 PackageStoreError - The package could not be deleted
189 self
.delete_package(pkg
.descriptor_id
)
190 self
.store_package(pkg
)
193 class NsdPackageFilesystemStore(PackageFilesystemStore
):
194 DEFAULT_ROOT_DIR
= os
.path
.join(
195 os
.environ
["RIFT_ARTIFACTS"],
196 "launchpad", "packages", "nsd"
199 def __init__(self
, log
, root_dir
=DEFAULT_ROOT_DIR
):
200 super().__init
__(log
, root_dir
)
203 class VnfdPackageFilesystemStore(PackageFilesystemStore
):
204 DEFAULT_ROOT_DIR
= os
.path
.join(
205 os
.environ
["RIFT_ARTIFACTS"],
206 "launchpad", "packages", "vnfd"
209 def __init__(self
, log
, root_dir
=DEFAULT_ROOT_DIR
):
210 super().__init
__(log
, root_dir
)