Skip to content

Commit

Permalink
Fix wrong container runtime detection on Linux
Browse files Browse the repository at this point in the history
Use "podman" when on Linux, and "docker" otherwise.
Show what the error was when the command failed.
  • Loading branch information
almet committed Sep 6, 2024
1 parent f739761 commit 9c8d25d
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 17 deletions.
2 changes: 1 addition & 1 deletion dangerzone/gui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import signal
import sys
import typing
from typing import Dict, List, Optional
from typing import List, Optional

import click
import colorama
Expand Down
88 changes: 73 additions & 15 deletions dangerzone/gui/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@
# FIXME: See https://github.com/freedomofpress/dangerzone/issues/320 for more details.
if typing.TYPE_CHECKING:
from PySide2 import QtCore, QtGui, QtSvg, QtWidgets
from PySide2.QtWidgets import QAction
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QAction, QTextEdit
else:
try:
from PySide6 import QtCore, QtGui, QtSvg, QtWidgets
from PySide6.QtCore import Qt
from PySide6.QtGui import QAction
from PySide6.QtWidgets import QTextEdit
except ImportError:
from PySide2 import QtCore, QtGui, QtSvg, QtWidgets
from PySide2.QtWidgets import QAction
from PySide2.QtWidgets import QAction, QTextEdit
from PySide2.QtCore import Qt

from .. import errors
from ..document import SAFE_EXTENSION, Document
Expand Down Expand Up @@ -434,10 +438,29 @@ def __init__(self, dangerzone: DangerzoneGui) -> None:
self.buttons = QtWidgets.QWidget()
self.buttons.setLayout(buttons_layout)

# Error
self.error_text = QTextEdit()
self.error_text.setReadOnly(True)
self.error_text.setStyleSheet(
"""
QTextEdit {
font-family: Consolas, Monospace;
font-size: 12px;
background-color: #fff;
color: #000;
padding: 10px;
}
"""
)
self.error_text.setVisible(False)
# Enable copying
self.error_text.setTextInteractionFlags(Qt.TextSelectableByMouse)

# Layout
layout = QtWidgets.QVBoxLayout()
layout.addStretch()
layout.addWidget(self.label)
layout.addWidget(self.error_text)
layout.addStretch()
layout.addWidget(self.buttons)
layout.addStretch()
Expand All @@ -448,49 +471,84 @@ def __init__(self, dangerzone: DangerzoneGui) -> None:

def check_state(self) -> None:
state: Optional[str] = None
error: Optional[str] = None

try:
if isinstance( # Sanity check
self.dangerzone.isolation_provider, Container
):
container_runtime = self.dangerzone.isolation_provider.get_runtime()
runtime_name = self.dangerzone.isolation_provider.get_runtime_name()
except NoContainerTechException as e:
log.error(str(e))
state = "not_installed"

else:
# Can we run `docker image ls` without an error
# Can we run `docker/podman image ls` without an error
with subprocess.Popen(
[container_runtime, "image", "ls"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
stderr=subprocess.PIPE,
startupinfo=get_subprocess_startupinfo(),
) as p:
p.communicate()
_, stderr = p.communicate()
if p.returncode != 0:
log.error("Docker is not running")
log.error(f"{runtime_name} is not running")
state = "not_running"
error = stderr.decode()
else:
# Always try installing the container
state = "install_container"

# Update the state
self.state_change(state)
self.state_change(state, error)

def state_change(self, state: str) -> None:
def state_change(self, state: str, error: str | None = None) -> None:
if state == "not_installed":
self.label.setText(
"<strong>Dangerzone Requires Docker Desktop</strong><br><br><a href='https://www.docker.com/products/docker-desktop'>Download Docker Desktop</a>, install it, and open it."
)
if platform.system() == "Linux":
self.label.setText(
(
"<strong>Dangerzone requires Podman</strong><br><br>"
"Install it and retry."
)
)
else:
self.label.setText(
(
"<strong>Dangerzone requires Docker Desktop</strong><br><br>"
"<a href='https://www.docker.com/products/docker-desktop'>Download Docker Desktop</a>"
", install it, and open it."
)
)
self.buttons.show()
elif state == "not_running":
self.label.setText(
"<strong>Dangerzone Requires Docker Desktop</strong><br><br>Docker is installed but isn't running.<br><br>Open Docker and make sure it's running in the background."
)
if platform.system() == "Linux":
# "not_running" here means that the `podman image ls` command failed.
message = (
"<strong>Dangerzone requires Podman</strong><br><br>"
"Podman is installed but cannot run properly. See errors below"
)
if error:
self.error_text.setPlainText(error)
self.error_text.setVisible(True)

self.label.setText(message)

else:
self.label.setText(
(
"<strong>Dangerzone requires Docker Desktop</strong><br><br>"
"Docker is installed but isn't running.<br><br>"
"Open Docker and make sure it's running in the background."
)
)
self.buttons.show()
else:
self.label.setText(
"Installing the Dangerzone container image.<br><br>This might take a few minutes..."
(
"Installing the Dangerzone container image.<br><br>"
"This might take a few minutes..."
)
)
self.buttons.hide()
self.install_container_t = InstallContainerThread(self.dangerzone)
Expand Down
2 changes: 1 addition & 1 deletion dangerzone/isolation_provider/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def assert_field_type(self, val: Any, _type: object) -> None:
# `int`.
#
# See https://stackoverflow.com/a/37888668
if not type(val) == _type:
if type(val) is not _type:
raise ValueError("Status field has incorrect type")

def parse_progress_trusted(self, document: Document, line: str) -> None:
Expand Down

0 comments on commit 9c8d25d

Please sign in to comment.