Initial upload of HyprArch releng configuration

This commit is contained in:
2026-03-03 20:31:33 +00:00
commit 7df61351c0
634 changed files with 36355 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@@ -0,0 +1,2 @@
SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
SPDX-License-Identifier: GPL-3.0-or-later

View File

@@ -0,0 +1,239 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Product branding information. This influences some global
# user-visible aspects of Calamares, such as the product
# name, window behavior, and the slideshow during installation.
#
# Additional styling can be done using the stylesheet.qss
# file, also in the branding directory.
---
componentName: default
### WELCOME / OVERALL WORDING
#
# These settings affect some overall phrasing and looks,
# which are most visible in the welcome page.
# This selects between different welcome texts. When false, uses
# the traditional "Welcome to the %1 installer.", and when true,
# uses "Welcome to the Calamares installer for %1." This allows
# to distinguish this installer from other installers for the
# same distribution.
welcomeStyleCalamares: true
# Should the welcome image (productWelcome, below) be scaled
# up beyond its natural size? If false, the image does not grow
# with the window but remains the same size throughout (this
# may have surprising effects on HiDPI monitors).
welcomeExpandingLogo: true
### WINDOW CONFIGURATION
#
# The settings here affect the placement of the Calamares
# window through hints to the window manager and initial
# sizing of the Calamares window.
# Size and expansion policy for Calamares.
# - "normal" or unset, expand as needed, use *windowSize*
# - "fullscreen", start as large as possible, ignore *windowSize*
# - "noexpand", don't expand automatically, use *windowSize*
windowExpanding: normal
# Size of Calamares window, expressed as w,h. Both w and h
# may be either pixels (suffix px) or font-units (suffix em).
# e.g. "800px,600px"
# "60em,480px"
# This setting is ignored if "fullscreen" is selected for
# *windowExpanding*, above. If not set, use constants defined
# in CalamaresUtilsGui, 800x520.
windowSize: 800px,520px
# Placement of Calamares window. Either "center" or "free".
# Whether "center" actually works does depend on the window
# manager in use (and only makes sense if you're not using
# *windowExpanding* set to "fullscreen").
windowPlacement: center
### PANELS CONFIGURATION
#
# Calamares has a main content area, and two panels (navigation
# and progress / sidebar). The panels can be controlled individually,
# or switched off. If both panels are switched off, the layout of
# the main content area loses its margins, on the assumption that
# you're doing something special.
# Kind of sidebar (panel on the left, showing progress).
# - "widget" or unset, use traditional sidebar (logo, items)
# - "none", hide it entirely
# - "qml", use calamares-sidebar.qml from branding folder
# In addition, you **may** specify a side, separated by a comma,
# from the kind. Valid sides are:
# - "left" (if not specified, uses this)
# - "right"
# - "top"
# - "bottom"
# For instance, "widget,right" is valid; so is "qml", which defaults
# to putting the sidebar on the left. Also valid is "qml,top".
# While "widget,top" is valid, the widgets code is **not** flexible
# and results will be terrible.
sidebar: widget
# Kind of navigation (button panel on the bottom).
# - "widget" or unset, use traditional navigation
# - "none", hide it entirely
# - "qml", use calamares-navigation.qml from branding folder
# In addition, you **may** specify a side, separated by a comma,
# from the kind. The same sides are valid as for *sidebar*,
# except the default is *bottom*.
navigation: widget
### STRINGS, IMAGES AND COLORS
#
# This section contains the "branding proper" of names
# and images, rather than global-look settings.
# These are strings shown to the user in the user interface.
# There is no provision for translating them -- since they
# are names, the string is included as-is.
#
# The four Url strings are the Urls used by the buttons in
# the welcome screen, and are not shown to the user. Clicking
# on the "Support" button, for instance, opens the link supportUrl.
# If a Url is empty, the corresponding button is not shown.
#
# bootloaderEntryName is how this installation / distro is named
# in the boot loader (e.g. in the GRUB menu).
#
# These strings support substitution from /etc/os-release
# if KDE Frameworks 5.58 are available at build-time. When
# enabled, ${varname} is replaced by the equivalent value
# from os-release. All the supported var-names are in all-caps,
# and are listed on the FreeDesktop.org site,
# https://www.freedesktop.org/software/systemd/man/os-release.html
# Note that ANSI_COLOR and CPE_NAME don't make sense here, and
# are not supported (the rest are). Remember to quote the string
# if it contains substitutions, or you'll get YAML exceptions.
#
# The *Url* entries are used on the welcome page, and they
# are visible as buttons there if the corresponding *show* keys
# are set to "true" (they can also be overridden).
strings:
productName: "${NAME}"
shortProductName: Generic
version: 2026.3
shortVersion: 2023.3
versionedName: HyprArch 03.26 "Droplet"
shortVersionedName: HyprArch 03.36
bootloaderEntryName: HyprArch
productUrl: https://hyprarch.stuple.net/
supportUrl: https://hyprarch.stuple.net/wiki
knownIssuesUrl: https://hyprarch.stuple.net/issues
releaseNotesUrl: https://hyprarch.stuple.net/news/
donateUrl: https://docs.codeberg.org/improving-codeberg/donate/
# These images are loaded from the branding module directory.
#
# productBanner is an optional image, which if present, will be shown
# on the welcome page of the application, above the welcome text.
# It is intended to have a width much greater than height.
# It is displayed at 64px height (also on HiDPI).
# Recommended size is 64px tall, and up to 460px wide.
# productIcon is used as the window icon, and will (usually) be used
# by the window manager to represent the application. This image
# should be square, and may be displayed by the window manager
# as small as 16x16 (but possibly larger).
# productLogo is used as the logo at the top of the left-hand column
# which shows the steps to be taken. The image should be square,
# and is displayed at 80x80 pixels (also on HiDPI).
# productWallpaper is an optional image, which if present, will replace
# the normal solid background on every page of the application.
# It can be any size and proportion,
# and will be tiled to fit the entire window.
# For a non-tiled wallpaper, the size should be the same as
# the overall window, see *windowSize* above (800x520).
# productWelcome is shown on the welcome page of the application in
# the middle of the window, below the welcome text. It can be
# any size and proportion, and will be scaled to fit inside
# the window. Use `welcomeExpandingLogo` to make it non-scaled.
# Recommended size is 320x150.
#
# These filenames can also use substitutions from os-release (see above).
images:
# productBanner: "banner.png"
productIcon: "squid.png"
productLogo: "squid.png"
# productWallpaper: "wallpaper.png"
productWelcome: "languages.png"
# Colors for text and background components.
#
# - SidebarBackground is the background of the sidebar
# - SidebarText is the (foreground) text color
# - SidebarBackgroundCurrent sets the background of the current step.
# Optional, and defaults to the application palette.
# - SidebarTextCurrent is the text color of the current step.
#
# These colors can **also** be set through the stylesheet, if the
# branding component also ships a stylesheet.qss. Then they are
# the corresponding CSS attributes of #sidebarApp.
style:
SidebarBackground: "#292F34"
SidebarText: "#FFFFFF"
SidebarTextCurrent: "#292F34"
SidebarBackgroundCurrent: "#D35400"
### SLIDESHOW
#
# The slideshow is displayed during execution steps (e.g. when the
# installer is actually writing to disk and doing other slow things).
# The slideshow can be a QML file (recommended) which can display
# arbitrary things -- text, images, animations, or even play a game --
# during the execution step. The QML **is** abruptly stopped when the
# execution step is done, though, so maybe a game isn't a great idea.
#
# The slideshow can also be a sequence of images (not recommended unless
# you don't want QML at all in your Calamares). The images are displayed
# at a rate of 1 every 2 seconds during the execution step.
#
# To configure a QML file, list a single filename:
# slideshow: "show.qml"
# To configure images, like the filenames (here, as an inline list):
# slideshow: [ "/etc/calamares/slideshow/0.png", "/etc/logo.png" ]
slideshow: "show.qml"
# There are two available APIs for a QML slideshow:
# - 1 (the default) loads the entire slideshow when the installation-
# slideshow page is shown and starts the QML then. The QML
# is never stopped (after installation is done, times etc.
# continue to fire).
# - 2 loads the slideshow on startup and calls onActivate() and
# onLeave() in the root object. After the installation is done,
# the show is stopped (first by calling onLeave(), then destroying
# the QML components).
#
# An image slideshow does not need to have the API defined.
slideshowAPI: 2
# These options are to customize online uploading of logs to pastebins:
# - type : Defines the kind of pastebin service to be used. Currently
# it accepts two values:
# - none : disables the pastebin functionality
# - fiche : use fiche pastebin server
# - url : Defines the address of pastebin service to be used.
# Takes string as input. Important bits are the host and port,
# the scheme is not used.
# - sizeLimit : Defines maximum size limit (in KiB) of log file to be pasted.
# The option must be set, to have the log option work.
# Takes integer as input. If < 0, no limit will be forced,
# else only last (approximately) 'n' KiB of log file will be pasted.
# Please note that upload size may be slightly over the limit (due
# to last minute logging), so provide a suitable value.
uploadServer :
type : "fiche"
url : "http://termbin.com:9999"
sizeLimit : -1

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View File

@@ -0,0 +1,2 @@
SPDX-FileCopyrightText: 2015 Teo Mrnjavac <teo@kde.org>
SPDX-License-Identifier: GPL-3.0-or-later

View File

@@ -0,0 +1,77 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2015 Teo Mrnjavac <teo@kde.org>
* SPDX-FileCopyrightText: 2018 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Calamares is Free Software: see the License-Identifier above.
*
*/
import QtQuick 2.0;
import calamares.slideshow 1.0;
Presentation
{
id: presentation
function nextSlide() {
console.log("QML Component (default slideshow) Next slide");
presentation.goToNextSlide();
}
Timer {
id: advanceTimer
interval: 1000
running: presentation.activatedInCalamares
repeat: true
onTriggered: nextSlide()
}
Slide {
Image {
id: background
source: "squid.png"
width: 200; height: 200
fillMode: Image.PreserveAspectFit
anchors.centerIn: parent
}
Text {
anchors.horizontalCenter: background.horizontalCenter
anchors.top: background.bottom
text: "This is a customizable QML slideshow.<br/>"+
"Distributions should provide their own slideshow and list it in <br/>"+
"their custom branding.desc file.<br/>"+
"To create a Calamares presentation in QML, import calamares.slideshow,<br/>"+
"define a Presentation element with as many Slide elements as needed."
wrapMode: Text.WordWrap
width: presentation.width
horizontalAlignment: Text.Center
}
}
Slide {
centeredText: qsTr("This is a second Slide element.")
}
Slide {
centeredText: qsTr("This is a third Slide element.")
}
// When this slideshow is loaded as a V1 slideshow, only
// activatedInCalamares is set, which starts the timer (see above).
//
// In V2, also the onActivate() and onLeave() methods are called.
// These example functions log a message (and re-start the slides
// from the first).
function onActivate() {
console.log("QML Component (default slideshow) activated");
presentation.currentSlide = 0;
}
function onLeave() {
console.log("QML Component (default slideshow) deactivated");
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -0,0 +1,2 @@
SPDX-FileCopyrightText: 2014 Teo Mrnjavac <teo@kde.org>
SPDX-License-Identifier: GPL-3.0-or-later

View File

@@ -0,0 +1,96 @@
/*
* SPDX-FileCopyrightText: no
* SPDX-License-Identifier: CC0-1.0
*/
/*
A branding component can ship a stylesheet (like this one)
which is applied to parts of the Calamares user-interface.
In principle, all parts can be styled through CSS.
Missing parts should be filed as issues.
The IDs are based on the object names in the C++ code.
You can use the Debug Dialog to find out object names:
- Open the debug dialog
- Choose tab *Tools*
- Click *Widget Tree* button
The list of object names is printed in the log.
Documentation for styling Qt Widgets through a stylesheet
can be found at
https://doc.qt.io/qt-5/stylesheet-examples.html
https://doc.qt.io/qt-5/stylesheet-reference.html
In Calamares, styling widget classes is supported (e.g.
using `QComboBox` as a selector).
This example stylesheet has all the actual styling commented out.
The examples are not exhaustive.
*/
/*** Generic Widgets.
*
* You can style **all** widgets of a given class by selecting
* the class name. Some widgets have specialized sub-selectors.
*/
/*
QPushButton { background-color: green; }
*/
/*** Main application window.
*
* The main application window has the sidebar, which in turn
* contains a logo and a list of items -- note that the list
* can **not** be styled, since it has its own custom C++
* delegate code.
*/
/*
#mainApp { }
#sidebarApp { }
#logoApp { }
*/
/*** Welcome module.
*
* There are plenty of parts, but the buttons are the most interesting
* ones (donate, release notes, ...). The little icon image can be
* styled through *qproperty-icon*, which is a little obscure.
* URLs can reference the QRC paths of the Calamares application
* or loaded via plugins or within the filesystem. There is no
* comprehensive list of available icons, though.
*/
/*
QPushButton#aboutButton { qproperty-icon: url(:/data/images/release.svg); }
#donateButton,
#supportButton,
#releaseNotesButton,
#knownIssuesButton { qproperty-icon: url(:/data/images/help.svg); }
*/
/*** Partitioning module.
*
* Many moving parts, which you will need to experiment with.
*/
/*
#bootInfoIcon { }
#bootInfoLable { }
#deviceInfoIcon { }
#defineInfoLabel { }
#scrollAreaWidgetContents { }
#partitionBarView { }
*/
/*** Licensing module.
*
* The licensing module paints individual widgets for each of
* the licenses. The item can be collapsed or expanded.
*/
/*
#licenseItem { }
#licenseItemFullText { }
*/

View File

@@ -0,0 +1,86 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Bootloader configuration. The bootloader is installed to allow
# the system to start (and pick one of the installed operating
# systems to run).
#
# Take note that Debian-derivatives that use unmodified GRUB EFI packages
# should specifically set *efiBootloaderId* to "debian" because that is
# hard-coded in `grubx64.efi`.
---
# A variable from global storage which overrides the value of efiBootLoader
#efiBootLoaderVar: "packagechooser_bootloader"
# Define which bootloader you want to use for EFI installations
# Possible options are 'grub', 'sb-shim', 'refind` and 'systemd-boot'.
efiBootLoader: "grub"
# systemd-boot configuration files settings
# kernelSearchPath is the path relative to the root of the install to search for kernels
# A kernel is identified by finding files which match regular expression, kernelPattern
kernelSearchPath: "/usr/lib/modules"
kernelPattern: "^vmlinuz.*"
# loaderEntries is an array of options to add to loader.conf for systemd-boot
# please note that the "default" option is added programmatically
loaderEntries:
- "timeout 5"
- "console-mode keep"
# systemd-boot and refind support custom kernel params
kernelParams: [ "quiet" ]
# A list of kernel names that refind should accept as kernels
#refindKernelList: [ "linux","linux-lts","linux-zen","linux-hardened" ]
# GRUB 2 binary names and boot directory
# Some distributions (e.g. Fedora) use grub2-* (resp. /boot/grub2/) names.
# These names are also used when using sb-shim, since that needs some
# GRUB functionality (notably grub-probe) to work. As needed, you may use
# complete paths like `/usr/bin/efibootmgr` for the executables.
#
grubInstall: "grub-install"
grubMkconfig: "grub-mkconfig"
grubCfg: "/boot/grub/grub.cfg"
grubProbe: "grub-probe"
efiBootMgr: "efibootmgr"
# Optionally set the bootloader ID to use for EFI. This is passed to
# grub-install --bootloader-id.
#
# If not set here, the value from bootloaderEntryName from branding.desc
# is used, with problematic characters (space and slash) replaced.
#
# The ID is also used as a directory name within the EFI environment,
# and the bootloader is copied from /boot/efi/EFI/<dirname>/ . When
# setting the option here, keep in mind that the name is sanitized
# (problematic characters, see above, are replaced).
#
# There are some special words possible at the end of *efiBootloaderId*:
# ${SERIAL} can be used to obtain a uniquely-numbered suffix
# that is added to the Id (yielding, e.g., `dirname1` or `dirname72`)
# ${RANDOM} can be used to obtain a unique 4-digit hex suffix
# ${PHRASE} can be used to obtain a unique 1-to-3-word suffix
# from a dictionary of space-themed words
# These words must be at the **end** of the *efiBootloaderId* value.
# There must also be at most one of them. If there is none, no suffix-
# processing is done and the *efiBootloaderId* is used unchanged.
#
# NOTE: Debian derivatives that use the unmodified Debian GRUB EFI
# packages may need to set this to "debian" because that is
# hard-coded in `grubx64.efi`.
#
# efiBootloaderId: "dirname"
# Optionally install a copy of the GRUB EFI bootloader as the EFI
# fallback loader (either bootia32.efi or bootx64.efi depending on
# the system). This may be needed on certain systems (Intel DH87MC
# seems to be the only one). If you set this to false, take care
# to add another module to optionally install the fallback on those
# boards that need it.
installEFIFallback: true
# Optionally install both BIOS and UEFI GRUB bootloaders.
installHybridGRUB: false

View File

@@ -0,0 +1,63 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Configuration for the contextual process job.
#
# Contextual processes are based on **global** configuration values.
# When a given global value (string) equals a given value, then
# the associated command is executed.
#
# Configuration consists of keys for global variable names (except
# *dontChroot* and *timeout*), and the sub-keys are strings to compare
# to the variable's value. If the variable has that particular value, the
# corresponding value (script) is executed. The top-level keys *dontChroot*
# and *timeout* are not global variable names. They have
# meaning just like in shellprocess.conf, that is they
# determine **where** the command runs and how long it has.
#
# The variable **may** contain dots, in which case the dot is used
# to select into maps inside global storage, e.g.
#
# - *firmwareType* is a simple global name
# - *branding.bootloader* is the *bootloader* value in the *branding* map
#
# Only a few global storage entries have well-defined sub-maps;
# branding is one of them, and *filesystem_use* is another. Note that
# variable names with dots **must** be quoted, or you will get a YAML error.
#
#
# You can check for an empty value with "".
#
# As a special case, the value-check "*" matches any value, but **only**
# if no other value-check matches. Use it as an *else* form for value-
# checks. Take care to put the asterisk in quotes. The value-check "*"
# **also** matches a literal asterisk as value; a confusing corner case
# is checking for an asterisk **and** having a wildcard match with
# different commands. This is currently not possible.
#
# Global configuration variables are not checked in a deterministic
# order, so do not rely on commands from one variable-check to
# always happen before (or after) checks on another
# variable. Similarly, the value-equality checks are not
# done in a deterministic order, but all of the value-checks
# for a given variable happen together. As a special case, the
# value-check for "*" (the *else* case) happens after all of the
# other value-checks, and only matches if none of the others do.
#
# The values after a value sub-keys are the same kinds of values
# as can be given to the *script* key in the shellprocess module.
# See shellprocess.conf for documentation on valid values and how
# variables are expanded in those commands.
---
dontChroot: false
firmwareType:
efi:
- "-pkg remove efi-firmware"
- command: "-mkinitramfsrd -abgn"
timeout: 120 # This is slow
bios: "-pkg remove bios-firmware"
"": "/bin/false no-firmware-type-set"
"*": "/bin/false some-other-firmware-value"
"branding.shortVersion":
"2020.2": "/bin/false february"
"2019.4": "/bin/true april"

View File

@@ -0,0 +1,80 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Configure one or more display managers (e.g. SDDM)
# with a "best effort" approach.
#
# This module also sets up autologin, if the feature is enabled in
# globalstorage (where it would come from the users page).
---
# The DM module attempts to set up all the DMs found in this list, in the
# precise order listed. The displaymanagers list can also be set in
# globalstorage, and in that case it overrides the setting here.
#
# If *sysconfigSetup* is set to *true* (see below, only relevant for
# openSUSE derivatives) then this list is ignored and only sysconfig
# is attempted. You can also list "sysconfig" in this list instead.
#
displaymanagers:
- slim
- sddm
- lightdm
- gdm
- mdm
- lxdm
- greetd
# Enable the following settings to force a desktop environment
# in your displaymanager configuration file. This will attempt
# to configure the given DE (without checking if it is installed).
# The DM configuration for each potential DM may **or may not**
# support configuring a default DE, so the keys are mandatory
# but their interpretation is up to the DM configuration.
#
# Subkeys of *defaultDesktopEnvironment* are (all mandatory):
# - *executable* a full path to an executable
# - *desktopFile* a .desktop filename
#
# If this is **not** set, then Calamares will look for installed
# DE's and pick the first one it finds that is actually installed.
#
# If this **is** set, and the *executable* key doesn't point to
# an installed file, then the .desktop file's TryExec key is
# used instead.
#
#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.
#
# The preferred way to pick sysconfig is to just list it in the
# *displaymanagers* list (as the only one).
#
sysconfigSetup: false
# Some DMs have specific settings. These can be customized here.
#
# greetd has configurable user and group; the user and group is created if it
# does not exist, and the user is set as default-session user.
#
# Some greeters for greetd (e.g gtkgreet or regreet) have support for a user's GTK CSS style to change appearance.
#
# lightdm has a list of greeters to look for, preferring them in order if
# they are installed (if not, picks the alphabetically first greeter that is installed).
#
greetd:
greeter_user: "tom_bombadil"
greeter_group: "wheel"
greeter_css_location: "/etc/greetd/style.css"
lightdm:
preferred_greeters: ["lightdm-greeter.desktop", "slick-greeter.desktop"]
sddm:
configuration_file: "/etc/sddm.conf"

View File

@@ -0,0 +1,47 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Configuration for the "finished" page, which is usually shown only at
# the end of the installation (successful or not).
---
# DEPRECATED
#
# 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
# DEPRECATED
#
# Initial state of the checkbox "restart now". Only relevant when the
# checkbox is shown by restartNowEnabled.
# restartNowChecked: false
# Behavior of the "restart system now" button.
#
# There are four usable values:
# - never
# Does not show the button and does not restart.
# This matches the old behavior with restartNowEnabled=false.
# - user-unchecked
# Shows the button, defaults to unchecked, restarts if it is checked.
# This matches the old behavior with restartNowEnabled=true and restartNowChecked=false.
# - user-checked
# Shows the button, defaults to checked, restarts if it is checked.
# This matches the old behavior with restartNowEnabled=true and restartNowChecked=true.
# - always
# Shows the button, checked, but the user cannot change it.
# This is new behavior.
#
# The three combinations of legacy values are still supported.
restartNowMode: user-unchecked
# 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,36 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Configuration for the "finishedq" page, which is usually shown only at
# the end of the installation (successful or not).
#
# See the documentation for the "finished" module for a full explanation
# of the configuration options; the description here applies primarily
# to the use that the QML makes of them.
---
# Behavior of the "restart system now" button.
#
# The example QML for this module offers a "Restart Now" button,
# which the user can click on. It calls directly to the restart
# function. If the user closes the installer in some other way,
# (the "Done" button or close-window) a restart **might** happen:
#
# - never
# Do not restart (this will also block the "Restart Now" button,
# so it is not very useful)
# - user-unchecked
# Do not restart on other ways of closing the window. No checkbox
# is shown in the example QML, so there is no way for the user to
# express a choice -- except by clicking the "Restart Now" button.
# - user-checked
# Do restart on other ways of closing the window. This makes close
# and "Restart Now" do the same thing. No checkbox is shown by the QML,
# so the machine will **always** restart.
# - always
# Same as above.
#
# For the **specific** example QML included with this module, only
# *user-unchecked* really makes sense.
restartNowMode: user-unchecked
restartNowCommand: "systemctl -i reboot"
notifyOnFinished: false

View File

@@ -0,0 +1,17 @@
# === This file is part of Calamares - <https://calamares.io> ===
#
# SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
# SPDX-License-Identifier: BSD-2-Clause
#
calamares_add_plugin(flatpakInfo
TYPE job
EXPORT_MACRO PLUGINDLLEXPORT_PRO
SOURCES
FlatpakInfoJob.h
ItemFlatpak.h
PackagePool.h
FlatpakInfoJob.cpp
ItemFlatpak.cpp
PackagePool.cpp
SHARED_LIB
)

View File

@@ -0,0 +1,63 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2023 Sławomir Lach <slawek@lach.art.pl>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Calamares is Free Software: see the License-Identifier above.
*
*/
#include "FlatpakInfoJob.h"
#include "utils/Runner.h"
#include "utils/Logger.h"
#include "utils/Variant.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "Settings.h"
#include <QProcess>
#include <unistd.h>
#include "ItemFlatpak.h"
#include "PackagePool.h"
FlatpakInfoJob::FlatpakInfoJob( QObject* parent )
: Calamares::CppJob( parent )
{
}
FlatpakInfoJob::~FlatpakInfoJob()
{
ItemFlatpak_freeMem();
}
QString
FlatpakInfoJob::prettyName() const
{
return tr( "Fill netinstall with flatpak packages" );
}
Calamares::JobResult
FlatpakInfoJob::exec()
{
QVariantList partitions;
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
downloadPackagesInfo();
serializePackagesInfo();
return Calamares::JobResult::ok();
}
void
FlatpakInfoJob::setConfigurationMap( const QVariantMap& map )
{
}
CALAMARES_PLUGIN_FACTORY_DEFINITION( FlatpakInfoJobFactory, registerPlugin< FlatpakInfoJob >(); )

View File

@@ -0,0 +1,43 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2023 Sławomir Lach <slawek@lach.art.pl>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Calamares is Free Software: see the License-Identifier above.
*
*/
#ifndef FLATPAKINFOJOB_H
#define FLATPAKINFOJOB_H
#include <QObject>
#include <QStringList>
#include <QVariantMap>
#include "CppJob.h"
#include "utils/PluginFactory.h"
#include "DllMacro.h"
/** @brief Create zpools and zfs datasets
*
*/
class PLUGINDLLEXPORT FlatpakInfoJob : public Calamares::CppJob
{
Q_OBJECT
public:
explicit FlatpakInfoJob( QObject* parent = nullptr );
~FlatpakInfoJob() override;
QString prettyName() const override;
Calamares::JobResult exec() override;
void setConfigurationMap( const QVariantMap& configurationMap ) override;
};
CALAMARES_PLUGIN_FACTORY_DECLARATION( FlatpakInfoJobFactory )
#endif // ZFSJOB_H

View File

@@ -0,0 +1,66 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2023 Sławomir Lach <slawek@lach.art.pl>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Calamares is Free Software: see the License-Identifier above.
*
*/
/* Qt */
#include <QVariantMap>
/* CPP */
#include <fstream>
#include <iostream>
/* Calamares */
#include "utils/Runner.h"
/* Module */
#include "ItemFlatpak.h"
#include "utils/Logger.h"
#include "utils/Variant.h"
PackageItem
fromFlatpak( const QVariantMap& itemMap, InstalledList &installed )
{
// check if it is installed
PackageItem item( Calamares::getString( itemMap, "appstream" ) );
item.setInstalled( false );
item.setInstalled( installed.contains( Calamares::getString( itemMap, "appstream" ) ) );
return item;
}
InstalledList::InstalledList()
{
long long int prev_pos;
long long int pos = 0;
QString line;
auto process = Calamares::System::instance()->targetEnvCommand(
QStringList { QString::fromLatin1( "flatpak" ),
QString::fromLatin1( "list" ),
QString::fromLatin1( "--app" ),
QString::fromLatin1( "--columns=application" ) } );
auto outputStr = process.second;
do {
prev_pos = pos;
pos = outputStr.indexOf('\n', prev_pos);
QString line = outputStr.mid(prev_pos, pos);
installed.append(line);
/* Increase by 1 to not stuck on newline */
++pos;
/* QString::indexOf returns -1 since no occurences. 0 = -1 + 1.*/
} while (0 != pos);
}
InstalledList::~InstalledList()
{
installed.clear();
}

View File

@@ -0,0 +1,110 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2023 Sławomir Lach <slawek@lach.art.pl>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Calamares is Free Software: see the License-Identifier above.
*/
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <QString>
#include <QDesktopServices>
#include <QVariantMap>
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "utils/Logger.h"
#include "utils/Variant.h"
#include "ItemFlatpak.h"
#include "PackagePool.h"
#include "utils/System.h"
void PackagePool::downloadPackagesInfo(InstalledList &list)
{
QHash<QString,bool> addedPackages;
QString line;
auto process = Calamares::System::instance()->targetEnvCommand( QStringList { QString::fromStdString( "flatpak" ), QString::fromStdString( "remotes" ), QString::fromStdString( "--columns=name" ) });
auto outputStr = process.second;
QTextStream output(&outputStr);
while (output.readLineInto(&line))
{
QString line2;
auto process2 = Calamares::System::instance()->targetEnvCommand(
QStringList { QString::fromStdString( "flatpak" ),
QString::fromStdString( "remote-ls" ),
QString::fromStdString( "--app" ),
QString::fromStdString( "--columns=application" ),
line } );
auto output2Str = process2.second;
QTextStream output2( &output2Str );
while ( output2.readLineInto( &line2 ) )
{
if ( line2 == "" )
{
continue;
}
QVariantMap itemMap;
if ( addedPackages.contains( line2 ) )
{
continue;
}
addedPackages.insert( line2, true );
itemMap.insert( "appstream", QVariant( line2 ) );
itemMap.insert( "id", QVariant( line2 ) );
PackageItem item = fromFlatpak( itemMap, list );
packages.append( item );
}
}
serializePackagesInfo();
}
void PackagePool::serializePackagesInfo()
{
QList<QVariant> changedValue;
auto* gs = Calamares::JobQueue::instance()->globalStorage();
// If an earlier packagechooser instance added this data to global storage, combine them
if ( gs->contains( "netinstallAdd" ) )
{
auto selectedOrig = gs->value( "netinstallAdd" );
changedValue = selectedOrig.toList();
for (auto current: packages)
{
QStringList selfInstall;
QVariantMap newValue;
newValue.insert("name", current.getAppStreamId());
if (current.getInstalled())
{
newValue.insert("selected", true);
newValue.insert("immutable", true);
newValue.insert("description", "[Already installed; cannot be uninstalled]");
}
else
{
newValue.insert("selected", false);
}
selfInstall.append(current.getAppStreamId());
newValue.insert("packages", selfInstall);
changedValue.append(newValue);
}
gs->remove( "netinstallAdd" );
}
gs->insert( "netinstallAdd", changedValue );
}

View File

@@ -0,0 +1,8 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# The flatpakinfo module will collect package list from configured flatpak repositories
#
#
#
---

View File

@@ -0,0 +1,7 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
---
type: "job"
name: "flatpakinfo"
interface: "qtplugin"
load: "libcalamares_job_flatpakInfo.so"

View File

@@ -0,0 +1,17 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
if( NOT Calamares_WITH_QML )
calamares_skip_module( "freebsddisk (QML is not supported in this build)" )
return()
endif()
calamares_add_plugin( freebsddisk
TYPE viewmodule
EXPORT_MACRO PLUGINDLLEXPORT_PRO
SOURCES
FreeBSDDiskViewStep.cpp
RESOURCES
freebsddisk.qrc
SHARED_LIB
)

View File

@@ -0,0 +1,42 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Calamares 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.
*
* Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
* License-Filename: LICENSES/GPL-3.0
*/
#include "FreeBSDDiskViewStep.h"
FreeBSDDiskViewStep::FreeBSDDiskViewStep( QObject* parent )
: Calamares::QmlViewStep( parent )
{
}
FreeBSDDiskViewStep::~FreeBSDDiskViewStep() {}
QString
FreeBSDDiskViewStep::prettyName() const
{
return tr( "Disk Setup" );
}
void
FreeBSDDiskViewStep::setConfigurationMap( const QVariantMap& configurationMap )
{
Calamares::QmlViewStep::setConfigurationMap( configurationMap ); // call parent implementation last
}
CALAMARES_PLUGIN_FACTORY_DEFINITION( FreeBSDDiskViewStepFactory, registerPlugin< FreeBSDDiskViewStep >(); )

View File

@@ -0,0 +1,44 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Calamares 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.
*
* Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
* License-Filename: LICENSES/GPL-3.0
*/
#ifndef FREEBSDDISKVIEWSTEP_H
#define FREEBSDDISKVIEWSTEP_H
#include "DllMacro.h"
#include "utils/PluginFactory.h"
#include "viewpages/QmlViewStep.h"
class PLUGINDLLEXPORT FreeBSDDiskViewStep : public Calamares::QmlViewStep
{
Q_OBJECT
public:
FreeBSDDiskViewStep( QObject* parent = nullptr );
virtual ~FreeBSDDiskViewStep() override;
QString prettyName() const override;
void setConfigurationMap( const QVariantMap& configurationMap ) override;
};
CALAMARES_PLUGIN_FACTORY_DECLARATION( FreeBSDDiskViewStepFactory )
#endif

View File

@@ -0,0 +1,10 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# The *freebsddisk* module can be used to pick a disk
# as an installer step. This module supports ZFSroot
# on one whole disk, and UFSroot on one whole disk.
#
---
qmlSearch: both

View File

@@ -0,0 +1,35 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Calamares 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.
*
* Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
* License-Filename: LICENSES/GPL-3.0
*/
import io.calamares.ui 1.0
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
import QtQuick.Controls.Material 2.1
Item {
Text {
anchors.top: parent.top
anchors.topMargin: 10
text: "Select a disk on which to install FreeBSD."
}
}

View File

@@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file alias="freebsddisk.qml">freebsddisk.qml</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,52 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Module that resizes a single FS to fill the entire (rest) of
# a device. This is used in OEM situations where an image is
# flashed onto an SD card (or similar) and used to boot a device,
# after which the FS should expand to fill the SD card.
#
# Example: a distro produces a 6GiB large image that is
# written to an 8GiB SD card; the FS should expand to take
# advantage of the unused 2GiB. The FS should expand much
# more if the same image is written to a 16GiB card.
---
# Which FS needs to be grown? Choose one way to identify it:
# - *fs* names a mount point which should already be mounted
# in the system.
# - *dev* names a device
fs: /
# dev: /dev/mmcblk0p1
# How much of the total remaining space should the FS use?
# The only sensible amount is "all of it". The value is
# in percent, so set it to 100. Perhaps a fixed size is
# needed (that would be weird though, since you don't know
# how big the card is), use MiB as suffix in that case.
# If missing, then it's assumed to be 0, and no resizing
# will happen.
#
# Percentages apply to **available space**.
size: 100%
# Resizing might not be worth it, though. Set the minimum
# that it must grow; if it cannot grow that much, the
# resizing is skipped. Can be in percentage or absolute
# size, as above. If missing, then it's assumed to be 0,
# which means resizing is always worthwhile.
#
# If *atleast* is not zero, then the setting *required*,
# below, becomes relevant.
#
# Percentages apply to **total device size**.
#atleast: 1000MiB
# When *atleast* is not zero, then the resize may be
# recommended (the default) or **required**. If the
# resize is required and cannot be carried out (because
# there's not enough space), then that is a fatal
# error for the installer. By default, resize is only
# recommended and it is not an error for no resize to be
# carried out.
required: false

View File

@@ -0,0 +1,37 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Creates /etc/fstab and /etc/crypttab in the target system.
# Also creates mount points for all the filesystems.
#
# When creating fstab entries for a filesystem, this module
# uses the options previously defined in the mount module
---
# Additional options added to each line in /etc/crypttab
crypttabOptions: luks
# For Debian and Debian-based distributions, change the above line to:
# crypttabOptions: luks,keyscript=/bin/cat
# Options for handling /tmp in /etc/fstab
# Currently default (required) and ssd are supported
# The corresponding string can contain the following variables:
# tmpfs: true or tmpfs: false to either mount /tmp as tmpfs or not
# options: "<mount options>"
#
# Example:
#tmpOptions:
# default:
# tmpfs: false
# options: ""
# ssd:
# tmpfs: true
# options: "defaults,noatime,mode=1777"
#
tmpOptions:
default:
tmpfs: false
options: ""
ssd:
tmpfs: true
options: "defaults,noatime,mode=1777"

View File

@@ -0,0 +1,51 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Create, overwrite or update /etc/default/grub in the target system.
#
# Write lines to /etc/default/grub (in the target system) based
# on calculated values and the values set in the *defaults* key
# in this configuration file.
#
# Calculated values are:
# - GRUB_DISTRIBUTOR, branding module, *bootloaderEntryName* (this
# string is sanitized, and see also setting *keep_distributor*)
# - GRUB_ENABLE_CRYPTODISK, based on the presence of filesystems
# that use LUKS
# - GRUB_CMDLINE_LINUX_DEFAULT, adding LUKS setup and plymouth
# support to the kernel.
---
# If set to true, always creates /etc/default/grub from scratch even if the file
# already existed. If set to false, edits the existing file instead.
overwrite: false
# If set to true, prefer to write files in /etc/default/grub.d/
# rather than the single file /etc/default/grub. If this is set,
# Calamares will write /etc/default/grub.d/00calamares.cfg instead.
prefer_grub_d: false
# If set to true, an **existing** setting for GRUB_DISTRIBUTOR is
# kept, not updated to the *bootloaderEntryName* from the branding file.
# Use this if the GRUB_DISTRIBUTOR setting in the file is "smart" in
# some way (e.g. uses shell-command substitution).
keep_distributor: false
# The default kernel params that should always be applied.
# This is an array of strings. If it is unset, the default is
# `["quiet"]`. To avoid the default, explicitly set this key
# to an empty list, `[]`.
kernel_params: [ "quiet" ]
# Default entries to write to /etc/default/grub if it does not exist yet or if
# we are overwriting it.
#
defaults:
GRUB_TIMEOUT: 5
GRUB_DEFAULT: "saved"
GRUB_DISABLE_SUBMENU: true
GRUB_TERMINAL_OUTPUT: "console"
GRUB_DISABLE_RECOVERY: true
# Set to true to force defaults to be used even when not overwriting
always_use_defaults: false

View File

@@ -0,0 +1,26 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Run mkinitcpio(8) with the given preset value
---
# This key defines the kernel to be loaded.
# It can have the following values:
# - the name of a single mkinitcpio preset
# - empty or unset
# - the literal string "all"
#
# If kernel is set to "all" or empty/unset then mkinitpio is called for all
# kernels. Otherwise it is called with a single preset with the value
# contained in kernel.
#
kernel: linux
# Set this to true to turn off mitigations for lax file
# permissions on initramfs (which, in turn, can compromise
# your LUKS encryption keys, CVS-2019-13179).
#
# If your initramfs are stored in the EFI partition or another non-POSIX
# filesystem, this has no effect as the file permissions cannot be changed.
# In this case, ensure the partition is mounted securely.
#
be_unsafe: false

View File

@@ -0,0 +1,38 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# The initcpiocfg module is responsible for the configuration of mkinitcpio.conf. Typically this
# module is used in conjunction with the initcpio module to generate the boot image when using mkinitcpio
---
#
# Determines if the systemd versions of the hooks should be used. This is false by default.
#
# Please note that using the systemd hooks result in no access to the emergency recovery shell
useSystemdHook: false
#
# Modifications to the standard list of hooks.
#
# There are three subkeys:
# - prepend, which puts hooks at the beginning of the
# list of hooks, in the order specified here,
# - append, which adds hooks at the end of the list of
# hooks, in the order specified here,
# - remove, which removes hooks from the list of hooks,
# wherever they may be.
#
# The example configuration here yields bogus, <stuff>, bogus
# initially, and then removes that hook again.
#
hooks:
prepend: [ bogus ]
append: [ bogus ]
remove: [ bogus ]
#
# In some cases, you may want to use a different source
# file than /etc/mkinitcpio.conf , e.g. because the live system
# does not match the target in a useful way. If unset or
# empty, defaults to /etc/mkinitcpio.conf
#
source: "/etc/mkinitcpio.conf"

View File

@@ -0,0 +1,3 @@
---
kernel: all
be_quiet: false

View File

@@ -0,0 +1,47 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# 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.
# Common paths for this are:
# - /lib/kbd/keymaps/xkb
# - /usr/share/kbd/keymaps/xkb
# 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
# Use the Locale1 service instead of directly managing configuration files.
# This is the modern mechanism for configuring the systemwide keyboard layout,
# and works on Wayland compositors to set the current layout.
# Defaults to false on X11 and true otherwise.
#useLocale1: true
# Guess the default layout from the user locale. If false, keeps the current
# OS keyboard layout as the default (useful if the layout is pre-configured).
#guessLayout: true
# Things that should be configured.
configure:
# Configure KWin (KDE Plasma) directly by editing the
# configuration file and informing KWin over DBus. This is
# useful in a system that uses Wayland but does **not** connect
# locale1 with KWin.
#
# Systems that use KDE Plasma Wayland and locale1 can instead start the
# compositor KWin with command-line argument `--locale1`. That
# argument makes this configuration option unnecessary.
kwin: false
# Configure keyboard when using Wayland with Gnome on Ubuntu 24.10+
gnome: false

View File

@@ -0,0 +1,19 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# 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,53 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Configuration file for License viewmodule, Calamares
# Syntax is YAML 1.2
---
# Define a list of licenses which may / must be accepted before continuing.
#
# Each entry in this list has the following keys:
# - id Entry identifier, must be unique. Not user visible. YAML: string.
# - name Pretty name for the software product, user visible and untranslatable. YAML: string.
# - vendor Pretty name for the software vendor, user visible and untranslatable. YAML: string, optional, default is empty.
# - type Package type identifier for presentation, not user visible but affects user visible strings. YAML: string.
# values: driver, gpudriver, browserplugin, codec, package, software; optional, default is software.
# - required If set to true, the user cannot proceed without accepting this license. YAML: boolean, optional, default is false.
# - url A URL for the license; a remote URL is not shown in Calamares, but a link
# to the URL is provided, which opens in the default web browser. A local
# URL (i.e. file:///) assumes that the contents are HTML or plain text, and
# displays the license in-line. YAML: string, mandatory.
# - expand A boolean value only relevant for **local** URLs. If true,
# the license text is displayed in "expanded" form by
# default, rather than requiring the user to first open it up.
# YAML: boolean, optional, default is false.
entries:
- id: nvidia
name: Nvidia
vendor: Nvidia Corporation
type: driver
url: http://developer.download.nvidia.com/cg/Cg_3.0/license.pdf
required: false
- id: amd
name: Catalyst
vendor: "Advanced Micro Devices, Inc."
type: gpudriver
url: http://support.amd.com/en-us/download/eula
required: false
- id: flashplugin
name: Adobe Flash
vendor: Adobe Systems Incorporated
type: browserplugin
url: http://www.adobe.com/products/eulas/pdfs/PlatformClients_PC_WWEULA_Combined_20100108_1657.pdf
required: true
# This example uses a file: link. This example uses a relative link, which
# is relative to where you run Calamares. Assuming you run it from build/
# as part of your testing, you'll get the LICENSE text for Calamares
# (which is the text of the GPLv3, not proprietary at all).
- id: mine_mine
name: Calamares Proprietary License
vendor: Calamares, Inc.
type: software
required: true
url: file:../LICENSE
expand: true

View File

@@ -0,0 +1,131 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
---
# These 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.
#
# Note that useSystemTimezone and GeoIP settings can change the
# starting time zone.
#
region: "America"
zone: "New_York"
# Instead of using *region* and *zone* specified above,
# you can use the system's notion of the timezone, instead.
# This can help if your system is automatically configured with
# a sensible TZ rather than chasing a fixed default.
#
# The default is false.
#
# useSystemTimezone: true
# Should changing the system location (e.g. clicking around on the timezone
# map) immediately reflect the changed timezone in the live system?
# By default, installers (with a target system) do, and setup (e.g. OEM
# configuration) does not, but you can switch it on here (or off, if
# you think it's annoying in the installer).
#
# Note that not all systems support live adjustment.
#
# adjustLiveTimezone: true
# System locales are detected in the following order:
#
# - /usr/share/i18n/SUPPORTED
# - localeGenPath (defaults to /etc/locale.gen if not set)
# - `locale -a` output
#
# Enable only when your Distribution is using a
# custom path for locale.gen
#
#localeGenPath: "/etc/locale.gen"
# GeoIP based Language settings: Leave commented out to disable GeoIP.
#
# GeoIP needs a working Internet connection.
# This can be managed from `welcome.conf` by adding
# internet to the list of required conditions. (The welcome
# module can also do its own GeoIP lookups, independently
# of the lookup done here. The lookup in the welcome module
# is used to establish language; this one is for timezone).
#
# The configuration is in three parts:
# - a *style*, which can be "json" or "xml" depending on the
# kind of data returned by the service, and
# - a *url* where the data is retrieved, and
# - an optional *selector*
# to pick the right field out of the returned data (e.g. field
# name in JSON or element name in XML).
#
# The default selector (when the setting is blank) is picked to
# work with existing JSON providers (which use "time_zone") and
# Ubiquity's XML providers (which use "TimeZone").
#
# If the service configured via *url* uses
# a different attribute name (e.g. "timezone") in JSON or a
# different element tag (e.g. "<Time_Zone>") in XML, set the
# selector to the name or tag to be used.
#
# In JSON:
# - if the string contains "." characters, this is used as a
# multi-level selector, e.g. "a.b" will select the timezone
# from data "{a: {b: "Europe/Amsterdam" } }".
# - each part of the string split by "." characters is used as
# a key into the JSON data.
# In XML:
# - all elements with the named tag (e.g. all TimeZone) elements
# from the document are checked; the first one with non-empty
# text value is used.
# Special case:
# - the *style* "fixed" is also supported. This ignores the data
# returned from the URL (but the URL must still be valid!)
# and just returns the value of the *selector*.
#
# An HTTP(S) request is made to *url*. The request should return
# valid data in a suitable format, depending on *style*;
# generally this includes a string value with the timezone
# in <region>/<zone> format. For services that return data which
# does not follow the conventions of "suitable data" described
# below, *selector* may be used to pick different data.
#
# Suitable JSON data looks like
# ```
# {"time_zone":"America/New_York"}
# ```
# Suitable XML data looks like
# ```
# <Response><TimeZone>Europe/Brussels</TimeZone></Response>
# ```
#
# To accommodate providers of GeoIP timezone data with peculiar timezone
# naming conventions, the following cleanups are performed automatically:
# - backslashes are removed
# - spaces are replaced with _
#
# To disable GeoIP checking, either comment-out the entire geoip section,
# or set the *style* key to an unsupported format (e.g. `none`).
# Also, note the analogous feature in src/modules/welcome/welcome.conf.
#
geoip:
style: "json"
url: "https://geoip.kde.org/v1/calamares"
selector: "" # leave blank for the default
# For testing purposes, you could use *fixed* style, to see how Calamares
# behaves in a particular zone:
#
# geoip:
# style: "fixed"
# url: "https://geoip.kde.org/v1/calamares" # Still needs to be valid!
# selector: "America/Vancouver" # this is the selected zone
#

View File

@@ -0,0 +1,100 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
---
# 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: "America"
zone: "New_York"
# System locales are detected in the following order:
#
# - /usr/share/i18n/SUPPORTED
# - localeGenPath (defaults to /etc/locale.gen if not set)
# - 'locale -a' output
#
# Enable only when your Distribution is using an
# custom path for locale.gen
#
#localeGenPath: "PATH_TO/locale.gen"
# GeoIP based Language settings: Leave commented out to disable GeoIP.
#
# GeoIP needs a working Internet connection.
# This can be managed from `welcome.conf` by adding
# internet to the list of required conditions.
#
# The configuration
# is in three parts: a *style*, which can be "json" or "xml"
# depending on the kind of data returned by the service, and
# a *url* where the data is retrieved, and an optional *selector*
# to pick the right field out of the returned data (e.g. field
# name in JSON or element name in XML).
#
# The default selector (when the setting is blank) is picked to
# work with existing JSON providers (which use "time_zone") and
# Ubiquity's XML providers (which use "TimeZone").
#
# If the service configured via *url* uses
# a different attribute name (e.g. "timezone") in JSON or a
# different element tag (e.g. "<Time_Zone>") in XML, set this
# string to the name or tag to be used.
#
# In JSON:
# - if the string contains "." characters, this is used as a
# multi-level selector, e.g. "a.b" will select the timezone
# from data "{a: {b: "Europe/Amsterdam" } }".
# - each part of the string split by "." characters is used as
# a key into the JSON data.
# In XML:
# - all elements with the named tag (e.g. all TimeZone) elements
# from the document are checked; the first one with non-empty
# text value is used.
#
#
# An HTTP(S) request is made to *url*. The request should return
# valid data in a suitable format, depending on *style*;
# generally this includes a string value with the timezone
# in <region>/<zone> format. For services that return data which
# does not follow the conventions of "suitable data" described
# below, *selector* may be used to pick different data.
#
# Note that this example URL works, but the service is shutting
# down in June 2018.
#
# Suitable JSON data looks like
# ```
# {"time_zone":"America/New_York"}
# ```
# Suitable XML data looks like
# ```
# <Response><TimeZone>Europe/Brussels</TimeZone></Response>
# ```
#
# To accommodate providers of GeoIP timezone data with peculiar timezone
# naming conventions, the following cleanups are performed automatically:
# - backslashes are removed
# - spaces are replaced with _
#
# Legacy settings "geoipStyle", "geoipUrl" and "geoipSelector"
# in the top-level are still supported, but I'd advise against.
#
# To disable GeoIP checking, either comment-out the entire geoip section,
# or set the *style* key to an unsupported format (e.g. `none`).
# Also, note the analogous feature in src/modules/welcome/welcome.conf.
#
geoip:
style: "json"
url: "https://geoip.kde.org/v1/calamares"
selector: "" # leave blank for the default

View File

@@ -0,0 +1,14 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Luksbootkeyfile configuration. A key file is created for the
# LUKS encrypted devices.
---
# Set Password-Based Key Derivation Function (PBKDF) algorithm
# for LUKS keyslot.
#
# There are three usable specific values: pbkdf2, argon2i or argon2id.
# There is one value equivalent to not setting it: default
#
# When not set (or explicitly set to "default"), the cryptsetup default is used
luks2Hash: default

View File

@@ -0,0 +1,7 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Writes an openswap configuration with LUKS settings to the given path
---
# Path of the configuration file to write (in the target system)
configFilePath: /etc/openswap.conf

View File

@@ -0,0 +1,56 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Machine-ID and other random data on the target system.
#
# This module can create a number of "random" things on the target:
# - a systemd machine-id file (hence the name of the Calamares module)
# with a random UUID.
# - a dbus machine-id file (or, optionally, link to the one from systemd)
# - an entropy file
#
---
# Whether to create /etc/machine-id for systemd.
# The default is *false*.
systemd: true
# If systemd is true, the kind of /etc/machine-id to create in the target
# - uuid (default) generates a UUID
# - systemd alias of uuid
# - blank creates the file but leaves it empty at 0 bytes
# - none alias of blank (use `systemd: false` if you don't want one at all)
# - literal-uninitialized creates the file and writes the string "uninitialized\n"
systemd-style: uuid
# Whether to create /var/lib/dbus/machine-id for D-Bus.
# The default is *false*.
dbus: true
# Whether /var/lib/dbus/machine-id should be a symlink to /etc/machine-id
# (ignored if dbus is false, or if there is no /etc/machine-id to point to).
# The default is *false*.
dbus-symlink: true
# Copy entropy from the host? If this is set to *true*, then
# any entropy file listed below will be copied from the host
# if it exists. Non-existent files will be generated from
# /dev/urandom . The default is *false*.
entropy-copy: false
# Which files to write (paths in the target). Each of these files is
# either generated from /dev/urandom or copied from the host, depending
# on the setting for *entropy-copy*, above.
entropy-files:
- /var/lib/urandom/random-seed
- /var/lib/systemd/random-seed
# Whether to create an entropy file /var/lib/urandom/random-seed
#
# DEPRECATED: list the file in entropy-files instead. If this key
# exists and is set to *true*, a warning is printed and Calamares
# behaves as if `/var/lib/urandom/random-seed` is listed in *entropy-files*.
#
# entropy: false
# Whether to create a symlink for D-Bus
#
# DEPRECATED: set *dbus-symlink* with the same meaning instead.
#
# symlink: false

View File

@@ -0,0 +1,15 @@
# SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
# SPDX-License-Identifier: GPL-3.0-or-later
calamares_add_plugin( mobile
TYPE viewmodule
EXPORT_MACRO PLUGINDLLEXPORT_PRO
SOURCES
Config.cpp
MobileQmlViewStep.cpp
PartitionJob.cpp
UsersJob.cpp
RESOURCES
mobile.qrc
SHARED_LIB
)

View File

@@ -0,0 +1,221 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
#include "Config.h"
#include "PartitionJob.h"
#include "UsersJob.h"
#include "ViewManager.h"
#include "utils/Logger.h"
#include "utils/Variant.h"
#include <QVariant>
Config::Config( QObject* parent )
: QObject( parent )
{
}
void
Config::setConfigurationMap( const QVariantMap& cfgMap )
{
using namespace Calamares;
if ( getBool( cfgMap, "bogus", false ) )
{
cWarning() << "Configuration key \"bogus\" is still set for *mobile*";
}
m_osName = getString( cfgMap, "osName", "(unknown)" );
m_arch = getString( cfgMap, "arch", "(unknown)" );
m_device = getString( cfgMap, "device", "(unknown)" );
m_userInterface = getString( cfgMap, "userInterface", "(unknown)" );
m_version = getString( cfgMap, "version", "(unknown)" );
m_reservedUsernames = getStringList( cfgMap, "reservedUsernames", QStringList { "adm", "at ", "bin", "colord",
"cron", "cyrus", "daemon", "ftp", "games", "geoclue", "guest", "halt", "lightdm", "lp", "mail", "man",
"messagebus", "news", "nobody", "ntp", "operator", "polkitd", "postmaster", "pulse", "root", "shutdown",
"smmsp", "squid", "sshd", "sync", "uucp", "vpopmail", "xfs" } );
// ensure m_cmdUsermod matches m_username
m_username = getString( cfgMap, "username", "user" );
m_userPasswordNumeric = getBool( cfgMap, "userPasswordNumeric", true );
m_builtinVirtualKeyboard = getBool( cfgMap, "builtinVirtualKeyboard", true );
m_featureSshd = getBool( cfgMap, "featureSshd", true );
m_featureFsType = getBool( cfgMap, "featureFsType", false );
m_cmdLuksFormat = getString( cfgMap, "cmdLuksFormat", "cryptsetup luksFormat --use-random" );
m_cmdLuksOpen = getString( cfgMap, "cmdLuksOpen", "cryptsetup luksOpen" );
m_cmdMount = getString( cfgMap, "cmdMount", "mount" );
m_targetDeviceRoot = getString( cfgMap, "targetDeviceRoot", "/dev/unknown" );
m_targetDeviceRootInternal = getString( cfgMap, "targetDeviceRootInternal", "" );
m_cmdMkfsRootBtrfs = getString( cfgMap, "cmdMkfsRootBtrfs", "mkfs.btrfs -L 'unknownOS_root'" );
m_cmdMkfsRootExt4 = getString( cfgMap, "cmdMkfsRootExt4", "mkfs.ext4 -L 'unknownOS_root'" );
m_cmdMkfsRootF2fs = getString( cfgMap, "cmdMkfsRootF2fs", "mkfs.f2fs -l 'unknownOS_root'" );
m_fsList = getStringList( cfgMap, "fsModel", QStringList { "ext4", "f2fs", "btrfs" } );
m_defaultFs = getString( cfgMap, "defaultFs", "ext4" );
m_fsIndex = m_fsList.indexOf( m_defaultFs );
m_fsType = m_defaultFs;
m_cmdInternalStoragePrepare = getString( cfgMap, "cmdInternalStoragePrepare", "ondev-internal-storage-prepare" );
m_cmdPasswd = getString( cfgMap, "cmdPasswd", "passwd" );
m_cmdUsermod = getString( cfgMap, "cmdUsermod", "xargs -I{} -n1 usermod -m -d /home/{} -l {} -c {} user");
m_cmdSshdEnable = getString( cfgMap, "cmdSshdEnable", "systemctl enable sshd.service" );
m_cmdSshdDisable = getString( cfgMap, "cmdSshdDisable", "systemctl disable sshd.service" );
m_cmdSshdUseradd = getString( cfgMap, "cmdSshdUseradd", "useradd -G wheel -m" );
}
Calamares::JobList
Config::createJobs()
{
QList< Calamares::job_ptr > list;
QString cmdSshd = m_isSshEnabled ? m_cmdSshdEnable : m_cmdSshdDisable;
/* Put users job in queue (should run after unpackfs) */
Calamares::Job* j = new UsersJob( m_featureSshd,
m_cmdPasswd,
m_cmdUsermod,
cmdSshd,
m_cmdSshdUseradd,
m_isSshEnabled,
m_username,
m_userPassword,
m_sshdUsername,
m_sshdPassword );
list.append( Calamares::job_ptr( j ) );
return list;
}
void
Config::runPartitionJobThenLeave( bool b )
{
Calamares::ViewManager* v = Calamares::ViewManager::instance();
QString cmdMkfsRoot;
if ( m_fsType == QStringLiteral( "btrfs" ) )
{
cmdMkfsRoot = m_cmdMkfsRootBtrfs;
}
else if ( m_fsType == QStringLiteral( "f2fs" ) )
{
cmdMkfsRoot = m_cmdMkfsRootF2fs;
}
else if ( m_fsType == QStringLiteral( "ext4" ) )
{
cmdMkfsRoot = m_cmdMkfsRootExt4;
}
else
{
v->onInstallationFailed( "Unknown filesystem: '" + m_fsType + "'", "" );
}
/* HACK: run partition job
* The "mobile" module has two jobs, the partition job and the users job.
* If we added both of them in Config::createJobs(), Calamares would run
* them right after each other. But we need the "unpackfs" module to run
* inbetween, that's why as workaround, the partition job is started here.
* To solve this properly, we would need to place the partition job in an
* own module and pass everything via globalstorage. But then we might as
* well refactor everything so we can unify the mobile's partition job with
* the proper partition job from Calamares. */
Calamares::Job* j = new PartitionJob( m_cmdInternalStoragePrepare,
m_cmdLuksFormat,
m_cmdLuksOpen,
cmdMkfsRoot,
m_cmdMount,
m_targetDeviceRoot,
m_targetDeviceRootInternal,
m_installFromExternalToInternal,
m_isFdeEnabled,
m_fdePassword );
Calamares::JobResult res = j->exec();
if ( res )
{
v->next();
}
else
{
v->onInstallationFailed( res.message(), res.details() );
}
}
void
Config::setUsername( const QString& username )
{
m_username = username;
emit usernameChanged( m_username );
}
void
Config::setUserPassword( const QString& userPassword )
{
m_userPassword = userPassword;
emit userPasswordChanged( m_userPassword );
}
void
Config::setSshdUsername( const QString& sshdUsername )
{
m_sshdUsername = sshdUsername;
emit sshdUsernameChanged( m_sshdUsername );
}
void
Config::setSshdPassword( const QString& sshdPassword )
{
m_sshdPassword = sshdPassword;
emit sshdPasswordChanged( m_sshdPassword );
}
void
Config::setIsSshEnabled( const bool isSshEnabled )
{
m_isSshEnabled = isSshEnabled;
}
void
Config::setFdePassword( const QString& fdePassword )
{
m_fdePassword = fdePassword;
emit fdePasswordChanged( m_fdePassword );
}
void
Config::setIsFdeEnabled( const bool isFdeEnabled )
{
m_isFdeEnabled = isFdeEnabled;
}
void
Config::setInstallFromExternalToInternal( const bool val )
{
m_installFromExternalToInternal = val;
}
void
Config::setFsType( int idx )
{
if ( idx >= 0 && idx < m_fsList.length() )
{
setFsType( m_fsList[ idx ] );
}
}
void
Config::setFsType( const QString& fsType )
{
if ( fsType != m_fsType )
{
m_fsType = fsType;
emit fsTypeChanged( m_fsType );
}
}
void
Config::setFsIndex( const int fsIndex )
{
m_fsIndex = fsIndex;
emit fsIndexChanged( m_fsIndex );
}

View File

@@ -0,0 +1,207 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
#pragma once
#include "Job.h"
#include <QObject>
#include <memory>
class Config : public QObject
{
Q_OBJECT
/* installer UI */
Q_PROPERTY( bool builtinVirtualKeyboard READ builtinVirtualKeyboard CONSTANT FINAL )
/* welcome */
Q_PROPERTY( QString osName READ osName CONSTANT FINAL )
Q_PROPERTY( QString arch READ arch CONSTANT FINAL )
Q_PROPERTY( QString device READ device CONSTANT FINAL )
Q_PROPERTY( QString userInterface READ userInterface CONSTANT FINAL )
Q_PROPERTY( QString version READ version CONSTANT FINAL )
/* reserved usernames (user_pass, ssh_credentials )*/
Q_PROPERTY( QStringList reservedUsernames READ reservedUsernames CONSTANT FINAL )
/* default user */
Q_PROPERTY( QString username READ username WRITE setUsername NOTIFY usernameChanged )
Q_PROPERTY( QString userPassword READ userPassword WRITE setUserPassword NOTIFY userPasswordChanged )
Q_PROPERTY( bool userPasswordNumeric READ userPasswordNumeric CONSTANT FINAL )
/* ssh server + credentials */
Q_PROPERTY( bool featureSshd READ featureSshd CONSTANT FINAL )
Q_PROPERTY( QString sshdUsername READ sshdUsername WRITE setSshdUsername NOTIFY sshdUsernameChanged )
Q_PROPERTY( QString sshdPassword READ sshdPassword WRITE setSshdPassword NOTIFY sshdPasswordChanged )
Q_PROPERTY( bool isSshEnabled READ isSshEnabled WRITE setIsSshEnabled )
/* full disk encryption */
Q_PROPERTY( QString fdePassword READ fdePassword WRITE setFdePassword NOTIFY fdePasswordChanged )
Q_PROPERTY( bool isFdeEnabled READ isFdeEnabled WRITE setIsFdeEnabled )
/* filesystem selection */
Q_PROPERTY( QString fsType READ fsType WRITE setFsType NOTIFY fsTypeChanged )
Q_PROPERTY( bool featureFsType READ featureFsType CONSTANT FINAL )
Q_PROPERTY( QStringList fsList READ fsList CONSTANT FINAL )
Q_PROPERTY( QString defaultFs READ defaultFs CONSTANT FINAL )
Q_PROPERTY( int fsIndex READ fsIndex WRITE setFsIndex NOTIFY fsIndexChanged )
/* partition job */
Q_PROPERTY( bool runPartitionJobThenLeave READ runPartitionJobThenLeaveDummy WRITE runPartitionJobThenLeave )
Q_PROPERTY( QString cmdInternalStoragePrepare READ cmdInternalStoragePrepare CONSTANT FINAL )
Q_PROPERTY( QString cmdLuksFormat READ cmdLuksFormat CONSTANT FINAL )
Q_PROPERTY( QString cmdLuksOpen READ cmdLuksOpen CONSTANT FINAL )
Q_PROPERTY( QString cmdMount READ cmdMount CONSTANT FINAL )
Q_PROPERTY( QString targetDeviceRoot READ targetDeviceRoot CONSTANT FINAL )
Q_PROPERTY( QString targetDeviceRootInternal READ targetDeviceRootInternal CONSTANT FINAL )
Q_PROPERTY(
bool installFromExternalToInternal READ installFromExternalToInternal WRITE setInstallFromExternalToInternal )
/* users job */
Q_PROPERTY( QString cmdSshdEnable READ cmdSshdEnable CONSTANT FINAL )
Q_PROPERTY( QString cmdSshdDisable READ cmdSshdDisable CONSTANT FINAL )
public:
Config( QObject* parent = nullptr );
void setConfigurationMap( const QVariantMap& );
Calamares::JobList createJobs();
/* installer UI */
bool builtinVirtualKeyboard() { return m_builtinVirtualKeyboard; }
/* welcome */
QString osName() const { return m_osName; }
QString arch() const { return m_arch; }
QString device() const { return m_device; }
QString userInterface() const { return m_userInterface; }
QString version() const { return m_version; }
/* reserved usernames (user_pass, ssh_credentials) */
QStringList reservedUsernames() const { return m_reservedUsernames; };
/* user */
QString username() const { return m_username; }
QString userPassword() const { return m_userPassword; }
void setUsername( const QString& username );
void setUserPassword( const QString& userPassword );
bool userPasswordNumeric() const { return m_userPasswordNumeric; }
/* ssh server + credentials */
bool featureSshd() { return m_featureSshd; }
QString sshdUsername() const { return m_sshdUsername; }
QString sshdPassword() const { return m_sshdPassword; }
bool isSshEnabled() { return m_isSshEnabled; }
void setSshdUsername( const QString& sshdUsername );
void setSshdPassword( const QString& sshdPassword );
void setIsSshEnabled( bool isSshEnabled );
/* full disk encryption */
QString fdePassword() const { return m_fdePassword; }
bool isFdeEnabled() { return m_isFdeEnabled; }
void setFdePassword( const QString& fdePassword );
void setIsFdeEnabled( bool isFdeEnabled );
/* filesystem selection */
bool featureFsType() { return m_featureFsType; };
QString fsType() const { return m_fsType; };
void setFsType( int idx );
void setFsType( const QString& fsType );
QStringList fsList() const { return m_fsList; };
int fsIndex() const { return m_fsIndex; };
void setFsIndex( const int fsIndex );
QString defaultFs() const { return m_defaultFs; };
/* partition job */
bool runPartitionJobThenLeaveDummy() { return 0; }
void runPartitionJobThenLeave( bool b );
QString cmdInternalStoragePrepare() const { return m_cmdInternalStoragePrepare; }
QString cmdLuksFormat() const { return m_cmdLuksFormat; }
QString cmdLuksOpen() const { return m_cmdLuksOpen; }
QString cmdMkfsRootBtrfs() const { return m_cmdMkfsRootBtrfs; }
QString cmdMkfsRootExt4() const { return m_cmdMkfsRootExt4; }
QString cmdMkfsRootF2fs() const { return m_cmdMkfsRootF2fs; }
QString cmdMount() const { return m_cmdMount; }
QString targetDeviceRoot() const { return m_targetDeviceRoot; }
QString targetDeviceRootInternal() const { return m_targetDeviceRootInternal; }
bool installFromExternalToInternal() { return m_installFromExternalToInternal; }
void setInstallFromExternalToInternal( const bool val );
/* users job */
QString cmdPasswd() const { return m_cmdPasswd; }
QString cmdUsermod() const { return m_cmdUsermod; }
QString cmdSshdEnable() const { return m_cmdSshdEnable; }
QString cmdSshdDisable() const { return m_cmdSshdDisable; }
QString cmdSshdUseradd() const { return m_cmdSshdUseradd; }
private:
/* installer UI */
bool m_builtinVirtualKeyboard;
/* welcome */
QString m_osName;
QString m_arch;
QString m_device;
QString m_userInterface;
QString m_version;
/* reserved usernames (user_pass, ssh_credentials) */
QStringList m_reservedUsernames;
/* default user */
QString m_username;
QString m_userPassword;
bool m_userPasswordNumeric;
/* ssh server + credentials */
bool m_featureSshd = false;
QString m_sshdUsername;
QString m_sshdPassword;
bool m_isSshEnabled = false;
/* full disk encryption */
QString m_fdePassword;
bool m_isFdeEnabled = false;
/* filesystem selection */
bool m_featureFsType = false;
QString m_defaultFs;
QString m_fsType;
// Index of the currently selected filesystem in UI.
int m_fsIndex = -1;
QStringList m_fsList;
/* partition job */
QString m_cmdInternalStoragePrepare;
QString m_cmdLuksFormat;
QString m_cmdLuksOpen;
QString m_cmdMkfsRootBtrfs;
QString m_cmdMkfsRootExt4;
QString m_cmdMkfsRootF2fs;
QString m_cmdMount;
QString m_targetDeviceRoot;
QString m_targetDeviceRootInternal;
bool m_installFromExternalToInternal = false;
/* users job */
QString m_cmdPasswd;
QString m_cmdUsermod;
QString m_cmdSshdEnable;
QString m_cmdSshdDisable;
QString m_cmdSshdUseradd;
signals:
/* booleans we don't read from QML (like isSshEnabled) don't need a signal */
/* default user */
void userPasswordChanged( QString userPassword );
void usernameChanged( QString username );
/* ssh server + credentials */
void sshdUsernameChanged( QString sshdUsername );
void sshdPasswordChanged( QString sshdPassword );
/* full disk encryption */
void fdePasswordChanged( QString fdePassword );
void fsTypeChanged( QString fsType );
void fsIndexChanged( int fsIndex );
};

View File

@@ -0,0 +1,73 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
#include "MobileQmlViewStep.h"
#include "Branding.h"
#include "GlobalStorage.h"
#include "locale/TranslationsModel.h"
#include "modulesystem/ModuleManager.h"
#include "utils/Dirs.h"
#include "utils/Logger.h"
#include "utils/Variant.h"
#include <QProcess>
CALAMARES_PLUGIN_FACTORY_DEFINITION( MobileQmlViewStepFactory, registerPlugin< MobileQmlViewStep >(); )
void
MobileQmlViewStep::setConfigurationMap( const QVariantMap& configurationMap )
{
m_config->setConfigurationMap( configurationMap );
Calamares::QmlViewStep::setConfigurationMap( configurationMap );
}
MobileQmlViewStep::MobileQmlViewStep( QObject* parent )
: Calamares::QmlViewStep( parent )
, m_config( new Config( this ) )
{
}
void
MobileQmlViewStep::onLeave()
{
return;
}
bool
MobileQmlViewStep::isNextEnabled() const
{
return false;
}
bool
MobileQmlViewStep::isBackEnabled() const
{
return false;
}
bool
MobileQmlViewStep::isAtBeginning() const
{
return true;
}
bool
MobileQmlViewStep::isAtEnd() const
{
return true;
}
Calamares::JobList
MobileQmlViewStep::jobs() const
{
return m_config->createJobs();
}
QObject*
MobileQmlViewStep::getConfig()
{
return m_config;
}

View File

@@ -0,0 +1,39 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
#ifndef PARTITION_QMLVIEWSTEP_H
#define PARTITION_QMLVIEWSTEP_H
#include "Config.h"
#include "utils/PluginFactory.h"
#include "viewpages/QmlViewStep.h"
#include <DllMacro.h>
#include <QObject>
#include <QVariantMap>
class PLUGINDLLEXPORT MobileQmlViewStep : public Calamares::QmlViewStep
{
Q_OBJECT
public:
explicit MobileQmlViewStep( QObject* parent = nullptr );
bool isNextEnabled() const override;
bool isBackEnabled() const override;
bool isAtBeginning() const override;
bool isAtEnd() const override;
Calamares::JobList jobs() const override;
void setConfigurationMap( const QVariantMap& configurationMap ) override;
void onLeave() override;
QObject* getConfig() override;
private:
Config* m_config;
};
CALAMARES_PLUGIN_FACTORY_DECLARATION( MobileQmlViewStepFactory )
#endif // PARTITION_QMLVIEWSTEP_H

View File

@@ -0,0 +1,136 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
#include "PartitionJob.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "Settings.h"
#include "utils/System.h"
#include "utils/Logger.h"
#include <QDir>
#include <QFileInfo>
PartitionJob::PartitionJob( const QString& cmdInternalStoragePrepare,
const QString& cmdLuksFormat,
const QString& cmdLuksOpen,
const QString& cmdMkfsRoot,
const QString& cmdMount,
const QString& targetDeviceRoot,
const QString& targetDeviceRootInternal,
bool installFromExternalToInternal,
bool isFdeEnabled,
const QString& password )
: Calamares::Job()
, m_cmdInternalStoragePrepare( cmdInternalStoragePrepare )
, m_cmdLuksFormat( cmdLuksFormat )
, m_cmdLuksOpen( cmdLuksOpen )
, m_cmdMkfsRoot( cmdMkfsRoot )
, m_cmdMount( cmdMount )
, m_targetDeviceRoot( targetDeviceRoot )
, m_targetDeviceRootInternal( targetDeviceRootInternal )
, m_installFromExternalToInternal( installFromExternalToInternal )
, m_isFdeEnabled( isFdeEnabled )
, m_password( password )
{
}
QString
PartitionJob::prettyName() const
{
return "Creating and formatting installation partition";
}
/* Fill the "global storage", so the following jobs (like unsquashfs) work.
The code is similar to modules/partition/jobs/FillGlobalStorageJob.cpp in
Calamares. */
void
FillGlobalStorage( const QString device, const QString pathMount )
{
using namespace Calamares;
GlobalStorage* gs = JobQueue::instance()->globalStorage();
QVariantList partitions;
QVariantMap partition;
/* See mapForPartition() in FillGlobalStorageJob.cpp */
partition[ "device" ] = device;
partition[ "mountPoint" ] = "/";
partition[ "claimed" ] = true;
/* Ignored by calamares modules used in combination with the "mobile"
* module, so we can get away with leaving them empty for now. */
partition[ "uuid" ] = "";
partition[ "fsName" ] = "";
partition[ "fs" ] = "";
partitions << partition;
gs->insert( "partitions", partitions );
gs->insert( "rootMountPoint", pathMount );
}
Calamares::JobResult
PartitionJob::exec()
{
using namespace Calamares;
using namespace Calamares;
using namespace std;
const QString pathMount = "/mnt/install";
const QString cryptName = "calamares_crypt";
QString cryptDev = "/dev/mapper/" + cryptName;
QString passwordStdin = m_password + "\n";
QString dev = m_targetDeviceRoot;
QList< QPair< QStringList, QString > > commands = {};
if ( m_installFromExternalToInternal )
{
dev = m_targetDeviceRootInternal;
commands.append( {
{ { "sh", "-c", m_cmdInternalStoragePrepare }, QString() },
} );
}
commands.append( { { { "mkdir", "-p", pathMount }, QString() } } );
if ( m_isFdeEnabled )
{
commands.append( {
{ { "sh", "-c", m_cmdLuksFormat + " " + dev }, passwordStdin },
{ { "sh", "-c", m_cmdLuksOpen + " " + dev + " " + cryptName }, passwordStdin },
{ { "sh", "-c", m_cmdMkfsRoot + " " + cryptDev }, QString() },
{ { "sh", "-c", m_cmdMount + " " + cryptDev + " " + pathMount }, QString() },
} );
}
else
{
commands.append( { { { "sh", "-c", m_cmdMkfsRoot + " " + dev }, QString() },
{ { "sh", "-c", m_cmdMount + " " + dev + " " + pathMount }, QString() } } );
}
foreach ( auto command, commands )
{
const QStringList args = command.first;
const QString stdInput = command.second;
const QString pathRoot = "/";
ProcessResult res
= System::runCommand( System::RunLocation::RunInHost, args, pathRoot, stdInput, chrono::seconds( 600 ) );
if ( res.getExitCode() )
{
return JobResult::error( "Command failed:<br><br>"
"'"
+ args.join( " " )
+ "'<br><br>"
" with output:<br><br>"
"'"
+ res.getOutput() + "'" );
}
}
FillGlobalStorage( m_isFdeEnabled ? cryptDev : dev, pathMount );
return JobResult::ok();
}

View File

@@ -0,0 +1,38 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
#pragma once
#include "Job.h"
class PartitionJob : public Calamares::Job
{
Q_OBJECT
public:
PartitionJob( const QString& cmdInternalStoragePrepare,
const QString& cmdLuksFormat,
const QString& cmdLuksOpen,
const QString& cmdMkfsRoot,
const QString& cmdMount,
const QString& targetDeviceRoot,
const QString& targetDeviceRootInternal,
bool installFromExternalToInternal,
bool isFdeEnabled,
const QString& password );
QString prettyName() const override;
Calamares::JobResult exec() override;
Calamares::JobList createJobs();
private:
QString m_cmdInternalStoragePrepare;
QString m_cmdLuksFormat;
QString m_cmdLuksOpen;
QString m_cmdMkfsRoot;
QString m_cmdMount;
QString m_targetDeviceRoot;
QString m_targetDeviceRootInternal;
bool m_installFromExternalToInternal;
bool m_isFdeEnabled;
QString m_password;
};

View File

@@ -0,0 +1,92 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
#include "UsersJob.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "Settings.h"
#include "utils/System.h"
#include "utils/Logger.h"
#include <QDir>
#include <QFileInfo>
UsersJob::UsersJob( bool featureSshd,
const QString& cmdPasswd,
const QString& cmdUsermod,
const QString& cmdSshd,
const QString& cmdSshdUseradd,
bool isSshEnabled,
const QString& username,
const QString& password,
const QString& sshdUsername,
const QString& sshdPassword )
: Calamares::Job()
, m_featureSshd( featureSshd )
, m_cmdPasswd( cmdPasswd )
, m_cmdUsermod( cmdUsermod )
, m_cmdSshd( cmdSshd )
, m_cmdSshdUseradd( cmdSshdUseradd )
, m_isSshEnabled( isSshEnabled )
, m_username( username )
, m_password( password )
, m_sshdUsername( sshdUsername )
, m_sshdPassword( sshdPassword )
{
}
QString
UsersJob::prettyName() const
{
return "Configuring users";
}
Calamares::JobResult
UsersJob::exec()
{
using namespace Calamares;
using namespace Calamares;
using namespace std;
QList< QPair< QStringList, QString > > commands = {
{ { "sh", "-c", m_cmdUsermod }, m_username + "\n" }
};
commands.append( { { "sh", "-c", m_cmdPasswd + " " + m_username }, m_password + "\n" + m_password + "\n" } );
if ( m_featureSshd )
{
commands.append( { { "sh", "-c", m_cmdSshd }, QString() } );
if ( m_isSshEnabled )
{
commands.append( { { "sh", "-c", m_cmdSshdUseradd + " " + m_sshdUsername }, QString() } );
commands.append(
{ { "sh", "-c", m_cmdPasswd + " " + m_sshdUsername }, m_sshdPassword + "\n" + m_sshdPassword + "\n" } );
}
}
foreach ( auto command, commands )
{
auto location = System::RunLocation::RunInTarget;
const QString pathRoot = "/";
const QStringList args = command.first;
const QString stdInput = command.second;
ProcessResult res = System::runCommand( location, args, pathRoot, stdInput, chrono::seconds( 30 ) );
if ( res.getExitCode() )
{
return JobResult::error( "Command failed:<br><br>"
"'"
+ args.join( " " )
+ "'<br><br>"
" with output:<br><br>"
"'"
+ res.getOutput() + "'" );
}
}
return JobResult::ok();
}

View File

@@ -0,0 +1,38 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
#pragma once
#include "Job.h"
class UsersJob : public Calamares::Job
{
Q_OBJECT
public:
UsersJob( bool featureSshd,
const QString& cmdPasswd,
const QString& cmdUsermod,
const QString& cmdSshd,
const QString& cmdSshdUseradd,
bool isSshEnabled,
const QString& username,
const QString& password,
const QString& sshdUsername,
const QString& sshdPassword );
QString prettyName() const override;
Calamares::JobResult exec() override;
Calamares::JobList createJobs();
private:
bool m_featureSshd;
QString m_cmdPasswd;
QString m_cmdUsermod;
QString m_cmdSshd;
QString m_cmdSshdUseradd;
bool m_isSshEnabled;
QString m_username;
QString m_password;
QString m_sshdUsername;
QString m_sshdPassword;
};

View File

@@ -0,0 +1,65 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
import io.calamares.core 1.0
import io.calamares.ui 1.0
import QtQuick 2.10
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.7 as Kirigami
import QtGraphicalEffects 1.0
import QtQuick.Window 2.3
import QtQuick.VirtualKeyboard 2.1
Item {
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
width: parent.width
height: parent.height
Text {
id: mainText
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 10
wrapMode: Text.WordWrap
text: "To protect your data in case your device gets stolen," +
" it is recommended to enable full disk encryption.<br>" +
"<br>" +
"If you enable full disk encryption, you will be asked for" +
" a password. Without this password, it is not possible to" +
" boot your device or access any data on it. Make sure that" +
" you don't lose this password!"
width: 200
}
Button {
id: firstButton
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: mainText.bottom
anchors.topMargin: 10
width: 200
text: qsTr("Enable")
onClicked: {
config.isFdeEnabled = true;
navNext();
}
}
Button {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: firstButton.bottom
anchors.topMargin: 10
width: 200
text: qsTr("Disable")
onClicked: {
config.isFdeEnabled = false;
navNextFeature();
}
}
}

View File

@@ -0,0 +1,80 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
import io.calamares.core 1.0
import io.calamares.ui 1.0
import QtQuick 2.10
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.7 as Kirigami
import QtGraphicalEffects 1.0
import QtQuick.Window 2.3
import QtQuick.VirtualKeyboard 2.1
Item {
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
width: parent.width
height: parent.height
TextField {
id: password
anchors.top: parent.top
placeholderText: qsTr("Password")
inputMethodHints: Qt.ImhPreferLowercase
echoMode: TextInput.Password
onTextChanged: validatePassword(password, passwordRepeat,
errorText)
text: config.fdePassword
onActiveFocusChanged: {
if(activeFocus) {
Qt.inputMethod.update(Qt.ImQueryInput);
}
}
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 50
width: 200
}
TextField {
id: passwordRepeat
anchors.top: password.bottom
placeholderText: qsTr("Password (repeat)")
echoMode: TextInput.Password
onTextChanged: validatePassword(password, passwordRepeat,
errorText)
text: config.fdePassword
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 10
width: 200
}
Text {
id: errorText
anchors.top: passwordRepeat.bottom
visible: false
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 10
width: 200
wrapMode: Text.WordWrap
}
Button {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: errorText.bottom
anchors.topMargin: 10
width: 200
text: qsTr("Continue")
onClicked: {
if (validatePassword(password, passwordRepeat, errorText)) {
config.fdePassword = password.text;
navNext();
}
}
}
}

View File

@@ -0,0 +1,59 @@
/* SPDX-FileCopyrightText: 2020 Undef <calamares@undef.tools>
* SPDX-License-Identifier: GPL-3.0-or-later */
import io.calamares.core 1.0
import io.calamares.ui 1.0
import QtQuick 2.10
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.7 as Kirigami
import QtGraphicalEffects 1.0
import QtQuick.Window 2.3
import QtQuick.VirtualKeyboard 2.1
Item {
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
width: parent.width
height: parent.height
Text {
id: mainText
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 10
wrapMode: Text.WordWrap
text: "Select the filesystem for root partition. If unsure, leave the default."
width: 200
}
ComboBox {
id: fsTypeCB
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: mainText.bottom
anchors.topMargin: 10
width: 150
height: 30
editable: false
model: config.fsList
/* Save the current state on selection so it is there when the back button is pressed */
onActivated: config.fsType = fsTypeCB.currentText;
Component.onCompleted: fsTypeCB.currentIndex = find( config.fsType, Qt.MatchContains );
}
Button {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: fsTypeCB.bottom
anchors.topMargin: 10
width: 200
text: qsTr("Continue")
onClicked: {
config.fsType = fsTypeCB.currentText;
navNextFeature();
}
}
}

View File

@@ -0,0 +1,60 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
import io.calamares.core 1.0
import io.calamares.ui 1.0
import QtQuick 2.10
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.7 as Kirigami
import QtGraphicalEffects 1.0
import QtQuick.Window 2.3
import QtQuick.VirtualKeyboard 2.1
Item {
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
width: parent.width
height: parent.height
Text {
id: mainText
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 10
wrapMode: Text.WordWrap
text: (function() {
var ret = "Once you hit 'install', the installation will begin." +
" It will typically take a few minutes. Do not power off the" +
" device until it is done.<br>";
if (config.installFromExternalToInternal) {
ret += "<b>After the installation, your device will shutdown" +
" automatically. You must remove the external storage" +
" (SD card) before booting again.</b>" +
"<br><br>" +
"Otherwise, your device will boot into the installer" +
" again, and not into the installed system."
} else {
ret += "Afterwards, it will reboot into the installed system.";
}
return ret;
}())
width: 200
}
Button {
id: firstButton
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: mainText.bottom
anchors.topMargin: 10
width: 200
text: qsTr("Install")
onClicked: navFinish()
}
}

View File

@@ -0,0 +1,64 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
import io.calamares.core 1.0
import io.calamares.ui 1.0
import QtQuick 2.10
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.7 as Kirigami
import QtGraphicalEffects 1.0
import QtQuick.Window 2.3
import QtQuick.VirtualKeyboard 2.1
Item {
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
width: parent.width
height: parent.height
Text {
id: mainText
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 10
wrapMode: Text.WordWrap
text: "The installation was started from an external storage medium." +
"<br>" +
"You can either install to the same medium and overwrite the" +
" installer, or install to the internal storage.<br>" +
"<br>" +
"Where would you like to install " + config.osName + "?"
width: 200
}
Button {
id: firstButton
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: mainText.bottom
anchors.topMargin: 10
width: 200
text: qsTr("Internal (eMMC)")
onClicked: {
config.installFromExternalToInternal = true;
navNext();
}
}
Button {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: firstButton.bottom
anchors.topMargin: 10
width: 200
text: qsTr("External (SD card)")
onClicked: {
config.installFromExternalToInternal = false;
navNextFeature();
}
}
}

View File

@@ -0,0 +1,58 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
import io.calamares.core 1.0
import io.calamares.ui 1.0
import QtQuick 2.10
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.7 as Kirigami
import QtGraphicalEffects 1.0
import QtQuick.Window 2.3
import QtQuick.VirtualKeyboard 2.1
Item {
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
width: parent.width
height: parent.height
Text {
id: mainText
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 10
wrapMode: Text.WordWrap
text: "Are you sure that you want to overwrite the internal storage?" +
"<br><br>" +
"<b>All existing data on the device will be lost!</b>"
width: 200
}
Button {
id: firstButton
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: mainText.bottom
anchors.topMargin: 10
width: 200
text: qsTr("Yes")
onClicked: {
navNext();
}
}
Button {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: firstButton.bottom
anchors.topMargin: 10
width: 200
text: qsTr("No")
onClicked: {
navBack();
}
}
}

View File

@@ -0,0 +1,173 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Commented out values are defaults.
# All commands are running with 'sh -c'.
---
# This entry exists only to keep the tests happy, remove it in
# any production configuration.
bogus: true
#######
### Target OS information
#######
## Operating System Name
# osName: "(unknown)"
## User Interface name (e.g. Plasma Mobile)
# userInterface: "(unknown)"
## User Interface assumes that the password is numeric (as of writing, this is
## the case with Plasma Mobile and Phosh)
# userPasswordNumeric: true
## OS version
# version: "(unknown)"
## Default username (for which the password will be set)
## Ensure also cmdUsermod command matches the default user, so it can be changed if desired.
# username: "user"
## reserved usernames (for user_pass username prompt and ssh_credentials)
# reservedUsernames:
# - adm
# - at
# - bin
# - colord
# - cron
# - cyrus
# - daemon
# - ftp
# - games
# - geoclue
# - guest
# - halt
# - lightdm
# - lp
# - mail
# - man
# - messagebus
# - news
# - nobody
# - ntp
# - operator
# - polkitd
# - postmaster
# - pulse
# - root
# - shutdown
# - smmsp
# - squid
# - sshd
# - sync
# - uucp
# - vpopmail
# - xfs
#######
### Target device information
#######
## Architecture (e.g. aarch64)
# arch: "(unknown)"
## Name of the device (e.g. PinePhone)
# device: "(unknown)"
## Partition that will be formatted and mounted (optionally with FDE) for the
## rootfs
# targetDeviceRoot: "/dev/unknown"
## Partition that will be formatted and mounted (optionally with FDE) for the
## rootfs, on internal storage. The installer OS must not set this, if it was
## booted from the internal storage (this is not checked in the mobile
## module!).
## If this is set, the user gets asked whether they want to install on internal
## or external storage. If the user chose internal storage,
## cmdInternalStoragePrepare (see below) runs before this partition gets
## formatted (see below). A note is displayed, that the device is powered off
## after installation and that the user should remove the external storage
## medium. So you need to adjust the installer OS to poweroff in that case, and
## not reboot. See postmarketos-ondev.git for reference.
# targetDeviceRootInternal: ""
######
### Installer Features
######
## Ask whether sshd should be enabled or not. If enabled, add a dedicated ssh
## user with proper username and password and suggest to change to key-based
## authentication after installation.
# featureSshd: true
## Ask the user, which filesystem to use.
# featureFsType: false
## Filesystems that the user can choose from.
#fsModel:
# - ext4
# - f2fs
# - btrfs
## Default filesystem to display in the dialog. If featureFsType is disabled,
## this gets used without asking the user.
# defaultFs: ext4
## Start Qt's virtual keyboard within the mobile module. Disable if you bring
## your own virtual keyboard (e.g. svkbd).
# builtinVirtualKeyboard: true
#######
### Commands running in the installer OS
#######
## Format the target partition with LUKS
## Arguments: <device>
## Stdin: password with \n
# cmdLuksFormat: "cryptsetup luksFormat --use-random"
## Open the formatted partition
## Arguments: <device> <mapping name>
## Stdin: password with \n
# cmdLuksOpen: "cryptsetup luksOpen"
## Format the rootfs with a file system
## Arguments: <device>
## Btrfs: to allow snapshots to work on the root subvolume, it is recommended that this
## command be a script which will create a subvolume and make it default
## An example can be found at:
## https://gitlab.com/mobian1/calamares-settings-mobian/-/merge_requests/2/diffs#diff-content-dde34f5f1c89e3dea63608c553bbc452dedf428f
# cmdMkfsRootBtrfs: "mkfs.btrfs -L 'unknownOS_root'"
# cmdMkfsRootExt4: "mkfs.ext4 -L 'unknownOS_root'"
# cmdMkfsRootF2fs: "mkfs.f2fs -l 'unknownOS_root'"
## Mount the partition after formatting with file system
## Arguments: <device> <mountpoint>
# cmdMount: "mount"
## When user selects installation from external storage to internal storage
## (see targetDeviceRootInternal above), use this command to prepare the
## internal storage medium. The command must create a partition table with
## two partitions (boot, root) and fill the boot partition. See the
## ondev-internal-storage-prepare.sh in postmarketos-ondev as example.
# cmdInternalStoragePrepare: "ondev-internal-storage-prepare"
#######
### Commands running in the target OS (chroot)
#######
## Change the username for the default user
## Stdin: username with \n
# cmdUsermod: "xargs -I{} -n1 usermod -m -d /home/{} -l {} -c {} user"
## Set the password for default user and sshd user
## Arguments: <username>
## Stdin: password twice, each time with \n
# cmdPasswd: "passwd"
## Enable or disable sshd
# cmdSshdEnable: "systemctl enable sshd.service"
# cmdSshdDisable: "systemctl disable sshd.service"
## Create the user for sshd
## Arguments: <username>
# cmdSshdUseradd: "useradd -G wheel -m"

View File

@@ -0,0 +1,390 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
import io.calamares.core 1.0
import io.calamares.ui 1.0
import QtQuick 2.10
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.7 as Kirigami
import QtGraphicalEffects 1.0
import QtQuick.Window 2.3
import QtQuick.VirtualKeyboard 2.1
Page
{
property var screen: "welcome"
property var screenPrevious: []
property var titles: {
"welcome": null, /* titlebar disabled */
"install_target": "Installation target",
"install_target_confirm": "Warning",
"user_pass": "User password",
"ssh_confirm": "SSH server",
"ssh_credentials": "SSH credentials",
"fs_selection": "Root filesystem",
"fde_confirm": "Full disk encryption",
"fde_pass": "Full disk encryption",
"install_confirm": "Ready to install",
"wait": null
}
property var features: [
{"name": "welcome",
"screens": ["welcome"]},
{"name": "installTarget",
"screens": ["install_target", "install_target_confirm"]},
{"name": "userPassword",
"screens": ["user_pass"]},
{"name": "sshd",
"screens": ["ssh_confirm", "ssh_credentials"]},
{"name": "fsType",
"screens": ["fs_selection"]},
{"name": "fde",
"screens": ["fde_confirm", "fde_pass"]},
{"name": "installConfirm",
"screens": ["install_confirm", "wait"]}
]
property var featureIdByScreen: (function() {
/* Put "features" above into an index of screen name -> feature id:
* featureIdByScreen = {"welcome": 0, "user_pass": 1, ...} */
var ret = {};
for (var i=0; i<features.length; i++) {
for (var j=0; j<features[i]["screens"].length; j++) {
ret[ features[i]["screens"][j] ] = i;
}
}
return ret;
}())
/* Only allow characters, that can be typed in with osk-sdl
* (src/keyboard.cpp). Details in big comment in validatePassword(). */
property var allowed_chars:
/* layer 0 */ "abcdefghijklmnopqrstuvwxyz" +
/* layer 1 */ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
/* layer 2 */ "1234567890" + "@#$%&-_+()" + ",\"':;!?" +
/* layer 3 */ "~`|·√πτ÷×¶" + "©®£€¥^°*{}" + "\\/<>=[]" +
/* bottom row */ " ."
Item {
id: appContainer
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
anchors.bottom: inputPanel.top
Item {
width: parent.width
height: parent.height
Rectangle {
id: mobileNavigation
width: parent.width
height: 30
color: "#e6e4e1"
Layout.fillWidth: true
border.width: 1
border.color: "#a7a7a7"
anchors.left: parent.left
anchors.right: parent.right
RowLayout {
width: parent.width
height: parent.height
spacing: 6
Button {
Layout.leftMargin: 6
id: mobileBack
text: "<"
background: Rectangle {
implicitWidth: 10
implicitHeight: 7
border.color: "#c1bab5"
border.width: 1
radius: 4
color: mobileBack.down ? "#dbdbdb" : "#f2f2f2"
}
onClicked: navBack()
}
Rectangle {
implicitHeight: 10
Layout.fillWidth: true
color: "#e6e4e1"
Text {
id: mobileTitle
text: ""
color: "#303638"
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
}
}
Rectangle {
color: "#e6e4e1"
Layout.rightMargin: 6
implicitWidth: 32
implicitHeight: 30
id: filler
}
}
}
Loader {
id: load
anchors.left: parent.left
anchors.top: mobileNavigation.bottom
anchors.right: parent.right
}
}
}
InputPanel {
id: inputPanel
y: Qt.inputMethod.visible ? parent.height - inputPanel.height : parent.height
visible: config.builtinVirtualKeyboard
anchors.left: parent.left
anchors.right: parent.right
}
Timer {
id: timer
}
function skipFeatureInstallTarget() {
return config.targetDeviceRootInternal == "";
}
/* Navigation related */
function navTo(name, historyPush=true) {
console.log("Navigating to screen: " + name);
if (historyPush)
screenPrevious.push(screen);
screen = name;
load.source = name + ".qml";
mobileNavigation.visible = (titles[name] !== null);
mobileTitle.text = "<b>" + titles[name] + "</b>";
Qt.inputMethod.hide();
}
function navFinish() {
/* Show a waiting screen and wait a second (so it can render). The big
* comment in Config.cpp::runPartitionJobThenLeave() explains why this
* is necessary. */
navTo("wait");
timer.interval = 1000;
timer.repeat = false;
timer.triggered.connect(function() {
/* Trigger Config.cpp::runPartitionJobThenLeave(). (We could expose
* the function directly with qmlRegisterSingletonType somehow, but
* I haven't seen existing Calamares code do that with the Config
* object, so just use the side effect of setting the variable, as
* done in existing code of Calamares modules.) */
config.runPartitionJobThenLeave = 1
});
timer.start();
}
function navNextFeature() {
var id;
/* Skip disabled features */
for (id = featureIdByScreen[screen] + 1; id < features.length; id++) {
/* First letter uppercase */
var name = features[id]["name"];
var nameUp = name.charAt(0).toUpperCase() + name.slice(1);
/* Check config.Feature<Name> */
var configOption = "feature" + nameUp;
if (config[configOption] === false) {
console.log("Skipping feature (disabled in config): " + name);
continue;
}
/* Check skipFeature<Name>() */
var funcName = "skipFeature" + nameUp;
if (eval("typeof " + funcName) === "function"
&& eval(funcName + "()")) {
console.log("Skipping feature (skip function): " + name);
continue;
}
break;
}
console.log("Navigating to feature: " + features[id]["name"]);
return navTo(features[id]["screens"][0]);
}
function navNext() {
var featureId = featureIdByScreen[screen];
var featureScreens = features[featureId]["screens"];
for (var i = 0; i<featureScreens.length; i++) {
/* Seek ahead until i is current screen */
if (featureScreens[i] != screen)
continue;
/* Navigate to next screen in same feature */
if (i + 1 < featureScreens.length) {
var screenNext = featureScreens[i + 1];
return navTo(screenNext);
}
/* Screen is last in feature */
return navNextFeature();
}
console.log("ERROR: navNext() failed for screen: " + screen);
}
function navBack() {
if (screenPrevious.length)
return navTo(screenPrevious.pop(), false);
ViewManager.back();
}
function onActivate() {
navTo(screen, false);
}
/* Input validation: show/clear failures */
function validationFailure(errorText, message="") {
errorText.text = message;
errorText.visible = true;
return false;
}
function validationFailureClear(errorText) {
errorText.text = "";
errorText.visible = false;
return true;
}
/* Input validation: user-screens (fde_pass, user_pass, ssh_credentials) */
function validatePin(userPin, userPinRepeat, errorText) {
var pin = userPin.text;
var repeat = userPinRepeat.text;
if (pin == "")
return validationFailure(errorText);
if (!pin.match(/^[0-9]*$/))
return validationFailure(errorText,
"Only digits are allowed.");
if (pin.length < 5)
return validationFailure(errorText,
"Too short: needs at least 5 digits.");
if (repeat == "")
return validationFailure(errorText);
if (repeat != pin)
return validationFailure(errorText,
"The PINs don't match.");
return validationFailureClear(errorText);
}
function validateUsername(username, errorText, extraReservedUsernames = []) {
var name = username.text;
var reserved = config.reservedUsernames.concat(extraReservedUsernames);
/* Validate characters */
for (var i = 0; i < name.length; i++) {
if (i) {
if (!name[i].match(/^[a-z0-9_-]$/))
return validationFailure(errorText,
"Characters must be lowercase" +
" letters, numbers,<br>" +
" underscores or minus signs.");
} else {
if (!name[i].match(/^[a-z_]$/))
return validationFailure(errorText,
"First character must be a" +
" lowercase letter or an" +
" underscore.");
}
}
/* Validate against reserved usernames */
for (var i = 0; i < reserved.length; i++) {
if (name == reserved[i])
return validationFailure(errorText, "Username '" +
reserved[i] +
"' is reserved.");
}
/* Passed */
return validationFailureClear(errorText);
}
function validateSshdUsername(username, errorText) {
return validateUsername(username, errorText, [config.username]);
}
function validateSshdPassword(password, passwordRepeat, errorText) {
var pass = password.text;
var repeat = passwordRepeat.text;
if (pass == "")
return validationFailure(errorText);
if (pass.length < 6)
return validationFailure(errorText,
"Too short: needs at least 6" +
" digits/characters.");
if (repeat == "")
return validationFailure(errorText);
if (pass != repeat)
return validationFailure(errorText, "Passwords don't match.");
return validationFailureClear(errorText);
}
function check_chars(input) {
for (var i = 0; i < input.length; i++) {
if (allowed_chars.indexOf(input[i]) == -1)
return false;
}
return true;
}
function allowed_chars_multiline() {
/* return allowed_chars split across multiple lines */
var step = 20;
var ret = "";
for (var i = 0; i < allowed_chars.length + step; i += step)
ret += allowed_chars.slice(i, i + step) + "\n";
return ret.trim();
}
function validatePassword(password, passwordRepeat, errorText) {
var pass = password.text;
var repeat = passwordRepeat.text;
if (pass == "")
return validationFailure(errorText);
/* This function gets called for the FDE password and for the user
* password. As of writing, all distributions shipping the mobile
* module are using osk-sdl to type in the FDE password after the
* installation, and another keyboard after booting up, to type in the
* user password. The osk-sdl password has the same keys as
* squeekboard's default layout, and other keyboards should be able to
* type these characters in as well. For now, verify that the password
* only contains characters that can be typed in by osk-sdl. If you
* need this to be more sophisticated, feel free to submit patches to
* make this more configurable. */
if (!check_chars(pass))
return validationFailure(errorText,
"The password must only contain" +
" these characters, others can possibly" +
" not be typed in after installation:\n" +
"\n" +
allowed_chars_multiline());
if (pass.length < 6)
return validationFailure(errorText,
"Too short: needs at least 6" +
" digits/characters.");
if (repeat == "")
return validationFailure(errorText);
if (pass != repeat)
return validationFailure(errorText, "Passwords don't match.");
return validationFailureClear(errorText);
}
}

View File

@@ -0,0 +1,21 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>mobile.qml</file>
<file>welcome.qml</file>
<file>install_target.qml</file> <!-- install from external to internal? -->
<file>install_target_confirm.qml</file> <!-- overwrite internal storage? -->
<file>user_pass.qml</file> <!-- default user: username, password -->
<file>ssh_confirm.qml</file> <!-- sshd: enable or not? -->
<file>ssh_credentials.qml</file> <!-- sshd user: username, password -->
<file>fs_selection.qml</file> <!-- filesystem selection -->
<file>fde_confirm.qml</file> <!-- enable FDE or not? -->
<file>fde_pass.qml</file> <!-- FDE password (optional) -->
<file>install_confirm.qml</file> <!-- final confirmation before install -->
<file>wait.qml</file> <!-- please wait while partitioning -->
</qresource>
</RCC>

View File

@@ -0,0 +1,68 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
import io.calamares.core 1.0
import io.calamares.ui 1.0
import QtQuick 2.10
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.7 as Kirigami
import QtGraphicalEffects 1.0
import QtQuick.Window 2.3
import QtQuick.VirtualKeyboard 2.1
Item {
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
width: parent.width
height: parent.height
Text {
id: mainText
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 30
wrapMode: Text.WordWrap
text: "If you don't know what SSH is, choose 'disable'.<br>" +
"<br>" +
"With 'enable', you will be asked for a second username and" +
" password. You will be able to login to the SSH server with" +
" these credentials via USB (172.16.42.1), Wi-Fi and possibly" +
" cellular network. It is recommended to replace the password" +
" with an SSH key after the installation.<br>" +
"<br>" +
"More information:<br>" +
"https://postmarketos.org/ssh"
width: 200
}
Button {
id: firstButton
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: mainText.bottom
anchors.topMargin: 40
width: 200
text: qsTr("Enable")
onClicked: {
config.isSshEnabled = true;
navNext();
}
}
Button {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: firstButton.bottom
anchors.topMargin: 40
width: 200
text: qsTr("Disable")
onClicked: {
config.isSshEnabled = false;
navNextFeature();
}
}
}

View File

@@ -0,0 +1,107 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
import io.calamares.core 1.0
import io.calamares.ui 1.0
import QtQuick 2.10
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.7 as Kirigami
import QtGraphicalEffects 1.0
import QtQuick.Window 2.3
import QtQuick.VirtualKeyboard 2.1
Item {
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
width: parent.width
height: parent.height
TextField {
id: username
anchors.top: parent.top
placeholderText: qsTr("SSH username")
inputMethodHints: Qt.ImhPreferLowercase
onTextChanged: validateSshdUsername(username, errorTextUsername)
text: config.sshdUsername
onActiveFocusChanged: {
if(activeFocus) {
Qt.inputMethod.update(Qt.ImQueryInput);
}
}
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 50
width: 200
}
Text {
id: errorTextUsername
anchors.top: username.bottom
visible: false
wrapMode: Text.WordWrap
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 50
width: 200
}
TextField {
id: password
anchors.top: errorTextUsername.bottom
placeholderText: qsTr("SSH password")
echoMode: TextInput.Password
onTextChanged: validateSshdPassword(password, passwordRepeat,
errorTextPassword)
text: config.sshdPassword
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 50
width: 200
}
TextField {
id: passwordRepeat
anchors.top: password.bottom
placeholderText: qsTr("SSH password (repeat)")
echoMode: TextInput.Password
onTextChanged: validateSshdPassword(password, passwordRepeat,
errorTextPassword)
text: config.sshdPassword
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 50
width: 200
}
Text {
id: errorTextPassword
anchors.top: passwordRepeat.bottom
visible: false
wrapMode: Text.WordWrap
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 50
width: 200
}
Button {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: errorTextPassword.bottom
anchors.topMargin: 40
width: 200
text: qsTr("Continue")
onClicked: {
if (validateSshdUsername(username, errorTextUsername) &&
validateSshdPassword(password, passwordRepeat,
errorTextPassword)) {
config.sshdUsername = username.text;
config.sshdPassword = password.text;
navNext();
}
}
}
}

View File

@@ -0,0 +1,143 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
import io.calamares.core 1.0
import io.calamares.ui 1.0
import QtQuick 2.10
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.7 as Kirigami
import QtGraphicalEffects 1.0
import QtQuick.Window 2.3
import QtQuick.VirtualKeyboard 2.1
Item {
property var passPlaceholder: (config.userPasswordNumeric
? "PIN"
: "Password")
property var hints: (config.userPasswordNumeric
? Qt.ImhDigitsOnly
: Qt.ImhPreferLowercase)
property var validatePassFunc: (config.userPasswordNumeric
? validatePin
: validatePassword);
property var validateNameFunc: validateUsername;
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
width: parent.width
height: parent.height
Text {
id: usernameDescription
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 10
wrapMode: Text.WordWrap
text: (function() {
return "Set the username of your user. The default" +
" username is \"" + config.username + "\".";
}())
width: 200
}
TextField {
id: username
anchors.top: usernameDescription.bottom
placeholderText: qsTr("Username")
onTextChanged: validateNameFunc(username, errorText)
text: config.username
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 10
width: 200
}
Text {
id: userPassDescription
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: username.bottom
anchors.topMargin: 10
wrapMode: Text.WordWrap
text: (function() {
if (config.userPasswordNumeric) {
return "Set the numeric password of your user. The" +
" lockscreen will ask for this PIN. This is" +
" <i>not</i> the PIN of your SIM card. Make sure to" +
" remember it.";
} else {
return "Set the password of your user. The lockscreen will" +
" ask for this password. Make sure to remember it.";
}
}())
width: 200
}
TextField {
id: userPass
anchors.top: userPassDescription.bottom
placeholderText: qsTr(passPlaceholder)
echoMode: TextInput.Password
onTextChanged: validatePassFunc(userPass, userPassRepeat, errorText)
text: config.userPassword
/* Let the virtual keyboard change to digits only */
inputMethodHints: hints
onActiveFocusChanged: {
if(activeFocus) {
Qt.inputMethod.update(Qt.ImQueryInput)
}
}
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 10
width: 200
}
TextField {
id: userPassRepeat
anchors.top: userPass.bottom
placeholderText: qsTr(passPlaceholder + " (repeat)")
inputMethodHints: hints
echoMode: TextInput.Password
onTextChanged: validatePassFunc(userPass, userPassRepeat, errorText)
text: config.userPassword
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 10
width: 200
}
Text {
anchors.top: userPassRepeat.bottom
id: errorText
visible: false
wrapMode: Text.WordWrap
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 10
width: 200
}
Button {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: errorText.bottom
anchors.topMargin: 10
width: 200
text: qsTr("Continue")
onClicked: {
if (validatePassFunc(userPass, userPassRepeat, errorText) && validateNameFunc(username, errorText)) {
config.userPassword = userPass.text;
config.username = username.text;
navNext();
}
}
}
}

View File

@@ -0,0 +1,45 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
import io.calamares.core 1.0
import io.calamares.ui 1.0
import QtQuick 2.10
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.7 as Kirigami
import QtGraphicalEffects 1.0
import QtQuick.Window 2.3
import QtQuick.VirtualKeyboard 2.1
Page
{
id: fdeWait
Item {
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
width: parent.width
height: parent.height
Image {
id: logo
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 10
height: 50
fillMode: Image.PreserveAspectFit
source: "file:///usr/share/calamares/branding/default-mobile/logo.png"
}
Text {
id: waitText
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: logo.bottom
anchors.topMargin: 50
wrapMode: Text.WordWrap
text: "Formatting and mounting target partition. This may" +
" take up to ten minutes, please be patient."
width: 200
}
}
}

View File

@@ -0,0 +1,65 @@
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
* SPDX-License-Identifier: GPL-3.0-or-later */
import io.calamares.core 1.0
import io.calamares.ui 1.0
import QtQuick 2.10
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.7 as Kirigami
import QtGraphicalEffects 1.0
import QtQuick.Window 2.3
import QtQuick.VirtualKeyboard 2.1
Page
{
id: welcome
Item {
id: appContainer
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
Item {
width: parent.width
height: parent.height
Image {
id: logo
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 10
height: 50
fillMode: Image.PreserveAspectFit
source: "file:///usr/share/calamares/branding/default-mobile/logo.png"
}
Text {
id: mainText
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: logo.bottom
anchors.topMargin: 10
horizontalAlignment: Text.AlignRight
text: "You are about to install<br>" +
"<b>" + config.osName +
" " + config.version + "</b><br>" +
"user interface " +
"<b>" + config.userInterface + "</b><br>" +
"architecture " +
"<b>" + config.arch + "</b><br>" +
"on your <br>" +
"<b>" + config.device + "</b><br>"
width: 200
}
Button {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: mainText.bottom
anchors.topMargin: 10
width: 200
text: qsTr("Continue")
onClicked: navNext()
}
}
}
}

View File

@@ -0,0 +1,125 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Mount filesystems in the target (generally, before treating the
# target as a usable chroot / "live" system). Filesystems are
# automatically mounted from the partitioning module. Filesystems
# listed here are **extra**. The filesystems listed in *extraMounts*
# are mounted in all target systems.
---
# Extra filesystems to mount. The key's value is a list of entries; each
# entry has five keys:
# - device The device node to mount
# - fs (optional) The filesystem type to use
# - mountPoint Where to mount the filesystem
# - options (optional) An array of options to pass to mount
# - efi (optional) A boolean that when true is only mounted for UEFI installs
#
# The device is not mounted if the mountPoint is unset or if the fs is
# set to unformatted.
#
extraMounts:
- device: proc
fs: proc
mountPoint: /proc
- device: sys
fs: sysfs
mountPoint: /sys
- device: /dev
mountPoint: /dev
options: [ bind ]
- device: tmpfs
fs: tmpfs
mountPoint: /run
- device: /run/udev
mountPoint: /run/udev
options: [ bind ]
- device: efivarfs
fs: efivarfs
mountPoint: /sys/firmware/efi/efivars
efi: true
# Btrfs subvolumes to create if root filesystem is on btrfs volume.
# If *mountpoint* is mounted already to another partition, it is ignored.
# Separate subvolume for swapfile is handled separately and automatically.
#
# It is possible to prevent subvolume creation -- this is likely only relevant
# for the root (/) subvolume -- by giving an empty string as a subvolume
# name. In this case no subvolume will be created.
#
btrfsSubvolumes:
- mountPoint: /
subvolume: /@
# As an alternative:
#
# subvolume: ""
- mountPoint: /home
subvolume: /@home
- mountPoint: /var/cache
subvolume: /@cache
- mountPoint: /var/log
subvolume: /@log
# The name of the btrfs subvolume holding the swapfile. This only used when
# a swapfile is selected and the root filesystem is btrfs
#
btrfsSwapSubvol: /@swap
# The mount options used to mount each filesystem.
#
# filesystem contains the name of the filesystem or on of three special
# values, "default", efi" and "btrfs_swap". The logic is applied in this manner:
# - If the partition is the EFI partition, the "efi" entry will be used
# - If the fs is btrfs and the subvolume is for the swapfile,
# the "btrfs_swap" entry is used
# - If the filesystem is an exact match for filesystem, that entry is used
# - If no match is found in the above, the default entry is used
# - If there is no match and no default entry, "defaults" is used
# - If the mountOptions key is not present, "defaults" is used
#
# Each filesystem entry contains 3 keys, all of which are optional
# options - An array of mount options that is used on all disk types
# ssdOptions - An array of mount options combined with options for ssds
# hddOptions - An array of mount options combined with options for hdds
# If combining these options results in an empty array, "defaults" is used
#
# Example 1
# In this example, there are specific options for ext4 and btrfs filesystems,
# the EFI partition and the subvolume holding the btrfs swapfile. All other
# filesystems use the default entry. For the btrfs filesystem, there are
# additional options specific to hdds and ssds
#
# mountOptions:
# - filesystem: default
# options: [ defaults ]
# - filesystem: efi
# options: [ defaults, umask=0077 ]
# - filesystem: ext4
# options: [ defaults ]
# - filesystem: btrfs
# options: [ defaults, compress=zstd:1 ]
# ssdOptions: [ discard=async ]
# hddOptions: [ autodefrag ]
# - filesystem: btrfs_swap
# options: [ defaults, noatime ]
#
# Example 2
# In this example there is a single default used by all filesystems
#
# mountOptions:
# - filesystem: default
# options: [ defaults ]
#
mountOptions:
- filesystem: default
options: [ defaults ]
- filesystem: efi
options: [ defaults, umask=0077 ]
- filesystem: btrfs
options: [ defaults, compress=zstd:1 ]
- filesystem: btrfs_swap
options: [ defaults, noatime ]

View File

@@ -0,0 +1,347 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
### Netinstall module
#
# The netinstall module allows distribution maintainers to ship minimal ISOs
# with only a basic set of preinstalled packages. At installation time, the
# user is presented with the choice to install groups of packages from a
# predefined list.
#
# Calamares will then use the *packages* module to install the packages.
# Without a *packages* module in the exec phase somewhere **after**
# this netinstall, nothing will actually get installed. The packages
# module must be correctly configured **and** the package manager must
# be runnable from within the installed system at the point where it
# is invoked, otherwise you'll get nothing.
#
# There are two basic deployment schemes:
# - static package lists; the packages do not change for this release.
# In this case, the package list file may be on the ISO-image itself
# as a separate file, **or** included in this configuration file.
# Either will do; separate file is easier to update independently
# of the Calamares configuration, while merged configurations use
# fewer files overall and are closer to self-documenting.
# - online package lists; the package list is fetched from a remote
# URL and handled otherwise like a static list. This can be useful
# if the package list needs updating during the lifetime of an ISO-
# image, e.g. packages are added or renamed.
#
# There is only one required key for this module, *groupsUrl*.
#
# This module supports multiple instances through the *label* key,
# which allows you to distinguish them in the UI.
---
# The *groupsUrl* determines where the data for the netinstall groups-and-
# packages comes from. The value of the key may be:
#
# - a single string (this is treated as a list with just that string in it)
# - a list of strings
#
# Each string is treated as a URL (see below for special cases. The
# list is examined **in order** and each URL is tried in turn. The
# first URL to load successfully -- even if it yields 0 packages --
# ends the process. This allows using a network URL and a (fallback)
# local URL for package lists, or for using multiple mirrors of
# netinstall data.
#
# The URL must point to a YAML file that follows the format described
# below at the key *groups* -- except for the special case URL "local".
# Note that the contents of the groups file is the **important**
# part of the configuration of this module. It specifies what
# groups and packages the user may select (and so what commands are to
# be run to install them).
#
# The format of the groups file is the same as the format of the
# *groups* key described below, **except** that a stand-alone
# groups file does not have to have the top-level *groups* key.
# (It **may** have one, though, for instance when you copy
# this configuration file to `netinstall.yaml` and key *groups*
# must have a list-of-groups as value; if the file does not have
# a top-level key *groups*, then the file must contain only a list of groups.
#
# Each item in the list *groupsUrl* may be:
# - A remote URL like `http://example.org/netinstall.php`
# - A local file URL like `file:///usr/share/calamares/netinstall.yaml`
# - The special-case literal string `local`
#
# Non-special case URLs are loaded as YAML; if the load succeeds, then
# they are interpreted like the *groups* key below. The special case
# `local` loads the data directly from **this** file.
#
groupsUrl: local
# Alternate form:
# groupsUrl: [ local ]
# Net-based package list, with fallback to local file
# groupsUrl:
# - http://example.com/calamares/netinstall.yaml
# - file:///etc/calamares/modules/netinstall.yaml
# If the installation can proceed without netinstall (e.g. the Live CD
# can create a working installed system, but netinstall is preferred
# to bring it up-to-date or extend functionality) leave this set to
# false (the default). If set to true, the netinstall data is required.
#
# This only has an effect if the netinstall data cannot be retrieved,
# or is corrupt: having "required" set, means the install cannot proceed.
# For local or file: type *groupsUrl* settings, this setting is not
# really meaningful.
required: false
# To support multiple instances of this module,
# some strings are configurable and translatable here.
# Sub-keys under *label* are used for the user interface.
# - *sidebar* This is the name of the module in the progress-tree / sidebar
# in Calamares.
# - *title* This is displayed above the list of packages.
# If no *sidebar* values are provided, defaults to "Package selection"
# and existing translations. If no *title* values are provided, no string
# is displayed.
#
# Translations are handled through `[ll]` notation, much like in
# `.desktop` files. The string associated with `key[ll]` is used for
# *key* when when the language *ll* (language-code, like *nl* or *en_GB*
# or *ja*) is used.
#
# The following strings are **already** known to Calamares and can be
# listed here in *untranslated* form (e.g. as value of *sidebar*)
# without bothering with the translations: they are picked up from
# the regular translation framework:
# - "Package selection"
# - "Office software"
# - "Office package"
# - "Browser software"
# - "Browser package"
# - "Web browser"
# - "Kernel"
# - "Services"
# - "Login"
# - "Desktop"
# - "Applications"
# - "Communication"
# - "Development"
# - "Office"
# - "Multimedia"
# - "Internet"
# - "Theming"
# - "Gaming"
# - "Utilities"
# Other strings should follow the translations format.
label:
sidebar: "Package selection"
# sidebar[nl]: "Pakketkeuze"
# sidebar[en_GB]: "Package choice"
# sidebar[ja]: "知りません" # "I don't know"
# title: "Office Package"
# title[nl]: "Kantoorsoftware"
# If, and only if, *groupsUrl* is set to the literal string `local`,
# groups data is read from this file. The value of *groups* must be
# a list. Each item in the list is a group (of packages, or subgroups,
# or both). A standalone groups file contains just the list,
# (without the top-level *groups* key, or just the top-level *groups*
# key and with the list as its value, like in this file).
#
# Using `local` is recommended only for small static package lists.
# Here it is used for documentation purposes.
#
#
### Groups Format
#
# Each item in the list describes one group. The following keys are
# required for each group:
#
# - *name* of the group; short and human-readable. Shown in the first
# column of the UI.
# - *description* of the group; longer and human-readable. Shown in the
# second column of the UI. This is one of the things that visually
# distinguishes groups (with descriptions) from packages (without).
# - *packages*, a list of packages that belong to this group.
# The items of the *packages* list are actual package names
# as passed to the package manager (e.g. `qt5-creator-dev`).
# This list may be empty (e.g. if your group contains only
# subgroups). This key isn't **really** required, either --
# one of *subgroups* or *packages* is.
#
# The following keys are **optional** for a group:
#
# - *hidden*: if true, do not show the group on the page. Defaults to false.
# - *selected*: if true, display the group as selected. Defaults to the
# parent group's value, if there is a parent group; top-level groups
# are set to true by default.
# - *critical*: if true, make the installation process fail if installing
# any of the packages in the group fails. Otherwise, just log a warning.
# Defaults to false. If not set in a subgroup (see below), inherits from
# the parent group.
# - *immutable*: if true, the state of the group (and all its subgroups)
# cannot be changed; no packages can be selected or deselected. No
# checkboxes are show for the group. Setting *immutable* to true
# really only makes sense in combination with *selected* set to true,
# so that the packages will be installed. (Setting a group to immutable
# can be seen as removing it from the user-interface.)
# - *noncheckable*: if true, the entire group cannot be selected or
# deselected by a single click. This does not affect any subgroups
# or child packages
# - *expanded*: if true, the group is shown in an expanded form (that is,
# not-collapsed) in the treeview on start. This only affects the user-
# interface. Only top-level groups are show expanded-initially.
# - *subgroups*: if present this follows the same structure as the top level
# groups, allowing sub-groups of packages to an arbitary depth.
# - *pre-install*: an optional command to run within the new system before
# the group's packages are installed. It will run before **each** package in
# the group is installed.
# - *post-install*: an optional command to run within the new system after
# the group's packages are installed. It will run after **each** package in
# the group is installed.
#
# If you set both *hidden* and *selected* for a top-level group, you are
# creating a "default" group of packages which will always be installed
# in the user's system. Hidden selected subgroups are installed if their
# parent is selected. Setting *hidden* to true without *selected*, or with
# *selected* set to false, is kind of pointless and will generate a warning.
#
# The *pre-install* and *post-install* commands are **not** passed to
# a shell; see the **packages** module configuration (i.e. `packages.conf`)
# for details. To use a full shell pipeline, call the shell explicitly.
#
# Non-critical groups are installed by calling the package manager
# individually, once for each package (and ignoring errors), while
# critical packages are installed in one single call to the package
# manager (and errors cause the installation to terminate).
#
#
#
# The *groups* key below contains some common patterns for packages
# and sub-groups, with documentation.
groups:
# This group is hidden, so the name and description are not really
# important. Since it is selected, these packages will be installed.
# It's non-critical, so they are installed one-by-one.
#
# This is a good approach for something you want up-to-date installed
# in the target system every time.
- name: "Default"
description: "Default group"
hidden: true
selected: true
critical: false
packages:
- base
- chakra-live-skel
# The Shells group contains only subgroups, no packages itself.
# The *critical* value is set for the subgroups that do not
# override it; *selected* is set to false but because one of
# the subgroups sets *selected* to true, the overall state of
# **this** group is partly-selected.
#
# Each of the sub-groups lists a bunch of packages that can
# be individually selected, so a user can pick (for instance)
# just one of the ZSH packages if they like.
- name: "Shells"
description: "Shells"
hidden: false
selected: false
critical: true
subgroups:
- name: "Bash"
description: "Bourne Again Shell"
selected: true
packages:
- bash
- bash-completion
- name: "Zsh"
description: "Zee shell, boss"
packages:
- zsh
- zsh-completion
- zsh-extensions
# The kernel group has no checkbox, because it is immutable.
# It can be (manually) expanded, and the packages inside it
# will be shown, also without checkboxes. This is a way to
# inform users that something will always be installed,
# sort of like a hidden+selected group but visible.
- name: "Kernel"
description: "Kernel bits"
hidden: false
selected: true
critical: true
immutable: true
packages:
- kernel
- kernel-debugsym
- kernel-nvidia
# *selected* defaults to true for top-level
- name: Communications
description: "Communications Software"
packages:
- ruqola
- konversation
- nheko
- quaternion
# Setting *selected* is supported. Here we also show off "rich"
# packages: ones with a package-name (for the package-manager)
# and a description (for the human).
- name: Editors
description: "Editing"
selected: false
packages:
- vi
- emacs
- nano
- name: kate-git
description: Kate (unstable)
- name: kate
description: KDE's text editor
# The "bare" package names can be intimidating, so you can use subgroups
# to provide human-readable names while hiding the packages themselves.
# This also allows you you group related packages -- suppose you feel
# that KDevelop should be installed always with PHP and Python support,
# but that support is split into multiple packages.
#
# So this subgroup (IDE) contains subgroups, one for each "package"
# we want to install. Each of those subgroups (Emacs, KDevelop)
# in turn contains **one** bogus subgroup, which then has the list
# of relevant packages. This extra-level-of-subgrouping allows us
# to list packages, while giving human-readable names.
#
# The name of the internal subgroup doesn't matter -- it is hidden
# from the user -- so we can give them all bogus names and
# descriptions, even the same name. Here, we use "Bogus". You
# can re-use the subgroup name, it doesn't really matter.
#
# Each internal subgroup is set to *hidden*, so it does not show up
# as an entry in the list, and it is set to *selected*,
# so that if you select its parent subgroup, the packages from
# the subgroup are selected with it and get installed.
- name: IDE
description: "Development Environment"
selected: false
subgroups:
- name: Emacs
description: LISP environment and editor
subgroups:
- name: Bogus
description: Bogus
hidden: true
selected: true
packages:
- emacs
- name: KDevelop
description: KDE's C++, PHP and Python environment
subgroups:
- name: Bogus
description: Bogus
hidden: true
selected: true
packages:
- kdevelop
- kdevelop-dev
- kdev-php
- kdev-python

View File

@@ -0,0 +1,43 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# The *notesqml* module can be used to display a QML file
# as an installer step. This is most useful for release-notes
# and similar somewhat-static content, but if you want to you
# can put SameGame in there as well.
#
# While the module compiles a QML file into a QRC for inclusion
# into the shared library, normal use will configure it with
# an external file, either from Calamares AppData directory or
# from the branding directory.
#
# ---
#
# QML modules can search for the QML inside the Qt resources
# (QRC) which are compiled into the module, or in the branding
# setup for Calamares, (or both of them, with branding taking
# precedence). This allows the module to ship a default UI and
# branding to optionally introduce a replacement file.
#
# Generally, leave the search method set to "both" because if
# you don't want to brand the UI, just don't ship a branding
# QML file for it.
#
# To support instanced QML modules, searches in the branding
# directory look for the full notesqml@instanceid name as well.
---
# Search mode. Valid values are "both", "qrc" and "branding"
qmlSearch: both
# Name of the QML file. If not set, uses the name of the instance
# of the module (e.g. if you list this module in `settings.conf`
# in the *instances* section, you get *id*, otherwise it would
# normally be "notesqml").
# qmlFilename: notesqml
# This is the name of the module in the progress-tree / sidebar
# in Calamares. To support multiple instances of the QML module,
# the name is configurable and translatable here.
qmlLabel:
notes: "Release Notes"
notes[nl]: "Opmerkingen"

View File

@@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# This is an OEM setup (phase-0) configuration file.
---
# The batch-identifier is written to /var/log/installer/oem-id.
# This value is put into the text box as the **suggested**
# OEM ID. If ${DATE} is included in the identifier, then
# that is replaced by the current date in yyyy-MM-dd (ISO) format.
#
# It is ok for the identifier to be empty.
#
# The identifier is written to the file as UTF-8 (this will be no
# different from ASCII, for most inputs) and followed by a newline.
# If the identifier is empty, only a newline is written.
batch-identifier: neon-${DATE}

View File

@@ -0,0 +1,5 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
---
configFilePath: /etc/conf.d/dmcrypt

View File

@@ -0,0 +1,20 @@
# The OS-FreeBSD module does "all the things" in a FreeBSD installation.
# Since the other modules -- users, fstab, grub, pretty much all of them
# -- are Linux-specific, it doesn't make much sense to fork each of them
# or provide alternatives, so instead we have one module that completes
# a FreeBSD installation based on the GlobalStorage values set by
# Calamares viewmodules.
#
# SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
# SPDX-License-Identifier: GPL-3.0-or-later
# License-Filename: LICENSE
#
calamares_add_plugin( os-freebsd
TYPE job
EXPORT_MACRO PLUGINDLLEXPORT_PRO
SOURCES
FreeBSDJob.cpp
SHARED_LIB
NO_CONFIG
)

View File

@@ -0,0 +1,58 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
* License-Filename: LICENSE
*/
#include "FreeBSDJob.h"
#include "CalamaresVersion.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "utils/Logger.h"
#include <QDateTime>
#include <QProcess>
#include <QThread>
FreeBSDJob::FreeBSDJob( QObject* parent )
: Calamares::CppJob( parent )
{
}
FreeBSDJob::~FreeBSDJob() {}
QString
FreeBSDJob::prettyName() const
{
return tr( "FreeBSD Installation Job" );
}
Calamares::JobResult
FreeBSDJob::exec()
{
emit progress( 0.1 );
cDebug() << "[FREEBSD]";
Calamares::JobQueue::instance()->globalStorage()->debugDump();
emit progress( 0.5 );
QThread::sleep( 3 );
emit progress( 1.0 );
return Calamares::JobResult::ok();
}
void
FreeBSDJob::setConfigurationMap( const QVariantMap& configurationMap )
{
// TODO: actually fetch something from that configuration
m_configurationMap = configurationMap;
}
CALAMARES_PLUGIN_FACTORY_DEFINITION( FreeBSDJobFactory, registerPlugin< FreeBSDJob >(); )

View File

@@ -0,0 +1,39 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
* License-Filename: LICENSE
*/
#ifndef FREEBSDJOB_H
#define FREEBSDJOB_H
#include "CppJob.h"
#include "DllMacro.h"
#include "utils/PluginFactory.h"
#include <QObject>
#include <QVariantMap>
class PLUGINDLLEXPORT FreeBSDJob : public Calamares::CppJob
{
Q_OBJECT
public:
explicit FreeBSDJob( QObject* parent = nullptr );
virtual ~FreeBSDJob() override;
QString prettyName() const override;
Calamares::JobResult exec() override;
void setConfigurationMap( const QVariantMap& configurationMap ) override;
private:
QVariantMap m_configurationMap;
};
CALAMARES_PLUGIN_FACTORY_DECLARATION( FreeBSDJobFactory )
#endif // FREEBSDJOB_H

View File

@@ -0,0 +1,276 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# === This file is part of Calamares - <https://github.com/calamares> ===
#
# Calamares 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.
#
# Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
#
# SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
# SPDX-License-Identifier: GPL-3.0-or-later
#
"""
=== NixOS Configuration
NixOS has its own "do all the things" configuration file which
declaratively handles what things need to be done in the target
system, and it has an existing tool to "execute" that declarative
specification. This module takes configuration values set by
Calamares viewmodules (e.g. the users module) and puts
them into the configuration file in the target system,
and then runs the necessary NixOS specific tools.
"""
import libcalamares
import os
from time import gmtime, strftime, sleep
import gettext
_ = gettext.translation("calamares-python",
localedir=libcalamares.utils.gettext_path(),
languages=libcalamares.utils.gettext_languages(),
fallback=True).gettext
# The following long **long** string is the entire text of
# a nix-configuration file. It is cribbed from, and adapted from,
# the sample file in https://github.com/itamar567/dotnix .
#
# We are going to substitute values into this text. However,
# Python's .format() function wants parens { } around variable
# names, and Nix's config file wants to use parens { } for block
# structure. So we have a compromise format here:
#
# - Write the config file as you would normally,
# - Write @@variable@@ instead of {variable}
#
# Some minor trickery later will massage this and substitute variables.
#
configuration_nix_sample = """# Nix configuration file
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
./command-not-found/command-not-found.nix
];
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# Use Zen Kernel
boot.kernelPackages = pkgs.linuxPackages_zen;
networking.hostName = "@@hostname@@"; # Define your hostname.
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# Set your time zone.
time.timeZone = "@@timezone@@";
# The global useDHCP flag is deprecated, therefore explicitly set to false here.
networking.useDHCP = false;
networking.interfaces.enp42s0.useDHCP = true;
# Select internationalisation properties.
i18n.defaultLocale = "en_US.UTF-8";
# Configure X11
services.xserver = {
enable = true;
windowManager.i3 = {
enable = true;
package = pkgs.i3-gaps;
};
# Set i3 to the default session in the display manager
displayManager.defaultSession = "none+i3";
};
# SSH fix
programs.ssh.askPassword = pkgs.lib.mkForce "";
# Enable CUPS to print documents.
services.printing.enable = true;
# Enable sound.
sound.enable = true;
hardware.pulseaudio.enable = true;
# Define a user account. Don't forget to set a password with passwd.
users.users.username = {
isNormalUser = true;
extraGroups = [ "wheel" "libvirtd" ];
};
# Disable password for sudo
security.sudo.extraRules= [{
groups = [ "wheel" ];
commands = [{
command = "ALL" ;
options= [ "NOPASSWD" ];
}];
}];
# Set ZSH as the default shell
users.defaultUserShell = pkgs.zsh;
# clean /tmp on boot
boot.cleanTmpDir=true;
# Config packages
nixpkgs.config = {
allowUnfree = true;
chromium = {
enableWideVine = true;
};
};
# Automatically upgrade the system
# This service is a modified version of https://github.com/NixOS/nixpkgs/blob/nixos-21.05/nixos/modules/tasks/auto-upgrade.nix#L122
systemd = {
services.nixos-upgrade = {
description = "NixOS Upgrade";
# We use --upgrade, so we need internet access
wants = [ "network-online.target" ];
restartIfChanged = false;
unitConfig.X-StopOnRemoval = false;
serviceConfig.Type = "oneshot";
environment = config.nix.envVars // {
inherit (config.environment.sessionVariables) NIX_PATH;
HOME = "/root";
} // config.networking.proxy.envVars;
path = with pkgs; [
coreutils
gnutar
xz.bin
gzip
gitMinimal
config.nix.package.out
];
script = let
nixos-rebuild =
"${config.system.build.nixos-rebuild}/bin/nixos-rebuild";
in ''
${nixos-rebuild} boot --upgrade
booted="$(readlink /run/booted-system/{initrd,kernel,kernel-modules})"
built="$(readlink /nix/var/nix/profiles/system/{initrd,kernel,kernel-modules})"
if [ "$booted" = "$built" ]; then
${nixos-rebuild} switch
fi
'';
};
# To start the service at boot, we will use a systemd timer
timers.nixos-upgrade = {
wantedBy = [ "timers.target" ];
partOf = [ "nixos-upgrade.service" ];
timerConfig.OnBootSec = "5s";
};
};
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
programs.mtr.enable = true;
programs.gnupg.agent = {
enable = true;
enableSSHSupport = true;
};
# Enable the OpenSSH daemon.
services.openssh.enable = true;
# Open ports in the firewall.
networking.firewall.enable = false;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "20.09"; # Did you read the comment?
}
"""
def pretty_name():
return _("NixOS Configuration.")
def catenate(d, key, *values):
"""
Sets @p d[key] to the string-concatenation of @p values
if none of the values are None.
This can be used to set keys conditionally based on
the values being found.
"""
if [v for v in values if v is None]:
return
d[key] = "".join(values)
def run():
"""NixOS Configuration."""
gs = libcalamares.globalstorage
text = configuration_nix_sample
# Collect variables to substitute into the main text
variables = dict()
catenate(variables, "hostname", gs.value("hostname"))
catenate(variables, "timezone", gs.value("locationRegion"), "/", gs.value("locationZone"))
# Check that all variables are used
for key in variables.keys():
pattern = "@@{key}@@".format(key=key)
if not pattern in text:
libcalamares.utils.warning("Variable '{key}' is not used.".format(key=key))
# Check that all patterns exist
import re
variable_pattern = re.compile("@@\w+@@")
for match in variable_pattern.finditer(text):
variable_name = text[match.start()+2:match.end()-2]
if not variable_name in variables:
libcalamares.utils.warning("Variable '{key}' is used but not defined.".format(key=variable_name))
# Do the substitutions
for key in variables.keys():
pattern = "@@{key}@@".format(key=key)
text = text.replace(pattern, str(variables[key]))
# Write the result to a temp-file, then run the main tool.
# There is no progress reporting from the tool, so it's going
# to seem like the module is hanging (see issue #1740).
configuration_filename = "/tmp/configuration.nix"
with open(configuration_filename, "w") as f:
f.write(text)
libcalamares.job.setprogress(0.1)
libcalamares.utils.check_target_env_call(["nix", configuration_filename])
# To indicate an error, return a tuple of:
# (message, detailed-error-message)
return None

View File

@@ -0,0 +1,11 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# The NixOS module writes a nix-configuration file and then calls
# the Nix configuration tool to do the actual work of building
# the target system.
---
type: "job"
name: "os-nixos"
interface: "python"
script: "main.py"

View File

@@ -0,0 +1,6 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
---
hostname: my-nix-host
locationRegion: Asia
locationZone: Kolkata

View File

@@ -0,0 +1,214 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# The configuration for the package manager starts with the
# *backend* key, which picks one of the backends to use.
# In `main.py` there is a base class `PackageManager`.
# Implementations must subclass that and set a (class-level)
# property *backend* to the name of the backend (e.g. "dummy").
# That property is used to match against the *backend* key here.
#
# You will have to add such a class for your package manager.
# It is fairly simple Python code. The API is described in the
# abstract methods in class `PackageManager`. Mostly, the only
# trick is to figure out the correct commands to use, and in particular,
# whether additional switches are required or not. Some package managers
# have more installer-friendly defaults than others, e.g., DNF requires
# passing --disablerepo=* -C to allow removing packages without Internet
# connectivity, and it also returns an error exit code if the package did
# not exist to begin with.
---
#
# Which package manager to use, options are:
# - apk - Alpine Linux package manager
# - apt - APT frontend for DEB and RPM
# - dnf - DNF, the new RPM frontend
# - dnf5 - DNF5, the newer new RPM frontend
# - entropy - Sabayon package manager (is being deprecated)
# - luet - Sabayon package manager (next-gen)
# - packagekit - PackageKit CLI tool
# - pacman - Pacman
# - pamac - Manjaro package manager
# - portage - Gentoo package manager
# - yum - Yum RPM frontend
# - zypp - Zypp RPM frontend
#
# Not actually a package manager, but suitable for testing:
# - dummy - Dummy manager, only logs
#
backend: dummy
#
# Often package installation needs an internet connection.
# Since you may allow system installation without a connection
# and want to offer OPTIONAL package installation, it's
# possible to have no internet, yet have this packages module
# enabled in settings.
#
# You can skip the whole module when there is no internet
# by setting "skip_if_no_internet" to true.
#
# You can run a package-manager specific update procedure
# before installing packages (for instance, to update the
# list of packages and dependencies); this is done only if there
# is an internet connection.
#
# Set "update_db" to 'true' for refreshing the database on the
# target system. On target installations, which got installed by
# unsquashing, a full system update may be needed. Otherwise
# post-installing additional packages may result in conflicts.
# Therefore set also "update_system" to 'true'.
#
skip_if_no_internet: false
update_db: true
update_system: false
# pacman specific options
#
# *num_retries* should be a positive integer which specifies the
# number of times the call to pacman will be retried in the event of a
# failure. If it is missing, it will be set to 0.
#
# *disable_download_timeout* is a boolean that, when true, includes
# the flag --disable-download-timeout on calls to pacman. When missing,
# false is assumed.
#
# *needed_only* is a boolean that includes the pacman argument --needed
# when set to true. If missing, false is assumed.
pacman:
num_retries: 0
disable_download_timeout: false
needed_only: false
#
# List of maps with package operations such as install or remove.
# Distro developers can provide a list of packages to remove
# from the installed system (for instance packages meant only
# for the live system).
#
# A job implementing a distro specific logic to determine other
# packages that need to be installed or removed can run before
# this one. Distro developers may want to install locale packages
# or remove drivers not needed on the installed system.
# Such a job would populate a list of dictionaries in the global
# storage called "packageOperations" and that list is processed
# after the static list in the job configuration (i.e. the list
# that is in this configuration file).
#
# Allowed package operations are:
# - *install*, *try_install*: will call the package manager to
# install one or more packages. The install target will
# abort the whole installation if package-installation
# fails, while try_install carries on. Packages may be
# listed as (localized) names, or as (localized) package-data.
# See below for the description of the format.
# - *localInstall*: this is used to call the package manager
# to install a package from a path-to-a-package. This is
# useful if you have a static package archive on the install media.
# The *pacman* package manager is the only one to specially support
# this operation (all others treat this the same as *install*).
# - *remove*, *try_remove*: will call the package manager to
# remove one or more packages. The remove target will
# abort the whole installation if package-removal fails,
# while try_remove carries on. Packages may be listed as
# (localized) names.
# One additional key is recognized, to help netinstall out:
# - *source*: ignored, does get logged
# Any other key is ignored, and logged as a warning.
#
# There are two formats for naming packages: as a name or as package-data,
# which is an object notation providing package-name, as well as pre- and
# post-install scripts.
#
# Here are both formats, for installing vi. The first one just names the
# package for vi (using the naming of the installed package manager), while
# the second contains three data-items; the pre-script is run before invoking
# the package manager, and the post-script runs once it is done.
#
# - install
# - vi
# - package: vi
# pre-script: touch /tmp/installing-vi
# post-script: rm -f /tmp/installing-vi
#
# The pre- and post-scripts are optional, but you cannot leave both out
# if you do use the *package* key: using "package: vi" with neither script
# option will trick Calamares into trying to install a package named
# "package: vi", which is unlikely to work.
#
# The pre- and post-scripts are **not** executed by a shell unless you
# explicitly invoke `/bin/sh` in them. The command-lines are passed
# to exec(), which does not understand shell syntax. In other words:
#
# pre-script: ls | wc -l
#
# Will fail, because `|` is passed as a command-line argument to ls,
# as are `wc`, and `-l`. No shell pipeline is set up, and ls is likely
# to complain. Invoke the shell explicitly:
#
# pre-script: /bin/sh -c \"ls | wc -l\"
#
# The above note on shell-expansion applies to versions up-to-and-including
# Calamares 3.2.12, but will change in future.
#
# Any package name may be localized; this is used to install localization
# packages for software based on the selected system locale. By including
# the string `LOCALE` in the package name, the following happens:
#
# - if the system locale is English (any variety), then the package is not
# installed at all,
# - otherwise `$LOCALE` or `${LOCALE}` is replaced by the 'lower-cased' BCP47
# name of the 'language' part of the selected system locale (not the
# country/region/dialect part), e.g. selecting "nl_BE" will use "nl"
# here.
#
# Take care that just plain `LOCALE` will not be replaced, so `foo-LOCALE` will
# be left unchanged, while `foo-$LOCALE` will be changed. However, `foo-LOCALE`
# **will** be removed from the list of packages (i.e. not installed), if
# English is selected. If a non-English locale is selected, then `foo-LOCALE`
# will be installed, unchanged (no language-name-substitution occurs).
#
# The following installs localizations for vi, if they are relevant; if
# there is no localization, installation continues normally.
#
# - install
# - vi-$LOCALE
# - package: vi-${LOCALE}
# pre-script: touch /tmp/installing-vi
# post-script: rm -f /tmp/installing-vi
#
# When installing packages, Calamares will invoke the package manager
# with a list of package names if it can; package-data prevents this because
# of the scripts that need to run. In other words, this:
#
# - install:
# - vi
# - binutils
# - package: wget
# pre-script: touch /tmp/installing-wget
#
# This will invoke the package manager three times, once for each package,
# because not all of them are simple package names. You can speed up the
# process if you have only a few pre-scripts, by using multiple install targets:
#
# - install:
# - vi
# - binutils
# - install:
# - package: wget
# pre-script: touch /tmp/installing-wget
#
# This will call the package manager once with the package-names "vi" and
# "binutils", and then a second time for "wget". When installing large numbers
# of packages, this can lead to a considerable time savings.
#
operations:
- install:
- vi
- vi-${LOCALE}
- wget
- binutils
- remove:
- vi
- wget
- binutils

View File

@@ -0,0 +1,392 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Options for EFI system partition.
#
# - *mountPoint*
# This setting specifies the mount point of the EFI system partition. Some
# distributions (Fedora, Debian, Manjaro, etc.) use /boot/efi, others (KaOS,
# etc.) use just /boot.
#
# Defaults to "/boot/efi", may be empty (but weird effects ensue)
# - *recommendedSize*
# This optional setting specifies the size of the EFI system partition.
# If nothing is specified, the default size of 300MiB will be used.
# When writing quantities here, M is treated as MiB, and if you really
# want one-million (10^6) bytes, use MB.
# - *minimumSize*
# This optional setting specifies the absolute minimum size of the EFI
# system partition. If nothing is specified, the *recommendedSize*
# is used instead.
# - *label*
# This optional setting specifies the name of the EFI system partition (see
# PARTLABEL; gpt only; requires KPMCore >= 4.2.0).
# If nothing is specified, the partition name is left unset.
#
# Going below the *recommended* size is allowed, but the user will
# get a warning that it might not work. Going below the *minimum*
# size is not allowed and the user will be told it will not work.
#
# Both quantities must be at least 32MiB, this is enforced by the EFI
# spec. If minimum is not specified, it defaults to the recommended
# size. Distros that allow more user latitude can set the minimum lower.
efi:
mountPoint: "/boot/efi"
recommendedSize: 300MiB
minimumSize: 32MiB
label: "EFI"
# Deprecated alias of efi.mountPoint
# efiSystemPartition: "/boot/efi"
# Deprecated alias of efi.recommendedSize
# efiSystemPartitionSize: 300MiB
# Deprecated alias of efi.label
# efiSystemPartitionName: EFI
# In autogenerated partitioning, allow the user to select a swap size?
# If there is exactly one choice, no UI is presented, and the user
# cannot make a choice -- this setting is used. If there is more than
# one choice, a UI is presented.
#
# Legacy settings *neverCreateSwap* and *ensureSuspendToDisk* correspond
# to values of *userSwapChoices* as follows:
# - *neverCreateSwap* is true, means [none]
# - *neverCreateSwap* is false, *ensureSuspendToDisk* is false, [small]
# - *neverCreateSwap* is false, *ensureSuspendToDisk* is true, [suspend]
#
# Autogenerated swap sizes are as follows:
# - *suspend*: Swap is always at least total memory size,
# and up to 4GiB RAM follows the rule-of-thumb 2 * memory;
# from 4GiB to 8 GiB it stays steady at 8GiB, and over 8 GiB memory
# swap is the size of main memory.
# - *small*: Follows the rules above, but Swap is at
# most 8GiB, and no more than 10% of available disk.
# In both cases, a fudge factor (usually 10% extra) is applied so that there
# is some space for administrative overhead (e.g. 8 GiB swap will allocate
# 8.8GiB on disk in the end).
#
# If *file* is enabled here, make sure to have the *fstab* module
# as well (later in the exec phase) so that the swap file is
# actually created.
userSwapChoices:
- none # Create no swap, use no swap
- small # Up to 4GB
- suspend # At least main memory size
# - reuse # Re-use existing swap, but don't create any (unsupported right now)
- file # To swap file instead of partition
# This optional setting specifies the name of the swap partition (see
# PARTLABEL; gpt only; requires KPMCore >= 4.2.0).
# If nothing is specified, the partition name is left unset.
# swapPartitionName: swap
# LEGACY SETTINGS (these will generate a warning)
# ensureSuspendToDisk: true
# neverCreateSwap: false
# This setting specifies the LUKS generation (i.e LUKS1, LUKS2) used internally by
# cryptsetup when creating an encrypted partition.
#
# This option is set to luks1 by default, as grub doesn't support LUKS2 + Argon2id
# currently. On the other hand grub does support LUKS2 with PBKDF2 and could therefore be
# also set to luks2. Also there are some patches for grub and Argon2.
# See: https://aur.archlinux.org/packages/grub-improved-luks2-git
#
# Choices: luks1, luks2 (in addition, "luks" means "luks1")
#
# The default is luks1
#
luksGeneration: luks1
# This setting determines if encryption should be allowed when using zfs. This
# setting has no effect unless zfs support is provided.
#
# This setting is to handle the fact that some bootloaders(such as grub) do not
# support zfs encryption.
#
# The default is true
#
# allowZfsEncryption: true
# Correctly draw nested (e.g. logical) partitions as such.
drawNestedPartitions: false
# Show/hide partition labels on manual partitioning page.
alwaysShowPartitionLabels: true
# Allow manual partitioning.
#
# When set to false, this option hides the "Manual partitioning" button,
# limiting the user's choice to "Erase", "Replace" or "Alongside".
# This can be useful when using a custom partition layout we don't want
# the user to modify.
#
# If nothing is specified, manual partitioning is enabled.
#allowManualPartitioning: true
# Show not encrypted boot partition warning.
#
# When set to false, this option does not show the
# "Boot partition not encrypted" warning when encrypting the
# root partition but not /boot partition.
#
# If nothing is specified, the warning is shown.
#showNotEncryptedBootMessage: true
# Initial selection on the Choice page
#
# There are four radio buttons (in principle: erase, replace, alongside, manual),
# and you can pick which of them, if any, is initially selected. For most
# installers, "none" is the right choice: it makes the user pick something specific,
# rather than accidentally being able to click past an important choice (in particular,
# "erase" is a dangerous choice).
#
# The default is "none"
#
initialPartitioningChoice: none
#
# Similarly, some of the installation choices may offer a choice of swap;
# the available choices depend on *userSwapChoices*, above, and this
# setting can be used to pick a specific one.
#
# The default is "none" (no swap) if that is one of the enabled options, otherwise
# one of the items from the options.
initialSwapChoice: none
# armInstall
#
# Leaves 16MB empty at the start of a drive when partitioning
# where usually the u-boot loader goes
#
# armInstall: false
# Default partition table type, used when a "erase" disk is made.
#
# When erasing a disk, a new partition table is created on disk.
# In other cases, e.g. Replace and Alongside, as well as when using
# manual partitioning, this partition table exists already on disk
# and it is left unmodified.
#
# Possible values: gpt, msdos (or other names defined by KPMcore).
# Names are case-sensitive.
#
# If nothing is specified, Calamares defaults to "gpt" if system is
# efi or "msdos" otherwise.
#
# defaultPartitionTableType: msdos
# Specify whether to create a partition table layout suitable for a hybrid
# (BIOS + EFI) bootloader installation. This will prepend both bios-boot and
# EFI system partitions to the partition layout, regardless of whether the
# booted system uses BIOS or EFI firmware. Defaults to false.
#
# createHybridBootloaderLayout: false
# Requirement for partition table type
#
# Restrict the installation on disks that match the type of partition
# tables that are specified.
#
# Possible values: msdos, gpt (or other names defined by KPMcore).
# Names are case-sensitive.
#
# If nothing is specified, Calamares defaults to both "msdos" and "gpt".
#
# requiredPartitionTableType: gpt
# requiredPartitionTableType:
# - msdos
# - gpt
# Default filesystem type, used when a "new" partition is made.
#
# When replacing a partition, the new filesystem type will be from the
# defaultFileSystemType value. In other cases, e.g. Erase and Alongside,
# as well as when using manual partitioning and creating a new
# partition, this filesystem type is pre-selected. Note that
# editing a partition in manual-creation mode will not automatically
# change the filesystem type to this default value -- it is not
# creating a new partition.
#
# Suggested values: ext2, ext3, ext4, reiser, xfs, jfs, btrfs
# If nothing is specified, Calamares defaults to "ext4".
#
# Names are case-sensitive and defined by KPMCore.
defaultFileSystemType: "ext4"
# Selectable filesystem type, used when "erase" is done.
#
# When erasing the disk, the *defaultFileSystemType* is used (see
# above), but it is also possible to give users a choice:
# list suitable filesystems here. A drop-down is provided
# to pick which is the filesystems will be used.
#
# The value *defaultFileSystemType* is added to this list (with a warning)
# if not present; the default pick is the *defaultFileSystemType*.
#
# If not specified at all, uses *defaultFileSystemType* without a
# warning (this matches traditional no-choice-available behavior best).
# availableFileSystemTypes: ["ext4","f2fs"]
# Per-directory filesystem restrictions.
#
# This optional setting specifies what filesystems the user can and cannot use
# for various directories and mountpoints when using manual partitioning.
#
# If nothing is specified, the only restriction enforced by default is that
# the EFI system partition must use the fat32 filesystem.
#
# Otherwise, the filesystem restrictions are defined as follow:
#
# directoryFilesystemRestrictions:
# - directory: "any"
# allowedFilesystemTypes: ["all"]
# - directory: "/"
# allowedFilesystemTypes: ["ext4","xfs","btrfs","jfs","f2fs"]
# - mountpoint: "efi"
# allowedFilesystemTypes: ["fat32"]
# onlyWhenMountpoint: true
#
# There can be any number of mountpoints listed, each entry having the
# following attributes:
# - mountpoint: mountpoint's full path
# or
# "any" to specify a global whitelist that applies to all
# mountpoints
# or
# "efi" to specify a whitelist specific to the EFI system
# partition, wherever that partition is located
# - allowedFilesystemTypes: the list of all filesystems valid for this
# mountpoint. If the list contains exactly one
# element, and that element is the special value
# "any", all filesystem types recognized by
# Calamares will be allowed.
# - onlyWhenMountpoint: Whether the restriction should apply only when the
# specified directory is a mountpoint. When set to
# true, Calamares will only enforce the listed
# restrictions when the user makes a separate partition
# for this directory and assigns the mountpoint
# accordingly. When set to false, Calamares will
# ensure this directory uses the specified filesystem
# even if the directory is part of a filesystem on a
# different mountpoint. Defaults to false.
# The ClearMounts job unmounts / unmaps things before partitioning.
# Some special entries under /dev/mapper are excepted from this process.
# The example lists the three hard-coded exceptions which always apply
# (they don't need to be listed here). Add other names or wildcards (with
# a trailing '*') to this list if the live-ISO has additional mounts.
essentialMounts: [ "live-*", "control", "ventoy" ]
# Show/hide LUKS related functionality in automated partitioning modes.
# Disable this if you choose not to deploy early unlocking support in GRUB2
# and/or your distribution's initramfs solution.
#
# BIG FAT WARNING:
#
# This option is unsupported, as it cuts out a crucial security feature.
# Disabling LUKS and shipping Calamares without a correctly configured GRUB2
# and initramfs is considered suboptimal use of the Calamares software. The
# Calamares team will not provide user support for any potential issue that
# may arise as a consequence of setting this option to false.
# It is strongly recommended that system integrators put in the work to support
# LUKS unlocking support in GRUB2 and initramfs/dracut/mkinitcpio/etc.
# For more information on setting up GRUB2 for Calamares with LUKS, see
# the Calamares website at https://calamares.io/docs/partitions/#luks .
#
# If nothing is specified, LUKS is enabled in automated modes.
#enableLuksAutomatedPartitioning: true
# When enableLuksAutomatedPartitioning is true, this option will pre-check
# encryption checkbox. This option is only usefull to help people to not forget
# to cypher their disk when installing in enterprise (for example).
#preCheckEncryption: false
# LVM support
#
# There is only one sub-key available, *enable* (defaults to true)
# which can be used to show (default) or hide the LVM buttons in the partitioning module.
lvm:
enable: true
# Partition layout.
#
# This optional setting specifies a custom partition layout.
#
# If nothing is specified, the default partition layout is a single partition
# for root that uses 100% of the space and uses the filesystem defined by
# defaultFileSystemType.
#
# Note: the EFI system partition is prepended automatically to the layout if
# needed; the swap partition is appended to the layout if enabled (selections
# "small" or "suspend" in *userSwapChoices*).
#
# Otherwise, the partition layout is defined as follow:
#
# partitionLayout:
# - name: "rootfs"
# type: "4f68bce3-e8cd-4db1-96e7-fbcaf984b709"
# filesystem: "ext4"
# noEncrypt: false
# mountPoint: "/"
# size: 20%
# minSize: 500M
# maxSize: 10G
# attributes: 0xffff000000000003
# - name: "home"
# type: "933ac7e1-2eb4-4f13-b844-0e14e2aef915"
# filesystem: "ext4"
# noEncrypt: false
# mountPoint: "/home"
# size: 3G
# minSize: 1.5G
# features:
# 64bit: false
# casefold: true
# - name: "data"
# filesystem: "fat32"
# mountPoint: "/data"
# features:
# sector-size: 4096
# sectors-per-cluster: 128
# size: 100%
#
# There can be any number of partitions, each entry having the following attributes:
# - name: filesystem label
# and
# partition name (gpt only; since KPMCore 4.2.0)
# - uuid: partition uuid (optional parameter; gpt only; requires KPMCore >= 4.2.0)
# - type: partition type (optional parameter; gpt only; requires KPMCore >= 4.2.0)
# - attributes: partition attributes (optional parameter; gpt only; requires KPMCore >= 4.2.0)
# - filesystem: filesystem type (optional parameter)
# - if not set at all, treat as "unformatted"
# - if "unformatted", no filesystem will be created
# - if "unknown" (or an unknown FS name, like "elephant") then the
# default filesystem type, or the user's choice, will be applied instead
# of "unknown" (e.g. the user might pick ext4, or xfs).
# - noEncrypt: whether this partition is exempt from encryption if enabled (optional parameter; default is false)
# - mountPoint: partition mount point (optional parameter; not mounted if unset)
# - size: partition size in bytes (append 'K', 'M' or 'G' for KiB, MiB or GiB)
# or
# % of the available drive space if a '%' is appended to the value
# - minSize: minimum partition size (optional parameter)
# - maxSize: maximum partition size (optional parameter)
# - features: filesystem features (optional parameter; requires KPMCore >= 4.2.0)
# name: boolean or integer or string
# Checking for available storage
#
# This overlaps with the setting of the same name in the welcome module's
# requirements section. If nothing is set by the welcome module, this
# value is used instead. It is still a problem if there is no required
# size set at all, and the replace and resize options will not be offered
# if no required size is set.
#
# The value is in Gibibytes (GiB).
#
# BIG FAT WARNING: except for OEM-phase-0 use, you should be using
# the welcome module, **and** configure this value in
# `welcome.conf`, not here.
# requiredStorage: 3.5

View File

@@ -0,0 +1,83 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# The Plasma Look-and-Feel module allows selecting a Plasma
# Look-and-Feel in the live- or host-system and switches the
# host Plasma session immediately to the chosen LnF; it
# can also write a LnF configuration to the target user / on
# the target system.
#
# This module should be used once in a view section (to get
# the UI) and once in the exec section (to apply the selection
# to the target user). It should come **after** the user module
# in exec, so that the target user has been created alrady.
---
# Full path to the Plasma look-and-feel tool (CLI program
# for querying and applying Plasma themes). If this is not
# set, no LNF setting will happen.
lnftool: "/usr/bin/lookandfeeltool"
# For systems where the user Calamares runs as (usually root,
# via either sudo or pkexec) has a clean environment, set this
# to the originating username; the lnftool will be run through
# "sudo -H -u <liveuser>" instead of directly.
#
# liveuser: "live"
# If *showAll* is true, then all installed themes are shown in the
# UI for selection, even if they are not listed in *themes* (below).
# This allows selection of all themes even while not all of them are
# listed in *themes* -- which is useful to show screenshots for those
# you do have a screenshot for. If *themes* is empty or missing,
# the value of *showAll* is treated as `true`.
showAll: false
# You can limit the list of Plasma look-and-feel themes by listing ids
# here. If this key is not present, all of the installed themes are listed.
# If the key is present, only installed themes that are **also** included
# in the list are shown (could be none!). See the *showAll* key, above,
# to change that.
#
# Themes may be listed by id, (e.g. fluffy-bunny, below) or as a theme
# and an image (e.g. breeze) which will be used to show a screenshot.
# Themes with no image set at all get a "missing screenshot" image; if the
# image file is not found, they get a color swatch based on the image name.
#
# The image may be an absolute path. If it is a relative path, though,
# it is searched in the current directory and in the branding directory
# (i.e. relative to the directory where your branding.desc lives).
#
# Valid forms of entries in the *themes* key:
# - A single string (unquoted), which is the theme id
# - A pair of *theme* and *image* keys, e.g.
# ```
# - theme: fluffy-bunny.desktop
# image: "fluffy-screenshot.png"
# ```
#
# The image screenshot is resized to 12x8 the current font size, with
# a minimum of 120x80 pixels. This allows the screenshot to scale up
# on HiDPI displays where the fonts are larger (in pixels).
themes:
- org.kde.fuzzy-pig.desktop
- theme: org.kde.breeze.desktop
image: "breeze.png"
- theme: org.kde.breezedark.desktop
image: "breeze-dark.png"
- org.kde.fluffy-bunny.desktop
# You can pre-select one of the themes; it is not applied
# immediately, but its radio-button is switched on to indicate
# that that is the theme (that is most likely) currently in use.
# Do this only on Live images where you are reasonably sure
# that the user is not going to change the theme out from under
# themselves before running the installer.
#
# If this key is present, its value should be the id of the theme
# which should be pre-selected. If absent, empty, or the pre-selected
# theme is not found on the live system, no theme will be pre-selected.
#
# As a special setting, use "*", to try to find the currently-
# selected theme by reading the Plasma configuration. This requires
# KF5::Config at build- and run-time.
preselect: "*"

View File

@@ -0,0 +1,31 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Plymouth Configuration Module
#
# This module can be used to setup the default plymouth theme to
# be used with your distribution
#
# You should only use this module if the plymouth package is installed
# on the build configurations of your distribution & the plymouth
# theme you want to configure is installed as well. If the unpacked
# filesystem configures a plymouth theme already, there is no need
# to change it here.
---
# Leave this commented if you want to use the default theme
# shipped with your distribution configurations. Make sure that
# the theme exists in the themes directory of plymouth path.
# Debian / Ubuntu comes with themes "joy", "script", "softwaves",
# possibly others. Look in /usr/share/plymouth/themes for more.
#
# Specifying a non-existent theme will leave the plymouth
# configuration set to that theme. It is up to plymouth to
# deal with that.
plymouth_theme: spinfinity

View File

@@ -0,0 +1,70 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Configuration for the preserve-files job
#
# The *files* key contains a list of files to preserve. Each element of
# the list should have one of these forms:
#
# - an absolute path (probably within the host system). This will be preserved
# as the same path within the target system (chroot). If, globally,
# *dontChroot* is true, then these items will be ignored (since the
# destination is the same as the source).
# - a map with a *dest* key. The *dest* value is a path interpreted in the
# target system (if the global *dontChroot* is true, then the host is the
# target as well). Relative paths are not recommended. There are two
# ways to select the source data for the file:
# - *from*, which must have one of the values, below; it is used to
# preserve files whose pathname is known to Calamares internally.
# - *src*, to refer to a path interpreted in the host system. Relative
# paths are not recommended, and are interpreted relative to where
# Calamares is being run.
# Exactly one of the two source keys (either *from* or *src*) must be set.
#
# Special values for the key *from* are:
# - *log*, for the complete log file (up to the moment the preservefiles
# module is run),
# - *config*, for a JSON dump of the contents of global storage.
# Note that this may contain sensitive information, and should be
# given restrictive permissions.
#
# A map with a *dest* key can have these additional fields:
# - *perm*, is a colon-separated tuple of <user>:<group>:<mode>
# where <mode> is in octal (e.g. 4777 for wide-open, 0400 for read-only
# by owner). If set, the file's ownership and permissions are set to
# those values within the target system; if not set, no permissions
# are changed.
# - *optional*, is a boolean; if this is set to `true` then failure to
# preserve the file will **not** be counted as a failure of the
# module, and installation will proceed. Set this for files that might
# not exist in the host system (e.g. nvidia configuration files that
# are created in some boot scenarios and not in others).
#
# The target path (*dest*) is modified by expanding variables in `${}`:
# - `ROOT` is replaced by the path to the target root (may be /).
# There is never any reason to use this, since the *dest* is already
# interpreted in the target system.
# - `USER` is replaced by the username entered by on the user
# page (may be empty, for instance if no user page is enabled)
#
#
#
files:
- from: log
dest: /var/log/Calamares.log
perm: root:wheel:600
- from: log
dest: /home/${USER}/installation.log
optional: true
- from: config
dest: /var/log/Calamares-install.json
perm: root:wheel:600
# - src: /var/log/nvidia.conf
# dest: /var/log/Calamares-nvidia.conf
# optional: true
# The *perm* key contains a default value to apply to all files listed
# above that do not have a *perm* key of their own. If not set,
# root:root:0400 (highly restrictive) is used.
#
# perm: "root:root:0400"

View File

@@ -0,0 +1,32 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Configuration for the rawfs module: raw filesystem copy to a block device
---
# To apply a custom partition layout, it has to be defined as a list of targets.
#
# For each target, the following attributes must be defined:
# * mountPoint: The mount point of the destination device on the installed system
# The corresponding block device will automatically be identified and used as the
# destination for the operation
# * source: The source filesystem; it can be the mount point of a locally (on the
# live system) mounted filesystem, a path to a disk image, or a block device
# * resize (optional): Expand the destination filesystem to fill the whole
# partition at the end of the operation; this works only with ext filesystems
# for now
targets:
- mountPoint: /
source: /
- mountPoint: /home
source: /images/home.img
resize: true
- mountPoint: /data
source: /dev/mmcblk0p3
# To support testing, set the *bogus* key to true. No actual work is done, but the
# module's logic is exercised.
# bogus: false

View File

@@ -0,0 +1,130 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# === This file is part of Calamares - <https://calamares.io> ===
#
# SPDX-FileCopyrightText: 2021 Anke Boersma <demm@kaosx.us>
# SPDX-License-Identifier: GPL-3.0-or-later
#
# Calamares is Free Software: see the License-Identifier above.
#
import libcalamares
import os
import subprocess
from libcalamares.utils import check_target_env_call
import gettext
_ = gettext.translation("calamares-python",
localedir=libcalamares.utils.gettext_path(),
languages=libcalamares.utils.gettext_languages(),
fallback=True).gettext
def pretty_name():
return _("Install rEFInd.")
def get_uuid():
partitions = libcalamares.globalstorage.value("partitions")
for partition in partitions:
if partition["mountPoint"] == "/":
libcalamares.utils.debug(partition["uuid"])
return partition["uuid"]
return None
def update_conf(uuid, conf_path):
"""
Updates the created rEFInd configuration file based on given parameters.
"""
partitions = libcalamares.globalstorage.value("partitions")
kernel_params = ["quiet", "systemd.show_status=0"]
swap = None # Partition UUID
swap_luks = None # LUKS name
cryptdevice_params = []
btrfs_params = ""
for partition in partitions:
if partition["fs"] == "linuxswap" and not "luksMapperName" in partition:
swap = partition["uuid"]
if partition["fs"] == "linuxswap" and "luksMapperName" in partition:
swap_luks = partition["luksMapperName"]
if partition["mountPoint"] == "/" and "luksMapperName" in partition:
cryptdevice_params = [
"cryptdevice=UUID={!s}:{!s}".format(partition["luksUuid"],
partition["luksMapperName"]),
"root=/dev/mapper/{!s}".format(partition["luksMapperName"]),
"resume=/dev/mapper/{!s}".format(partition["luksMapperName"])
]
# rEFInd with a BTRFS root filesystem needs to be told
# about the root subvolume.
if partition["mountPoint"] == "/" and partition["fs"] == "btrfs":
btrfs_params = "rootflags=subvol=@"
if cryptdevice_params:
kernel_params.extend(cryptdevice_params)
else:
kernel_params.append("root=UUID={!s}".format(uuid))
if swap:
kernel_params.append("resume=UUID={!s}".format(swap))
if swap_luks:
kernel_params.append("resume=/dev/mapper/{!s}".format(swap_luks))
if btrfs_params:
kernel_params.append(btrfs_params)
with open(conf_path, "r") as refind_file:
filedata = [x.strip() for x in refind_file.readlines()]
with open(conf_path, 'w') as refind_file:
for line in filedata:
if line.startswith('"Boot with standard options"'):
line = '"Boot with standard options" "rw {!s}"'.format(" ".join(kernel_params))
refind_file.write(line + "\n")
def efi_partitions(efi_boot_path):
"""
The (one) partition mounted on @p efi_boot_path, or an empty list.
"""
return [p for p in libcalamares.globalstorage.value("partitions") if p["mountPoint"] == efi_boot_path]
def install_refind():
install_path = libcalamares.globalstorage.value("rootMountPoint")
uuid = get_uuid()
conf_path = os.path.join(install_path, "boot/refind_linux.conf")
# TODO: some distro's use /boot/efi , so maybe this needs to
# become configurable (that depends on what rEFInd likes).
efi_boot_path = "/boot"
# Might not have a /boot configured in the system at all; warn and don't operate
if not efi_partitions(efi_boot_path):
libcalamares.utils.warning("No partition mounted on {!s}".format(efi_boot_path))
# This isn't returned as an error, but the installation
# probably won't boot because no bootloader was installed.
return None
subprocess.call(
["refind-install", "--root", "{!s}".format(install_path)])
update_conf(uuid, conf_path)
def run():
"""
Optional entry for when providing bootloader choices.
Values taken from a packagechooser instance.
Module won't run, if value not present.
"""
bootchoice = libcalamares.globalstorage.value("packagechooser_bootchoice")
if bootchoice == "refind":
return install_refind()

View File

@@ -0,0 +1,11 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
---
type: "job"
name: "refind"
interface: "python"
script: "main.py"
noconfig: true
# The partition module sets up the needed paths in
# global storage, which is used to decide how to install.
requiredModules: [ "partition" ]

View File

@@ -0,0 +1,12 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
---
## This file should be present in the same directory as the EFISTUB kernel and initramfs files
## More info at http://www.rodsbooks.com/refind/linux.html , http://www.rodsbooks.com/efi-bootloaders/efistub.html
## File is not needed when rEFInd is installed with the `refind-install` option, it will be created automatically.
#"Boot with defaults" "root=PARTUUID=XXXXXXXX rootfstype=XXXX rw add_efi_memmap"
#"Boot to terminal" "root=PARTUUID=XXXXXXXX rootfstype=XXXX rw add_efi_memmap systemd.unit=multi-user.target"

View File

@@ -0,0 +1,13 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Removes a single user (with userdel) from the system.
# This is typically used in OEM setups or if the live user
# spills into the target system.
#
# The module never fails; if userdel fails, this is logged
# but the module still reports success and installation / setup
# continues as normal.
---
# Username in the target system to be removed.
username: live

View File

@@ -0,0 +1,54 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Systemd units manipulation.
#
# This module can perform actions using systemd units,
# (for example, enabling, disabling, or masking services, sockets, paths, etc.)
---
# There is one key for this module: *units*. Its value is a list of entries.
# Each entry has three keys:
# - *name* is the (string) name of the systemd unit that is being changed.
# Use quotes. You can use any valid systemd unit here (for example,
# "NetworkManager.service", "cups.socket", "lightdm", "gdm", etc.)
# - *action* is the (string) action that you want to perform over the unit
# (for example, "enable", "disable", "mask", "unmask", etc.). Please
# ensure that the action can actually run under chroot (otherwise it is
# pointless)
# - *mandatory* is a boolean option, which states whether the change
# must be done successfully. If systemd reports an error while changing
# a mandatory entry, the installation will fail. When mandatory is false,
# errors for that systemd unit are ignored. If mandatory
# is not specified, the default is false.
#
# The order of operations is the same as the order in which entries
# appear in the list
# # This example enables NetworkManager.service (and fails if it can't),
# # disables cups.socket (and ignores failure). Then it enables the
# # graphical target (e.g. so that SDDM runs for login), and
# # finally masks pacman-init (an ArchLinux-only service).
# #
# units:
# - name: "NetworkManager.service"
# action: "enable"
# mandatory: true
#
# - name: "cups.socket"
# action: "disable"
# # The property "mandatory" is taken to be false by default here
# # because it is not specified
#
# - name: "graphical.target"
# action: "enable"
# # The property "mandatory" is taken to be false by default here
# # because it is not specified
#
# - name: "pacman-init.service"
# action: "mask"
# # The property "mandatory" is taken to be false by default here
# # because it is not specified
# By default, no changes are made.
units: []

View File

@@ -0,0 +1,146 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Configuration for the shell process job.
#
# Executes a list of commands found under the key *script*.
# If the top-level key *dontChroot* is true, then the commands
# are executed in the context of the live system, otherwise
# in the context of the target system. In all of the commands,
# the following variable expansions will take place:
# - `ROOT` is replaced by the root mount point of the **target**
# system from the point of view of the command (when run in the target
# system, e.g. when *dontChroot* is false, that will be `/`).
# - `USER` is replaced by the username, set on the user page.
# - `LANG` is replaced by the language chosen for the user-interface
# of Calamares, set on the welcome page. This may not reflect the
# chosen system language from the locale page.
#
# As a special case, variables of the form `gs[key]` where `key` is
# a dotted-keys string and `gs` is literally the letters `g` and `s`,
# use **any** value from Global Storage. For example,
#
# gs[branding.bootloader]
#
# This variable refers to the GS value stored in `bootloader` in the
# `branding` map. Examine the Debug window for information about the
# keys stored in GS. Only strings and integers are exposed this way,
# lists and other data types do not set any variable this way.
#
# Variables are written as `${var}`, e.g. `${ROOT}`.
# Write `$$` to get a shell-escaped `\$` in the shell command.
# It is not possible to get an un-escaped `$` in the shell command
# (either the command will fail because of undefined variables, or
# you get a shell-escaped `\$`).
#
# The (global) timeout for the command list can be set with
# the *timeout* key. The value is a time in seconds, default
# is 30 seconds if not set. The timeout **must** be tuned, either
# globally or per-command (see below in the description of *script*),
# to the load or expected running-time of the command.
#
# - Setting a timeout of 30 for a `touch` command is probably exessive
# - Setting a timeout of 1 for a `touch` command might be low,
# on a slow disk where touch needs to be loaded from CDROM
# - Setting a timeout of 30 for a 1GB download is definitely low
# - Setting a timeout of 3600 for a 1GB download is going to leave
# the user in uncertainty for a loooong time.
#
# The (global) verbosity of a command can be set to `true` or `false`.
# When set to `true`, command output is logged one line at a time.
# Otherwise the output is logged when the command completes.
# Line-at-a-time logging is appropriate for commands that take
# a long time to complete and produce their own (progress) output.
#
# If a command starts with "-" (a single minus sign), then the
# return value of the command following the - is ignored; otherwise,
# a failing command will abort the installation. This is much like
# make's use of - in a command.
#
# The value of *script* may be:
# - a single string; this is one command that is executed.
# - a single object (see below).
# - a list of items; these are executed one at a time, by
# separate shells (/bin/sh -c is invoked for each command).
# Each list item may be:
# - a single string; this is one command that is executed.
# - a single object, specifying a key *command* and (optionally)
# a key *timeout* to set the timeout for this specific
# command differently from the global setting. An optional
# key *environment* is a list of strings to put into the
# environment of the command. An optional key *verbose*
# overrides the global *verbose* setting in this file.
#
# Using a single object is not generally useful because the same effect
# can be obtained with a single string and a global timeout, except
# when the command needs environment-settings. When there are
# multiple commands to execute, one of them might have
# a different timeout than the others.
#
# The environment strings should all be "KEY='some value'" strings,
# as if they can be typed into the shell. Quoting the environment
# strings with "" in YAML is recommended. Adding the '' quotes ensures
# that the value will not be interpreted by the shell. Writing
# environment strings is the same as placing `export KEY='some value' ;`
# in front of the *command*.
#
# Calamares variable expansion is **also** done on the environment strings.
# Write `$$` to get a literal `$` in the shell command.
#
# To change the description of the job, set the *name* entries in *i18n*.
---
# Set to true to run in host, rather than target system
dontChroot: false
# Tune this for the commands you're actually running, or
# use the list-of-items form of commands to tune the timeout
# for each command individually.
timeout: 10
# This will copy the output from the command into the Calamares
# log file. No processing is done beyond log-each-line-separately,
# so this can introduce weirdness in the log if the script
# outputs e.g. escape codes.
#
# The default is `false`. This can also be set for each
# command individually.
verbose: false
# Script may be a single string (because false returns an error exit
# code, this will trigger a failure in the installation):
#
# script: "/usr/bin/false"
# Script may be a list of strings (because false returns an error exit
# code, **but** the command starts with a "-", the error exit is
# ignored and installation continues):
#
# script:
# - "-/usr/bin/false"
# - "/bin/ls"
# - "/usr/bin/true"
# Script may be a list of items
# - if the touch command fails, it is ignored
# - there is nothing special about the invocation of true
# - the slowloris command has a different timeout from the other commands
# - the echo command logs its output line-by-line
script:
- "-touch ${ROOT}/tmp/thingy"
- "/usr/bin/true"
- command: "/usr/local/bin/slowloris"
timeout: 3600
- command: "echo -e '\e[33;2mred\e[33;0m' ; echo second line"
verbose: true
# You can change the description of the job (as it is displayed in the
# progress bar during installation) by defining an *i18n* key, which
# has a *name* field and optionally, translations as *name[lang]*.
#
# Without a translation here, the default name from the source code
# is used, "Shell Processes Job".
#
# i18n:
# name: "Shell process"
# name[nl]: "Schelpenpad"
# name[en_GB]: "Just a moment"

View File

@@ -0,0 +1,63 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# === This file is part of Calamares - <https://github.com/calamares> ===
#
# Calamares 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.
#
# Calamares 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 Calamares. If not, see <http://www.gnu.org/licenses/>.
#
# SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
# SPDX-License-Identifier: GPL-3.0-or-later
# License-Filename: LICENSES/GPL-3.0
"""
The slowpython module is slow.
"""
import libcalamares
from time import sleep
import gettext
_ = gettext.translation("calamares-python",
localedir=libcalamares.utils.gettext_path(),
languages=libcalamares.utils.gettext_languages(),
fallback=True).gettext
def pretty_name():
return _("Slow python job.")
status = _("Slow python step {}/10").format(0)
def pretty_status_message():
return status
def run():
"""Slow python job."""
try:
timeout = int(libcalamares.job.timeout)
except:
timeout = 30
if not (3 <= timeout <= 600):
timeout = 30
libcalamares.utils.debug("Slow python job for {} seconds".format(timeout))
global status
step = timeout / 10.0
for x in range(11):
status = _("Slow python step {}/10").format(x)
libcalamares.job.setprogress(x / 10.0)
sleep(step)
return None

View File

@@ -0,0 +1,10 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# The slowpython module is .. just slow. It can be used
# in testing to allow the slideshow time to run.
---
type: "job"
interface: "python"
name: "slowpython"
script: "main.py"

View File

@@ -0,0 +1,11 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# This is an example module for Python Job Modules.
#
# The slowpython module is just slow. It does produce
# progress output, in 10 steps during the timeout period.
---
# Number of seconds this module will take to run
timeout: 30

View File

@@ -0,0 +1,105 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Settings for various kinds of tracking that Distributions can
# enable. Distributions looking at tracking should be aware of
# the privacy (and hence communications) impact of that tracking,
# and are advised to consult the Mozilla and KDE policies on
# privacy and user tracking.
#
# There are three areas of tracking (-configuration) supported
# by Calamares It is up to individual Distributions to create
# suitable backends / configuration scripts for each. The
# different areas are:
#
# install: This is "phone home" functionality at the end of the
# install process. When enabled, it contacts the given
# URL. The URL can contain the special token $MACHINE,
# which is replaced by the machine-id of the installed
# system (if available, blank otherwise).
#
# machine: This enables machine-level tracking on a (semi-)
# continuous basis. It is meant to keep track of installed
# systems and their continued use / updating.
#
# user: This area enables user-level tracking, along the lines
# of the KDE User Telemetry Policy. It enables specific
# collection of data at a user- and application-level,
# possibly including actions done in an application.
# For the KDE environment, this enables user tracking
# with the appropriate framework, and the KDE User Telemetry
# policy applies.
#
# Each area has a key *enabled*. If the area is enabled, it is shown to
# the user. This defaults to false, which means no tracking would be
# configured or enabled by Calamares.
#
# Each area has a key *policy*, which is a Url to be opened when
# the user clicks on the corresponding Help button for an explanation
# of the details of that particular kind of tracking. If no policy
# is set, that tracking style is disabled. The example policy links
# go to Calamares' generic user manual (which is a terrible idea
# for a distribution: you have GDPR obligations under most of these
# tracking styles, so do your homework).
#
# Each area may have other configuration keys, depending on the
# area and how it needs to be configured.
#
# Globally, there are two other keys:
#
# policy: (optional) url about tracking settings for this distro.
# default: (optional) level to enable by default
#
---
# This is the global policy; it is displayed as a link on the page.
# If blank or commented out, no link is displayed on the tracking
# page. You **must** provide policy links per-area as well.
policy: "https://calamares.io/docs/tracking#policy"
# This is the default area to enable for tracking. If commented out,
# empty, or otherwise invalid, "none" is used, so no tracking by default.
# Setting an area here also checks the areas before it (install, machine,
# then user) by default -- subject to those areas being enabled at all.
# default: user
# The install area has one specific configuration key:
# url: this URL (remember to include the protocol, and prefer https)
# is fetched (with a GET request, and the data discarded) at
# the end of the installation process. The following tokens
# are replaced in the url (possibly by blank strings, or by 0).
# - $CPU (cpu make and model)
# - $MEMORY (amount of main memory available)
# - $DISK (total amount of disk attached)
# Typically these are used as GET parameters, as in the example.
#
# Note that phone-home only works if the system has an internet
# connection; it is a good idea to require internet in the welcome
# module then.
install:
enabled: false
policy: "https://calamares.io/docs/tracking#policy"
url: "https://example.com/install.php?c=$CPU&m=$MEMORY"
# The machine area has one specific configuration key:
# style: This string specifies what kind of tracking configuration
# needs to be done. See below for valid styles.
#
# Available styles:
# - *updatemanager* replaces the literal string "${MACHINE_ID}" with the contents of
# /etc/machine-id, in lines starting with "URI" in the file /etc/update-manager/meta-release
machine:
enabled: false
style: updatemanager
policy: "https://calamares.io/docs/tracking#policy"
# The user area has one specific configuration key:
# style: This string specifies what kind of tracking configuration
# needs to be done. See below for valid styles.
#
# Available styles:
# - *kuserfeedback* sets up KUserFeedback tracking (applicable to the KDE
# Plasma Desktop) for each KUserFeedback area listed in *areas*.
user:
enabled: false
style: kuserfeedback
areas: [ PlasmaUserFeedback ]

View File

@@ -0,0 +1,14 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
### Umount Module
#
# This module represents the last part of the installation, the unmounting
# of partitions used for the install. After this, there is no regular way
# to modify the target system anymore.
#
---
# Setting emergency to true will make it so this module is still run
# when a prior module fails
emergency: true

View File

@@ -0,0 +1,121 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Unsquash / unpack a filesystem. Multiple sources are supported, and
# they may be squashed or plain filesystems.
#
# Configuration:
#
# from globalstorage: rootMountPoint
# from job.configuration: the path to where to mount the source image(s)
# for copying an ordered list of unpack mappings for image file <->
# target dir relative to rootMountPoint.
---
# Each list item is unpacked, in order, to the target system.
#
# Each list item has the following **mandatory** attributes:
# - *source* path relative to the live / intstalling system to the image
# - *sourcefs* the type of the source files; valid entries are
# - `ext4` (copies the filesystem contents)
# - `squashfs` (unsquashes)
# - `file` (copies a file or directory)
# - (may be others if mount supports it)
# - *destination* path relative to rootMountPoint (so in the target
# system) where this filesystem is unpacked. It may be an
# empty string, which effectively is / (the root) of the target
# system.
#
# Each list item **optionally** can include the following attributes:
# - *exclude* is a list of values that is expanded into --exclude
# arguments for rsync (each entry in exclude gets its own --exclude).
# - *excludeFile* is a single file that is passed to rsync as an
# --exclude-file argument. This should be a full pathname
# inside the **host** filesystem.
# - *weight* is useful when the entries take wildly different
# times to unpack (e.g. with a squashfs, and one single file)
# and the total weight of this module should be distributed
# differently between the entries. (This is only relevant when
# there is more than one entry; by default all the entries
# have the same weight, 1)
#
# EXAMPLES
#
# Usually you list a filesystem image to unpack; you can use
# squashfs or an ext4 image. An empty destination is equivalent to "/",
# the root of the target system. The destination directory must exist
# in the target system.
#
# - source: "/path/to/filesystem.sqfs"
# sourcefs: "squashfs"
# destination: ""
#
# Multiple entries are unpacked in-order; if there is more than one
# item then only the first must exist beforehand -- it's ok to
# create directories with one unsquash and then to use those
# directories as a target from a second unsquash.
#
# - source: "/path/to/another/filesystem.img"
# sourcefs: "ext4"
# destination: ""
# - source: "/path/to/another/filesystem2.img"
# sourcefs: "ext4"
# destination: "/usr/lib/extra"
#
# You can list filesystem source paths relative to the Calamares run
# directory, if you use -d (this is only useful for testing, though).
#
# - source: ./example.sqfs
# sourcefs: squashfs
# destination: ""
#
# You can list individual files (copied one-by-one), or directories
# (the files inside this directory are copied directly to the destination,
# so no "dummycpp/" subdirectory is created in this example).
# Do note that the target directory must exist already (e.g. from
# extracting some other filesystem).
#
# - source: ../CHANGES
# sourcefs: file
# destination: "/tmp/derp"
# - source: ../src/modules/dummycpp
# sourcefs: file
# destination: "/tmp/derp"
#
# The *destination* and *source* are handed off to rsync, so the semantics
# of trailing slashes apply. In order to *rename* a file as it is
# copied, specify one single file (e.g. CHANGES) and a full pathname
# for its destination name, as in the example below.
#
# It is also possible to dynamically (conditionally) unpack a source by passing a boolean
# value for *condition*. This may be true or false (constant) or name a globalstorage
# value. Use '.' to separate parts of a globalstorage name if it is nested.
#
# This is used in e.g. stacked squashfses, where the user can select a specific
# install type. The default value of *condition* is true.
#
# - source: ./example.minimal.sqfs
# sourcefs: squashfs
# destination: ""
# condition: false
# - source: ./example.standard.sqfs
# sourcefs: squashfs
# destination: ""
# condition: exampleGlobalStorageVariable.subkey
#
# You may also wish to include optional squashfses, which may not exist at certain times
# depending on your image tooling. If an optional squashfs is not found, it is simply
# skipped.
#
# - source: ./example.standard.sqfs
# sourcefs: squashfs
# destination: ""
# - source: ./example.extras.sqfs
# sourcefs: squashfs
# destination: ""
# optional: true
unpack:
- source: "/run/archiso/bootmnt/arch/x86_64/airootfs.sfs"
sourcefs: "squashfs"
destination: ""

Some files were not shown because too many files have changed in this diff Show More