From b6daf66149a30d084b46f9078c47aeff64201e23 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 8 Aug 2026 13:39:04 +0000 Subject: [PATCH 1/6] Add snap packaging for KLog Package KLog as a strictly confined snap so it can be installed on any GNU/Linux distribution running snapd, independently of the Qt version that distribution ships. The recipe builds against core26 (Ubuntu 26.04). KLog links against Qt6 Location for the map window, and upstream Qt had no QtLocation between 6.0 and 6.4, so the module is absent from the Ubuntu 24.04 archive that core24 snaps are built from. The KDE neon extensions ship a newer Qt but explicitly leave out QtCharts, which KLog needs for the statistics widgets. Ubuntu 26.04 carries the complete Qt 6.10 set as well as Hamlib, so every dependency comes from the distribution archive: nothing is built from source and no third-party apt repository is involved. core26 has no GNOME/KDE desktop extension yet, so snap/local/klog-launch does the work those extensions normally do for a Qt application - Qt plugin and QML search paths, the library path for the staged Qt, fontconfig and the XDG data directories - and the "gpu" extension provides the Mesa userspace drivers the QtQuick map needs. Because a confined snap gets its own home, KLog's data directory becomes ~/snap/klog/current/.klog. The launcher copies an existing ~/.klog into it on the first run so a logbook made by the .deb is not left behind; the original is never modified and KLOG_SNAP_NO_MIGRATE=1 skips the copy. Added: snap/snapcraft.yaml the recipe snap/local/klog-launch command-chain wrapper devscripts/snap-create-package.sh build helper, matching the .deb one .github/workflows/snap.yml CI build, artifact and store publishing INSTALL-snap installing, interfaces, building, publishing The build checks that the translations made it into the package, the same check the Debian package script performs, and CI additionally verifies that the QtLocation QML module, the geoservices plugins and the Qt SQLite driver are present. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019NH3YWvwLzEr3nZuQdhUZM --- .github/workflows/snap.yml | 78 ++++++++++ .gitignore | 7 + Changelog | 1 + INSTALL-snap | 179 +++++++++++++++++++++ INSTALL.txt | 2 + README.md | 13 ++ devscripts/snap-create-package.sh | 113 ++++++++++++++ snap/local/klog-launch | 114 ++++++++++++++ snap/snapcraft.yaml | 249 ++++++++++++++++++++++++++++++ src/CMakeLists.txt | 1 + 10 files changed, 757 insertions(+) create mode 100644 .github/workflows/snap.yml create mode 100644 INSTALL-snap create mode 100755 devscripts/snap-create-package.sh create mode 100755 snap/local/klog-launch create mode 100644 snap/snapcraft.yaml diff --git a/.github/workflows/snap.yml b/.github/workflows/snap.yml new file mode 100644 index 000000000..bb8a16a8b --- /dev/null +++ b/.github/workflows/snap.yml @@ -0,0 +1,78 @@ +name: Build Snap package + +on: + push: + branches: [ master, main ] + tags: [ 'v*' ] + pull_request: + branches: [ master, main ] + workflow_dispatch: + +permissions: + contents: read + +jobs: + build-snap: + name: Build snap + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: recursive + + # snapcraft reads snap/snapcraft.yaml, builds against core26 in an LXD + # container and leaves klog__.snap in the workspace. + - name: Build snap + id: snapcraft + uses: snapcore/action-build@v1 + + - name: Check the package contents + run: | + sudo apt-get update + sudo apt-get install -y squashfs-tools + SNAP="${{ steps.snapcraft.outputs.snap }}" + echo "Built: $SNAP" + # Translations are silently skipped when LinguistTools is missing, + # which would ship an English-only KLog. + unsquashfs -l "$SNAP" | grep -q "usr/share/klog/translations/klog_.*\.qm" \ + || { echo "ERROR: no translations in the snap"; exit 1; } + # The map window needs the QtLocation QML module and the OSM plugin. + unsquashfs -l "$SNAP" | grep -q "qt6/qml/QtLocation" \ + || { echo "ERROR: QtLocation QML module missing"; exit 1; } + unsquashfs -l "$SNAP" | grep -q "qt6/plugins/geoservices" \ + || { echo "ERROR: geoservices plugins missing"; exit 1; } + # The logbook is a SQLite database. + unsquashfs -l "$SNAP" | grep -q "qt6/plugins/sqldrivers/libqsqlite" \ + || { echo "ERROR: Qt SQLite driver missing"; exit 1; } + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: KLog-snap-package + path: ${{ steps.snapcraft.outputs.snap }} + + - name: Create Release + if: startsWith(github.ref, 'refs/tags/v') + uses: softprops/action-gh-release@v2 + with: + files: ${{ steps.snapcraft.outputs.snap }} + name: KLog ${{ github.ref_name }} + draft: false + prerelease: ${{ contains(github.ref_name, 'RC') || contains(github.ref_name, 'alpha') || contains(github.ref_name, 'beta') }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Publishing to the Snap Store needs the SNAPCRAFT_STORE_CREDENTIALS + # secret, created with: snapcraft export-login --snaps=klog \ + # --acls package_access,package_push,package_update,package_release - + # The step is skipped while the secret is not configured. + - name: Publish to the Snap Store + if: startsWith(github.ref, 'refs/tags/v') && env.SNAPCRAFT_STORE_CREDENTIALS != '' + uses: snapcore/action-publish@v1 + env: + SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }} + with: + snap: ${{ steps.snapcraft.outputs.snap }} + release: ${{ (contains(github.ref_name, 'RC') || contains(github.ref_name, 'alpha') || contains(github.ref_name, 'beta')) && 'beta' || 'stable' }} diff --git a/.gitignore b/.gitignore index e16b77028..505a12fca 100644 --- a/.gitignore +++ b/.gitignore @@ -339,3 +339,10 @@ tests/tst_qsodatacache/.qt/QtDeployTargets.cmake tests/tst_qsodatacache/resources.qrc.depends src/macOSDeploy-M.sh Testing/* + +# snapcraft build artefacts (snap/snapcraft.yaml itself is tracked) +/parts/ +/stage/ +/prime/ +.snapcraft/ +*.snap diff --git a/Changelog b/Changelog index 34a9806ae..f27c3a861 100644 --- a/Changelog +++ b/Changelog @@ -20,6 +20,7 @@ TBD - 2.6 - Bugfix: Fix BAND_RX export when RX band is empty (TNX YL3GBC) - Bugfix: Apply the same BAND_RX guard (skip empty, "0" and same-as-BAND values) to the Club Log real-time upload, which also fixes 2-character RX bands (6m/4m/2m) being dropped. - Maintenance: The ADIF file is now always produced by a single serializer (QSO::getADIF); removed the unused per-destination ADIF writers and moved the BAND/BAND_RX "0" check into Adif::getADIFField() so it is enforced in one single place. +- New feature: KLog can be packaged as a snap, so it can be installed on any GNU/Linux distribution with snapd regardless of the Qt version that distribution ships. The recipe is in snap/snapcraft.yaml, the build script in devscripts/snap-create-package.sh, and INSTALL-snap covers installing it, the interfaces that have to be connected for CAT control and printing, and where the logbook lives. A logbook already in ~/.klog is copied into the snap the first time it runs. July 2026 - 2.5.3 - Bugfix: BandRX was not synced with FreqRX if FreqRX was not defined and BandRX was same as BandTX. diff --git a/INSTALL-snap b/INSTALL-snap new file mode 100644 index 000000000..0499e0768 --- /dev/null +++ b/INSTALL-snap @@ -0,0 +1,179 @@ +Installing and building the KLog snap package +============================================= + +A snap is a self-contained package: it carries Qt6, Hamlib and everything +else KLog needs, so it installs on any GNU/Linux distribution with snapd +regardless of which Qt version that distribution ships. + +If you have any suggestion for this file, please contact me. (Contact +details in the AUTHORS file). + + +1. Installing +------------- + +From the Snap Store, once the package has been published: + + sudo snap install klog + +From a locally built or downloaded file: + + sudo snap install --dangerous klog_2.6-alpha_amd64.snap + +("--dangerous" is only needed because a local file is not signed by the +store; it says nothing about the package itself.) + +Then run it from your application menu, or from a terminal with: + + klog + + +2. Connecting the interfaces +---------------------------- + +A snap only gets the permissions it asks for. Most of the ones KLog uses +(the desktop session, the network, your home directory, removable media) +are connected automatically when you install it. Three are not, because +snapd never connects them without being asked: + + * CAT control over a USB adapter or a built-in USB radio interface: + + sudo snap connect klog:raw-usb + + * CAT control over a serial port. First find the slot for your radio: + + snap interface serial-port + + and then connect it, using the slot name from that listing: + + sudo snap connect klog:serial-port + + On most desktop distributions snapd creates one slot per USB-serial + adapter as you plug it in, so the slot only exists while the radio is + connected. + + * Printing the log: + + sudo snap connect klog:cups-control + +You can see the state of every interface at any time with: + + snap connections klog + + +3. Where the logbook lives +-------------------------- + +A strictly confined snap gets its own home directory, so KLog's data +directory is: + + ~/snap/klog/current/.klog + +not ~/.klog. The logbook, the settings and the downloaded cty.dat all live +there, and snapd includes it in "snap save" snapshots. + +The first time you run the snap, if you already have a ~/.klog from a .deb +or from a KLog you built yourself, it is copied into the snap's own +directory so your log is there waiting for you. The original ~/.klog is +never modified, and the copy only happens when the snap has no logbook of +its own yet. To start from an empty logbook instead: + + KLOG_SNAP_NO_MIGRATE=1 klog + +Note that the two copies are independent from that point on. If you keep +using both the .deb and the snap, they will drift apart. + + +4. Known limitations of the snap +-------------------------------- + + * Signing a LoTW upload calls the external TQSL program. A strictly + confined snap cannot run programs installed on the host, so the + "sign and upload to LoTW" button does not work from the snap. Export + the ADIF file and sign it with TQSL outside KLog, or use the .deb. + + * Serial ports only become visible after the serial-port interface has + been connected, so the port list in Setup -> Hamlib will be empty + until you do that. + + +5. Building the snap +-------------------- + +Install the tooling (LXD is the build backend snapcraft uses by default): + + sudo snap install snapcraft --classic + sudo snap install lxd + sudo lxd init --auto + sudo usermod -a -G lxd "$USER" + +Log out and back in so the group membership takes effect, then either run +the helper script: + + cd devscripts + bash snap-create-package.sh + +or call snapcraft directly from the top of the source tree: + + snapcraft pack + +Either way you end up with klog__.snap. The helper script +additionally checks that the translations made it into the package and +moves the result into devscripts/, next to the other packages. + +The recipe is snap/snapcraft.yaml and the run-time wrapper it installs is +snap/local/klog-launch. + + +6. Why the recipe uses base: core26 +----------------------------------- + +KLog links against Qt6 Location for the map window. Upstream Qt dropped +QtLocation for Qt 6.0 to 6.4 and only brought it back in 6.5, so it is +simply not in the Ubuntu 24.04 archive that core24 snaps are built from - +there is no qt6-location-dev or libqt6location6 package there at all. + +The KDE neon snapcraft extensions do provide a recent Qt, but they +explicitly do not ship QtCharts, which KLog needs for the statistics +widgets, so they would mean building Qt modules from source inside the +recipe. + +Ubuntu 26.04, which core26 is built from, carries the full Qt 6.10 set - +Charts, Location, Positioning, SerialPort, Quick - as well as Hamlib. +Every dependency therefore comes from the distribution archive: nothing is +built from source and no third-party apt repository is involved. + +core26 does not have a GNOME or KDE desktop extension yet, so the work +those extensions normally do for a Qt application (Qt plugin and QML +search paths, fontconfig, the XDG data directories) is done by +snap/local/klog-launch. Hardware accelerated graphics for the QtQuick map +comes from the "gpu" extension. Once a desktop extension supports +core26, most of that wrapper can be dropped. + + +7. Publishing to the Snap Store +------------------------------- + +The name has to be registered once, by the account that will own it: + + snapcraft login + snapcraft register klog + +If the name is already taken by an unrelated project, either request a +transfer through the store's dispute process or change the "name:" field +in snap/snapcraft.yaml (klog-hamradio, for example) before registering. + +Uploading a build: + + snapcraft upload --release=edge klog__.snap + +.github/workflows/snap.yml builds the snap on every push and uploads it as +a workflow artifact. On a v* tag it also attaches the .snap to the GitHub +release, and publishes it to the Snap Store if the repository has a +SNAPCRAFT_STORE_CREDENTIALS secret, created with: + + snapcraft export-login --snaps=klog \ + --acls package_access,package_push,package_update,package_release - + + +73 diff --git a/INSTALL.txt b/INSTALL.txt index d0bfddb84..6d5d7b8af 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -4,6 +4,8 @@ Please read: INSTALL-linux.txt for linux installations. + INSTALL-snap for the snap package (any linux distribution with snapd). + INSTALL-macOS.txt for macOS installations. INSTALL-win.txt for Windows installations. diff --git a/README.md b/README.md index 3231ca812..eed22a2a0 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,19 @@ The Telegram chat group in Spanish: ## Install Read the INSTALL.txt for installation purposes. +On GNU/Linux KLog can also be built and installed as a snap package, which +bundles Qt6 and Hamlib and therefore runs on any distribution with snapd +regardless of the Qt version that distribution ships: + +``` +snapcraft pack +sudo snap install --dangerous klog_*.snap +``` + +Once the package is published in the Snap Store, `sudo snap install klog` will +be all that is needed. See [INSTALL-snap](INSTALL-snap) for the interfaces you +have to connect for CAT control and printing, and for where the logbook lives. + Please send all your suggestions & bug reports. I hope you enjoy KLog! diff --git a/devscripts/snap-create-package.sh b/devscripts/snap-create-package.sh new file mode 100755 index 000000000..bb034a684 --- /dev/null +++ b/devscripts/snap-create-package.sh @@ -0,0 +1,113 @@ +#!/bin/bash +# Script to build the KLog snap package +# Can be run locally or called from Jenkins/GitHub Actions +# +# Usage: +# cd devscripts +# bash snap-create-package.sh +# +# Requirements: +# - snapd, snapcraft and a build backend (LXD is the default) +# sudo snap install snapcraft --classic +# sudo snap install lxd && sudo lxd init --auto +# sudo usermod -a -G lxd "$USER" # log out and back in afterwards +# - Must be run from the devscripts directory +# +# The recipe lives in snap/snapcraft.yaml and builds against core26 +# (Ubuntu 26.04), which is the first Ubuntu release carrying Qt6 Location. +# +#*************************************************************************** +# +# snap-create-package.sh +# ------------------- +# begin : aug 2026 +# copyright : (C) 2026 by Jaime Robles +# email : jaime@robles.es +# +#***************************************************************************** +# * This file is part of KLog. * +# * * +# * KLog is free software: you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License as published by * +# * the Free Software Foundation, either version 3 of the License, or * +# * (at your option) any later version. * +# * * +# * KLog is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU General Public License for more details. * +# * * +# * You should have received a copy of the GNU General Public License * +# * along with KLog. If not, see . * +# * * +#*****************************************************************************/ + +set -e + +DEVSCRIPTS_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_DIR="$(dirname "$DEVSCRIPTS_DIR")" + +# --- Read version from CMakeLists.txt (same source the recipe uses) --- +KLOG_VERSION=$(grep 'APP_PKGVERSION' "$PROJECT_DIR/CMakeLists.txt" | sed 's/.*"\(.*\)".*/\1/') +if [ -z "$KLOG_VERSION" ]; then + KLOG_VERSION=$(grep 'project(KLog VERSION' "$PROJECT_DIR/CMakeLists.txt" | awk '{print $3}') +fi + +echo "Building KLog $KLOG_VERSION snap package" + +# --- Check the toolchain is there --- +if ! command -v snapcraft >/dev/null 2>&1; then + echo "ERROR: snapcraft not found. Install it with:" + echo " sudo snap install snapcraft --classic" + exit 1 +fi + +ARCH=$(dpkg --print-architecture 2>/dev/null || uname -m) +echo "Architecture: $ARCH" + +# --- Clean previous build --- +echo "[1/3] Cleaning..." +rm -f "$DEVSCRIPTS_DIR"/klog_*.snap +(cd "$PROJECT_DIR" && snapcraft clean) + +# --- Build --- +echo "[2/3] Building the snap (this pulls the core26 and mesa-2604 snaps the" +echo " first time and takes a while)..." +(cd "$PROJECT_DIR" && snapcraft pack) + +# --- Find whatever snapcraft generated and move it next to the other packages --- +echo "[3/3] Collecting the artifact..." +SNAP_FILE=$(find "$PROJECT_DIR" -maxdepth 1 -name "klog_*.snap" | head -1) +if [ -z "$SNAP_FILE" ]; then + echo "ERROR: snapcraft did not generate any .snap file" + exit 1 +fi + +# --- Check the translations made it into the package --- +# The .qm files are installed into usr/share/klog/translations, which is where +# KLog looks for them. If LinguistTools is missing they are silently skipped, +# and KLog would be shipped in English only. +if command -v unsquashfs >/dev/null 2>&1; then + if ! unsquashfs -l "$SNAP_FILE" | grep -q "usr/share/klog/translations/klog_.*\.qm"; then + echo "ERROR: $SNAP_FILE contains no KLog translation files" + echo " Check that Qt6 LinguistTools (lrelease) is available." + exit 1 + fi +else + echo "WARNING: unsquashfs not available, skipping the translations check" +fi + +mv "$SNAP_FILE" "$DEVSCRIPTS_DIR/" +FINAL_NAME=$(basename "$SNAP_FILE") + +echo "" +echo "Done! KLog $KLOG_VERSION -> devscripts/$FINAL_NAME" +echo "" +echo "Install it locally with:" +echo " sudo snap install --dangerous devscripts/$FINAL_NAME" +echo "" +echo "Then connect the interfaces that are not connected automatically:" +echo " sudo snap connect klog:raw-usb" +echo " sudo snap connect klog:cups-control" +echo " snap interface serial-port # find your radio's slot" +echo " sudo snap connect klog:serial-port " diff --git a/snap/local/klog-launch b/snap/local/klog-launch new file mode 100755 index 000000000..a47c3edeb --- /dev/null +++ b/snap/local/klog-launch @@ -0,0 +1,114 @@ +#!/bin/bash +#*************************************************************************** +# klog-launch +# ------------------- +# begin : aug 2026 +# copyright : (C) 2026 by Jaime Robles +# email : jaime@robles.es +# +#***************************************************************************** +# * This file is part of KLog. * +# * * +# * KLog is free software: you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License as published by * +# * the Free Software Foundation, either version 3 of the License, or * +# * (at your option) any later version. * +# * * +# * KLog is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU General Public License for more details. * +# * * +# * You should have received a copy of the GNU General Public License * +# * along with KLog. If not, see . * +# * * +#*****************************************************************************/ +# +# command-chain wrapper for the KLog snap. +# +# core26 has no GNOME/KDE snapcraft extension yet, so the environment those +# extensions would normally set up for a Qt application is set up here: plugin +# and QML search paths, the library path for the staged Qt, fontconfig and the +# XDG data directories. It also performs the one-time logbook migration +# described in INSTALL-snap. +# +# A command-chain entry must exec the next command in the chain, so this script +# always ends with `exec "$@"`. + +set -u + +# --------------------------------------------------------------------------- +# Multiarch directory of the staged libraries (x86_64-linux-gnu, +# aarch64-linux-gnu, ...). Derived at run time so the snap stays +# architecture independent. +# --------------------------------------------------------------------------- +arch_triplet="" +for dir in "$SNAP"/usr/lib/*-linux-gnu*; do + if [ -d "$dir/qt6" ]; then + arch_triplet="${dir##*/}" + break + fi +done + +if [ -z "$arch_triplet" ]; then + echo "klog: no Qt6 directory found under $SNAP/usr/lib - broken snap?" >&2 + exec "$@" +fi + +qt_libdir="$SNAP/usr/lib/$arch_triplet" + +# --------------------------------------------------------------------------- +# Qt runtime. The plugins (xcb/wayland platform, sqlite driver, OSM +# geoservices, image formats) and the QML modules used by the map window are +# dlopen()ed, so Qt has to be told where they are. +# --------------------------------------------------------------------------- +export QT_PLUGIN_PATH="$qt_libdir/qt6/plugins${QT_PLUGIN_PATH:+:$QT_PLUGIN_PATH}" +export QML_IMPORT_PATH="$qt_libdir/qt6/qml${QML_IMPORT_PATH:+:$QML_IMPORT_PATH}" +export QML2_IMPORT_PATH="$QML_IMPORT_PATH" + +# Prepended, never replaced: the gpu extension has already put the host's +# Mesa userspace drivers on the path and those must stay reachable. +export LD_LIBRARY_PATH="$qt_libdir:$SNAP/usr/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" + +# --------------------------------------------------------------------------- +# Desktop data: the .desktop entry, the icon and KLog's own .qm translations +# live under $SNAP/usr/share. +# --------------------------------------------------------------------------- +export XDG_DATA_DIRS="$SNAP/usr/share:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" + +# The desktop interface bind-mounts the host font directories into the snap; +# fontconfig itself is staged, and this is its configuration. +if [ -f "$SNAP/etc/fonts/fonts.conf" ]; then + export FONTCONFIG_PATH="$SNAP/etc/fonts" + export FONTCONFIG_FILE="$SNAP/etc/fonts/fonts.conf" +fi + +# --------------------------------------------------------------------------- +# One-time logbook migration. +# +# Under strict confinement HOME is $SNAP_USER_DATA (~/snap/klog/current), so +# KLog's QDir::homePath()+"/.klog" resolves inside the snap and a logbook made +# by the .deb or by a self-built KLog would appear to have vanished. Copy it +# across on the first run. The copy is only made when the snap has no logbook +# of its own yet, and the original is never touched. +# +# Set KLOG_SNAP_NO_MIGRATE=1 to start with an empty logbook instead. +# --------------------------------------------------------------------------- +if [ -z "${KLOG_SNAP_NO_MIGRATE:-}" ] && + [ -n "${SNAP_REAL_HOME:-}" ] && + [ -n "${HOME:-}" ] && + [ "$SNAP_REAL_HOME" != "$HOME" ] && + [ ! -e "$HOME/.klog" ] && + [ -d "$SNAP_REAL_HOME/.klog" ]; then + if cp -a "$SNAP_REAL_HOME/.klog" "$HOME/.klog.migrating" 2>/dev/null && + mv "$HOME/.klog.migrating" "$HOME/.klog" 2>/dev/null; then + echo "klog: copied the logbook from $SNAP_REAL_HOME/.klog to $HOME/.klog" >&2 + echo "klog: the original was left untouched; the snap uses its own copy from now on" >&2 + else + rm -rf "$HOME/.klog.migrating" + echo "klog: could not copy $SNAP_REAL_HOME/.klog, starting with an empty logbook" >&2 + echo "klog: is the home interface connected? (snap connect klog:home)" >&2 + fi +fi + +exec "$@" diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml new file mode 100644 index 000000000..9c156c4a7 --- /dev/null +++ b/snap/snapcraft.yaml @@ -0,0 +1,249 @@ +#*************************************************************************** +# snapcraft.yaml +# ------------------- +# begin : aug 2026 +# copyright : (C) 2026 by Jaime Robles +# email : jaime@robles.es +# +#***************************************************************************** +# * This file is part of KLog. * +# * * +# * KLog is free software: you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License as published by * +# * the Free Software Foundation, either version 3 of the License, or * +# * (at your option) any later version. * +# * * +# * KLog is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU General Public License for more details. * +# * * +# * You should have received a copy of the GNU General Public License * +# * along with KLog. If not, see . * +# * * +#*****************************************************************************/ +# +# Build with: snapcraft (see devscripts/snap-create-package.sh) +# Install with: sudo snap install --dangerous ./klog_*.snap +# +# Why base: core26 +# ---------------- +# KLog links against Qt6 Location (the world map in the Map window). QtLocation +# was dropped upstream for Qt 6.0-6.4 and only came back in Qt 6.5, so it is +# absent from the Ubuntu 24.04 archive that core24 is built from - there is no +# qt6-location-dev/libqt6location6 there at all. The KDE neon extensions are +# not an option either: they explicitly do not ship QtCharts, which KLog also +# needs for the statistics widgets. Ubuntu 26.04 (core26) carries the complete +# Qt 6.10 set - Charts, Location, Positioning, SerialPort, Quick - plus Hamlib, +# so every dependency comes from the distribution archive with nothing built +# from source and no third-party apt repositories. +# +# core26 has no GNOME/KDE desktop extension yet, so the desktop plumbing the +# extension would normally do (Qt plugin/QML search paths, fontconfig, XDG +# data dirs) is done by snap/local/klog-launch instead. Hardware accelerated +# graphics, needed by the QtQuick map, comes from the "gpu" extension. + +name: klog +adopt-info: klog +base: core26 +license: GPL-3.0-or-later +summary: Ham radio DX logging program +description: | + KLog is a free (as in freedom) hamradio logging program for GNU/Linux, + macOS and Windows. + + It provides general purpose DX logging support: + + * QSO logging with DXCC, WAZ, ITU zone and grid locator tracking + * ADIF import and export + * Statistics and charts (QSOs per band, mode, year, continent, DXCC ...) + * DX cluster client with a DX assistant + * eQSL, LoTW, ClubLog and QRZ.com logbook integration + * Satellite QSO support + * CAT control through Hamlib + * A UDP server that logs QSOs sent by WSJT-X and compatible programs + + The logbook lives in ~/snap/klog/current/.klog. On first run the snap copies + an existing ~/.klog logbook (from a .deb or a self-built KLog) into that + location so nothing is lost when moving to the snap; set + KLOG_SNAP_NO_MIGRATE=1 to skip that. + + Some interfaces are not connected automatically and are needed for CAT + control and printing: + + sudo snap connect klog:raw-usb + sudo snap connect klog:serial-port + sudo snap connect klog:cups-control + + See INSTALL-snap in the source tree for the details. + +# The store icon. The .desktop entry gets its own icon path at build time. +icon: src/img/klog_256x256.png + +website: https://github.com/ea4k/klog +source-code: https://github.com/ea4k/klog +issues: https://github.com/ea4k/klog/issues +contact: jaime@robles.es + +# "grade" says whether the revision may be released to the stable channel, not +# whether the KLog release itself is stable. Pre-releases are published to the +# edge/beta channels; the grade does not need to change for that. +grade: stable +confinement: strict +compression: lzo + +platforms: + amd64: + arm64: + +apps: + klog: + command: usr/bin/klog + command-chain: + - bin/klog-launch + desktop: usr/share/applications/io.github.ea4k.klog.desktop + common-id: io.github.ea4k.klog + # Mesa userspace drivers for the QtQuick map. On core26 this pulls in the + # mesa-2604 provider snap through the gpu-2604 content interface. + extensions: + - gpu + plugs: + # Desktop session: windowing, clipboard, notifications, xdg-open for the + # "look this callsign up on QRZ.com" links, and the host font set. + - desktop + - desktop-legacy + - wayland + - x11 + - unity7 + - opengl + # cty.dat and satellite data downloads, DX cluster telnet sessions and + # the eQSL/LoTW/ClubLog/QRZ.com web services. + - network + # UDP server listening for WSJT-X (default port 2237). + - network-bind + # ADIF/Cabrillo import and export outside the snap's own directory. + - home + - removable-media + # Hamlib CAT control over a serial or USB-serial link. Neither of these + # connects automatically; see INSTALL-snap. + - serial-port + - raw-usb + # Printing the log. Manual connection. + - cups-control + +parts: + klog: + plugin: cmake + source: . + source-type: local + cmake-parameters: + - -DCMAKE_BUILD_TYPE=Release + - -DCMAKE_INSTALL_PREFIX=/usr + - -DBUILD_TESTING=OFF + # Defaults to ON in CMakeLists.txt; there are no tests in this build. + - -DKLOG_COVERAGE=OFF + build-packages: + - build-essential + - cmake + - pkg-config + # Hamlib, found through pkg-config by cmake/FindHamlib.cmake. + - libhamlib-dev + # Qt6 modules KLog links against, in the order find_package() asks for + # them: Charts Concurrent Core Gui Location Network Positioning + # PrintSupport Qml Quick QuickWidgets SerialPort Sql Widgets. + - qt6-base-dev + - qt6-charts-dev + - qt6-declarative-dev + - qt6-declarative-private-dev + - qt6-location-dev + - qt6-positioning-dev + - qt6-serialport-dev + # LinguistTools (cmake config) and lrelease/lupdate, for qt_add_translations(). + - qt6-tools-dev + - qt6-tools-dev-tools + - qt6-l10n-tools + - libgl1-mesa-dev + - libxkbcommon-dev + - libudev-dev + stage-packages: + # Only the leaf libraries are listed; apt pulls libqt6core6t64, + # libqt6gui6, libqt6widgets6, libqt6network6, libqt6qml6, libqt6quick6 + # and the rest of the dependency tree in automatically. + - libqt6charts6 + - libqt6location6 + - libqt6positioning6 + - libqt6printsupport6 + - libqt6quickwidgets6 + - libqt6serialport6 + - libqt6svg6 + # Qt plugins are dlopen()ed, so they are never pulled in as a dependency + # and have to be requested by hand. + - libqt6sql6-sqlite # the logbook is a SQLite database + - qt6-qpa-plugins # xcb platform plugin + - qt6-wayland # wayland platform plugin + - qt6-location-plugins # OSM geoservices plugin used by the map + - qt6-image-formats-plugins + - qt6-translations-l10n # translations of Qt's own standard dialogs + # QML modules imported by src/widgets/map/*.qml. + - qml6-module-qtlocation + - qml6-module-qtpositioning + - qml6-module-qtquick + - qml6-module-qtquick-controls + - qml6-module-qtquick-layouts + - qml6-module-qtquick-shapes + - qml6-module-qtquick-templates + - qml6-module-qtquick-window + - libhamlib4t64 + # The desktop interface bind-mounts /usr/share/fonts and the fontconfig + # cache from the host into the snap, but fontconfig itself is not in the + # base, so the configuration it needs has to be staged here. + - fontconfig + - libxcb-cursor0 + override-pull: | + craftctl default + # Keep the snap version in step with APP_PKGVERSION in CMakeLists.txt. + version="$(sed -n 's/^set(APP_PKGVERSION[[:space:]]*"\(.*\)").*/\1/p' \ + "${CRAFT_PART_SRC}/CMakeLists.txt" | head -1)" + if [ -z "$version" ]; then + echo "ERROR: could not read APP_PKGVERSION from CMakeLists.txt" >&2 + exit 1 + fi + craftctl set version="$version" + override-build: | + craftctl default + + desktop="${CRAFT_PART_INSTALL}/usr/share/applications/io.github.ea4k.klog.desktop" + # "Icon=klog" resolves through the icon theme, which is not set up inside + # the snap. Point it at the file the install rules put in the snap. + sed -i 's|^Icon=klog$|Icon=${SNAP}/usr/share/pixmaps/klog.png|' "$desktop" + if ! grep -q '^Icon=\${SNAP}/usr/share/pixmaps/klog.png$' "$desktop"; then + echo "ERROR: failed to rewrite Icon= in $desktop" >&2 + exit 1 + fi + + # The .qm files are silently skipped when LinguistTools is missing, which + # would ship an English-only KLog. Same check as the .deb build script. + if ! ls "${CRAFT_PART_INSTALL}"/usr/share/klog/translations/klog_*.qm >/dev/null 2>&1; then + echo "ERROR: no translations were built into the snap" >&2 + exit 1 + fi + + # Command-chain wrapper: Qt search paths, fontconfig and the one-time + # logbook migration. Kept out of the klog part so a rebuild of the wrapper + # does not rebuild KLog. + launcher: + plugin: dump + source: snap/local + organize: + klog-launch: bin/klog-launch + stage: + - bin/klog-launch + override-build: | + craftctl default + chmod 755 "${CRAFT_PART_INSTALL}/klog-launch" + +layout: + # QLibraryInfo has /usr/share/qt6 compiled in, which inside the snap would be + # the (empty) core26 base. Qt's own translations live there. + /usr/share/qt6: + bind: $SNAP/usr/share/qt6 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 95901e432..35418b1c2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -222,6 +222,7 @@ set(KLOG_DOC ../COPYING ../INSTALL-es.txt ../INSTALL-linux + ../INSTALL-snap ../INSTALL.txt ../NEWS ../README From 8a25b1da42b482b8a1ea0772a290990fc09bd002 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 8 Aug 2026 14:49:43 +0000 Subject: [PATCH 2/6] snap: confirm core26 and document that the base is not a host requirement core26 (Ubuntu 26.04) is the newest snap base available - bases are only made from LTS releases, so there is nothing above it - and it is the only Ubuntu that carries both Qt6 Location and Qt6 Charts, the two modules KLog needs that no earlier base can supply. Record the exact versions the archive publishes (Qt 6.10.2, Hamlib 4.6.5) and spell out that the base is what KLog is built against, not what the user has to be running: snapd pulls the base snap in as a dependency, so the package installs the same on Ubuntu 22.04, Debian, Fedora or Arch. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019NH3YWvwLzEr3nZuQdhUZM --- INSTALL-snap | 13 +++++++++++-- snap/snapcraft.yaml | 11 ++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/INSTALL-snap b/INSTALL-snap index 0499e0768..fb5876574 100644 --- a/INSTALL-snap +++ b/INSTALL-snap @@ -138,11 +138,20 @@ explicitly do not ship QtCharts, which KLog needs for the statistics widgets, so they would mean building Qt modules from source inside the recipe. -Ubuntu 26.04, which core26 is built from, carries the full Qt 6.10 set - -Charts, Location, Positioning, SerialPort, Quick - as well as Hamlib. +Ubuntu 26.04, which core26 is built from, carries the full Qt 6.10.2 set - +Charts, Location, Positioning, SerialPort, Quick - as well as Hamlib 4.6.5. Every dependency therefore comes from the distribution archive: nothing is built from source and no third-party apt repository is involved. +The base is what KLog is built and run against, not what you have to be +running. snapd downloads the core26 base snap as a dependency, so the +package installs and runs the same on Ubuntu 22.04 or 24.04, on Debian, +Fedora, Arch or anywhere else snapd is available. That is the whole point +of picking the newest LTS base: KLog gets a current Qt everywhere, without +asking anyone to upgrade their distribution. core26 is also as far as this +can go - snap bases are only made from LTS releases, so there is no core +base for Ubuntu 26.10 or any other interim release. + core26 does not have a GNOME or KDE desktop extension yet, so the work those extensions normally do for a Qt application (Qt plugin and QML search paths, fontconfig, the XDG data directories) is done by diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 9c156c4a7..89755775e 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -34,9 +34,14 @@ # qt6-location-dev/libqt6location6 there at all. The KDE neon extensions are # not an option either: they explicitly do not ship QtCharts, which KLog also # needs for the statistics widgets. Ubuntu 26.04 (core26) carries the complete -# Qt 6.10 set - Charts, Location, Positioning, SerialPort, Quick - plus Hamlib, -# so every dependency comes from the distribution archive with nothing built -# from source and no third-party apt repositories. +# Qt 6.10.2 set - Charts, Location, Positioning, SerialPort, Quick - plus +# Hamlib 4.6.5, so every dependency comes from the distribution archive with +# nothing built from source and no third-party apt repositories. +# +# The base says what KLog is built and run against, not what the user has to +# be running: snapd pulls the core26 base snap in as a dependency, so this +# installs just as well on Ubuntu 22.04, Debian, Fedora or Arch. Snap bases +# only exist for LTS releases, so core26 is the newest one available. # # core26 has no GNOME/KDE desktop extension yet, so the desktop plumbing the # extension would normally do (Qt plugin/QML search paths, fontconfig, XDG From d1961345a43825e9c17e1c60f87875cb27e372a0 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 8 Aug 2026 15:01:53 +0000 Subject: [PATCH 3/6] INSTALL-snap: document authenticating without a keyring "snapcraft login" keeps its token in the system keyring, so on a build server, in a container or over SSH it fails outright with "No keyring found to store or retrieve credentials from". Section 7 sent the reader straight into that command with no warning. Explain the headless route instead: "snapcraft export-login" does not touch the keyring, and exporting SNAPCRAFT_STORE_CREDENTIALS from the file it writes authenticates every snapcraft command in the shell. Note that the first export cannot use --snaps, since credentials can only be scoped to a snap that is already registered, and point at the web registration form as the alternative that needs no working CLI login. Also state up front that building the snap needs no store account at all. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019NH3YWvwLzEr3nZuQdhUZM --- INSTALL-snap | 56 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/INSTALL-snap b/INSTALL-snap index fb5876574..0aa3078de 100644 --- a/INSTALL-snap +++ b/INSTALL-snap @@ -163,26 +163,76 @@ core26, most of that wrapper can be dropped. 7. Publishing to the Snap Store ------------------------------- -The name has to be registered once, by the account that will own it: +Building the snap needs no Snap Store account at all. Everything in this +section is only about publishing it. +7.1 Logging in on a machine with no keyring +------------------------------------------- + +"snapcraft login" keeps its token in the system keyring, so on a build +server, in a container, or over SSH it fails with: + + No keyring found to store or retrieve credentials from. + +"snapcraft export-login" does not use the keyring. It asks for the same +email, password and second factor and writes the credentials out instead of +storing them, which is the supported way to authenticate on a headless +machine: + + snapcraft export-login ~/.klog-snap-credentials + export SNAPCRAFT_STORE_CREDENTIALS="$(cat ~/.klog-snap-credentials)" + snapcraft whoami + +Every snapcraft command run in that shell is then authenticated. The +credentials file is as good as a password: keep it at mode 600 and out of +the source tree. + +Do the first export without --snaps. Credentials can only be restricted to +a snap that already exists, so that flag cannot be used until the name has +been registered. + +If you would rather have a working keyring on that machine: + + sudo apt install gnome-keyring + dbus-run-session -- bash + gnome-keyring-daemon --unlock # type a password, then Ctrl-D snapcraft login + +which only lasts for that D-Bus session. + +7.2 Registering the name +------------------------- + +The name has to be registered once, by the account that will own it, +either from the CLI once you are authenticated: + snapcraft register klog +or through the web form, which needs no working CLI login and tells you +straight away whether the name is free: + + https://snapcraft.io/account/register-snap + If the name is already taken by an unrelated project, either request a transfer through the store's dispute process or change the "name:" field in snap/snapcraft.yaml (klog-hamradio, for example) before registering. -Uploading a build: +7.3 Uploading +-------------- snapcraft upload --release=edge klog__.snap .github/workflows/snap.yml builds the snap on every push and uploads it as a workflow artifact. On a v* tag it also attaches the .snap to the GitHub release, and publishes it to the Snap Store if the repository has a -SNAPCRAFT_STORE_CREDENTIALS secret, created with: +SNAPCRAFT_STORE_CREDENTIALS secret. Once the name is registered, create the +narrow credentials for that secret with: snapcraft export-login --snaps=klog \ --acls package_access,package_push,package_update,package_release - +The trailing "-" writes them to the terminal so they can be pasted into the +GitHub secret rather than left in a file. + 73 From 98b3a0f9dbcc4837434cbba6521f63dd3edb39d3 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 8 Aug 2026 15:04:28 +0000 Subject: [PATCH 4/6] INSTALL-snap: the klog store name is already registered The publishing section told the reader to check whether "klog" was free and what to do if an unrelated project held it. The name is registered to the KLog account, which is the name the recipe builds under, so drop the speculation and say so. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019NH3YWvwLzEr3nZuQdhUZM --- INSTALL-snap | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/INSTALL-snap b/INSTALL-snap index 0aa3078de..dd8b98a93 100644 --- a/INSTALL-snap +++ b/INSTALL-snap @@ -200,22 +200,18 @@ If you would rather have a working keyring on that machine: which only lasts for that D-Bus session. -7.2 Registering the name -------------------------- +7.2 The registered name +------------------------ -The name has to be registered once, by the account that will own it, -either from the CLI once you are authenticated: +The name "klog" is already registered in the Snap Store to the KLog +account, and that is the name snap/snapcraft.yaml builds under, so there is +nothing to do here. It is kept for the record that a name is registered +once, by the account that will own it, with: - snapcraft register klog + snapcraft register -or through the web form, which needs no working CLI login and tells you -straight away whether the name is free: - - https://snapcraft.io/account/register-snap - -If the name is already taken by an unrelated project, either request a -transfer through the store's dispute process or change the "name:" field -in snap/snapcraft.yaml (klog-hamradio, for example) before registering. +or through https://snapcraft.io/account/register-snap, which needs no +working CLI login. 7.3 Uploading -------------- From 370218eb06318c02c8caca764e14d0e768c5a45a Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 8 Aug 2026 15:09:01 +0000 Subject: [PATCH 5/6] Add a Jenkins pipeline for the snap package devscripts/jenkins/Jenkinsfile.snap builds the snap on the debian-stable agent in the same shape as the other platform jobs: power the ESXi VM on, build, verify, upload to the NAS, power it off, and power it off again from the failure handler. It reuses the credentials klog-debian-stable already needs, so Jenkins gains no new secrets. The agent does not need any Qt6 or Hamlib development package, because snapcraft builds inside an LXD container running Ubuntu 26.04. What it does need is snapd, snapcraft, LXD and a jenkins user in the lxd group, none of which the .deb build required, so the pipeline opens with a Preflight stage that checks for each of them and reports the exact missing command instead of failing later mid-build. Two details specific to running snapcraft under Jenkins are handled in the build script as well, so it behaves the same when called by hand: - /snap/bin is only put on PATH by a login shell, and Jenkins runs sh non-login, so snapcraft would not be found at all. - snapcraft clean has nothing to do on a fresh checkout, and its non-zero exit must not abort the run. It also pins SNAPCRAFT_BUILD_ENVIRONMENT to lxd and fails with the setup commands if LXD is missing or unreachable, since core26 cannot be built destructively on a Debian host. klog-snap and klog-debian-stable share the one VM, so Jenkinsfile.all runs them sequentially inside its "Debian stable" stage; in parallel the first to finish would power the machine off under the other. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019NH3YWvwLzEr3nZuQdhUZM --- INSTALL-snap | 45 ++++++++++++++++++++++++++++++ devscripts/jenkins/Jenkinsfile.all | 7 +++++ devscripts/snap-create-package.sh | 34 +++++++++++++++++++++- 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/INSTALL-snap b/INSTALL-snap index dd8b98a93..a02692577 100644 --- a/INSTALL-snap +++ b/INSTALL-snap @@ -124,6 +124,51 @@ moves the result into devscripts/, next to the other packages. The recipe is snap/snapcraft.yaml and the run-time wrapper it installs is snap/local/klog-launch. +Note that the build host does not need any Qt6 or Hamlib development +package. snapcraft builds inside an LXD container running Ubuntu 26.04 and +installs the build dependencies in there, which is also why a Debian stable +machine can produce this package. + +5.1 Building it on Jenkins +--------------------------- + +devscripts/jenkins/Jenkinsfile.snap drives the build on the debian-stable +agent, in the same shape as the other platform jobs: power the VM on, build, +verify, upload to the NAS, power it off. Create the job as "klog-snap" with +Pipeline script from SCM and that file as the script path. + +It uses the same credentials as klog-debian-stable (esxi-ssh, esxi-host, +esxi-vmid-debian-stable, nas-host, nas-user, nas-password), so there is +nothing new to add to Jenkins. + +Set the agent up once, as root: + + apt install snapd squashfs-tools + ln -s /var/lib/snapd/snap /snap # Debian needs this for classic snaps + snap install snapcraft --classic + snap install lxd + lxd init --auto + usermod -aG lxd jenkins # the user the Jenkins agent runs as + +Then restart the Jenkins agent, otherwise it keeps the group list it started +with and snapcraft cannot reach LXD. Check it worked with: + + sudo -u jenkins lxc list + +The pipeline has a Preflight stage that tests exactly this and stops with +the missing command if anything is not in place, rather than failing later +in the middle of a build. + +Two things to expect on the first run: it is slow, because LXD has to fetch +the Ubuntu 26.04 image and snapcraft the core26 and mesa-2604 snaps, and the +VM needs enough disk for that (allow around 15 GB free). The Build stage has +a 90 minute timeout for this reason. + +Because klog-snap and klog-debian-stable share that one VM, they must never +run at the same time — the first to finish would power the machine off under +the other. Jenkinsfile.all therefore runs them one after the other inside its +"Debian stable" stage instead of in parallel. + 6. Why the recipe uses base: core26 ----------------------------------- diff --git a/devscripts/jenkins/Jenkinsfile.all b/devscripts/jenkins/Jenkinsfile.all index 512c75990..57b718e6d 100644 --- a/devscripts/jenkins/Jenkinsfile.all +++ b/devscripts/jenkins/Jenkinsfile.all @@ -50,11 +50,18 @@ pipeline { } } + // Both jobs use the debian-stable VM, so they run one after the + // other: in parallel they would fight over it and the first to + // finish would power the VM off under the other. stage('Debian stable') { steps { build job: 'klog-debian-stable', wait: true, propagate: true + + build job: 'klog-snap', + wait: true, + propagate: true } } diff --git a/devscripts/snap-create-package.sh b/devscripts/snap-create-package.sh index bb034a684..982da38cc 100755 --- a/devscripts/snap-create-package.sh +++ b/devscripts/snap-create-package.sh @@ -56,19 +56,51 @@ fi echo "Building KLog $KLOG_VERSION snap package" # --- Check the toolchain is there --- +# Snap binaries live in /snap/bin, which is only added to PATH by a login +# shell. Jenkins and other CI runners use non-login shells. +case ":$PATH:" in + *:/snap/bin:*) ;; + *) PATH="/snap/bin:$PATH"; export PATH ;; +esac + if ! command -v snapcraft >/dev/null 2>&1; then echo "ERROR: snapcraft not found. Install it with:" echo " sudo snap install snapcraft --classic" + echo " On Debian, classic snaps also need:" + echo " sudo ln -s /var/lib/snapd/snap /snap" exit 1 fi +# KLog builds against core26, so snapcraft needs a container to build in: the +# host itself is only usable with --destructive-mode, and only if the host is +# Ubuntu 26.04. LXD is snapcraft's default backend for core22 and newer. +export SNAPCRAFT_BUILD_ENVIRONMENT="${SNAPCRAFT_BUILD_ENVIRONMENT:-lxd}" + +if [ "$SNAPCRAFT_BUILD_ENVIRONMENT" = "lxd" ]; then + if ! command -v lxc >/dev/null 2>&1; then + echo "ERROR: LXD not found. Install and initialise it with:" + echo " sudo snap install lxd" + echo " sudo lxd init --auto" + exit 1 + fi + if ! lxc list >/dev/null 2>&1; then + echo "ERROR: cannot talk to LXD as $(id -un). Add the user to the group:" + echo " sudo usermod -aG lxd $(id -un)" + echo " then log out and back in (or restart the CI agent) so the" + echo " new group takes effect." + exit 1 + fi +fi + ARCH=$(dpkg --print-architecture 2>/dev/null || uname -m) echo "Architecture: $ARCH" +echo "Build backend: $SNAPCRAFT_BUILD_ENVIRONMENT" # --- Clean previous build --- echo "[1/3] Cleaning..." rm -f "$DEVSCRIPTS_DIR"/klog_*.snap -(cd "$PROJECT_DIR" && snapcraft clean) +# Nothing to clean on a fresh checkout, and that is not an error. +(cd "$PROJECT_DIR" && snapcraft clean) || true # --- Build --- echo "[2/3] Building the snap (this pulls the core26 and mesa-2604 snaps the" From 47aca56c61f671a33a95a8ee8bad67272ebabf36 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 8 Aug 2026 15:17:57 +0000 Subject: [PATCH 6/6] Keep the snap build out of the klog-all orchestrator Revert Jenkinsfile.all to exactly what it was: klog-snap runs on its own with Build Now, not as part of the all-platforms run. Keep the note about the two jobs sharing the debian-stable VM, since it still applies the day klog-snap is added there - each job powers the machine off when it finishes, so a parallel branch would pull the VM out from under klog-debian-stable. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019NH3YWvwLzEr3nZuQdhUZM --- INSTALL-snap | 13 +++++++++---- devscripts/jenkins/Jenkinsfile.all | 7 ------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/INSTALL-snap b/INSTALL-snap index a02692577..115719aad 100644 --- a/INSTALL-snap +++ b/INSTALL-snap @@ -164,10 +164,15 @@ the Ubuntu 26.04 image and snapcraft the core26 and mesa-2604 snaps, and the VM needs enough disk for that (allow around 15 GB free). The Build stage has a 90 minute timeout for this reason. -Because klog-snap and klog-debian-stable share that one VM, they must never -run at the same time — the first to finish would power the machine off under -the other. Jenkinsfile.all therefore runs them one after the other inside its -"Debian stable" stage instead of in parallel. +klog-snap is deliberately not part of the klog-all orchestrator for now, so +run it on its own with Build Now. + +Should it be added there later, keep in mind that it shares the VM with +klog-debian-stable and the two must never run at the same time: each powers +the machine off when it finishes, so in parallel the first to end would pull +the VM out from under the other. Chain them inside the existing "Debian +stable" stage rather than adding a parallel branch, or give the snap build +an agent of its own. 6. Why the recipe uses base: core26 diff --git a/devscripts/jenkins/Jenkinsfile.all b/devscripts/jenkins/Jenkinsfile.all index 57b718e6d..512c75990 100644 --- a/devscripts/jenkins/Jenkinsfile.all +++ b/devscripts/jenkins/Jenkinsfile.all @@ -50,18 +50,11 @@ pipeline { } } - // Both jobs use the debian-stable VM, so they run one after the - // other: in parallel they would fight over it and the first to - // finish would power the VM off under the other. stage('Debian stable') { steps { build job: 'klog-debian-stable', wait: true, propagate: true - - build job: 'klog-snap', - wait: true, - propagate: true } }