mirror of
https://github.com/freedomofpress/dangerzone.git
synced 2025-04-28 18:02:38 +02:00
FIXUP: Prepare #193
This commit is contained in:
parent
a014fee3e5
commit
02b4fc2a94
3 changed files with 73 additions and 52 deletions
|
@ -3,6 +3,7 @@ import os
|
||||||
import platform
|
import platform
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import traceback
|
||||||
import typing
|
import typing
|
||||||
from multiprocessing.pool import ThreadPool
|
from multiprocessing.pool import ThreadPool
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
@ -388,15 +389,25 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
|
|
||||||
|
|
||||||
class InstallContainerThread(QtCore.QThread):
|
class InstallContainerThread(QtCore.QThread):
|
||||||
finished = QtCore.Signal()
|
finished = QtCore.Signal(str)
|
||||||
|
|
||||||
def __init__(self, dangerzone: DangerzoneGui) -> None:
|
def __init__(self, dangerzone: DangerzoneGui) -> None:
|
||||||
super(InstallContainerThread, self).__init__()
|
super(InstallContainerThread, self).__init__()
|
||||||
self.dangerzone = dangerzone
|
self.dangerzone = dangerzone
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
self.dangerzone.isolation_provider.install()
|
error = None
|
||||||
self.finished.emit()
|
try:
|
||||||
|
installed = self.dangerzone.isolation_provider.install()
|
||||||
|
except Exception as e:
|
||||||
|
log.error("Installation problemo")
|
||||||
|
error = "".join(traceback.format_exception(e))
|
||||||
|
self.finished.emit(error)
|
||||||
|
else:
|
||||||
|
if not installed:
|
||||||
|
# FIXME: Improve this.
|
||||||
|
self.finished.emit("Failed to install the container image")
|
||||||
|
self.finished.emit(None)
|
||||||
|
|
||||||
|
|
||||||
class WaitingWidget(QtWidgets.QWidget):
|
class WaitingWidget(QtWidgets.QWidget):
|
||||||
|
@ -416,7 +427,6 @@ class WaitingWidgetContainer(WaitingWidget):
|
||||||
#
|
#
|
||||||
# Linux states
|
# Linux states
|
||||||
# - "install_container"
|
# - "install_container"
|
||||||
finished = QtCore.Signal()
|
|
||||||
|
|
||||||
def __init__(self, dangerzone: DangerzoneGui) -> None:
|
def __init__(self, dangerzone: DangerzoneGui) -> None:
|
||||||
super(WaitingWidgetContainer, self).__init__()
|
super(WaitingWidgetContainer, self).__init__()
|
||||||
|
@ -441,17 +451,7 @@ class WaitingWidgetContainer(WaitingWidget):
|
||||||
# Error
|
# Error
|
||||||
self.error_text = QTextEdit()
|
self.error_text = QTextEdit()
|
||||||
self.error_text.setReadOnly(True)
|
self.error_text.setReadOnly(True)
|
||||||
self.error_text.setStyleSheet(
|
self.error_text.setProperty("style", "container_error")
|
||||||
"""
|
|
||||||
QTextEdit {
|
|
||||||
font-family: Consolas, Monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
background-color: #fff;
|
|
||||||
color: #000;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
self.error_text.setVisible(False)
|
self.error_text.setVisible(False)
|
||||||
# Enable copying
|
# Enable copying
|
||||||
self.error_text.setTextInteractionFlags(Qt.TextSelectableByMouse)
|
self.error_text.setTextInteractionFlags(Qt.TextSelectableByMouse)
|
||||||
|
@ -503,56 +503,66 @@ class WaitingWidgetContainer(WaitingWidget):
|
||||||
# Update the state
|
# Update the state
|
||||||
self.state_change(state, error)
|
self.state_change(state, error)
|
||||||
|
|
||||||
|
def show_error(self, msg: str, details: str | None = None) -> None:
|
||||||
|
self.label.setText(msg)
|
||||||
|
if details is not None:
|
||||||
|
self.error_text.setPlainText(details)
|
||||||
|
self.error_text.setVisible(True)
|
||||||
|
else:
|
||||||
|
self.error_text.setVisible(False)
|
||||||
|
self.buttons.show()
|
||||||
|
|
||||||
|
def show_message(self, msg: str) -> None:
|
||||||
|
self.label.setText(msg)
|
||||||
|
self.error_text.setVisible(False)
|
||||||
|
self.buttons.hide()
|
||||||
|
|
||||||
|
def installation_finished(self, error: str | None = None) -> None:
|
||||||
|
if error:
|
||||||
|
msg = (
|
||||||
|
"Installing the Dangerzone container image.<br><br>"
|
||||||
|
"An unexpected error occurred:"
|
||||||
|
)
|
||||||
|
self.show_error(msg, error)
|
||||||
|
else:
|
||||||
|
self.finished.emit()
|
||||||
|
|
||||||
def state_change(self, state: str, error: str | None = None) -> None:
|
def state_change(self, state: str, error: str | None = None) -> None:
|
||||||
if state == "not_installed":
|
if state == "not_installed":
|
||||||
if platform.system() == "Linux":
|
if platform.system() == "Linux":
|
||||||
self.label.setText(
|
self.show_error(
|
||||||
(
|
|
||||||
"<strong>Dangerzone requires Podman</strong><br><br>"
|
"<strong>Dangerzone requires Podman</strong><br><br>"
|
||||||
"Install it and retry."
|
"Install it and retry."
|
||||||
)
|
)
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
self.label.setText(
|
self.show_error(
|
||||||
(
|
|
||||||
"<strong>Dangerzone requires Docker Desktop</strong><br><br>"
|
"<strong>Dangerzone requires Docker Desktop</strong><br><br>"
|
||||||
"<a href='https://www.docker.com/products/docker-desktop'>Download Docker Desktop</a>"
|
"<a href='https://www.docker.com/products/docker-desktop'>Download Docker Desktop</a>"
|
||||||
", install it, and open it."
|
", install it, and open it."
|
||||||
)
|
)
|
||||||
)
|
|
||||||
self.buttons.show()
|
|
||||||
elif state == "not_running":
|
elif state == "not_running":
|
||||||
if platform.system() == "Linux":
|
if 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.<br>"
|
||||||
|
"See errors below:",
|
||||||
|
error,
|
||||||
)
|
)
|
||||||
if error:
|
|
||||||
self.error_text.setPlainText(error)
|
|
||||||
self.error_text.setVisible(True)
|
|
||||||
|
|
||||||
self.label.setText(message)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.label.setText(
|
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."
|
||||||
)
|
)
|
||||||
)
|
|
||||||
self.buttons.show()
|
|
||||||
else:
|
else:
|
||||||
self.label.setText(
|
self.show_message(
|
||||||
(
|
|
||||||
"Installing the Dangerzone container image.<br><br>"
|
"Installing the Dangerzone container image.<br><br>"
|
||||||
"This might take a few minutes..."
|
"This might take a few minutes...",
|
||||||
)
|
)
|
||||||
)
|
|
||||||
self.buttons.hide()
|
|
||||||
self.install_container_t = InstallContainerThread(self.dangerzone)
|
self.install_container_t = InstallContainerThread(self.dangerzone)
|
||||||
self.install_container_t.finished.connect(self.finished)
|
self.install_container_t.finished.connect(self.installation_finished)
|
||||||
self.install_container_t.start()
|
self.install_container_t.start()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -168,7 +168,7 @@ class Container(IsolationProvider):
|
||||||
startupinfo=get_subprocess_startupinfo(),
|
startupinfo=get_subprocess_startupinfo(),
|
||||||
)
|
)
|
||||||
|
|
||||||
chunk_size = 10240
|
chunk_size = 4 << 20
|
||||||
compressed_container_path = get_resource_path("container.tar.gz")
|
compressed_container_path = get_resource_path("container.tar.gz")
|
||||||
with gzip.open(compressed_container_path) as f:
|
with gzip.open(compressed_container_path) as f:
|
||||||
while True:
|
while True:
|
||||||
|
@ -178,7 +178,11 @@ class Container(IsolationProvider):
|
||||||
p.stdin.write(chunk)
|
p.stdin.write(chunk)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
p.communicate()
|
_, err = p.communicate()
|
||||||
|
if p.returncode < 0:
|
||||||
|
raise RuntimeError(f"Could not install container image: {err}")
|
||||||
|
|
||||||
|
log.info("Container image installation finished successfully")
|
||||||
|
|
||||||
if not Container.is_container_installed():
|
if not Container.is_container_installed():
|
||||||
log.error("Failed to install the container image")
|
log.error("Failed to install the container image")
|
||||||
|
@ -192,7 +196,6 @@ class Container(IsolationProvider):
|
||||||
"""
|
"""
|
||||||
See if the podman container is installed. Linux only.
|
See if the podman container is installed. Linux only.
|
||||||
"""
|
"""
|
||||||
# Get the image id
|
|
||||||
with open(get_resource_path("image-id.txt")) as f:
|
with open(get_resource_path("image-id.txt")) as f:
|
||||||
expected_image_id = f.read().strip()
|
expected_image_id = f.read().strip()
|
||||||
|
|
||||||
|
|
|
@ -48,3 +48,11 @@ QLabel.version {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
padding-bottom: 5px; /* align with 'dangerzone' font */
|
padding-bottom: 5px; /* align with 'dangerzone' font */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QTextEdit[style="container_error"] {
|
||||||
|
font-family: Consolas, Monospace;
|
||||||
|
font-size: 12px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: #000000;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue