Skip to content

Commit

Permalink
Overwrite user resources when the originals have changed.
Browse files Browse the repository at this point in the history
Excepting configs and disks which can be customized.
  • Loading branch information
grossmj committed Nov 9, 2024
1 parent db1fb29 commit a60e0d4
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 10 deletions.
19 changes: 14 additions & 5 deletions gns3server/controller/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from importlib import resources as importlib_resources

from ..config import Config
from ..utils import parse_version
from ..utils import parse_version, md5sum
from ..utils.images import default_images_directory

from .project import Project
Expand Down Expand Up @@ -289,12 +289,21 @@ async def load_projects(self):
except OSError as e:
log.error(str(e))


@staticmethod
def install_resource_files(dst_path, resource_name):
def install_resource_files(dst_path, resource_name, upgrade_resources=True):
"""
Install files from resources to user's file system
"""

def should_copy(src, dst, upgrade_resources):
if not os.path.exists(dst):
return True
if upgrade_resources is False:
return False
# copy the resource if it is different
return md5sum(src) != md5sum(dst)

if hasattr(sys, "frozen") and sys.platform.startswith("win"):
resource_path = os.path.normpath(os.path.join(os.path.dirname(sys.executable), resource_name))
for filename in os.listdir(resource_path):
Expand All @@ -303,7 +312,7 @@ def install_resource_files(dst_path, resource_name):
else:
for entry in importlib_resources.files('gns3server').joinpath(resource_name).iterdir():
full_path = os.path.join(dst_path, entry.name)
if entry.is_file() and not os.path.exists(full_path):
if entry.is_file() and should_copy(str(entry), full_path, upgrade_resources):
log.debug(f'Installing {resource_name} resource file "{entry.name}" to "{full_path}"')
shutil.copy(str(entry), os.path.join(dst_path, entry.name))
elif entry.is_dir():
Expand All @@ -319,7 +328,7 @@ def _install_base_configs(self):
dst_path = self.configs_path()
log.info(f"Installing base configs in '{dst_path}'")
try:
Controller.install_resource_files(dst_path, "configs")
Controller.install_resource_files(dst_path, "configs", upgrade_resources=False)
except OSError as e:
log.error(f"Could not install base config files to {dst_path}: {e}")

Expand All @@ -332,7 +341,7 @@ def _install_builtin_disks(self):
dst_path = self.disks_path()
log.info(f"Installing built-in disks in '{dst_path}'")
try:
Controller.install_resource_files(dst_path, "disks")
Controller.install_resource_files(dst_path, "disks", upgrade_resources=False)
except OSError as e:
log.error(f"Could not install disk files to {dst_path}: {e}")

Expand Down
6 changes: 2 additions & 4 deletions gns3server/controller/appliance_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def _custom_appliances_path(self):
os.makedirs(appliances_path, exist_ok=True)
return appliances_path

def builtin_appliances_path(self, delete_first=False):
def builtin_appliances_path(self):
"""
Get the built-in appliance storage directory
"""
Expand All @@ -91,8 +91,6 @@ def builtin_appliances_path(self, delete_first=False):
appname = vendor = "GNS3"
resources_path = os.path.expanduser(server_config.get("resources_path", platformdirs.user_data_dir(appname, vendor, roaming=True)))
appliances_dir = os.path.join(resources_path, "appliances")
if delete_first:
shutil.rmtree(appliances_dir, ignore_errors=True)
os.makedirs(appliances_dir, exist_ok=True)
return appliances_dir

Expand All @@ -101,7 +99,7 @@ def install_builtin_appliances(self):
At startup we copy the built-in appliances files.
"""

dst_path = self.builtin_appliances_path(delete_first=True)
dst_path = self.builtin_appliances_path()
log.info(f"Installing built-in appliances in '{dst_path}'")
from . import Controller
try:
Expand Down
12 changes: 12 additions & 0 deletions gns3server/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import posixpath
import socket
import errno
import hashlib


def force_unix_path(path):
Expand Down Expand Up @@ -120,3 +121,14 @@ def is_ipv6_enabled() -> bool:
if e.errno == errno.EADDRINUSE:
return True
raise

def md5sum(filename):
"""
Calculate the MD5 checksum of a file.
"""

hash_md5 = hashlib.md5()
with open(filename, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
return hash_md5.hexdigest()
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ psutil>=6.1.0
async-timeout>=4.0.3,<4.1
distro>=1.9.0
py-cpuinfo>=9.0.0,<10.0
platformdirs>=2.4.0
platformdirs>=2.4.0,<3 # platformdirs >=3 conflicts when building Debian packages
importlib-resources>=1.3; python_version < '3.9'
truststore>=0.10.0; python_version >= '3.10'

0 comments on commit a60e0d4

Please sign in to comment.