mirror of
https://github.com/GNS3/gns3-server
synced 2025-01-11 16:41:04 +00:00
Change file timestamps if necessary because ZIP does not support timestamps before 1980. Fixes #1360.
This commit is contained in:
parent
814526ba26
commit
38b72079b2
@ -16,6 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import json
|
import json
|
||||||
import asyncio
|
import asyncio
|
||||||
import aiohttp
|
import aiohttp
|
||||||
@ -23,6 +24,7 @@ import zipfile
|
|||||||
import tempfile
|
import tempfile
|
||||||
import zipstream
|
import zipstream
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -77,6 +79,7 @@ def export_project(project, temporary_dir, include_images=False, keep_compute_id
|
|||||||
# ignore the .gns3 file
|
# ignore the .gns3 file
|
||||||
if file.endswith(".gns3"):
|
if file.endswith(".gns3"):
|
||||||
continue
|
continue
|
||||||
|
_patch_mtime(path)
|
||||||
zstream.write(path, os.path.relpath(path, project._path), compress_type=zipfile.ZIP_DEFLATED)
|
zstream.write(path, os.path.relpath(path, project._path), compress_type=zipfile.ZIP_DEFLATED)
|
||||||
|
|
||||||
# Export files from remote computes
|
# Export files from remote computes
|
||||||
@ -99,12 +102,29 @@ def export_project(project, temporary_dir, include_images=False, keep_compute_id
|
|||||||
f.write(data)
|
f.write(data)
|
||||||
response.close()
|
response.close()
|
||||||
f.close()
|
f.close()
|
||||||
|
_patch_mtime(temp_path)
|
||||||
zstream.write(temp_path, arcname=compute_file["path"], compress_type=zipfile.ZIP_DEFLATED)
|
zstream.write(temp_path, arcname=compute_file["path"], compress_type=zipfile.ZIP_DEFLATED)
|
||||||
downloaded_files.add(compute_file['path'])
|
downloaded_files.add(compute_file['path'])
|
||||||
|
|
||||||
return zstream
|
return zstream
|
||||||
|
|
||||||
|
|
||||||
|
def _patch_mtime(path):
|
||||||
|
"""
|
||||||
|
Patch the file mtime because ZIP does not support timestamps before 1980
|
||||||
|
|
||||||
|
:param path: file path
|
||||||
|
"""
|
||||||
|
|
||||||
|
if sys.platform.startswith("win"):
|
||||||
|
# only UNIX type platforms
|
||||||
|
return
|
||||||
|
st = os.stat(path)
|
||||||
|
file_date = datetime.fromtimestamp(st.st_mtime)
|
||||||
|
if file_date.year < 1980:
|
||||||
|
new_mtime = file_date.replace(year=1980).timestamp()
|
||||||
|
os.utime(path, (st.st_atime, new_mtime))
|
||||||
|
|
||||||
def _is_exportable(path):
|
def _is_exportable(path):
|
||||||
"""
|
"""
|
||||||
:returns: True if file should not be included in the final archive
|
:returns: True if file should not be included in the final archive
|
||||||
@ -228,6 +248,7 @@ def _export_local_image(image, zstream):
|
|||||||
|
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
arcname = os.path.join("images", directory, os.path.basename(image))
|
arcname = os.path.join("images", directory, os.path.basename(image))
|
||||||
|
_patch_mtime(path)
|
||||||
zstream.write(path, arcname)
|
zstream.write(path, arcname)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ class Snapshot:
|
|||||||
with tempfile.TemporaryDirectory() as tmpdir:
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
zipstream = yield from export_project(self._project, tmpdir, keep_compute_id=True, allow_all_nodes=True)
|
zipstream = yield from export_project(self._project, tmpdir, keep_compute_id=True, allow_all_nodes=True)
|
||||||
yield from wait_run_in_executor(self._create_snapshot_file, zipstream)
|
yield from wait_run_in_executor(self._create_snapshot_file, zipstream)
|
||||||
except OSError as e:
|
except (ValueError, OSError, RuntimeError) as e:
|
||||||
raise aiohttp.web.HTTPConflict(text="Could not create snapshot file '{}': {}".format(self.path, e))
|
raise aiohttp.web.HTTPConflict(text="Could not create snapshot file '{}': {}".format(self.path, e))
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
|
@ -304,8 +304,8 @@ class ProjectHandler:
|
|||||||
yield from response.write_eof()
|
yield from response.write_eof()
|
||||||
# Will be raise if you have no space left or permission issue on your temporary directory
|
# Will be raise if you have no space left or permission issue on your temporary directory
|
||||||
# RuntimeError: something was wrong during the zip process
|
# RuntimeError: something was wrong during the zip process
|
||||||
except (OSError, RuntimeError) as e:
|
except (ValueError, OSError, RuntimeError) as e:
|
||||||
raise aiohttp.web.HTTPNotFound(text="Can't export project: {}".format(str(e)))
|
raise aiohttp.web.HTTPNotFound(text="Cannot export project: {}".format(str(e)))
|
||||||
|
|
||||||
@Route.post(
|
@Route.post(
|
||||||
r"/projects/{project_id}/import",
|
r"/projects/{project_id}/import",
|
||||||
|
Loading…
Reference in New Issue
Block a user