Install Docker resources in writable location

This commit is contained in:
grossmj committed 2023-11-13 11:23:26 +10:00
1 parent 303cbf3642
commit 09ff807055
5 files changed
+68 -36

No files matched your search

+28 -5
View File
@@ -25,7 +25,7 @@ import asyncio
import logging
import aiohttp
import shutil
import subprocess
import platformdirs
from gns3server.utils import parse_version
from gns3server.utils.asyncio import locking
@@ -59,11 +59,9 @@ class Docker(BaseManager):
self._api_version = DOCKER_MINIMUM_API_VERSION
@staticmethod
async def install_busybox():
async def install_busybox(dst_dir):
if not sys.platform.startswith("linux"):
return
dst_busybox = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "bin", "busybox")
dst_busybox = os.path.join(dst_dir, "bin", "busybox")
if os.path.isfile(dst_busybox):
return
for busybox_exec in ("busybox-static", "busybox.static", "busybox"):
@@ -91,6 +89,31 @@ class Docker(BaseManager):
raise DockerError(f"Could not install busybox: {e}")
raise DockerError("No busybox executable could be found")
@staticmethod
def resources_path():
"""
Get the Docker resources storage directory
"""
appname = vendor = "GNS3"
docker_resources_dir = os.path.join(platformdirs.user_data_dir(appname, vendor, roaming=True), "docker", "resources")
os.makedirs(docker_resources_dir, exist_ok=True)
return docker_resources_dir
async def install_resources(self):
"""
Copy the necessary resources to a writable location and install busybox
"""
try:
dst_path = self.resources_path()
log.info(f"Installing Docker resources in '{dst_path}'")
from gns3server.controller import Controller
Controller.instance().install_resource_files(dst_path, "compute/docker/resources")
await self.install_busybox(dst_path)
except OSError as e:
raise DockerError(f"Could not install Docker resources to {dst_path}: {e}")
async def _check_connection(self):
if not self._connected:
+10 -6
View File
@@ -299,12 +299,15 @@ class DockerVM(BaseNode):
:returns: Return the path that we need to map to local folders
"""
resources = get_resource("compute/docker/resources")
if not os.path.exists(resources):
raise DockerError(f"{resources} is missing, can't start Docker container")
try:
resources_path = self.manager.resources_path()
except OSError as e:
raise DockerError(f"Cannot access resources: {e}")
log.info(f'Mount resources from "{resources_path}"')
binds = [{
"Type": "bind",
"Source": resources,
"Source": resources_path,
"Target": "/gns3",
"ReadOnly": True
}]
@@ -394,6 +397,8 @@ class DockerVM(BaseNode):
if ":" in os.path.splitdrive(self.working_dir)[1]:
raise DockerError("Cannot create a Docker container with a project directory containing a colon character (':')")
#await self.manager.install_resources()
try:
image_infos = await self._get_image_information()
except DockerHttp404Error:
@@ -545,8 +550,7 @@ class DockerVM(BaseNode):
Starts this Docker container.
"""
# make sure busybox is installed
await self.manager.install_busybox()
await self.manager.install_resources()
try:
state = await self._get_container_state()