mirror of
https://github.com/freedomofpress/dangerzone.git
synced 2025-04-28 09:52:37 +02:00
Add a set-container-runtime
option to dangerzone-cli
This sets the container runtime in the settings, and provides an easy way to do so for users, without having to mess with the json settings. When setting the container runtime, one can just pass "podman" and the path to the executable will be stored in the settings.
This commit is contained in:
parent
86eab5d222
commit
0a7b79f61a
5 changed files with 56 additions and 13 deletions
|
@ -11,6 +11,7 @@ from .isolation_provider.container import Container
|
||||||
from .isolation_provider.dummy import Dummy
|
from .isolation_provider.dummy import Dummy
|
||||||
from .isolation_provider.qubes import Qubes, is_qubes_native_conversion
|
from .isolation_provider.qubes import Qubes, is_qubes_native_conversion
|
||||||
from .logic import DangerzoneCore
|
from .logic import DangerzoneCore
|
||||||
|
from .settings import Settings
|
||||||
from .util import get_version, replace_control_chars
|
from .util import get_version, replace_control_chars
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ def print_header(s: str) -> None:
|
||||||
)
|
)
|
||||||
@click.argument(
|
@click.argument(
|
||||||
"filenames",
|
"filenames",
|
||||||
required=True,
|
required=False,
|
||||||
nargs=-1,
|
nargs=-1,
|
||||||
type=click.UNPROCESSED,
|
type=click.UNPROCESSED,
|
||||||
callback=args.validate_input_filenames,
|
callback=args.validate_input_filenames,
|
||||||
|
@ -48,17 +49,33 @@ def print_header(s: str) -> None:
|
||||||
flag_value=True,
|
flag_value=True,
|
||||||
help="Run Dangerzone in debug mode, to get logs from gVisor.",
|
help="Run Dangerzone in debug mode, to get logs from gVisor.",
|
||||||
)
|
)
|
||||||
|
@click.option(
|
||||||
|
"--set-container-runtime",
|
||||||
|
required=False,
|
||||||
|
help="The path to the container runtime you want to set in the settings",
|
||||||
|
)
|
||||||
@click.version_option(version=get_version(), message="%(version)s")
|
@click.version_option(version=get_version(), message="%(version)s")
|
||||||
@errors.handle_document_errors
|
@errors.handle_document_errors
|
||||||
def cli_main(
|
def cli_main(
|
||||||
output_filename: Optional[str],
|
output_filename: Optional[str],
|
||||||
ocr_lang: Optional[str],
|
ocr_lang: Optional[str],
|
||||||
filenames: List[str],
|
filenames: Optional[List[str]],
|
||||||
archive: bool,
|
archive: bool,
|
||||||
dummy_conversion: bool,
|
dummy_conversion: bool,
|
||||||
debug: bool,
|
debug: bool,
|
||||||
|
set_container_runtime: Optional[str] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
setup_logging()
|
setup_logging()
|
||||||
|
display_banner()
|
||||||
|
if set_container_runtime:
|
||||||
|
settings = Settings()
|
||||||
|
container_runtime = settings.set_custom_runtime(
|
||||||
|
set_container_runtime, autosave=True
|
||||||
|
)
|
||||||
|
click.echo(f"Set the settings container_runtime to {container_runtime}")
|
||||||
|
sys.exit(0)
|
||||||
|
elif not filenames:
|
||||||
|
raise click.UsageError("Missing argument 'FILENAMES...'")
|
||||||
|
|
||||||
if getattr(sys, "dangerzone_dev", False) and dummy_conversion:
|
if getattr(sys, "dangerzone_dev", False) and dummy_conversion:
|
||||||
dangerzone = DangerzoneCore(Dummy())
|
dangerzone = DangerzoneCore(Dummy())
|
||||||
|
@ -67,7 +84,6 @@ def cli_main(
|
||||||
else:
|
else:
|
||||||
dangerzone = DangerzoneCore(Container(debug=debug))
|
dangerzone = DangerzoneCore(Container(debug=debug))
|
||||||
|
|
||||||
display_banner()
|
|
||||||
if len(filenames) == 1 and output_filename:
|
if len(filenames) == 1 and output_filename:
|
||||||
dangerzone.add_document_from_filename(filenames[0], output_filename, archive)
|
dangerzone.add_document_from_filename(filenames[0], output_filename, archive)
|
||||||
elif len(filenames) > 1 and output_filename:
|
elif len(filenames) > 1 and output_filename:
|
||||||
|
|
|
@ -16,6 +16,14 @@ log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Runtime(object):
|
class Runtime(object):
|
||||||
|
"""Represents the container runtime to use.
|
||||||
|
|
||||||
|
- It can be specified via the settings, using the "container_runtime" key,
|
||||||
|
which should point to the full path of the runtime;
|
||||||
|
- If the runtime is not specified via the settings, it defaults
|
||||||
|
to "podman" on Linux and "docker" on macOS and Windows.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
|
|
||||||
|
@ -26,14 +34,22 @@ class Runtime(object):
|
||||||
self.name = self.path.stem
|
self.name = self.path.stem
|
||||||
else:
|
else:
|
||||||
self.name = self.get_default_runtime_name()
|
self.name = self.get_default_runtime_name()
|
||||||
binary_path = shutil.which(self.name)
|
self.path = Runtime.path_from_name(self.name)
|
||||||
if binary_path is None or not os.path.exists(binary_path):
|
|
||||||
raise errors.NoContainerTechException(self.name)
|
|
||||||
self.path = Path(binary_path)
|
|
||||||
|
|
||||||
if self.name not in ("podman", "docker"):
|
if self.name not in ("podman", "docker"):
|
||||||
raise errors.UnsupportedContainerRuntime(self.name)
|
raise errors.UnsupportedContainerRuntime(self.name)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def path_from_name(name: str) -> Path:
|
||||||
|
name_path = Path(name)
|
||||||
|
if name_path.is_file():
|
||||||
|
return name_path
|
||||||
|
else:
|
||||||
|
runtime = shutil.which(name_path)
|
||||||
|
if runtime is None:
|
||||||
|
raise errors.NoContainerTechException(name)
|
||||||
|
return Path(runtime)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_default_runtime_name() -> str:
|
def get_default_runtime_name() -> str:
|
||||||
return "podman" if platform.system() == "Linux" else "docker"
|
return "podman" if platform.system() == "Linux" else "docker"
|
||||||
|
|
|
@ -605,17 +605,18 @@ class WaitingWidgetContainer(WaitingWidget):
|
||||||
)
|
)
|
||||||
elif platform.system() == "Linux":
|
elif platform.system() == "Linux":
|
||||||
# "not_running" here means that the `podman image ls` command failed.
|
# "not_running" here means that the `podman image ls` command failed.
|
||||||
message = (
|
self.show_error(
|
||||||
"<strong>Dangerzone requires Podman</strong><br><br>"
|
"<strong>Dangerzone requires Podman</strong><br><br>"
|
||||||
"Podman is installed but cannot run properly. See errors below"
|
"Podman is installed but cannot run properly. See errors below",
|
||||||
|
error,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
message = (
|
self.show_error(
|
||||||
"<strong>Dangerzone requires Docker Desktop</strong><br><br>"
|
"<strong>Dangerzone requires Docker Desktop</strong><br><br>"
|
||||||
"Docker is installed but isn't running.<br><br>"
|
"Docker is installed but isn't running.<br><br>"
|
||||||
"Open Docker and make sure it's running in the background."
|
"Open Docker and make sure it's running in the background.",
|
||||||
|
error,
|
||||||
)
|
)
|
||||||
self.show_error(message, error)
|
|
||||||
else:
|
else:
|
||||||
self.show_message(
|
self.show_message(
|
||||||
"Installing the Dangerzone container image.<br><br>"
|
"Installing the Dangerzone container image.<br><br>"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, Any, Dict
|
from typing import TYPE_CHECKING, Any, Dict
|
||||||
|
|
||||||
from packaging import version
|
from packaging import version
|
||||||
|
@ -42,6 +43,15 @@ class Settings:
|
||||||
def custom_runtime_specified(self) -> bool:
|
def custom_runtime_specified(self) -> bool:
|
||||||
return "container_runtime" in self.settings
|
return "container_runtime" in self.settings
|
||||||
|
|
||||||
|
def set_custom_runtime(self, runtime: str, autosave: bool = False) -> Path:
|
||||||
|
from .container_utils import Runtime # Avoid circular import
|
||||||
|
|
||||||
|
container_runtime = Runtime.path_from_name(runtime)
|
||||||
|
self.settings["container_runtime"] = str(container_runtime)
|
||||||
|
if autosave:
|
||||||
|
self.save()
|
||||||
|
return container_runtime
|
||||||
|
|
||||||
def get(self, key: str) -> Any:
|
def get(self, key: str) -> Any:
|
||||||
return self.settings[key]
|
return self.settings[key]
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ def test_get_runtime_name_non_linux(mocker: MockerFixture, tmp_path: Path) -> No
|
||||||
assert Runtime().name == "docker"
|
assert Runtime().name == "docker"
|
||||||
|
|
||||||
|
|
||||||
def test_get_unsupported_runtime_name(mocker: MockerFixture, tmp_path: Path):
|
def test_get_unsupported_runtime_name(mocker: MockerFixture, tmp_path: Path) -> None:
|
||||||
mocker.patch("dangerzone.settings.get_config_dir", return_value=tmp_path)
|
mocker.patch("dangerzone.settings.get_config_dir", return_value=tmp_path)
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
settings.set(
|
settings.set(
|
||||||
|
|
Loading…
Reference in a new issue