Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 51 additions & 30 deletions BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,27 +183,27 @@ Overview of the qubes you'll create:
| ------------ | -------- | ------------------------------------------------------ |
| dz | app qube | Dangerzone development |
| dz-dvm | app qube | offline disposable template for performing conversions |
| fedora-42-dz | template | template for the other two qubes |
| fedora-43-dz | template | template for the other two qubes |

#### In `dom0`:

The following instructions require typing commands in a terminal in dom0.

1. Create a new Fedora **template** (`fedora-42-dz`) for Dangerzone development:
1. Create a new Fedora **template** (`fedora-43-dz`) for Dangerzone development:

```
qvm-clone fedora-42 fedora-42-dz
qvm-clone fedora-43 fedora-43-dz
```

> :bulb: Alternatively, you can use your base Fedora 41 template in the
> following instructions. In that case, skip this step and replace
> `fedora-42-dz` with `fedora-42` in the steps below.
> `fedora-43-dz` with `fedora-43` in the steps below.

2. Create an offline disposable template (app qube) called `dz-dvm`, based on the `fedora-42-dz`
2. Create an offline disposable template (app qube) called `dz-dvm`, based on the `fedora-43-dz`
template. This will be the qube where the documents will be sanitized:

```
qvm-create --class AppVM --label red --template fedora-42-dz \
qvm-create --class AppVM --label red --template fedora-43-dz \
--prop netvm="" --prop template_for_dispvms=True \
--prop default_dispvm='' dz-dvm
```
Expand All @@ -212,7 +212,7 @@ The following instructions require typing commands in a terminal in dom0.
and initiating the sanitization process:

```
qvm-create --class AppVM --label red --template fedora-42-dz dz
qvm-create --class AppVM --label red --template fedora-43-dz dz
qvm-volume resize dz:private $(numfmt --from=auto 20Gi)
```

Expand Down Expand Up @@ -242,35 +242,48 @@ loads the server code dynamically each time it's run, instead of having
to build and install a server package each time the developer wants to
test it.

1. Clone the Dangerzone project:
1. Follow the [Fedora installation instructions](#Fedora) up until
`poetry run mazette install`.

```
git clone https://github.com/freedomofpress/dangerzone
cd dangerzone

2. Clone the Dangerzone image repo, which holds the server-side conversion
component:

```sh
cd ~
git clone https://github.com/freedomofpress/dangerzone-image
```

2. Follow the Fedora instructions for setting up the development environment.
3. Install some extra build dependencies:

3. Build a dangerzone `.rpm` for qubes with the command
```sh
sudo dnf install -y python3-uv-build python3-pymupdf python3-magic
```

4. Build the Dangerzone RPM packages for Qubes:

```sh
./install/linux/build-rpm.py --qubes
./dangerzone/install/linux/build-rpm.py --qubes
./dangerzone-image/qubes/build-rpm.sh
```

4. Copy the produced `.rpm` file into `fedora-42-dz`
5. Copy the produced `.rpm` files into `fedora-43-dz`:

```sh
qvm-copy dist/*.x86_64.rpm
qvm-copy ./dangerzone/dist/*.x86_64.rpm \
./dangerzone-image/qubes/dist/*.noarch.rpm
```

#### In the `fedora-42-dz` template
#### In the `fedora-43-dz` template

1. Install the `.rpm` package you just copied
1. Install the `.rpm` packages you just copied, in order to get the Dangerzone
dependencies:

```sh
sudo dnf install ~/QubesIncoming/dz/*.rpm
```

2. Shutdown the `fedora-42-dz` template
2. Shutdown the `fedora-43-dz` template.

### Developing Dangerzone

Expand All @@ -279,12 +292,13 @@ are that you need to set the environment variable `QUBES_CONVERSION=1` when
you wish to test the Qubes conversion, run the following commands on the `dz` development qube:

```sh
export DANGERZONE_DEV=1 QUBES_CONVERSION=1

# run the CLI
QUBES_CONVERSION=1 poetry run dangerzone-cli --help
poetry run dangerzone-cli --help

# run the GUI
QUBES_CONVERSION=1 poetry run dangerzone
poetry run dangerzone
```

And when creating a `.rpm` you'll need to enable the `--qubes` flag.
Expand All @@ -297,15 +311,22 @@ And when creating a `.rpm` you'll need to enable the `--qubes` flag.
./install/linux/build-rpm.py --qubes
```

For changes in the server side components, you can simply edit them locally,
and they will be mirrored to the disposable qube through the `dz.ConvertDev`
RPC call.

The only reason to build a new Qubes RPM and install it in the `fedora-42-dz`
template for development is if:

1. The project requires new server-side components.
2. The code for `qubes/dz.ConvertDev` needs to be updated.
> [!TIP]
Comment thread
apyrgio marked this conversation as resolved.
> For faster changes to the server side components, you can let Dangerzone know
> about the location of `dangerzone-image` repo:
>
> ```sh
> export DANGERZONE_INSECURE_CONVERTER_PATH=~/dangerzone-image/src
> ```
>
> From there on, you can make changes in the `dangerzone-image` repo, and they
> will be mirrored to the disposable qube through the `dz.ConvertDev` RPC call.
>
> The only reason to build a new Qubes RPM and install it in the `fedora-43-dz`
> template for development is if:
>
> 1. The project requires new server-side components.
> 2. The code for `qubes/dz.ConvertDev` needs to be updated.

## macOS

Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ since 0.4.1, and this project adheres to [Semantic Versioning](https://semver.or
- Bump `vfkit` to 0.6.3 (now signed upstream, switching to `vfkit-unsigned`
with a relaxed `>=0.6.1` pin) and `cosign` to 2.6.3 in `mazette.lock`,
and regenerate `poetry.lock` with Poetry 2.3.
- Update the build instructions for Qubes, in order to work with the new
`dangerzone-insecure-converter-qubes` RPM package.
([#1463](https://github.com/freedomofpress/dangerzone/pull/1463))

## [0.10.0](https://github.com/freedomofpress/dangerzone/releases/tag/v0.10.0) - 2025-12-02

Expand Down
8 changes: 4 additions & 4 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,8 @@ After the above command completes, restart your computer to complete the install

> [!IMPORTANT]
> This section will install Dangerzone in your **default template**
> (`fedora-42` as of writing this). If you want to install it in a different
> one, make sure to replace `fedora-42` with the template of your choice.
> (`fedora-43` as of writing this). If you want to install it in a different
> one, make sure to replace `fedora-43` with the template of your choice.

The following steps must be completed once. Make sure you run them in the
specified qubes.
Expand All @@ -249,7 +249,7 @@ Create a **disposable**, offline app qube (`dz-dvm`), based on your default
template. This will be the qube where the documents will be sanitized:

```sh
qvm-create --class AppVM --label red --template fedora-42 \
qvm-create --class AppVM --label red --template fedora-43 \
--prop netvm="" --prop template_for_dispvms=True \
--prop default_dispvm='' dz-dvm
```
Expand All @@ -262,7 +262,7 @@ document, with the following contents:
dz.Convert * @anyvm @dispvm:dz-dvm allow
```

#### In the `fedora-42` template
#### In the `fedora-43` template

Install Dangerzone:

Expand Down
24 changes: 12 additions & 12 deletions dangerzone/isolation_provider/qubes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import sys
import zipfile
from pathlib import Path
from typing import IO, Callable, Optional
from typing import IO

from ..document import Document
from ..updater.signatures import is_container_tar_bundled
Expand All @@ -25,7 +25,8 @@ def get_max_parallel_conversions(self) -> int:
return 1

def start_doc_to_pixels_proc(self, document: Document) -> subprocess.Popen:
dev_mode = getattr(sys, "dangerzone_dev", False) is True
conv_mod_path = os.environ.get("DANGERZONE_INSECURE_CONVERTER_PATH", None)
Comment thread
almet marked this conversation as resolved.
dev_mode = getattr(sys, "dangerzone_dev", False) is True and conv_mod_path
if dev_mode:
# Use dz.ConvertDev RPC call instead, if we are in development mode.
# Basically, the change is that we also transfer the necessary Python
Expand All @@ -48,8 +49,9 @@ def start_doc_to_pixels_proc(self, document: Document) -> subprocess.Popen:

if dev_mode:
assert p.stdin is not None
assert conv_mod_path is not None
# Send the dangerzone module first.
self.teleport_dz_module(p.stdin)
self.teleport_dz_module(conv_mod_path, p.stdin)

return p

Expand Down Expand Up @@ -83,20 +85,18 @@ def terminate_doc_to_pixels_proc(
if p.stdout:
p.stdout.close()

def teleport_dz_module(self, wpipe: IO[bytes]) -> None:
"""Send the conversion module to another qube, as a zipfile."""
# Grab the absolute file path of the conversion module.
import conversion as _conv

_conv_path = Path(_conv.__file__).parent
def teleport_dz_module(self, conv_path: str, wpipe: IO[bytes]) -> None:
"""Send the dangerzone module to another qube, as a zipfile."""
# Grab the absolute file path of the dangerzone module.
temp_file = io.BytesIO()

with zipfile.ZipFile(temp_file, "w") as z:
for root, _, files in os.walk(_conv_path):
z.mkdir("dangerzone_insecure_converter/")
for root, _, files in os.walk(conv_path):
for file in files:
if file.endswith(".py"):
file_path = os.path.join(root, file)
relative_path = os.path.relpath(file_path, _conv_path.parent)
relative_path = os.path.relpath(file_path, conv_path)
z.write(file_path, relative_path)

# Send the following data:
Expand All @@ -109,7 +109,7 @@ def teleport_dz_module(self, wpipe: IO[bytes]) -> None:


def is_qubes_native_conversion() -> bool:
"""Returns True if the conversion should be run using Qubes OS's diposable
"""Returns True if the conversion should be run using Qubes OS's disposable
VMs and False if not."""
if os.path.exists("/usr/share/qubes/marker-vm"):
if getattr(sys, "dangerzone_dev", False):
Expand Down
15 changes: 3 additions & 12 deletions install/linux/dangerzone.spec
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ BuildRequires: python3-devel
# Qubes-only requirements (server-side)
Requires: python3-magic
Requires: libreoffice

# Qubes-only dependency, to install a single RPM package in the Fedora template.
Requires: dangerzone-insecure-converter-qubes
%else
# Container-only requirements
Requires: podman
Expand Down Expand Up @@ -250,13 +253,6 @@ install -pm 755 -d %{buildroot}/usr/share/dangerzone/vendor/
install -pm 755 share/vendor/* %{buildroot}/usr/share/dangerzone/vendor
%endif

# In case we create a package for Qubes, add some extra files under
# /etc/qubes-rpc.
%if 0%{?_qubes}
install -pm 755 -d %{buildroot}/etc/qubes-rpc
install -pm 755 qubes/* %{buildroot}/etc/qubes-rpc
%endif

%check
# Detect if the filesystem has been affecting our file permissions.
bad_files=$(find %{buildroot} -perm 0600)
Expand All @@ -276,11 +272,6 @@ fi
%license LICENSE
%doc README.md

%if 0%{?_qubes}
# Include some configuration files for Qubes.
/etc/qubes-rpc
%endif

# Remove any stale .egg-info directories, to help users affected by
# https://github.com/freedomofpress/dangerzone/issues/514
%post
Expand Down
2 changes: 0 additions & 2 deletions qubes/dz.Convert

This file was deleted.

39 changes: 0 additions & 39 deletions qubes/dz.ConvertDev

This file was deleted.

4 changes: 0 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,6 @@ def noop(*args: Any, **kwargs: Any) -> bool:
)


class TestBase:
sample_doc = str(test_docs_dir / BASIC_SAMPLE_PDF)


def pytest_configure(config: pytest.Config) -> None:
config.addinivalue_line(
"markers",
Expand Down
4 changes: 4 additions & 0 deletions tests/gui/test_main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
)
from dangerzone.isolation_provider.container import Container
from dangerzone.isolation_provider.dummy import Dummy
from dangerzone.isolation_provider.qubes import is_qubes_native_conversion
from dangerzone.updater import (
LAST_KNOWN_LOG_INDEX,
EmptyReport,
Expand Down Expand Up @@ -811,6 +812,9 @@ def test_close_event(
handle_task_container_stop_spy.assert_called_once()


@pytest.mark.skipif(
is_qubes_native_conversion(), reason="Qubes native conversion is enabled"
)
def test_user_prompts(qtbot: QtBot, window: MainWindow, mocker: MockerFixture) -> None:
"""Test prompting users to ask them if they want to enable update checks."""
# First run
Expand Down
7 changes: 7 additions & 0 deletions tests/gui/test_startup.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import typing

import pytest
from pytest_mock import MockerFixture
from pytestqt.qtbot import QtBot

if typing.TYPE_CHECKING:
from PySide2 import QtCore

from dangerzone.gui import startup
from dangerzone.isolation_provider.qubes import is_qubes_native_conversion
from dangerzone.startup import MachineInitTask, MachineStartTask, Task
from dangerzone.updater import ErrorReport, InstallationStrategy, ReleaseReport
from dangerzone.updater import errors as update_errors

# It doesn't make sense to test the startup logic in a Qubes platform, since
# we don't make much use of it.
if is_qubes_native_conversion():
pytest.skip("Qubes native conversion is enabled", allow_module_level=True)


class StartupThreadMocker(startup.StartupThread):
def __init__(self, qtbot: QtBot, mocker: MockerFixture) -> None:
Expand Down
Loading
Loading