2 # Copyright 2017 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): Nandan Sinha
25 gi
.require_version('RwVnfdYang', '1.0')
26 gi
.require_version('RwNsdYang', '1.0')
27 from gi
.repository
import (
36 class PackageCopyError(Exception):
39 class CopyStatus(enum
.Enum
):
47 TaskStatus
= RwPkgMgmtYang
.TaskStatus
51 CopyStatus
.STARTED
: TaskStatus
.QUEUED
.value_nick
.upper(),
52 CopyStatus
.UNINITIATED
: TaskStatus
.QUEUED
.value_nick
.upper(),
53 CopyStatus
.IN_PROGRESS
: TaskStatus
.IN_PROGRESS
.value_nick
.upper(),
54 CopyStatus
.COMPLETED
: TaskStatus
.COMPLETED
.value_nick
.upper(),
55 CopyStatus
.FAILED
: TaskStatus
.FAILED
.value_nick
.upper(),
56 CopyStatus
.CANCELLED
: TaskStatus
.CANCELLED
.value_nick
.upper()
59 def __init__(self
, transaction_id
):
60 self
.transaction_id
= transaction_id
61 self
.state
= CopyStatus
.UNINITIATED
63 def set_state(self
, state
):
70 job
= RwPkgMgmtYang
.CopyJob
.from_dict({
71 "transaction_id": self
.transaction_id
,
72 "status": CopyMeta
.STATUS_MAP
[self
.state
]
76 class PackageFileCopier
:
78 "vnfd": (RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd
, 'vnfd rw-vnfd'),
79 "nsd" : (RwNsdYang
.YangData_Nsd_NsdCatalog_Nsd
, 'nsd rw-nsd')
83 def from_rpc_input(cls
, rpc_input
, proxy
, log
=None):
86 rpc_input
.package_type
,
87 rpc_input
.package_name
,
97 self
.src_package_id
= pkg_id
98 self
.package_type
= pkg_type
.lower()
99 self
.dest_package_name
= pkg_name
100 self
.dest_package_id
= str(uuid
.uuid4())
101 self
.transaction_id
= str(uuid
.uuid4())
104 self
.meta
= CopyMeta(self
.transaction_id
)
105 self
.src_package
= None
106 self
.dest_desc_msg
= None
108 # Start of delegate calls
109 def call_delegate(self
, event
):
110 if not self
.delegate
:
113 # Send out the descriptor message to be posted on success
114 # Otherwise send out the CopyJob yang conversion from meta object.
115 if event
== "on_download_succeeded":
116 getattr(self
.delegate
, event
)(self
.dest_desc_msg
)
118 getattr(self
.delegate
, event
)(self
.meta
.to_yang())
120 def _copy_tree(self
):
122 Locate directory tree of the source descriptor folder.
123 Copy directory tree to destination descriptor folder.
128 store
= self
.proxy
._get
_store
(self
.package_type
)
129 src_path
= store
._get
_package
_dir
(self
.src_package_id
)
130 self
.src_package
= store
.get_package(self
.src_package_id
)
132 self
.dest_copy_path
= os
.path
.join(
133 store
.DEFAULT_ROOT_DIR
,
134 self
.dest_package_id
)
135 self
.log
.debug("Copying contents from {src} to {dest}".
136 format(src
=src_path
, dest
=self
.dest_copy_path
))
138 shutil
.copytree(src_path
, self
.dest_copy_path
)
140 def _create_descriptor_file(self
):
141 """ Update descriptor file for the newly copied descriptor catalog.
142 Use the existing descriptor file to create a descriptor proto gi object,
143 change some identifiers, and create a new descriptor yaml file from it.
146 src_desc_file
= self
.src_package
.descriptor_file
147 src_desc_contents
= self
.src_package
.descriptor_msg
.as_dict()
148 src_desc_contents
.update(
149 id =self
.dest_package_id
,
150 name
= self
.dest_package_name
,
151 short_name
= self
.dest_package_name
154 desc_cls
, modules
= PackageFileCopier
.DESCRIPTOR_MAP
[self
.package_type
]
155 self
.dest_desc_msg
= desc_cls
.from_dict(src_desc_contents
)
156 dest_desc_path
= os
.path
.join(self
.dest_copy_path
,
157 "{pkg_name}_{pkg_type}.yaml".format(pkg_name
=self
.dest_package_name
, pkg_type
=self
.package_type
))
158 model
= RwYang
.Model
.create_libncx()
159 for module
in modules
.split():
160 model
.load_module(module
)
162 with
open(dest_desc_path
, "w") as fh
:
163 fh
.write(self
.dest_desc_msg
.to_yaml(model
))
165 copied_desc_file
= os
.path
.join(self
.dest_copy_path
, os
.path
.basename(src_desc_file
))
166 if os
.path
.exists(copied_desc_file
):
167 self
.log
.debug("Deleting copied yaml from old source %s" % (copied_desc_file
))
168 os
.remove(copied_desc_file
)
172 if self
.package_type
not in PackageFileCopier
.DESCRIPTOR_MAP
:
173 raise PackageCopyError("Package type {} not currently supported for copy operations".format(self
.package_type
))
176 self
._create
_descriptor
_file
()
177 self
.copy_succeeded()
179 except Exception as e
:
180 self
.log
.exception(str(e
))
185 def copy_failed(self
):
186 self
.meta
.set_state(CopyStatus
.FAILED
)
187 self
.call_delegate("on_download_failed")
189 def copy_progress(self
):
190 self
.meta
.set_state(CopyStatus
.IN_PROGRESS
)
191 self
.call_delegate("on_download_progress")
193 def copy_succeeded(self
):
194 self
.meta
.set_state(CopyStatus
.COMPLETED
)
195 self
.call_delegate("on_download_succeeded")
197 def copy_finished(self
):
198 self
.call_delegate("on_download_finished")