CI: AppImage support

- Add a script for building a Calamares AppImage file (this is
   useful in *some* limited contexts, not a general way to distribute
   Calamares since it's much more efficient to use installed libs).
 - Add example config files for this AppImage build.
 - Download the linuxdeploy tools if they are missing
 - Document script flags some more
This commit is contained in:
Adriaan de Groot 2019-03-18 18:50:17 -04:00
parent 2b7832857c
commit ed2f9b744d
10 changed files with 511 additions and 0 deletions

45
ci/AppImage.md Normal file
View File

@ -0,0 +1,45 @@
# AppImage building for Calamares
> It is possible to build Calamares as an AppImage (perhaps other
> containerized formats as well). This might make sense for
> OEM phase-1 deployments in environments where Calamares is
> not using the native toolkit.
## AppImage tools
You will need
- [`linuxdeploy-x86_64.AppImage`](https://github.com/linuxdeploy/linuxdeploy/releases)
- [`linuxdeploy-plugin-qt-x86_64.AppImage`](https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases)
- [`linuxdeploy-plugin-conda.sh`](https://github.com/linuxdeploy/linuxdeploy-plugin-conda)
These tools should run -- they are bundled as AppImages after all -- on
any modern Linux system. The [AppImage packaging documentation](https://docs.appimage.org/packaging-guide/)
explains how the whole tooling works.
If the tools are not present, the build script (see below) will download them,
but you should save them for later.
## AppImage build
From the **source** directory, run `ci/AppImage.sh`:
- Use `--tools-dir` to copy the tools from a local cache rather than
downloading them again.
- Run it with `--cmake-args` for special CMake handling.
- Use `--skip-build` to avoid rebuilding Calamares all the time.
- Use `--config-dir` to copy in Calamares configuration files (e.g.
*settings.conf* and the module configuration files) from a given
directory.
The build process will:
- copy (or download) the AppImage tools into a fresh build directory
- configure and build Calamares with suitable settings
- modifies the standard `.desktop` file to be AppImage-compatible
- builds the image with the AppImage tools
## AppImage caveats
The resulting AppImage, `Calamares-x86_64.AppImage`, can be run as if it is
a regular Calamares executable. For internal reasons it always passes the
`-X` flag; any other command-line flags are passed in unchanged. Internally,
`XDG_*_DIRS` are used to get Calamares to find the resources inside the AppImage
rather than in the host system.

227
ci/AppImage.sh Normal file
View File

@ -0,0 +1,227 @@
#! /bin/sh
#
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright 2019 Adriaan de Groot <adridg@FreeBSD.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
### END LICENSES
### USAGE
#
# Shell script to help build an AppImage for Calamares.
#
# Usage:
# AppImage.sh [-T|--tools-dir <dir>]
# [-C|--cmake-args <args>]
# [-c|--config-dir <dir>]
# [-s|--skip-build]
#
# Multiple --cmake-args arguments will be collected together and passed to
# CMake before building the application.
#
# Use --tools-dir to indicate where the linuxdeploy tools are located.
#
# Use --config to copy a config-directory (with settings.conf and others)
# into the resulting image,
#
### END USAGE
TOOLS_DIR="."
CMAKE_ARGS=""
NO_SKIP_BUILD="true"
CONFIG_DIR=""
while test "$#" -gt 0
do
case "x$1" in
x--help|x-h)
sed -e '1,/USAGE/d' -e '/END.USAGE/,$d' < "$0"
return 0
;;
x--tools-dir|x-T)
TOOLS_DIR="$2"
shift
;;
x--cmake-args|x-C)
CMAKE_ARGS="$CMAKE_ARGS $2"
shift
;;
x--config-dir|x-c)
CONFIG_DIR="$2"
shift
;;
x--skip-build|x-s)
NO_SKIP_BUILD="false"
;;
*)
echo "! Unknown argument '$1'."
exit 1
;;
esac
test "$#" -gt 0 || { echo "! Missing arguments."; exit 1; }
shift
done
### Check where we're running
#
BIN_DIR=$( cd $( dirname "$0" ) && pwd -P )
test -d "$BIN_DIR" || { echo "! Could not find BIN_DIR"; exit 1; }
test -f "$BIN_DIR/AppImage.sh" || { echo "! $BIN_DIR does not have AppImage.sh"; exit 1; }
SRC_DIR=$( cd "$BIN_DIR/.." && pwd -P )
test -d "$SRC_DIR" || { echo "! Could not find SRC_DIR"; exit 1; }
test -d "$SRC_DIR/ci" || { echo "! $SRC_DIR isn't a top-level Calamares checkout"; exit 1; }
test -f "$SRC_DIR/CMakeLists.txt" || { echo "! SRC_DIR is missing CMakeLists.txt"; exit 1; }
### Check pre-requisites
#
BUILD_DIR=build-AppImage
test -d "$BUILD_DIR" || mkdir -p "$BUILD_DIR"
test -d "$BUILD_DIR" || { echo "! Could not create $BUILD_DIR"; exit 1; }
for tool in linuxdeploy-x86_64.AppImage linuxdeploy-plugin-qt-x86_64.AppImage linuxdeploy-plugin-conda.sh
do
if test -x "$BUILD_DIR/$tool" ; then
# This tool is ok
:
else
if test -f "$TOOLS_DIR/$tool" ; then
cp "$TOOLS_DIR/$tool" "$BUILD_DIR/$tool" || exit 1
else
fetch=$( grep "^# URL .*$tool\$" "$0" | sed 's/# URL *//' )
curl -L -o "$BUILD_DIR/$tool" "$fetch"
fi
chmod +x "$BUILD_DIR/$tool"
test -x "$BUILD_DIR/$tool" || { echo "! Missing tool $tool in tools-dir $TOOLS_DIR"; exit 1; }
fi
done
if test -z "$CONFIG_DIR" ; then
echo "# Using basic settings.conf"
else
test -f "$CONFIG_DIR/settings.conf" || { echo "! No settings.conf in $CONFIG_DIR"; exit 1; }
fi
### Clean up build-directory
#
rm -rf "$BUILD_DIR/AppDir"
if $NO_SKIP_BUILD ; then
rm -rf "$BUILD_DIR/build"
mkdir "$BUILD_DIR/build" || { echo "! Could not create $BUILD_DIR/build for the cmake-build."; exit 1; }
else
test -d "$BUILD_DIR/build" || { echo "! No build found in $BUILD_DIR, but --skip-build is given."; exit 1; }
test -x "$BUILD_DIR/build/calamares" || { echo "! No complete build found in $BUILD_DIR/build ."; exit 1; }
fi
mkdir "$BUILD_DIR/AppDir" || { echo "! Could not create $BUILD_DIR/AppDir for the AppImage install."; exit 1; }
LOG_FILE="$BUILD_DIR/AppImage.log"
rm -f "$LOG_FILE"
### Build Calamares
#
if $NO_SKIP_BUILD ; then
echo "# Running cmake ..."
(
cd "$BUILD_DIR/build" &&
cmake "$SRC_DIR" -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib $CMAKE_ARGS
) > "$LOG_FILE" 2>&1 || { tail -10 "$LOG_FILE" ; echo "! Could not run CMake"; exit 1; }
echo "# Running make ..."
(
cd "$BUILD_DIR/build" &&
make -j4
) > "$LOG_FILE" 2>&1 || { tail -10 "$LOG_FILE" ; echo "! Could not run make"; exit 1; }
fi
echo "# Running make install ..."
(
cd "$BUILD_DIR/build" &&
make install DESTDIR=../AppDir
) > "$LOG_FILE" 2>&1 || { tail -10 "$LOG_FILE" ; echo "! Could not run make install"; exit 1; }
### Modify installation
#
IMAGE_DIR="$BUILD_DIR/AppDir"
# Munge the desktop file to not use absolute paths or pkexec
sed -i \
-e 's+^Exec=.*+Exec=calamares+' \
-e 's+^Name=.*+Name=Calamares+' \
"$IMAGE_DIR"/usr/share/applications/calamares.desktop
# Replace the executable with a shell-proxy
test -x "$IMAGE_DIR/usr/bin/calamares" || { echo "! Does not seem to have installed calamares"; exit 1; }
mv "$IMAGE_DIR/usr/bin/calamares" "$IMAGE_DIR/usr/bin/calamares.bin"
cat > "$IMAGE_DIR/usr/bin/calamares" <<"EOF"
#! /bin/sh
#
# Calamares proxy-script
export XDG_DATA_DIRS="$APPDIR/usr/share/calamares:"
export XDG_CONFIG_DIRS="$APPDIR/etc/calamares:$D/usr/share:"
cd "$APPDIR"
exec "$APPDIR"/usr/bin/calamares.bin -X "$@"
EOF
chmod 755 "$IMAGE_DIR/usr/bin/calamares"
test -x "$IMAGE_DIR/usr/bin/calamares" || { echo "! Does not seem to have proxy for calamares"; exit 1; }
### Install additional files
#
PLUGIN_DIR=$( qmake -query QT_INSTALL_PLUGINS )
for plugin in \
libpmsfdiskbackendplugin.so \
libpmdummybackendplugin.so
do
cp "$PLUGIN_DIR/$plugin" "$IMAGE_DIR/usr/lib" || { echo "! Could not copy plugin $plugin"; exit 1; }
done
# Install configuration files
ETC_DIR="$IMAGE_DIR"/etc/calamares
mkdir -p "$ETC_DIR"
test -d "$ETC_DIR" || { echo "! Could not create /etc/calamares in image."; exit 1; }
if test -z "$CONFIG_DIR" ; then
echo "# Using basic settings.conf"
cp "$SRC_DIR/settings.conf" "$ETC_DIR"
else
test -f "$CONFIG_DIR/settings.conf" || { echo "! No settings.conf in $CONFIG_DIR"; exit 1; }
mkdir -p "$ETC_DIR/modules"
cp "$CONFIG_DIR/settings.conf" "$ETC_DIR"
test -d "$CONFIG_DIR/modules" && cp -r "$CONFIG_DIR/modules" "$ETC_DIR"
test -d "$CONFIG_DIR/branding" && cp -r "$CONFIG_DIR/branding" "$IMAGE_DIR/usr/share/calamares"
fi
### Build the AppImage
#
#
echo "# Building AppImage"
(
export QT_SELECT=qt5 # Otherwise might pick Qt4 in image
export LD_LIBRARY_PATH=AppDir/usr/lib # RPATH isn't set in the executable
cd "$BUILD_DIR" &&
./linuxdeploy-x86_64.AppImage --appdir=AppDir/ --plugin=qt --output=appimage
) > "$LOG_FILE" 2>&1 || { tail -10 "$LOG_FILE" ; echo "! Could not create image"; exit 1; }
exit 0
### Database for installation
#
# URL https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
# URL https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage
# URL https://raw.githubusercontent.com/TheAssassin/linuxdeploy-plugin-conda/master/linuxdeploy-plugin-conda.sh

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,28 @@
# Configure one or more display managers (e.g. SDDM)
# with a "best effort" approach.
---
#The DM module attempts to set up all the DMs found in this list, in that precise order.
#It also sets up autologin, if the feature is enabled in globalstorage.
#The displaymanagers list can also be set in globalstorage, and in that case it overrides anything set up here.
displaymanagers:
- slim
- sddm
- lightdm
- gdm
- mdm
- lxdm
- kdm
#Enable the following settings to force a desktop environment in your displaymanager configuration file:
#defaultDesktopEnvironment:
# executable: "startkde"
# desktopFile: "plasma"
#If true, try to ensure that the user, group, /var directory etc. for the
#display manager are set up correctly. This is normally done by the distribution
#packages, and best left to them. Therefore, it is disabled by default.
basicSetup: false
#If true, setup autologin for openSUSE. This only makes sense on openSUSE
#derivatives or other systems where /etc/sysconfig/displaymanager exists.
sysconfigSetup: false

View File

@ -0,0 +1,21 @@
# Configuration for the "finished" page, which is usually shown only at
# the end of the installation (successful or not).
---
# The finished page can hold a "restart system now" checkbox.
# If this is false, no checkbox is shown and the system is not restarted
# when Calamares exits.
restartNowEnabled: true
# Initial state of the checkbox "restart now". Only relevant when the
# checkbox is shown by restartNowEnabled.
restartNowChecked: false
# If the checkbox is shown, and the checkbox is checked, then when
# Calamares exits from the finished-page it will run this command.
# If not set, falls back to "shutdown -r now".
restartNowCommand: "systemctl -i reboot"
# When the last page is (successfully) reached, send a DBus notification
# to the desktop that the installation is done. This works only if the
# user as whom Calamares is run, can reach the regular desktop session bus.
notifyOnFinished: false

View File

@ -0,0 +1,16 @@
# NOTE: you must have ckbcomp installed and runnable
# on the live system, for keyboard layout previews.
---
# The name of the file to write X11 keyboard settings to
# The default value is the name used by upstream systemd-localed.
# Relative paths are assumed to be relative to /etc/X11/xorg.conf.d
xOrgConfFileName: "/etc/X11/xorg.conf.d/00-keyboard.conf"
# The path to search for keymaps converted from X11 to kbd format
# Leave this empty if the setting does not make sense on your distribution.
convertedKeymapPath: "/lib/kbd/keymaps/xkb"
# Write keymap configuration to /etc/default/keyboard, usually
# found on Debian-related systems.
# Defaults to true if nothing is set.
#writeEtcDefaultKeyboard: true

View File

@ -0,0 +1,31 @@
---
# This settings are used to set your default system time zone.
# Time zones are usually located under /usr/share/zoneinfo and
# provided by the 'tzdata' package of your Distribution.
#
# Distributions using systemd can list available
# time zones by using the timedatectl command.
# timedatectl list-timezones
#
# The starting timezone (e.g. the pin-on-the-map) when entering
# the locale page can be set through keys *region* and *zone*.
# If either is not set, defaults to America/New_York.
#
region: "Europe"
zone: "Amsterdam"
# Enable only when your Distribution is using an
# custom path for locale.gen
#localeGenPath: "PATH_TO/locale.gen"
# GeoIP based Language settings:
#
# GeoIP need an working Internet connection.
#
geoipUrl: "https://geoip.kde.org/v1/calamares"
# GeoIP style. Leave commented out for the "legacy" interpretation.
# This setting only makes sense if geoipUrl is set, enabliing geoIP.
geoipStyle: "json"

View File

@ -0,0 +1,62 @@
# Configuration for the one-user-system user module.
#
# Besides these settings, the user module also places the following
# keys into the globalconfig area, based on user input in the view step.
#
# - hostname
# - username
# - password (obscured)
# - autologinUser (if enabled, set to username)
#
# These globalconfig keys are set when the jobs for this module
# are created.
---
# Used as default groups for the created user.
# Adjust to your Distribution defaults.
defaultGroups:
- users
- lp
- video
- network
- storage
- wheel
- audio
# Some Distributions require a 'autologin' group for the user.
# Autologin causes a user to become automatically logged in to
# the desktop environment on boot.
# Disable when your Distribution does not require such a group.
autologinGroup: autologin
# You can control the initial state for the 'autologin checkbox' in UsersViewStep here.
# Possible values are: true to enable or false to disable the checkbox by default
doAutologin: true
# When set to a non-empty string, Calamares creates a sudoers file for the user.
# /etc/sudoers.d/10-installer
# Remember to add sudoersGroup to defaultGroups.
#
# If your Distribution already sets up a group of sudoers in its packaging,
# remove this setting (delete or comment out the line below). Otherwise,
# the setting will be duplicated in the /etc/sudoers.d/10-installer file,
# potentially confusing users.
sudoersGroup: wheel
# Setting this to false , causes the root account to be disabled.
setRootPassword: true
# You can control the initial state for the 'root password checkbox' in UsersViewStep here.
# Possible values are: true to enable or false to disable the checkbox by default.
# When enabled the user password is used for the root account too.
# NOTE: doReusePassword requires setRootPassword to be enabled.
doReusePassword: true
# These are optional password-requirements that a distro can enforce
# on the user. The values given in this sample file disable each check,
# as if the check was not listed at all.
passwordRequirements:
minLength: -1 # Password at least this many characters
maxLength: -1 # Password at most this many characters
libpwquality:
- minlen=0
- minclass=0
userShell: /bin/bash

View File

@ -0,0 +1,46 @@
# Configuration for the welcome module. The welcome page
# displays some information from the branding file.
# Which parts it displays can be configured through
# the show* variables.
#
# In addition to displaying the welcome page, this module
# can check requirements for installation.
---
# Display settings for various buttons on the welcome page.
showSupportUrl: true
showKnownIssuesUrl: true
showReleaseNotesUrl: true
# Requirements checking. These are general, generic, things
# that are checked. They may not match with the actual requirements
# imposed by other modules in the system.
requirements:
# Amount of available disk, in GB. Floating-point is allowed here.
# Note that this does not account for *usable* disk, so it is possible
# to pass this requirement, yet have no space to install to.
requiredStorage: 5.5
# Amount of available RAM, in GB. Floating-point is allowed here.
requiredRam: 1.0
# To check for internet connectivity, Calamares does a HTTP GET
# on this URL; on success (e.g. HTTP code 200) internet is OK.
internetCheckUrl: http://google.com
# List conditions to check. Each listed condition will be
# probed in some way, and yields true or false according to
# the host system satisfying the condition.
#
# This sample file lists all the conditions that are known.
check:
- ram
- power
- internet
- root
- screen
# List conditions that **must** be satisfied (from the list
# of conditions, above) for installation to proceed.
# If any of these conditions are not met, the user cannot
# continue past the welcome page.
required:
- ram

View File

@ -0,0 +1,35 @@
# Configuration file for Calamares
# Syntax is YAML 1.2
---
modules-search: [ usr/lib/calamares/modules ]
# YAML: list of maps of string:string key-value pairs.
#instances:
#- id: owncloud
# module: webview
# config: owncloud.conf
# Sequence section. This section describes the sequence of modules, both
# viewmodules and jobmodules, as they should appear and/or run.
sequence:
- show:
- welcome
- locale
- keyboard
- users
- summary
- exec:
- locale
- keyboard
- users
- displaymanager
- networkcfg
- show:
- finished
branding: default
prompt-install: false
# OEM mode
dont-chroot: true
disable-cancel: false