-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for PyQt5 #610
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
The preflight updater GUI currently supports both PyQt4 and PyQt5. To | ||
enforce the use of PyQt5, set the environment variable SDW_UPDATER_QT to 5. | ||
|
||
## Why support PyQt4 and PyQt5? | ||
|
||
Qubes 4.0.3 uses an end-of-life Fedora template in dom0 (fedora-25). See | ||
rationale here: | ||
|
||
https://www.qubes-os.org/doc/supported-versions/#note-on-dom0-and-eol | ||
|
||
fedora-25 only includes PyQt4, which is why we have to support it for now. | ||
The next version of Qubes, Qubes 4.1, will include PyQt5 in dom0. | ||
|
||
## Installing PyQt4 | ||
|
||
PyQt4 is no longer maintained, and is best installed through system | ||
packages, e.g., https://packages.debian.org/buster/python3-pyqt4 | ||
|
||
## Installing PyQt5 | ||
|
||
The recommended version of PyQt5 is included in the developer requirements | ||
for this project, which you can install via: | ||
|
||
pip install --require-hashes -r dev-requirements.txt |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,5 +2,6 @@ bandit | |
black | ||
pip-tools | ||
pip | ||
PyQt5==5.11.3 | ||
pytest | ||
pytest-cov |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
# Form implementation generated from reading ui file 'sdw_updater.ui' | ||
# | ||
# Created by: PyQt5 UI code generator 5.10.1 | ||
# | ||
# WARNING! All changes made in this file will be lost! | ||
|
||
from PyQt5 import QtCore, QtGui, QtWidgets | ||
|
||
|
||
class Ui_UpdaterDialog(object): | ||
def setupUi(self, UpdaterDialog): | ||
UpdaterDialog.setObjectName("UpdaterDialog") | ||
UpdaterDialog.resize(520, 300) | ||
sizePolicy = QtWidgets.QSizePolicy( | ||
QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred | ||
) | ||
sizePolicy.setHorizontalStretch(0) | ||
sizePolicy.setVerticalStretch(0) | ||
sizePolicy.setHeightForWidth(UpdaterDialog.sizePolicy().hasHeightForWidth()) | ||
UpdaterDialog.setSizePolicy(sizePolicy) | ||
UpdaterDialog.setMaximumSize(QtCore.QSize(600, 420)) | ||
self.gridLayout_2 = QtWidgets.QGridLayout(UpdaterDialog) | ||
self.gridLayout_2.setObjectName("gridLayout_2") | ||
self.gridLayout = QtWidgets.QGridLayout() | ||
self.gridLayout.setContentsMargins(-1, 15, -1, 15) | ||
self.gridLayout.setHorizontalSpacing(3) | ||
self.gridLayout.setObjectName("gridLayout") | ||
spacerItem = QtWidgets.QSpacerItem( | ||
20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed | ||
) | ||
self.gridLayout.addItem(spacerItem, 1, 1, 1, 5) | ||
self.clientOpenButton = QtWidgets.QPushButton(UpdaterDialog) | ||
self.clientOpenButton.setStyleSheet("") | ||
self.clientOpenButton.setAutoDefault(True) | ||
self.clientOpenButton.setObjectName("clientOpenButton") | ||
self.gridLayout.addWidget(self.clientOpenButton, 7, 4, 1, 1) | ||
self.proposedActionDescription = QtWidgets.QLabel(UpdaterDialog) | ||
sizePolicy = QtWidgets.QSizePolicy( | ||
QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum | ||
) | ||
sizePolicy.setHorizontalStretch(0) | ||
sizePolicy.setVerticalStretch(0) | ||
sizePolicy.setHeightForWidth( | ||
self.proposedActionDescription.sizePolicy().hasHeightForWidth() | ||
) | ||
self.proposedActionDescription.setSizePolicy(sizePolicy) | ||
self.proposedActionDescription.setAlignment( | ||
QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop | ||
) | ||
self.proposedActionDescription.setWordWrap(True) | ||
self.proposedActionDescription.setObjectName("proposedActionDescription") | ||
self.gridLayout.addWidget(self.proposedActionDescription, 4, 1, 1, 5) | ||
spacerItem1 = QtWidgets.QSpacerItem( | ||
40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum | ||
) | ||
self.gridLayout.addItem(spacerItem1, 7, 1, 1, 1) | ||
self.rebootButton = QtWidgets.QPushButton(UpdaterDialog) | ||
self.rebootButton.setStyleSheet("") | ||
self.rebootButton.setAutoDefault(True) | ||
self.rebootButton.setObjectName("rebootButton") | ||
self.gridLayout.addWidget(self.rebootButton, 7, 3, 1, 1) | ||
self.applyUpdatesButton = QtWidgets.QPushButton(UpdaterDialog) | ||
self.applyUpdatesButton.setStyleSheet("") | ||
self.applyUpdatesButton.setAutoDefault(True) | ||
self.applyUpdatesButton.setDefault(False) | ||
self.applyUpdatesButton.setObjectName("applyUpdatesButton") | ||
self.gridLayout.addWidget(self.applyUpdatesButton, 7, 2, 1, 1) | ||
self.cancelButton = QtWidgets.QPushButton(UpdaterDialog) | ||
self.cancelButton.setStyleSheet("") | ||
self.cancelButton.setAutoDefault(True) | ||
self.cancelButton.setObjectName("cancelButton") | ||
self.gridLayout.addWidget(self.cancelButton, 7, 5, 1, 1) | ||
self.progressBar = QtWidgets.QProgressBar(UpdaterDialog) | ||
self.progressBar.setProperty("value", 0) | ||
self.progressBar.setObjectName("progressBar") | ||
self.gridLayout.addWidget(self.progressBar, 2, 1, 1, 5) | ||
self.headline = QtWidgets.QLabel(UpdaterDialog) | ||
sizePolicy = QtWidgets.QSizePolicy( | ||
QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed | ||
) | ||
sizePolicy.setHorizontalStretch(0) | ||
sizePolicy.setVerticalStretch(0) | ||
sizePolicy.setHeightForWidth(self.headline.sizePolicy().hasHeightForWidth()) | ||
self.headline.setSizePolicy(sizePolicy) | ||
font = QtGui.QFont() | ||
font.setPointSize(18) | ||
font.setBold(True) | ||
font.setItalic(False) | ||
font.setWeight(75) | ||
self.headline.setFont(font) | ||
self.headline.setObjectName("headline") | ||
self.gridLayout.addWidget(self.headline, 0, 1, 1, 5) | ||
spacerItem2 = QtWidgets.QSpacerItem( | ||
20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed | ||
) | ||
self.gridLayout.addItem(spacerItem2, 3, 1, 1, 5) | ||
self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1) | ||
|
||
self.retranslateUi(UpdaterDialog) | ||
QtCore.QMetaObject.connectSlotsByName(UpdaterDialog) | ||
|
||
def retranslateUi(self, UpdaterDialog): | ||
_translate = QtCore.QCoreApplication.translate | ||
UpdaterDialog.setWindowTitle( | ||
_translate("UpdaterDialog", "SecureDrop Workstation preflight updater") | ||
) | ||
self.clientOpenButton.setText(_translate("UpdaterDialog", "Continue")) | ||
self.proposedActionDescription.setText(_translate("UpdaterDialog", "Description goes here")) | ||
self.rebootButton.setText(_translate("UpdaterDialog", "Reboot")) | ||
self.applyUpdatesButton.setText(_translate("UpdaterDialog", "Start Updates")) | ||
self.cancelButton.setText(_translate("UpdaterDialog", "Cancel")) | ||
self.headline.setText(_translate("UpdaterDialog", "Headline goes here")) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,9 @@ | |
# Folder where logs are stored | ||
LOG_DIRECTORY = os.path.join(BASE_DIRECTORY, "logs") | ||
|
||
# File that contains Qubes version information (overridden by tests) | ||
OS_RELEASE_FILE = "/etc/os-release" | ||
|
||
# Shared error string | ||
LOCK_ERROR = "Error obtaining lock on '{}'. Process may already be running." | ||
|
||
|
@@ -108,3 +111,55 @@ def is_conflicting_process_running(list): | |
sdlog.error("Conflicting process '{}' is currently running.".format(name)) | ||
return True | ||
return False | ||
|
||
|
||
def get_qubes_version(): | ||
""" | ||
Helper function for checking the Qubes version. Returns None if not on Qubes. | ||
""" | ||
is_qubes = False | ||
version = None | ||
try: | ||
with open(OS_RELEASE_FILE) as f: | ||
for line in f: | ||
try: | ||
key, value = line.rstrip().split("=") | ||
except ValueError: | ||
continue | ||
Comment on lines
+127
to
+128
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pytest is telling me that these two lines don't have test coverage There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll add a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in fd6b824 |
||
|
||
if key == "NAME" and "qubes" in value.lower(): | ||
is_qubes = True | ||
if key == "VERSION": | ||
version = value | ||
except FileNotFoundError: | ||
return None | ||
|
||
if not is_qubes: | ||
return None | ||
|
||
return version | ||
|
||
|
||
def get_qt_version(): | ||
""" | ||
Determine the version of Qt appropriate for the environment we're in. | ||
""" | ||
qubes_version = get_qubes_version() | ||
|
||
# For now we must support both Qt4 and Qt5. We default to Qt4, because | ||
# that's used in Qubes 4.0, the current stable version. | ||
if qubes_version is not None and "4.1" in qubes_version: | ||
default_version = 5 | ||
else: | ||
default_version = 4 | ||
|
||
version_str = os.getenv("SDW_UPDATER_QT", default_version) | ||
try: | ||
version = int(version_str) | ||
except ValueError: | ||
version = None | ||
|
||
if version in [4, 5]: | ||
return version | ||
else: | ||
raise ValueError("Qt version not supported: {}".format(version_str)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# No line | ||
VERSION= | ||
[we're doing toml now] | ||
RELEASES = [ ["gamma", "delta"], [1, 2] ] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
NAME=Qubes | ||
VERSION="4.0 (R4.0)" | ||
ID=qubes | ||
VERSION_ID=4.0 | ||
PRETTY_NAME="Qubes 4.0 (R4.0)" | ||
ANSI_COLOR="0;31" | ||
CPE_NAME="cpe:/o:ITL:qubes:4.0" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
NAME=Qubes | ||
VERSION="4.1 (R4.1)" | ||
ID=qubes | ||
VERSION_ID=4.0 | ||
PRETTY_NAME="Qubes 4.1 (R4.1)" | ||
ANSI_COLOR="0;31" | ||
CPE_NAME="cpe:/o:ITL:qubes:4.1" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
NAME="Ubuntu" | ||
VERSION="18.04.5 LTS (Bionic Beaver)" | ||
ID=ubuntu | ||
ID_LIKE=debian | ||
PRETTY_NAME="Ubuntu 18.04.5 LTS" | ||
VERSION_ID="18.04" | ||
HOME_URL="https://www.ubuntu.com/" | ||
SUPPORT_URL="https://help.ubuntu.com/" | ||
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" | ||
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" | ||
VERSION_CODENAME=bionic | ||
UBUNTU_CODENAME=bionic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For packaging, this file is handled by https://github.com/freedomofpress/securedrop-workstation/blob/main/rpm-build/SPECS/securedrop-workstation-dom0-config.spec#L82-L83