From 7179d6f734a3321c4bc2b4b806619462ce2af850 Mon Sep 17 00:00:00 2001 From: Alex Pyrgiotis Date: Mon, 10 Jun 2024 18:32:54 +0300 Subject: [PATCH] Get container runtime version Get the (major, minor) parts of the Docker/Podman version, to check if some specific features can be used, or if we need a fallback. These features are related with the upcoming gVisor integration, and will be added in subsequent commits. --- dangerzone/isolation_provider/container.py | 35 +++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/dangerzone/isolation_provider/container.py b/dangerzone/isolation_provider/container.py index 1f3982f..07164ae 100644 --- a/dangerzone/isolation_provider/container.py +++ b/dangerzone/isolation_provider/container.py @@ -7,7 +7,7 @@ import shlex import shutil import subprocess import sys -from typing import Any, List, Optional +from typing import Any, List, Optional, Tuple from ..conversion import errors from ..document import Document @@ -44,6 +44,39 @@ class Container(IsolationProvider): runtime_name = "docker" return runtime_name + @staticmethod + def get_runtime_version() -> Tuple[int, int]: + """Get the major/minor parts of the Docker/Podman version. + + Some of the operations we perform in this module rely on some Podman features + that are not available across all of our platforms. In order to have a proper + fallback, we need to know the Podman version. More specifically, we're fine with + just knowing the major and minor version, since writing/installing a full-blown + semver parser is an overkill. + """ + # Get the Docker/Podman version, using a Go template. + runtime = Container.get_runtime_name() + cmd = [runtime, "version", "-f", "{{.Client.Version}}"] + try: + version = subprocess.run( + cmd, capture_output=True, check=True + ).stdout.decode() + except Exception as e: + msg = f"Could not get the version of the {runtime.capitalize()} tool: {e}" + raise RuntimeError(msg) from e + + # Parse this version and return the major/minor parts, since we don't need the + # rest. + try: + major, minor, _ = version.split(".", 3) + return (int(major), int(minor)) + except Exception as e: + msg = ( + f"Could not parse the version of the {runtime.capitalize()} tool" + f" (found: '{version}') due to the following error: {e}" + ) + raise RuntimeError(msg) + @staticmethod def get_runtime() -> str: container_tech = Container.get_runtime_name()