diff --git a/BUILD.md b/BUILD.md
index cef74da..824f050 100644
--- a/BUILD.md
+++ b/BUILD.md
@@ -9,12 +9,10 @@ git submodule update
## Debian/Ubuntu
-You need [podman](https://podman.io/getting-started/installation) ([these instructions](https://kushaldas.in/posts/podman-on-debian-buster.html) are useful for installing in Debian or Ubuntu).
-
Install dependencies:
```sh
-sudo apt install -y python3 python3-pyqt5 python3-appdirs python3-click python3-xdg
+sudo apt install -y python-all python3-stdeb docker.io python3 python3-pyqt5 python3-appdirs python3-click python3-xdg
```
Run from source tree:
@@ -29,6 +27,26 @@ Create a .deb:
./install/linux/build_deb.py
```
+## Fedora
+
+Install dependencies:
+
+```sh
+sudo dnf install -y rpm-build python3 python3-qt5 python3-appdirs python3-click
+```
+
+Run from source tree:
+
+```sh
+./dev_script/dangerzone
+```
+
+Create a .rpm:
+
+```sh
+./install/linux/build_rpm.py
+```
+
## macOS
Install Xcode from the Mac App Store. Once it's installed, run it for the first time to set it up. Also, run this to make sure command line tools are installed: `xcode-select --install`. And finally, open Xcode, go to Preferences > Locations, and make sure under Command Line Tools you select an installed version from the dropdown. (This is required for installing Qt5.)
diff --git a/dangerzone/__init__.py b/dangerzone/__init__.py
index 4b9e3de..06bcb36 100644
--- a/dangerzone/__init__.py
+++ b/dangerzone/__init__.py
@@ -48,6 +48,12 @@ def main(filename):
# Common object
common = Common(app)
+ # If we're using Linux and docker, see if we need to add the user to the docker group
+ if platform.system() == "Linux" and common.container_runtime == "/usr/bin/docker":
+ if not common.ensure_user_is_in_docker_group():
+ print("Failed to add user to docker group")
+ return
+
# See if we need to install Docker...
if platform.system() == "Darwin" and (
not is_docker_installed(common) or not is_docker_ready(common)
diff --git a/dangerzone/common.py b/dangerzone/common.py
index 718956a..9a2e449 100644
--- a/dangerzone/common.py
+++ b/dangerzone/common.py
@@ -6,7 +6,7 @@ import appdirs
import platform
import subprocess
import shlex
-from PyQt5 import QtGui
+from PyQt5 import QtCore, QtGui, QtWidgets
if platform.system() == "Darwin":
import CoreServices
@@ -14,6 +14,8 @@ if platform.system() == "Darwin":
import plistlib
elif platform.system() == "Linux":
+ import grp
+ import getpass
from xdg.DesktopEntry import DesktopEntry
from .settings import Settings
@@ -62,7 +64,14 @@ class Common(object):
"C:\\Program Files\\Docker\\Docker\\resources\\bin\\docker.exe"
)
else:
- self.container_runtime = "podman"
+ # Linux
+
+ # If this is fedora-like, use podman
+ if os.path.exists("/usr/bin/dnf"):
+ self.container_runtime = "/usr/bin/podman"
+ # Otherwise, use docker
+ else:
+ self.container_runtime = "/usr/bin/docker"
# Preload list of PDF viewers on computer
self.pdf_viewers = self._find_pdf_viewers()
@@ -351,6 +360,39 @@ class Common(object):
return pdf_viewers
+ def ensure_user_is_in_docker_group(self):
+ try:
+ groupinfo = grp.getgrnam("docker")
+ except:
+ # Ignore if group is not found
+ return True
+
+ username = getpass.getuser()
+ if username not in groupinfo.gr_mem:
+ # User is not in docker group, so prompt about adding the user to the docker group
+ message = "Dangerzone requires Docker.
Click Ok to add your user to the 'docker' group. You will have to type your login password."
+ if Alert(self, message).launch():
+ p = subprocess.run(
+ [
+ "/usr/bin/pkexec",
+ "/usr/sbin/usermod",
+ "-a",
+ "-G",
+ "docker",
+ username,
+ ]
+ )
+ if p.returncode == 0:
+ message = "Great! Now you must log out of your computer and log back in, and then you can use Dangerzone."
+ Alert(self, message).launch()
+ else:
+ message = "Failed to add your user to the 'docker' group, quitting."
+ Alert(self, message).launch()
+
+ return False
+
+ return True
+
def get_subprocess_startupinfo(self):
if platform.system() == "Windows":
startupinfo = subprocess.STARTUPINFO()
@@ -358,3 +400,55 @@ class Common(object):
return startupinfo
else:
return None
+
+
+class Alert(QtWidgets.QDialog):
+ def __init__(self, common, message):
+ super(Alert, self).__init__()
+ self.common = common
+
+ self.setWindowTitle("dangerzone")
+ self.setWindowIcon(self.common.get_window_icon())
+ self.setModal(True)
+
+ flags = (
+ QtCore.Qt.CustomizeWindowHint
+ | QtCore.Qt.WindowTitleHint
+ | QtCore.Qt.WindowSystemMenuHint
+ | QtCore.Qt.WindowCloseButtonHint
+ | QtCore.Qt.WindowStaysOnTopHint
+ )
+ self.setWindowFlags(flags)
+
+ logo = QtWidgets.QLabel()
+ logo.setPixmap(
+ QtGui.QPixmap.fromImage(
+ QtGui.QImage(self.common.get_resource_path("icon.png"))
+ )
+ )
+
+ label = QtWidgets.QLabel()
+ label.setText(message)
+ label.setWordWrap(True)
+
+ message_layout = QtWidgets.QHBoxLayout()
+ message_layout.addWidget(logo)
+ message_layout.addWidget(label)
+
+ ok_button = QtWidgets.QPushButton("Ok")
+ ok_button.clicked.connect(self.accept)
+ cancel_button = QtWidgets.QPushButton("Cancel")
+ cancel_button.clicked.connect(self.reject)
+
+ buttons_layout = QtWidgets.QHBoxLayout()
+ buttons_layout.addStretch()
+ buttons_layout.addWidget(ok_button)
+ buttons_layout.addWidget(cancel_button)
+
+ layout = QtWidgets.QVBoxLayout()
+ layout.addLayout(message_layout)
+ layout.addLayout(buttons_layout)
+ self.setLayout(layout)
+
+ def launch(self):
+ return self.exec_() == QtWidgets.QDialog.Accepted
diff --git a/install/linux/build_rpm.py b/install/linux/build_rpm.py
new file mode 100755
index 0000000..dc243da
--- /dev/null
+++ b/install/linux/build_rpm.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import os
+import sys
+import inspect
+import subprocess
+import shutil
+
+sys.path.insert(
+ 0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+)
+import dangerzone
+
+version = dangerzone.dangerzone_version
+root = os.path.dirname(
+ os.path.dirname(
+ os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
+ )
+)
+
+
+def run(cmd):
+ subprocess.run(cmd, cwd=root, check=True)
+
+
+def main():
+ build_path = os.path.join(root, "build")
+ dist_path = os.path.join(root, "dist")
+
+ print("* Deleting old build and dist")
+ if os.path.exists(build_path):
+ shutil.rmtree(build_path)
+ if os.path.exists(dist_path):
+ shutil.rmtree(dist_path)
+
+ print("* Building RPM package")
+ run(
+ [
+ "python3",
+ "setup.py",
+ "bdist_rpm",
+ "--requires=python3-qt5,python3-appdirs,python3-click",
+ ]
+ )
+
+ print("")
+ print("* To install run:")
+ print("sudo dnf install dist/dangerzone-{}-1.noarch.rpm".format(version))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/stdeb.cfg b/stdeb.cfg
index aff747a..cc6c6d6 100644
--- a/stdeb.cfg
+++ b/stdeb.cfg
@@ -1,6 +1,6 @@
[DEFAULT]
Package3: dangerzone
-Depends3: python3, python3-pyqt5, python3-appdirs, python3-click, python3-xdg
+Depends3: docker.io, python3, python3-pyqt5, python3-appdirs, python3-click, python3-xdg
Build-Depends: python3, python3-all
Suite: bionic
X-Python3-Version: >= 3.7
\ No newline at end of file