Export project with the GNS3VM

This commit is contained in:
Julien Duponchelle committed 2016-07-21 20:17:36 +02:00
1 parent 88ffd43c97
commit 9b499dc51e
8 files changed
+105 -37

No files matched your search

+27 -1
View File
@@ -270,7 +270,23 @@ class Compute:
}
@asyncio.coroutine
def steam_file(self, project, path):
def download_file(self, project, path):
"""
Read file of a project and download it
:param project: A project object
:param path: The path of the file in the project
:returns: A file stream
"""
url = self._getUrl("/projects/{}/files/{}".format(project.id, path))
response = yield from self._session().request("GET", url, auth=self._auth)
if response.status == 404:
raise aiohttp.web.HTTPNotFound(text="{} not found on compute".format(path))
return response.content
@asyncio.coroutine
def stream_file(self, project, path):
"""
Read file of a project and stream it
@@ -447,3 +463,13 @@ class Compute:
if image not in [i['filename'] for i in images]:
images.append({"filename": image, "path": image})
return images
@asyncio.coroutine
def list_files(self, project):
"""
List files in the project on computes
"""
path = "/projects/{}/files".format(project.id)
res = yield from self.http_query("GET", path, timeout=120)
return res.json
+41 -7
View File
@@ -17,12 +17,15 @@
import os
import json
import asyncio
import aiohttp
import zipfile
import tempfile
import zipstream
def export_project(project, include_images=False):
@asyncio.coroutine
def export_project(project, temporary_dir, include_images=False):
"""
Export the project as zip. It's a ZipStream object.
The file will be read chunk by chunk when you iterate on
@@ -30,6 +33,7 @@ def export_project(project, include_images=False):
It will ignore some files like snapshots and
:param temporary_dir: A temporary dir where to store intermediate data
:returns: ZipStream object
"""
@@ -45,12 +49,7 @@ def export_project(project, include_images=False):
_export_project_file(project, os.path.join(project._path, file), z, include_images)
for root, dirs, files in os.walk(project._path, topdown=True):
# Remove snapshots and capture
if os.path.split(root)[-1:][0] == "project-files":
dirs[:] = [d for d in dirs if d not in ("snapshots", "tmp")]
# Ignore log files and OS noise
files = [f for f in files if not f.endswith('_log.txt') and not f.endswith('.log') and f != '.DS_Store']
files = [f for f in files if not _filter_files(os.path.join(root, f))]
for file in files:
path = os.path.join(root, file)
@@ -66,9 +65,44 @@ def export_project(project, include_images=False):
pass
else:
z.write(path, os.path.relpath(path, project._path), compress_type=zipfile.ZIP_DEFLATED)
for compute in project.computes:
if compute.id == "vm":
compute_files = yield from compute.list_files(project)
for compute_file in compute_files:
if not _filter_files(compute_file["path"]):
(fp, temp_path) = tempfile.mkstemp(dir=temporary_dir)
stream = yield from compute.download_file(project, compute_file["path"])
while True:
data = yield from stream.read(512)
if not data:
break
fp.write(data)
z.write(temp_path, arcname=compute_file["path"], compress_type=zipfile.ZIP_DEFLATED)
return z
def _filter_files(path):
"""
:returns: True if file should not be included in the final archive
"""
s = os.path.normpath(path).split(os.path.sep)
try:
i = s.index("project-files")
if s[i + 1] in ("tmp", "captures", "snapshots"):
return True
except (ValueError, IndexError):
pass
file_name = os.path.basename(path)
# Ignore log files and OS noises
if file_name.endswith('_log.txt') or file_name.endswith('.log') or file_name == '.DS_Store':
return True
return False
def _export_project_file(project, path, z, include_images):
"""
Take a project file (.gns3) and patch it for the export
+2 -2
View File
@@ -149,9 +149,9 @@ class Project:
@property
def computes(self):
"""
:return: Dictonnary of computes used by the project
:return: List of computes used by the project
"""
return self._computes
return self._project_created_on_compute
def remove_allocated_node_name(self, name):
"""
+1 -1
View File
@@ -138,4 +138,4 @@ class UDPLink(Link):
"""
if self._capture_node:
compute = self._capture_node["node"].compute
return compute.steam_file(self._project, "tmp/captures/" + self._capture_file_name)
return compute.stream_file(self._project, "tmp/captures/" + self._capture_file_name)