Skip to content

Commit bd813b0

Browse files
committed
Merge branch '2.2' into 3.0
# Conflicts: # requirements.txt # setup.py
2 parents e83e12b + 11c9802 commit bd813b0

File tree

4 files changed

+30
-11
lines changed

4 files changed

+30
-11
lines changed

gns3server/controller/__init__.py

+14-5
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131

3232
from ..config import Config
33-
from ..utils import parse_version
33+
from ..utils import parse_version, md5sum
3434
from ..utils.images import default_images_directory
3535

3636
from .project import Project
@@ -308,12 +308,21 @@ async def load_projects(self):
308308
except OSError as e:
309309
log.error(str(e))
310310

311+
311312
@staticmethod
312-
def install_resource_files(dst_path, resource_name):
313+
def install_resource_files(dst_path, resource_name, upgrade_resources=True):
313314
"""
314315
Install files from resources to user's file system
315316
"""
316317

318+
def should_copy(src, dst, upgrade_resources):
319+
if not os.path.exists(dst):
320+
return True
321+
if upgrade_resources is False:
322+
return False
323+
# copy the resource if it is different
324+
return md5sum(src) != md5sum(dst)
325+
317326
if hasattr(sys, "frozen") and sys.platform.startswith("win"):
318327
resource_path = os.path.normpath(os.path.join(os.path.dirname(sys.executable), resource_name))
319328
for filename in os.listdir(resource_path):
@@ -322,7 +331,7 @@ def install_resource_files(dst_path, resource_name):
322331
else:
323332
for entry in importlib_resources.files('gns3server').joinpath(resource_name).iterdir():
324333
full_path = os.path.join(dst_path, entry.name)
325-
if entry.is_file() and not os.path.exists(full_path):
334+
if entry.is_file() and should_copy(str(entry), full_path, upgrade_resources):
326335
log.debug(f'Installing {resource_name} resource file "{entry.name}" to "{full_path}"')
327336
shutil.copy(str(entry), os.path.join(dst_path, entry.name))
328337
elif entry.is_dir():
@@ -338,7 +347,7 @@ def _install_base_configs(self):
338347
dst_path = self.configs_path()
339348
log.info(f"Installing base configs in '{dst_path}'")
340349
try:
341-
Controller.install_resource_files(dst_path, "configs")
350+
Controller.install_resource_files(dst_path, "configs", upgrade_resources=False)
342351
except OSError as e:
343352
log.error(f"Could not install base config files to {dst_path}: {e}")
344353

@@ -351,7 +360,7 @@ def _install_builtin_disks(self):
351360
dst_path = self.disks_path()
352361
log.info(f"Installing built-in disks in '{dst_path}'")
353362
try:
354-
Controller.install_resource_files(dst_path, "disks")
363+
Controller.install_resource_files(dst_path, "disks", upgrade_resources=False)
355364
except OSError as e:
356365
log.error(f"Could not install disk files to {dst_path}: {e}")
357366

gns3server/controller/appliance_manager.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def _custom_appliances_path(self) -> str:
9595
os.makedirs(appliances_path, exist_ok=True)
9696
return appliances_path
9797

98-
def builtin_appliances_path(self, delete_first=False):
98+
def builtin_appliances_path(self):
9999
"""
100100
Get the built-in appliance storage directory
101101
"""
@@ -107,8 +107,6 @@ def builtin_appliances_path(self, delete_first=False):
107107
else:
108108
resources_path = os.path.expanduser(resources_path)
109109
appliances_dir = os.path.join(resources_path, "appliances")
110-
if delete_first:
111-
shutil.rmtree(appliances_dir, ignore_errors=True)
112110
os.makedirs(appliances_dir, exist_ok=True)
113111
return appliances_dir
114112

@@ -117,7 +115,7 @@ def install_builtin_appliances(self):
117115
At startup we copy the built-in appliances files.
118116
"""
119117

120-
dst_path = self.builtin_appliances_path(delete_first=True)
118+
dst_path = self.builtin_appliances_path()
121119
log.info(f"Installing built-in appliances in '{dst_path}'")
122120
from . import Controller
123121
try:

gns3server/utils/__init__.py

+12
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import posixpath
2424
import socket
2525
import errno
26+
import hashlib
2627

2728

2829
def force_unix_path(path):
@@ -109,3 +110,14 @@ def is_ipv6_enabled() -> bool:
109110
if e.errno == errno.EADDRINUSE:
110111
return True
111112
raise
113+
114+
def md5sum(filename):
115+
"""
116+
Calculate the MD5 checksum of a file.
117+
"""
118+
119+
hash_md5 = hashlib.md5()
120+
with open(filename, "rb") as f:
121+
for chunk in iter(lambda: f.read(4096), b""):
122+
hash_md5.update(chunk)
123+
return hash_md5.hexdigest()

requirements.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Jinja2>=3.1.4,<3.2
1010
sentry-sdk>=2.17,<2.18 # optional dependency
1111
psutil>=6.1.0
1212
distro>=1.9.0
13-
py-cpuinfo==9.0.0
13+
py-cpuinfo>=9.0.0,<10.0
1414
sqlalchemy==2.0.36
1515
aiosqlite==0.20.0
1616
alembic==1.13.3
@@ -19,6 +19,6 @@ python-jose[cryptography]==3.3.0
1919
email-validator==2.2.0
2020
watchfiles==0.24.0
2121
zstandard==0.23.0
22-
platformdirs==4.3.6
22+
platformdirs>=2.4.0,<3 # platformdirs >=3 conflicts when building Debian packages
2323
importlib-resources>=1.3; python_version <= '3.9'
2424
truststore>=0.10.0; python_version >= '3.10'

0 commit comments

Comments
 (0)