diff --git a/docker/appimage/build-appimage.sh b/docker/appimage/build-appimage.sh index 2099cb7c..2b20f80e 100644 --- a/docker/appimage/build-appimage.sh +++ b/docker/appimage/build-appimage.sh @@ -1,102 +1,114 @@ #!/bin/sh # Build an AppImage of Kleopatra # Copyright (C) 2021 g10 Code GmbH # # Software engineering by Ingo Klöcker # # This file is part of GnuPG. # # GnuPG 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. # # GnuPG 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 this program; if not, see . # # SPDX-License-Identifier: GPL-3.0+ set -e source /opt/rh/devtoolset-7/enable cd /src/packages ./download.sh cd /src ./configure --enable-appimage --enable-maintainer-mode --disable-manuals cd /src make if [ -f /src/src/gnupg-vsd/custom.mk ]; then GNUPG_BUILD_VSD=yes else GNUPG_BUILD_VSD=no fi export GNUPG_BUILD_VSD echo 'rootdir = $APPDIR/usr' >/build/AppDir/usr/bin/gpgconf.ctl if [ $GNUPG_BUILD_VSD = yes ]; then echo 'sysconfdir = /etc/gnupg-vsd' >>/build/AppDir/usr/bin/gpgconf.ctl else echo 'sysconfdir = /etc/gnupg' >>/build/AppDir/usr/bin/gpgconf.ctl fi +# Copy the start-shell helper for use AppRun +cp /src/src/appimage/start-shell /build/AppDir/ +chmod +x /build/AppDir/start-shell + +# Copy standard global configuration +if [ $GNUPG_BUILD_VSD = yes ]; then + mkdir -p /build/AppDir/usr/share/gnupg/conf/gnupg-vsd + rsync -av --delete --omit-dir-times \ + /src/src/gnupg-vsd/Standard/etc/gnupg/ \ + /build/AppDir/usr/share/gnupg/conf/gnupg-vsd/ +fi + export PATH=/opt/linuxdeploy/usr/bin:$PATH export LD_LIBRARY_PATH=/build/install/lib # tell the linuxdeploy qt-plugin where to find qmake export QMAKE=/build/install/bin/qmake # create plugin directories expected by linuxdeploy qt-plugin # workaround for # [qt/stdout] Deploy[qt/stderr] terminate called after throwing an instance of 'boost::filesystem::filesystem_error' # [qt/stderr] what(): boost::filesystem::directory_iterator::construct: No such file or directory: "/build/AppDir/usr/plugins/sqldrivers" # ERROR: Failed to run plugin: qt (exit code: 6) mkdir -p /build/install/plugins/sqldrivers # copy KDE plugins for d in iconengines kf5 pim; do mkdir -p /build/AppDir/usr/plugins/${d}/ rsync -av --delete --omit-dir-times /build/install/lib64/plugins/${d}/ /build/AppDir/usr/plugins/${d}/ done cd /build # Remove existing AppRun and wrapped AppRun, that may be left over # from a previous run of linuxdeploy, to ensure that our custom AppRun # is deployed rm -f /build/AppDir/AppRun /build/AppDir/AppRun.wrapped 2>/dev/null # Remove existing translations that may be left over from a previous # run of linuxdeploy rm -rf /build/AppDir/usr/translations # Remove the version files to make sure that only one will be created. rm -f /build/AppDir/GnuPG-VS-Desktop-VERSION 2>/dev/null rm -f /build/AppDir/GnuPG-Desktop-VERSION 2>/dev/null # Extract gnupg version or (for VSD builds) Kleopatra version for use # as filename of the AppImage if [ $GNUPG_BUILD_VSD = yes ]; then myversion=$(grep KLEOPATRA_VERSION_STRING /build/build/kleopatra-*-build/version-kleopatra.h | cut -d '"' -f 2 | cut -d '.' -f 1-3) OUTPUT=gnupg-vs-desktop-${myversion}-x86_64.AppImage echo $myversion >/build/AppDir/GnuPG-VS-Desktop-VERSION else myversion=$(grep '^file gnupg/gnupg-2.*tar' /src/packages/packages.current \ | sed -n 's,.*/gnupg-\(2.*\).tar.*,\1,p') OUTPUT=gnupg-desktop-${myversion}-x86_64.AppImage echo $myversion >/build/AppDir/GnuPG-Desktop-VERSION fi export OUTPUT linuxdeploy --appdir /build/AppDir \ --desktop-file /build/AppDir/usr/share/applications/org.kde.kleopatra.desktop \ --icon-file /build/AppDir/usr/share/icons/hicolor/256x256/apps/kleopatra.png \ --custom-apprun /src/src/appimage/AppRun \ --plugin qt \ --output appimage \ 2>&1 | tee /build/logs/linuxdeploy-gnupg-desktop.log diff --git a/src/appimage/AppRun b/src/appimage/AppRun index ad8aaaef..3e2581fe 100755 --- a/src/appimage/AppRun +++ b/src/appimage/AppRun @@ -1,87 +1,131 @@ #! /usr/bin/env bash this_dir="$(readlink -f "$(dirname "$0")")" +if [ "$1" = "--debug" ]; then + shift + set -x +else + set -e +fi + if [ -f "${APPDIR}/GnuPG-VS-Desktop-VERSION" ]; then myname="GnuPG VS-Desktop "$(cat "${APPDIR}/GnuPG-VS-Desktop-VERSION") else myname="GnuPG Desktop "$(cat "${APPDIR}/GnuPG-Desktop-VERSION") fi -if [ "$1" = "--help" ]; then +if [ "$1" = "--help" -o "$1" = "--version" ]; then echo "$myname" - cat <&2 + exit 2 + fi + fi exit 0 fi -if [ "$1" = "--debug" ]; then - shift - set -x -fi export PATH="${APPDIR}/usr/bin:${PATH}" export XDG_DATA_DIRS="${APPDIR}/usr/share:${XDG_DATA_DIRS:-/usr/share}:/usr/share" export XDG_CONFIG_DIRS="${APPDIR}/usr/etc/xdg:${XDG_CONFIG_DIRS:-/etc/xdg}:/etc/xdg" # Allow GnuPG config scripts to detect the appimage install. We can't # rely on APPDIR because other appimages might come with their own # gnupg version. Change the value to "vsd" for a GnuPG VS-Desktop build. if [ -f "${APPDIR}/GnuPG-VS-Desktop-VERSION" ]; then _gnupg_appimage=vsd else _gnupg_appimage=generic fi export _gnupg_appimage if [ -z "$SHELL" ]; then SHELL="$(grep '/bash$' /etc/shells 2>/dev/null)" if [ -z "$SHELL" ]; then export SHELL=/bin/bash fi fi + + +mycleanup () { + if [ -n $"gnupg_SETUPINIFILE" ]; then + rm -f $"gnupg_SETUPINIFILE" + fi +} + +gnupg_SETUPINIFILE= +trap mycleanup 0 INT QUIT + + if [ "$1" = "-c" -o "$1" = "-i" ]; then shift if [ ! -x "$SHELL" ]; then - echo "No shell found" >&2 + echo "error: no shell found" >&2 exit 2 fi if [ -n "$1" ]; then pgm="$SHELL" pgmargs="-c $@" else - pgm="$SHELL" - pgmargs=-i + export gnupg_SETUPINIFILE SHELL + if [ $(id -u) -eq 0 -a ! -d /etc/gnupg-vsd ]; then + echo "no global configuration - installing default" >&2 + mkdir /etc/gnupg-vsd + cp "${APPDIR}"/usr/share/gnupg/conf/gnupg-vsd/* /etc/gnupg-vsd/ + fi + if echo "$SHELL" | grep '/bash$' >/dev/null 2>&1; then + pgm="${APPDIR}/start-shell" + pgmargs= + gnupg_SETUPINIFILE="/tmp/gnupg-tmp.$(id -u).$$.ini" + else + pgm="$SHELL" + pgmargs="-i" + fi echo Welcome to "$myname"\! >&2 echo "(type \"exit\" to leave)" >&2 echo "" >&2 fi else + if [ $(id -u) -eq 0 ]; then + echo "error: the GUI may not be run by root" >&2 + exit 2 + fi # Ignore the optional --gui option if [ "$1" = "--gui" ]; then shift fi if [ -x "${this_dir}/usr/bin/kleopatra" ];then pgm="${this_dir}/usr/bin/kleopatra" pgmargs="$@" else echo "Kleopatra not found" >&2 exit 2 fi fi # Start gpg-agent launching a program. gpg-agent will then watch for # termination of the program and kill itself after this has been # detected. We also steal an existing socket so that already running # system instances of gpg-agent are not anymore used. "${this_dir}/usr/bin/gpg-agent" --steal-socket --daemon -- $pgm $pgmargs echo Goodbye from "$myname"\! >&2 diff --git a/src/appimage/Makefile.am b/src/appimage/Makefile.am index d282699d..e42c3f5a 100644 --- a/src/appimage/Makefile.am +++ b/src/appimage/Makefile.am @@ -1,196 +1,196 @@ # Makefile.am - Makefile for building AppImage of Kleopatra # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2021 g10 Code GmbH # # Software engineering by Ingo Klöcker # # This file is part of Gpg4win. # # Gpg4win 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 2 of the License, or # (at your option) any later version. # # Gpg4win 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 this program; if not, see . # # SPDX-License-Identifier: GPL-2.0+ -EXTRA_DIST = AppRun +EXTRA_DIST = AppRun start-shell root := /build stampdir := $(root)/stamps # Source packages for the AppImage appimage_spkgs = sqlite libgpg-error libassuan npth libgcrypt libksba gnupg \ pinentry gpgme paperkey # Qt packages for the AppImage appimage_qtpkgs = qtbase qttools qtx11extras qtwayland qtsvg qttranslations # KDE packages for the AppImage appimage_kdepkgs = kconfig kwidgetsaddons ki18n extra-cmake-modules \ kcompletion kwindowsystem kcoreaddons libkleo kcodecs \ kmime kconfigwidgets kxmlgui kguiaddons kitemviews \ kiconthemes kleopatra breeze-icons kitemmodels karchive \ kcrash kdbusaddons # Binary packages for the AppImage appimage_bpkgs = kde-l10n appimage_pkg_gpgme_configure = --enable-languages=cpp,qt \ --disable-gpg-test \ --disable-gpgsm-test # TODO: Disable Qt Sql? # TODO: Disable Qt Testlib? appimage_pkg_qtbase_configure = ../$$$${pkg_version}/configure -opensource \ -confirm-license \ -platform linux-g++ \ -release \ -shared \ -prefix $$$${pkgidir} \ -I '$(idir)/include' \ -L '$(idir)/lib' \ -opengl desktop \ -no-glib \ -accessibility \ -nomake examples \ -nomake tests \ -no-sql-mysql \ -no-sql-sqlite \ -no-sql-odbc \ -no-sql-psql \ -no-sql-tds \ -v \ OPENSSL_INCDIR=/usr/include/openssl11 define appimage_pkg_qtbase_post_install (cd $$$${pkgbdir}; \ make install;) endef appimage_pkg_qttools_configure = \ "$(idir)/bin/qmake" ../$$$${pkg_version} define appimage_pkg_qttools_post_install (cd $$$${pkgbdir}; \ mkdir -p $$$${pkgidir}; \ cp -r bin lib include $$$${pkgidir}) endef appimage_pkg_qtx11extras_configure = \ "$(idir)/bin/qmake" ../$$$${pkg_version} define appimage_pkg_qtx11extras_post_install (cd $$$${pkgbdir}; \ mkdir -p $$$${pkginstallroot}; \ make install INSTALL_ROOT=$$$${pkginstallroot}; \ mkdir -p $$$${pkgidir}; \ mv $$$${pkgbladir}/* $$$${pkgidir}; \ rm -rf $$$${pkginstallroot};) endef appimage_pkg_qtwayland_configure = \ "$(idir)/bin/qmake" ../$$$${pkg_version} define appimage_pkg_qtwayland_post_install (cd $$$${pkgbdir}; \ mkdir -p $$$${pkginstallroot}; \ make install INSTALL_ROOT=$$$${pkginstallroot}; \ mkdir -p $$$${pkgidir}; \ mv $$$${pkgbladir}/* $$$${pkgidir}; \ rm -rf $$$${pkginstallroot};) endef appimage_pkg_qtsvg_configure = \ "$(idir)/bin/qmake" ../$$$${pkg_version} # XXX Adding the qtconf after qtsvg is a weird hack # because somhow (yay qmake) zlib is not linked if # the qt conf exists before that. The qt conf is # needed for qttranslations to find the correct path # of the translation tools. define appimage_pkg_qtsvg_post_install (cd $$$${pkgbdir}; \ mkdir -p $$$${pkgidir}; \ cp -r lib include plugins $$$${pkgidir}; \ mkdir -p $$$${pkgidir}/bin; \ echo "[Paths]" > $$$${pkgidir}/bin/qt.conf; \ echo "Prefix = .." >> $$$${pkgidir}/bin/qt.conf) endef appimage_pkg_qttranslations_configure = \ "$(idir)/bin/qmake" ../$$$${pkg_version} define appimage_pkg_qttranslations_post_install ( rm -rf $$$${pkgidir}/translations; \ mkdir -p $$$${pkgidir}; \ cp -r $$$${pkgbdir}/translations $$$${pkgidir}/translations;) endef # do not create the huge icon resource files appimage_pkg_breeze_icons_configure = -DBINARY_ICONS_RESOURCE=OFF appimage_pkg_kcompletion_configure = \ -DBUILD_DESIGNERPLUGIN=OFF appimage_pkg_kconfigwidgets_configure = \ -DBUILD_DESIGNERPLUGIN=OFF appimage_pkg_ki18n_configure = -DBUILD_WITH_QML=OFF appimage_pkg_kiconthemes_configure = \ -DBUILD_DESIGNERPLUGIN=OFF appimage_pkg_kitemviews_configure = \ -DBUILD_DESIGNERPLUGIN=OFF appimage_pkg_kwidgetsaddons_configure = \ -DBUILD_DESIGNERPLUGIN=OFF # FIXME: Uses spaces in distribution text appimage_pkg_kxmlgui_configure = \ -DBUILD_DESIGNERPLUGIN=OFF \ -DFORCE_DISABLE_KGLOBALACCEL=ON \ -DXMLGUI_DISTRIBUTION_TEXT=g10_Code_GmbH_AppImage appimage_pkg_libkleo_configure = \ -DBOOST_INCLUDEDIR=/usr/include/boost169 \ -DBOOST_LIBRARYDIR=/usr/lib64/boost169 appimage_pkg_kleopatra_configure = \ -DBOOST_INCLUDEDIR=/usr/include/boost169 \ -DBOOST_LIBRARYDIR=/usr/lib64/boost169 \ -DDISABLE_KWATCHGNUPG=ON \ -DRELEASE_SERVICE_VERSION=AppImage-$(VERSION) ######################################################################## # Now do the bunch of the work. This is a bunch of dirty magic to # integrate our special makefile into automake, while not actually # including it (make should include it). This is in turn necessary # because automake can't deal with the elegant magic in the actual # Makefile. define INCLUDE_BY_MAKE include $(1) endef $(eval $(call INCLUDE_BY_MAKE,appimage.mk)) clean-local: clean-appimage license.blurb: $(top_srcdir)/doc/license-page $(top_srcdir)/doc/GPLv3 cat $(top_srcdir)/doc/license-page $(top_srcdir)/doc/GPLv3 >$@ all-local: $(stampdir)/stamp-final @echo "###################################################" @echo " AppDir prepared successfully for the AppImage!" @echo " Now run linuxdeploy to create the AppImage." @echo "###################################################" diff --git a/src/appimage/start-shell b/src/appimage/start-shell new file mode 100644 index 00000000..68e257a4 --- /dev/null +++ b/src/appimage/start-shell @@ -0,0 +1,10 @@ +#!/bin/sh +# This script is started instead of bash by gpg-agent so +# that we can set prompts etc. $SHELL is assumed to be bash. + +SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) +export SSH_AUTH_SOCK +cat >"$gnupg_SETUPINIFILE" <<'EOF' +PS1="$(echo "$PS1" | sed 's,\\\$ $,(GnuPG Shell)\\\$ ,')" +EOF +exec "$SHELL" --init-file "$gnupg_SETUPINIFILE"