diff --git a/docker-run-cli/pyproject.toml b/docker-run-cli/pyproject.toml index c2fbc2c..f086878 100644 --- a/docker-run-cli/pyproject.toml +++ b/docker-run-cli/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "docker-run-cli" -version = "0.9.2" +version = "0.9.3" description = "'docker run' and 'docker exec' with useful defaults" license = {file = "LICENSE"} readme = "README.md" diff --git a/docker-run-cli/src/docker_run/__init__.py b/docker-run-cli/src/docker_run/__init__.py index 5143f87..09ffdf7 100644 --- a/docker-run-cli/src/docker_run/__init__.py +++ b/docker-run-cli/src/docker_run/__init__.py @@ -1,2 +1,2 @@ __name__ = "docker-run" -__version__ = "0.9.2" \ No newline at end of file +__version__ = "0.9.3" \ No newline at end of file diff --git a/docker-run-cli/src/docker_run/core.py b/docker-run-cli/src/docker_run/core.py index d54637e..6b51630 100644 --- a/docker-run-cli/src/docker_run/core.py +++ b/docker-run-cli/src/docker_run/core.py @@ -7,7 +7,7 @@ from typing import Any, Dict, List, Tuple import docker_run -from docker_run.utils import log, runCommand +from docker_run.utils import log, runCommand, validDockerContainerName from docker_run.plugins.plugin import Plugin # automatically load all available plugins inheriting from `Plugin` @@ -21,6 +21,7 @@ if isinstance(cls, type) and issubclass(cls, Plugin) and cls is not Plugin: PLUGINS.append(cls) +DEFAULT_CONTAINER_NAME = validDockerContainerName(os.path.basename(os.getcwd())) def parseArguments() -> Tuple[argparse.Namespace, List[str], List[str]]: @@ -45,7 +46,7 @@ def format_help(self): parser.add_argument("--help", action="help", default=argparse.SUPPRESS, help="show this help message and exit") parser.add_argument("--image", help="image name (may also be specified without --image as last argument before command)") - parser.add_argument("--name", default=os.path.basename(os.getcwd()), help="container name; generates `docker exec` command if already running") + parser.add_argument("--name", default=DEFAULT_CONTAINER_NAME, help="container name; generates `docker exec` command if already running") parser.add_argument("--no-name", action="store_true", help="disable automatic container name (current directory)") parser.add_argument("--verbose", action="store_true", help="print generated command") parser.add_argument("--version", action="store_true", help="show program's version number and exit") @@ -88,14 +89,19 @@ def buildDockerCommand(args: Dict[str, Any], unknown_args: List[str] = [], cmd_a # check for running container if args["no_name"]: args["name"] = None - new_container = False - running_containers = runCommand('docker ps --format "{{.Names}}"')[0].split('\n') - new_container = not (args["name"] in running_containers) + new_container = True + else: + new_container = False + running_containers = runCommand('docker ps --format "{{.Names}}"')[0].split('\n') + new_container = not (args["name"] in running_containers) + if not new_container and args["image"] is not None and len(args["image"]) > 0: + args["name"] = None if args["name"] == DEFAULT_CONTAINER_NAME else args["name"] + new_container = True if new_container: # docker run log_msg = f"Starting new container " - if not args["no_name"]: + if args["name"] is not None: log_msg += f"'{args['name']}'" log(log_msg + " ...") docker_cmd = ["docker", "run"] diff --git a/docker-run-cli/src/docker_run/plugins/core.py b/docker-run-cli/src/docker_run/plugins/core.py index c4d8982..38957b2 100644 --- a/docker-run-cli/src/docker_run/plugins/core.py +++ b/docker-run-cli/src/docker_run/plugins/core.py @@ -92,6 +92,9 @@ def x11GuiForwardingFlags(cls, docker_network: str = "bridge") -> List[str]: display = os.environ.get("DISPLAY") if display is None: return [] + + if cls.OS == "Darwin": + runCommand(f"xhost +local:") xsock = "/tmp/.X11-unix" xauth = tempfile.NamedTemporaryFile(prefix='.docker.xauth.', delete=False).name @@ -101,9 +104,9 @@ def x11GuiForwardingFlags(cls, docker_network: str = "bridge") -> List[str]: os.chmod(xauth, 0o777) if docker_network != "host" and not display.startswith(":"): - display="172.17.0.1:" + display.split(":")[1] + display = "172.17.0.1:" + display.split(":")[1] if cls.OS == "Darwin": - display="host.docker.internal:" + display.split(":")[1] + display = "host.docker.internal:" + display.split(":")[1] flags = [] flags.append(f"--env DISPLAY={display}") diff --git a/docker-run-cli/src/docker_run/utils.py b/docker-run-cli/src/docker_run/utils.py index 8120027..c75122d 100644 --- a/docker-run-cli/src/docker_run/utils.py +++ b/docker-run-cli/src/docker_run/utils.py @@ -1,3 +1,4 @@ +import re import subprocess import sys from typing import Tuple @@ -28,3 +29,21 @@ def runCommand(cmd: str, *args, **kwargs) -> Tuple[str, str]: raise RuntimeError(f"System command '{cmd}' failed: {exc.stderr.decode()}") return output.stdout.decode(), output.stderr.decode() + + +def validDockerContainerName(name: str) -> str: + """Cleans a string such that it is a valid Docker container name. + + [a-zA-Z0-9][a-zA-Z0-9_.-] + + Args: + name (str): raw name + + Returns: + str: valid container name + """ + + name = re.sub('[^a-zA-Z0-9_.-]', '-', name) + name = re.sub('^[^a-zA-Z0-9]+', '', name) + + return name diff --git a/docker-run-docker-ros/pyproject.toml b/docker-run-docker-ros/pyproject.toml index 1b99393..8678337 100644 --- a/docker-run-docker-ros/pyproject.toml +++ b/docker-run-docker-ros/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "docker-run-docker-ros" -version = "1.0.1" +version = "1.0.2" description = "docker-run plugin for Docker images built by docker-ros" license = {file = "LICENSE"} readme = "README.md" diff --git a/docker-run-docker-ros/src/docker_run/plugins/docker_ros.py b/docker-run-docker-ros/src/docker_run/plugins/docker_ros.py index ff5085a..63f920d 100644 --- a/docker-run-docker-ros/src/docker_run/plugins/docker_ros.py +++ b/docker-run-docker-ros/src/docker_run/plugins/docker_ros.py @@ -6,7 +6,7 @@ from docker_run.plugins.plugin import Plugin -__version__ = "1.0.1" +__version__ = "1.0.2" class DockerRosPlugin(Plugin): @@ -33,7 +33,9 @@ def getRunFlags(cls, args: Dict[str, Any], unknown_args: List[str]) -> List[str] @classmethod def getExecFlags(cls, args: Dict[str, Any], unknown_args: List[str]) -> List[str]: flags = [] - if not args["no_user"] and runCommand(f"docker exec {args['name']} sh -c 'echo $DOCKER_ROS'")[0][:-1] == "1": + is_docker_ros = (runCommand(f"docker exec {args['name']} printenv DOCKER_ROS")[0][:-1] == "1") + is_non_root = (len(runCommand(f"docker exec {args['name']} printenv DOCKER_UID")[0][:-1]) > 0) + if not args["no_user"] and is_docker_ros and is_non_root: flags += cls.userExecFlags() return flags