151 lines
4.9 KiB
Markdown
151 lines
4.9 KiB
Markdown
<!--
|
|
# SPDX-License-Identifier: BSD-2-Clause
|
|
# SPDX-FileCopyrightText: 2023 KDE e.V.
|
|
# SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
|
|
-->
|
|
|
|
# flatpaksigner.py - A Flatpak Signing and Publishing Service
|
|
|
|
This service takes a Flatpak bundle file and adds it to a remote repository
|
|
signing the commits. The remote repository is fetched and re-uploaded with
|
|
rsync.
|
|
|
|
## Prerequisites
|
|
|
|
The service needs an SFTP server for exchanging data with the clients.
|
|
|
|
For signing the commits you need a private OpenPGP key. No password must be
|
|
required for using the key, i.e. either the private key is not protected with
|
|
a password or the private key is preloaded in gpg-agent.
|
|
|
|
Additionally, the following tools must be available in the path:
|
|
|
|
- `flatpak`
|
|
- `rsync`
|
|
- `ostree` - used for creating a new repo
|
|
|
|
## Installation
|
|
|
|
### Install the Service
|
|
|
|
Clone this repository on a server that shall provide the service,
|
|
create a virtual environment, and install the requirements.
|
|
|
|
```sh
|
|
git clone https://invent.kde.org/sysadmin/ci-notary-service.git flatpaksigner
|
|
cd flatpaksigner
|
|
python3 -m venv .venv
|
|
. .venv/bin/activate
|
|
pip3 install -r requirements.txt
|
|
```
|
|
|
|
### Configure the Service
|
|
|
|
Copy `flatpaksigner.sample.ini` to `flatpaksigner.ini` and replace the example values
|
|
with the appropriate values for your installation.
|
|
|
|
Then copy `flatpaksigner-projects.sample.yaml` to `flatpaksigner-projects.yaml` and
|
|
specify the settings for the projects you want to use service for.
|
|
|
|
Create a signing key for the repository, e.g. use
|
|
|
|
```sh
|
|
gpg --quick-gen-key "My Flatpak Repo Signing Key <flatpaks@example.net>" default default never
|
|
```
|
|
|
|
to create a key with default algorithm and usage that doesn't expire. When asked
|
|
for a passphrase press Return and confirm that you do not want to protect the key
|
|
with a passphrase. This has to be done twice because two key pairs are generated.
|
|
You should get output like this:
|
|
|
|
```
|
|
gpg: revocation certificate stored as '~/.gnupg/openpgp-revocs.d/A8C4AA3035D600F41C5240DAE27DF85D87A8FD63.rev'
|
|
public and secret key created and signed.
|
|
|
|
pub ed25519 2023-12-07 [SC]
|
|
A8C4AA3035D600F41C5240DAE27DF85D87A8FD63
|
|
uid My Flatpak Repo Signing Key <flatpaks@example.net>
|
|
sub cv25519 2023-12-07 [E]
|
|
```
|
|
|
|
Add the fingerprint of the signing key to the `flatpaksigner-projects.yaml`.
|
|
Then export the public key of the signing key to a file, e.g. with
|
|
|
|
```sh
|
|
gpg --export A8C4AA3035D600F41C5240DAE27DF85D87A8FD63 >~/repo_keys/A8C4AA3035D600F41C5240DAE27DF85D87A8FD63.gpg
|
|
```
|
|
|
|
where `~/repo_keys/` is the location you specified as `RepoKeysLocation` in
|
|
`flatpaksigner.ini`. The service will use the public key when it generates
|
|
`.flatpakref` files for the signed and published applications.
|
|
|
|
## Run the Service
|
|
|
|
Activate the virtual environment and start `flatpaksigner.py`.
|
|
|
|
```sh
|
|
cd ~/flatpaksigner
|
|
. .venv/bin/activate
|
|
python3 flatpaksigner.py --id workerA --config flatpaksigner.ini
|
|
```
|
|
|
|
where you replace `workerA` with a unique alpha-numeric ID for each instance
|
|
of `flatpaksigner.py` you start. You can run multiple instances, but the
|
|
behavior is undefined if multiple instances operate on the same repository.
|
|
Therefore, it's recommended to run only one service per repository.
|
|
|
|
## Use the Service to Sign and Publish a Flatpak Bundle
|
|
|
|
Clone this repository on the client, create a virtual environment, and install
|
|
the requirements.
|
|
|
|
```sh
|
|
git clone https://invent.kde.org/sysadmin/ci-notary-service.git flatpaksigner
|
|
cd flatpaksigner
|
|
python3 -m venv .venv
|
|
. .venv/bin/activate
|
|
pip3 install -r requirements.txt
|
|
```
|
|
|
|
Copy `signflatpak.sample.ini` to `signflatpak.ini` and replace the example values
|
|
with the appropriate values for your installation. In particular, the value
|
|
for `BasePath` must match the corresponding value in the settings of the
|
|
service.
|
|
|
|
Then run `signflatpak.py` to sign and publish the Flatpak bundle
|
|
|
|
```sh
|
|
python3 signflatpak.py --config signflatpak.ini <flatpak bundle file>
|
|
```
|
|
|
|
## Manage the Service with systemd
|
|
|
|
We set up the service under the user's control with a per-user systemd instance.
|
|
|
|
Copy `flatpaksigner-user.sample.service` to `~/.config/systemd/user/flatpaksigner-user.service`
|
|
and modify it as needed. The example uses the username as ID of the service
|
|
worker. Make sure that the ID is unique if you run multiple service workers.
|
|
|
|
Start the service with
|
|
|
|
```sh
|
|
systemctl --user start flatpaksigner-user.service
|
|
```
|
|
|
|
If you want the service to be started automatically, then enable autostart with
|
|
|
|
```sh
|
|
systemctl --user enable flatpaksigner-user.service
|
|
```
|
|
|
|
Note: By default, the systemd user instance and thus the user-managed services are
|
|
started after the first login of a user and killed after the last session of the
|
|
user is closed. To start the user instance right after boot, and keep the systemd
|
|
user instance running after the last session closes you have to enable lingering
|
|
for the user:
|
|
|
|
```sh
|
|
loginctl enable-linger USERNAME
|
|
```
|
|
|
|
For more details on user-managed services see https://wiki.archlinux.org/title/Systemd/User.
|