initial commit
This commit is contained in:
commit
3a783587af
BIN
etc/calamares/branding/default/banner.png
Normal file
BIN
etc/calamares/branding/default/banner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
2
etc/calamares/branding/default/banner.png.license
Normal file
2
etc/calamares/branding/default/banner.png.license
Normal file
@ -0,0 +1,2 @@
|
||||
SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
239
etc/calamares/branding/default/branding.desc
Normal file
239
etc/calamares/branding/default/branding.desc
Normal 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: false
|
||||
|
||||
# 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: Condor Linux
|
||||
#shortProductName: Generic
|
||||
version: 2024.10.13
|
||||
shortVersion: 2023.10.13
|
||||
versionedName: Condor Linux "Uchiha"
|
||||
#shortVersionedName: Condor Linux
|
||||
bootloaderEntryName: Condor Linux
|
||||
productUrl: https://condorcs.net/CondorLinux
|
||||
supportUrl: https://condorcs.net/CondorLinux
|
||||
knownIssuesUrl: https://condorcs.net/CondorLinux
|
||||
releaseNotesUrl: https://condorcs.net/CondorLinux
|
||||
#donateUrl:
|
||||
|
||||
# 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
|
17
etc/calamares/branding/default/lang/calamares-default_ar.ts
Normal file
17
etc/calamares/branding/default/lang/calamares-default_ar.ts
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="ar">
|
||||
<context>
|
||||
<name>show</name>
|
||||
<message>
|
||||
<location filename="../show.qml" line="64"/>
|
||||
<source>This is a second Slide element.</source>
|
||||
<translation>عرض الثاني</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../show.qml" line="68"/>
|
||||
<source>This is a third Slide element.</source>
|
||||
<translation>عرض الثالث</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
17
etc/calamares/branding/default/lang/calamares-default_en.ts
Normal file
17
etc/calamares/branding/default/lang/calamares-default_en.ts
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="en">
|
||||
<context>
|
||||
<name>show</name>
|
||||
<message>
|
||||
<location filename="../show.qml" line="64"/>
|
||||
<source>This is a second Slide element.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../show.qml" line="68"/>
|
||||
<source>This is a third Slide element.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
17
etc/calamares/branding/default/lang/calamares-default_eo.ts
Normal file
17
etc/calamares/branding/default/lang/calamares-default_eo.ts
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="eo">
|
||||
<context>
|
||||
<name>show</name>
|
||||
<message>
|
||||
<location filename="../show.qml" line="64"/>
|
||||
<source>This is a second Slide element.</source>
|
||||
<translation>Ĉi tio estas la dua gliteja.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../show.qml" line="68"/>
|
||||
<source>This is a third Slide element.</source>
|
||||
<translation>Ĉi tio estas la tria gliteja.</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
17
etc/calamares/branding/default/lang/calamares-default_fr.ts
Normal file
17
etc/calamares/branding/default/lang/calamares-default_fr.ts
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="fr">
|
||||
<context>
|
||||
<name>show</name>
|
||||
<message>
|
||||
<location filename="../show.qml" line="64"/>
|
||||
<source>This is a second Slide element.</source>
|
||||
<translation>Ceci est la deuxieme affiche.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../show.qml" line="68"/>
|
||||
<source>This is a third Slide element.</source>
|
||||
<translation>La troisième affice ce trouve ici.</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
17
etc/calamares/branding/default/lang/calamares-default_nl.ts
Normal file
17
etc/calamares/branding/default/lang/calamares-default_nl.ts
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="nl">
|
||||
<context>
|
||||
<name>show</name>
|
||||
<message>
|
||||
<location filename="../show.qml" line="64"/>
|
||||
<source>This is a second Slide element.</source>
|
||||
<translation>Dit is het tweede Dia element.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../show.qml" line="68"/>
|
||||
<source>This is a third Slide element.</source>
|
||||
<translation>Dit is het derde Dia element.</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
BIN
etc/calamares/branding/default/languages.png
Normal file
BIN
etc/calamares/branding/default/languages.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 84 KiB |
2
etc/calamares/branding/default/languages.png.license
Normal file
2
etc/calamares/branding/default/languages.png.license
Normal file
@ -0,0 +1,2 @@
|
||||
SPDX-FileCopyrightText: 2015 Teo Mrnjavac <teo@kde.org>
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
77
etc/calamares/branding/default/show.qml
Normal file
77
etc/calamares/branding/default/show.qml
Normal 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");
|
||||
}
|
||||
|
||||
}
|
BIN
etc/calamares/branding/default/squid.png
Normal file
BIN
etc/calamares/branding/default/squid.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
2
etc/calamares/branding/default/squid.png.license
Normal file
2
etc/calamares/branding/default/squid.png.license
Normal file
@ -0,0 +1,2 @@
|
||||
SPDX-FileCopyrightText: 2014 Teo Mrnjavac <teo@kde.org>
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
96
etc/calamares/branding/default/stylesheet.qss
Normal file
96
etc/calamares/branding/default/stylesheet.qss
Normal 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 { }
|
||||
*/
|
500
etc/calamares/modules/unpackfs/main.py
Normal file
500
etc/calamares/modules/unpackfs/main.py
Normal file
@ -0,0 +1,500 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# === This file is part of Calamares - <https://calamares.io> ===
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2014 Teo Mrnjavac <teo@kde.org>
|
||||
# SPDX-FileCopyrightText: 2014 Daniel Hillenbrand <codeworkx@bbqlinux.org>
|
||||
# SPDX-FileCopyrightText: 2014 Philip Müller <philm@manjaro.org>
|
||||
# SPDX-FileCopyrightText: 2017 Alf Gaida <agaida@siduction.org>
|
||||
# SPDX-FileCopyrightText: 2019 Kevin Kofler <kevin.kofler@chello.at>
|
||||
# SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-FileCopyrightText: 2020 Gabriel Craciunescu <crazy@frugalware.org>
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#
|
||||
# Calamares is Free Software: see the License-Identifier above.
|
||||
#
|
||||
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
import libcalamares
|
||||
|
||||
import gettext
|
||||
_ = gettext.translation("calamares-python",
|
||||
localedir=libcalamares.utils.gettext_path(),
|
||||
languages=libcalamares.utils.gettext_languages(),
|
||||
fallback=True).gettext
|
||||
|
||||
def pretty_name():
|
||||
return _("Filling up filesystems.")
|
||||
|
||||
# This is going to be changed from various methods
|
||||
status = pretty_name()
|
||||
|
||||
def pretty_status_message():
|
||||
return status
|
||||
|
||||
class UnpackEntry:
|
||||
"""
|
||||
Extraction routine using rsync.
|
||||
|
||||
:param source:
|
||||
:param sourcefs:
|
||||
:param destination:
|
||||
"""
|
||||
__slots__ = ('source', 'sourcefs', 'destination', 'copied', 'total', 'exclude', 'excludeFile',
|
||||
'mountPoint', 'weight')
|
||||
|
||||
def __init__(self, source, sourcefs, destination):
|
||||
"""
|
||||
@p source is the source file name (might be an image file, or
|
||||
a directory, too)
|
||||
@p sourcefs is a type indication; "file" is special, as is
|
||||
"squashfs".
|
||||
@p destination is where the files from the source go. This is
|
||||
**already** prefixed by rootMountPoint, so should be a
|
||||
valid absolute path within the host system.
|
||||
|
||||
The members copied and total are filled in by the copying process.
|
||||
"""
|
||||
self.source = source
|
||||
self.sourcefs = sourcefs
|
||||
self.destination = destination
|
||||
self.exclude = None
|
||||
self.excludeFile = None
|
||||
self.copied = 0
|
||||
self.total = 0
|
||||
self.mountPoint = None
|
||||
self.weight = 1
|
||||
|
||||
def is_file(self):
|
||||
return self.sourcefs == "file"
|
||||
|
||||
def do_count(self):
|
||||
"""
|
||||
Counts the number of files this entry has.
|
||||
"""
|
||||
# Need a name we can use like a global
|
||||
class counter(object):
|
||||
count = 0
|
||||
def cb_count(s):
|
||||
counter.count += 1
|
||||
|
||||
if self.sourcefs == "squashfs":
|
||||
libcalamares.utils.host_env_process_output(["unsquashfs", "-l", self.source], cb_count)
|
||||
|
||||
elif self.sourcefs == "ext4":
|
||||
libcalamares.utils.host_env_process_output(["find", self.mountPoint, "-type", "f"], cb_count)
|
||||
|
||||
elif self.is_file():
|
||||
# Hasn't been mounted, copy directly; find handles both
|
||||
# files and directories.
|
||||
libcalamares.utils.host_env_process_output(["find", self.source, "-type", "f"], cb_count)
|
||||
|
||||
self.total = counter.count
|
||||
return self.total
|
||||
|
||||
def do_mount(self, base):
|
||||
"""
|
||||
Mount given @p entry as loop device underneath @p base
|
||||
|
||||
A *file* entry (e.g. one with *sourcefs* set to *file*)
|
||||
is not mounted and just ignored.
|
||||
|
||||
:param base: directory to place all the mounts in.
|
||||
|
||||
:returns: None, but throws if the mount failed
|
||||
"""
|
||||
imgbasename = os.path.splitext(
|
||||
os.path.basename(self.source))[0]
|
||||
imgmountdir = os.path.join(base, imgbasename)
|
||||
os.makedirs(imgmountdir, exist_ok=True)
|
||||
|
||||
# This is where it *would* go (files bail out before actually mounting)
|
||||
self.mountPoint = imgmountdir
|
||||
|
||||
if self.is_file():
|
||||
return
|
||||
|
||||
if os.path.isdir(self.source):
|
||||
r = libcalamares.utils.mount(self.source, imgmountdir, "", "--bind")
|
||||
elif os.path.isfile(self.source):
|
||||
r = libcalamares.utils.mount(self.source, imgmountdir, self.sourcefs, "loop")
|
||||
else: # self.source is a device
|
||||
r = libcalamares.utils.mount(self.source, imgmountdir, self.sourcefs, "")
|
||||
|
||||
if r != 0:
|
||||
libcalamares.utils.debug("Failed to mount '{}' (fs={}) (target={})".format(self.source, self.sourcefs, imgmountdir))
|
||||
raise subprocess.CalledProcessError(r, "mount")
|
||||
|
||||
|
||||
ON_POSIX = 'posix' in sys.builtin_module_names
|
||||
|
||||
|
||||
def global_excludes():
|
||||
"""
|
||||
List excludes for rsync.
|
||||
"""
|
||||
lst = []
|
||||
extra_mounts = libcalamares.globalstorage.value("extraMounts")
|
||||
if extra_mounts is None:
|
||||
extra_mounts = []
|
||||
|
||||
for extra_mount in extra_mounts:
|
||||
mount_point = extra_mount["mountPoint"]
|
||||
|
||||
if mount_point:
|
||||
lst.extend(['--exclude', mount_point + '/'])
|
||||
|
||||
return lst
|
||||
|
||||
def file_copy(source, entry, progress_cb):
|
||||
"""
|
||||
Extract given image using rsync.
|
||||
|
||||
:param source: Source file. This may be the place the entry's
|
||||
image is mounted, or if it's a single file, the entry's source value.
|
||||
:param entry: The UnpackEntry being copied.
|
||||
:param progress_cb: A callback function for progress reporting.
|
||||
Takes a number and a total-number.
|
||||
"""
|
||||
import time
|
||||
|
||||
dest = entry.destination
|
||||
|
||||
# `source` *must* end with '/' otherwise a directory named after the source
|
||||
# will be created in `dest`: ie if `source` is "/foo/bar" and `dest` is
|
||||
# "/dest", then files will be copied in "/dest/bar".
|
||||
if not source.endswith("/") and not os.path.isfile(source):
|
||||
source += "/"
|
||||
|
||||
num_files_total_local = 0
|
||||
num_files_copied = 0 # Gets updated through rsync output
|
||||
|
||||
args = ['rsync', '-aHAXSr', '--filter=-x trusted.overlay.*']
|
||||
args.extend(global_excludes())
|
||||
if entry.excludeFile:
|
||||
args.extend(["--exclude-from=" + entry.excludeFile])
|
||||
if entry.exclude:
|
||||
for f in entry.exclude:
|
||||
args.extend(["--exclude", f])
|
||||
args.extend(['--progress', source, dest])
|
||||
|
||||
# last_num_files_copied trails num_files_copied, and whenever at least 107 more
|
||||
# files (file_count_chunk) have been copied, progress is reported and
|
||||
# last_num_files_copied is updated. The chunk size isn't "tidy"
|
||||
# so that all the digits of the progress-reported number change.
|
||||
#
|
||||
file_count_chunk = 107
|
||||
|
||||
class counter(object):
|
||||
last_num_files_copied = 0
|
||||
last_timestamp_reported = time.time()
|
||||
last_total_reported = 0
|
||||
|
||||
def output_cb(line):
|
||||
# rsync outputs progress in parentheses. Each line will have an
|
||||
# xfer and a chk item (either ir-chk or to-chk) as follows:
|
||||
#
|
||||
# - xfer#x => Interpret it as 'file copy try no. x'
|
||||
# - ir-chk=x/y, where:
|
||||
# - x = number of files yet to be checked
|
||||
# - y = currently calculated total number of files.
|
||||
# - to-chk=x/y, which is similar and happens once the ir-chk
|
||||
# phase (collecting total files) is over.
|
||||
#
|
||||
# If you're copying directory with some links in it, the xfer#
|
||||
# might not be a reliable counter (for one increase of xfer, many
|
||||
# files may be created).
|
||||
m = re.findall(r'xfr#(\d+), ..-chk=(\d+)/(\d+)', line)
|
||||
|
||||
if m:
|
||||
# we've got a percentage update
|
||||
num_files_remaining = int(m[0][1])
|
||||
num_files_total_local = int(m[0][2])
|
||||
# adjusting the offset so that progressbar can be continuesly drawn
|
||||
num_files_copied = num_files_total_local - num_files_remaining
|
||||
|
||||
now = time.time()
|
||||
if (num_files_copied - counter.last_num_files_copied >= file_count_chunk) or (now - counter.last_timestamp_reported > 0.5):
|
||||
counter.last_num_files_copied = num_files_copied
|
||||
counter.last_timestamp_reported = now
|
||||
counter.last_total_reported = num_files_total_local
|
||||
progress_cb(num_files_copied, num_files_total_local)
|
||||
|
||||
try:
|
||||
returncode = libcalamares.utils.host_env_process_output(args, output_cb)
|
||||
except subprocess.CalledProcessError as e:
|
||||
returncode = e.returncode
|
||||
|
||||
progress_cb(counter.last_num_files_copied, counter.last_total_reported) # Push towards 100%
|
||||
|
||||
# Mark this entry as really done
|
||||
entry.copied = entry.total
|
||||
|
||||
# 23 is the return code rsync returns if it cannot write extended
|
||||
# attributes (with -X) because the target file system does not support it,
|
||||
# e.g., the FAT EFI system partition. We need -X because distributions
|
||||
# using file system capabilities and/or SELinux require the extended
|
||||
# attributes. But distributions using SELinux may also have SELinux labels
|
||||
# set on files under /boot/efi, and rsync complains about those. The only
|
||||
# clean way would be to split the rsync into one with -X and
|
||||
# --exclude /boot/efi and a separate one without -X for /boot/efi, but only
|
||||
# if /boot/efi is actually an EFI system partition. For now, this hack will
|
||||
# have to do. See also:
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=868755#c50
|
||||
# for the same issue in Anaconda, which uses a similar workaround.
|
||||
if returncode != 0 and returncode != 23:
|
||||
libcalamares.utils.warning("rsync failed with error code {}.".format(returncode))
|
||||
return _("rsync failed with error code {}.").format(returncode)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
class UnpackOperation:
|
||||
"""
|
||||
Extraction routine using unsquashfs.
|
||||
|
||||
:param entries:
|
||||
"""
|
||||
|
||||
def __init__(self, entries):
|
||||
self.entries = entries
|
||||
self.entry_for_source = dict((x.source, x) for x in self.entries)
|
||||
self.total_weight = sum([e.weight for e in entries])
|
||||
|
||||
def report_progress(self):
|
||||
"""
|
||||
Pass progress to user interface
|
||||
"""
|
||||
progress = float(0)
|
||||
|
||||
current_total = 0
|
||||
current_done = 0 # Files count in the current entry
|
||||
complete_count = 0
|
||||
complete_weight = 0 # This much weight already finished
|
||||
for entry in self.entries:
|
||||
if entry.total == 0:
|
||||
# Total 0 hasn't counted yet
|
||||
continue
|
||||
if entry.total == entry.copied:
|
||||
complete_weight += entry.weight
|
||||
complete_count += 1
|
||||
else:
|
||||
# There is at most *one* entry in-progress
|
||||
current_total = entry.total
|
||||
current_done = entry.copied
|
||||
complete_weight += entry.weight * ( 1.0 * current_done ) / current_total
|
||||
break
|
||||
|
||||
if current_total > 0:
|
||||
progress = ( 1.0 * complete_weight ) / self.total_weight
|
||||
|
||||
global status
|
||||
status = _("Unpacking image {}/{}, file {}/{}").format((complete_count+1), len(self.entries), current_done, current_total)
|
||||
libcalamares.job.setprogress(progress)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
Extract given image using unsquashfs.
|
||||
|
||||
:return:
|
||||
"""
|
||||
global status
|
||||
source_mount_path = tempfile.mkdtemp()
|
||||
|
||||
try:
|
||||
complete = 0
|
||||
for entry in self.entries:
|
||||
status = _("Starting to unpack {}").format(entry.source)
|
||||
libcalamares.job.setprogress( ( 1.0 * complete ) / len(self.entries) )
|
||||
entry.do_mount(source_mount_path)
|
||||
entry.do_count() # Fill in the entry.total
|
||||
|
||||
self.report_progress()
|
||||
error_msg = self.unpack_image(entry, entry.mountPoint)
|
||||
|
||||
if error_msg:
|
||||
return (_("Failed to unpack image \"{}\"").format(entry.source),
|
||||
error_msg)
|
||||
complete += 1
|
||||
|
||||
return None
|
||||
finally:
|
||||
shutil.rmtree(source_mount_path, ignore_errors=True, onerror=None)
|
||||
|
||||
|
||||
def unpack_image(self, entry, imgmountdir):
|
||||
"""
|
||||
Unpacks image.
|
||||
|
||||
:param entry:
|
||||
:param imgmountdir:
|
||||
:return:
|
||||
"""
|
||||
def progress_cb(copied, total):
|
||||
""" Copies file to given destination target.
|
||||
|
||||
:param copied:
|
||||
"""
|
||||
entry.copied = copied
|
||||
if total > entry.total:
|
||||
entry.total = total
|
||||
self.report_progress()
|
||||
|
||||
try:
|
||||
if entry.is_file():
|
||||
source = entry.source
|
||||
else:
|
||||
source = imgmountdir
|
||||
|
||||
return file_copy(source, entry, progress_cb)
|
||||
finally:
|
||||
if not entry.is_file():
|
||||
subprocess.check_call(["umount", "-l", imgmountdir])
|
||||
|
||||
|
||||
def get_supported_filesystems_kernel():
|
||||
"""
|
||||
Reads /proc/filesystems (the list of supported filesystems
|
||||
for the current kernel) and returns a list of (names of)
|
||||
those filesystems.
|
||||
"""
|
||||
PATH_PROCFS = '/proc/filesystems'
|
||||
|
||||
if os.path.isfile(PATH_PROCFS) and os.access(PATH_PROCFS, os.R_OK):
|
||||
with open(PATH_PROCFS, 'r') as procfile:
|
||||
filesystems = procfile.read()
|
||||
filesystems = filesystems.replace(
|
||||
"nodev", "").replace("\t", "").splitlines()
|
||||
return filesystems
|
||||
|
||||
return []
|
||||
|
||||
|
||||
def get_supported_filesystems():
|
||||
"""
|
||||
Returns a list of all the supported filesystems
|
||||
(valid values for the *sourcefs* key in an item.
|
||||
"""
|
||||
return ["file"] + get_supported_filesystems_kernel()
|
||||
|
||||
|
||||
def repair_root_permissions(root_mount_point):
|
||||
"""
|
||||
If the / of the system gets permission 777, change it down
|
||||
to 755. Any other permission is left alone. This
|
||||
works around standard behavior from squashfs where
|
||||
permissions are (easily, accidentally) set to 777.
|
||||
"""
|
||||
existing_root_mode = os.stat(root_mount_point).st_mode & 0o777
|
||||
if existing_root_mode == 0o777:
|
||||
try:
|
||||
os.chmod(root_mount_point, 0o755) # Want / to be rwxr-xr-x
|
||||
except OSError as e:
|
||||
libcalamares.utils.warning("Could not set / to safe permissions: {}".format(e))
|
||||
# But ignore it
|
||||
|
||||
|
||||
def extract_weight(entry):
|
||||
"""
|
||||
Given @p entry, a dict representing a single entry in
|
||||
the *unpack* list, returns its weight (1, or whatever is
|
||||
set if it is sensible).
|
||||
"""
|
||||
w = entry.get("weight", None)
|
||||
if w:
|
||||
try:
|
||||
wi = int(w)
|
||||
return wi if wi > 0 else 1
|
||||
except ValueError:
|
||||
libcalamares.utils.warning("*weight* setting {!r} is not valid.".format(w))
|
||||
except TypeError:
|
||||
libcalamares.utils.warning("*weight* setting {!r} must be number.".format(w))
|
||||
return 1
|
||||
|
||||
|
||||
def run():
|
||||
"""
|
||||
Unsquash filesystem.
|
||||
"""
|
||||
root_mount_point = libcalamares.globalstorage.value("rootMountPoint")
|
||||
|
||||
if not root_mount_point:
|
||||
libcalamares.utils.warning("No mount point for root partition")
|
||||
return (_("No mount point for root partition"),
|
||||
_("globalstorage does not contain a \"rootMountPoint\" key."))
|
||||
if not os.path.exists(root_mount_point):
|
||||
libcalamares.utils.warning("Bad root mount point \"{}\"".format(root_mount_point))
|
||||
return (_("Bad mount point for root partition"),
|
||||
_("rootMountPoint is \"{}\", which does not exist.".format(root_mount_point)))
|
||||
|
||||
if libcalamares.job.configuration.get("unpack", None) is None:
|
||||
libcalamares.utils.warning("No *unpack* key in job configuration.")
|
||||
return (_("Bad unpackfs configuration"),
|
||||
_("There is no configuration information."))
|
||||
|
||||
supported_filesystems = get_supported_filesystems()
|
||||
|
||||
# Bail out before we start when there are obvious problems
|
||||
# - unsupported filesystems
|
||||
# - non-existent sources
|
||||
# - missing tools for specific FS
|
||||
for entry in libcalamares.job.configuration["unpack"]:
|
||||
source = os.path.abspath(entry["source"])
|
||||
sourcefs = entry["sourcefs"]
|
||||
|
||||
if sourcefs not in supported_filesystems:
|
||||
libcalamares.utils.warning("The filesystem for \"{}\" ({}) is not supported by your current kernel".format(source, sourcefs))
|
||||
libcalamares.utils.warning(" ... modprobe {} may solve the problem".format(sourcefs))
|
||||
return (_("Bad unpackfs configuration"),
|
||||
_("The filesystem for \"{}\" ({}) is not supported by your current kernel").format(source, sourcefs))
|
||||
if not os.path.exists(source):
|
||||
libcalamares.utils.warning("The source filesystem \"{}\" does not exist".format(source))
|
||||
return (_("Bad unpackfs configuration"),
|
||||
_("The source filesystem \"{}\" does not exist").format(source))
|
||||
if sourcefs == "squashfs":
|
||||
if shutil.which("unsquashfs") is None:
|
||||
libcalamares.utils.warning("Failed to find unsquashfs")
|
||||
|
||||
return (_("Bad unpackfs configuration"),
|
||||
_("Failed to find unsquashfs, make sure you have the squashfs-tools package installed.") +
|
||||
" " + _("Failed to unpack image \"{}\"").format(source))
|
||||
|
||||
unpack = list()
|
||||
|
||||
is_first = True
|
||||
for entry in libcalamares.job.configuration["unpack"]:
|
||||
source = os.path.abspath(entry["source"])
|
||||
sourcefs = entry["sourcefs"]
|
||||
destination = os.path.abspath(root_mount_point + entry["destination"])
|
||||
|
||||
if not os.path.isdir(destination) and sourcefs != "file":
|
||||
libcalamares.utils.warning(("The destination \"{}\" in the target system is not a directory").format(destination))
|
||||
if is_first:
|
||||
return (_("Bad unpackfs configuration"),
|
||||
_("The destination \"{}\" in the target system is not a directory").format(destination))
|
||||
else:
|
||||
libcalamares.utils.debug(".. assuming that the previous targets will create that directory.")
|
||||
|
||||
unpack.append(UnpackEntry(source, sourcefs, destination))
|
||||
# Optional settings
|
||||
if entry.get("exclude", None):
|
||||
unpack[-1].exclude = entry["exclude"]
|
||||
if entry.get("excludeFile", None):
|
||||
unpack[-1].excludeFile = entry["excludeFile"]
|
||||
unpack[-1].weight = extract_weight(entry)
|
||||
|
||||
is_first = False
|
||||
|
||||
repair_root_permissions(root_mount_point)
|
||||
try:
|
||||
unpackop = UnpackOperation(unpack)
|
||||
return unpackop.run()
|
||||
finally:
|
||||
repair_root_permissions(root_mount_point)
|
10
etc/calamares/modules/unpackfs/module.desc
Normal file
10
etc/calamares/modules/unpackfs/module.desc
Normal file
@ -0,0 +1,10 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
# Syntax is YAML 1.2
|
||||
---
|
||||
type: "job"
|
||||
name: "unpackfs"
|
||||
interface: "python"
|
||||
script: "main.py"
|
||||
requiredModules: [ mount ]
|
||||
weight: 12
|
37
etc/calamares/modules/unpackfs/runtests.sh
Normal file
37
etc/calamares/modules/unpackfs/runtests.sh
Normal file
@ -0,0 +1,37 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
# Test preparation for unpackfs; since there's a bunch
|
||||
# of fiddly bits than need to be present for the tests,
|
||||
# do that in a script rather than entirely in CTest.
|
||||
#
|
||||
SRCDIR=$( dirname "$0" )
|
||||
|
||||
# For test 3
|
||||
mkdir /tmp/unpackfs-test-run-rootdir3
|
||||
|
||||
# For test 7
|
||||
mkdir /tmp/unpackfs-test-run-rootdir3/realdest
|
||||
|
||||
# For test 9
|
||||
mkdir /tmp/unpackfs-test-run-rootdir3/smalldest
|
||||
if test 0 = $( id -u ) ; then
|
||||
mount -t tmpfs -o size=32M tmpfs /tmp/unpackfs-test-run-rootdir3/smalldest
|
||||
dd if=/dev/zero of=/tmp/unpackfs-test-run-rootdir3/smalldest/bogus.zero bs=1M count=1
|
||||
fi
|
||||
|
||||
# Run tests
|
||||
sh "$SRCDIR/../testpythonrun.sh" unpackfs
|
||||
|
||||
# Cleanup test 9
|
||||
if test 0 = $( id -u ) ; then
|
||||
umount /tmp/unpackfs-test-run-rootdir3/smalldest
|
||||
fi
|
||||
|
||||
# Cleanup test 7
|
||||
rm -rf /tmp/unpackfs-test-run-rootdir3/realdest
|
||||
|
||||
# Cleanup test 3
|
||||
rmdir /tmp/unpackfs-test-run-rootdir3
|
4
etc/calamares/modules/unpackfs/tests/1.global
Normal file
4
etc/calamares/modules/unpackfs/tests/1.global
Normal file
@ -0,0 +1,4 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
bogus: true
|
4
etc/calamares/modules/unpackfs/tests/2.global
Normal file
4
etc/calamares/modules/unpackfs/tests/2.global
Normal file
@ -0,0 +1,4 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
rootMountPoint: /tmp/unpackfs-test-run-rootdir/
|
4
etc/calamares/modules/unpackfs/tests/3.global
Normal file
4
etc/calamares/modules/unpackfs/tests/3.global
Normal file
@ -0,0 +1,4 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
rootMountPoint: /tmp/unpackfs-test-run-rootdir3/
|
4
etc/calamares/modules/unpackfs/tests/3.job
Normal file
4
etc/calamares/modules/unpackfs/tests/3.job
Normal file
@ -0,0 +1,4 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
unpack: []
|
4
etc/calamares/modules/unpackfs/tests/4.global
Normal file
4
etc/calamares/modules/unpackfs/tests/4.global
Normal file
@ -0,0 +1,4 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
rootMountPoint: /tmp/unpackfs-test-run-rootdir3/
|
10
etc/calamares/modules/unpackfs/tests/4.job
Normal file
10
etc/calamares/modules/unpackfs/tests/4.job
Normal file
@ -0,0 +1,10 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# Test that a "bogus" sourcefs (a filesystem kind that does not
|
||||
# exist) fails gracefully.
|
||||
---
|
||||
unpack:
|
||||
- source: .
|
||||
sourcefs: bogus
|
||||
destination: /
|
4
etc/calamares/modules/unpackfs/tests/5.global
Normal file
4
etc/calamares/modules/unpackfs/tests/5.global
Normal file
@ -0,0 +1,4 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
rootMountPoint: /tmp/unpackfs-test-run-rootdir3/
|
7
etc/calamares/modules/unpackfs/tests/5.job
Normal file
7
etc/calamares/modules/unpackfs/tests/5.job
Normal file
@ -0,0 +1,7 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
unpack:
|
||||
- source: ./fakesource
|
||||
sourcefs: ext4
|
||||
destination: fakedest
|
4
etc/calamares/modules/unpackfs/tests/6.global
Normal file
4
etc/calamares/modules/unpackfs/tests/6.global
Normal file
@ -0,0 +1,4 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
rootMountPoint: /tmp/unpackfs-test-run-rootdir3/
|
7
etc/calamares/modules/unpackfs/tests/6.job
Normal file
7
etc/calamares/modules/unpackfs/tests/6.job
Normal file
@ -0,0 +1,7 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
unpack:
|
||||
- source: .
|
||||
sourcefs: ext4
|
||||
destination: fakedest
|
4
etc/calamares/modules/unpackfs/tests/7.global
Normal file
4
etc/calamares/modules/unpackfs/tests/7.global
Normal file
@ -0,0 +1,4 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
rootMountPoint: /tmp/unpackfs-test-run-rootdir3/
|
7
etc/calamares/modules/unpackfs/tests/7.job
Normal file
7
etc/calamares/modules/unpackfs/tests/7.job
Normal file
@ -0,0 +1,7 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
unpack:
|
||||
- source: .
|
||||
sourcefs: ext4
|
||||
destination: realdest
|
6
etc/calamares/modules/unpackfs/tests/8.global
Normal file
6
etc/calamares/modules/unpackfs/tests/8.global
Normal file
@ -0,0 +1,6 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
rootMountPoint: /tmp/unpackfs-test-run-rootdir/
|
||||
localeConf:
|
||||
- LANG: nl
|
7
etc/calamares/modules/unpackfs/tests/8.job
Normal file
7
etc/calamares/modules/unpackfs/tests/8.job
Normal file
@ -0,0 +1,7 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
unpack:
|
||||
- source: .
|
||||
sourcefs: ext4
|
||||
destination: realdest
|
5
etc/calamares/modules/unpackfs/tests/9.global
Normal file
5
etc/calamares/modules/unpackfs/tests/9.global
Normal file
@ -0,0 +1,5 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
# This test uses a small destination FS, to make rsync fail
|
||||
---
|
||||
rootMountPoint: /tmp/unpackfs-test-run-rootdir3/
|
8
etc/calamares/modules/unpackfs/tests/9.job
Normal file
8
etc/calamares/modules/unpackfs/tests/9.job
Normal file
@ -0,0 +1,8 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
# This test uses a small destination FS, to make rsync fail
|
||||
---
|
||||
unpack:
|
||||
- source: .
|
||||
sourcefs: ext4
|
||||
destination: smalldest
|
100
etc/calamares/modules/unpackfs/unpackfs.conf
Normal file
100
etc/calamares/modules/unpackfs/unpackfs.conf
Normal file
@ -0,0 +1,100 @@
|
||||
# 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.
|
||||
|
||||
unpack:
|
||||
- source: ../CHANGES
|
||||
sourcefs: file
|
||||
destination: "/tmp/changes.txt"
|
||||
weight: 1 # Single file
|
||||
- source: src/qml/calamares/slideshow
|
||||
sourcefs: file
|
||||
destination: "/tmp/slideshow/"
|
||||
exclude: [ "*.qmlc", "qmldir" ]
|
||||
weight: 5 # Lots of files
|
||||
# excludeFile: /etc/calamares/modules/unpackfs/exclude-list.txt
|
21
etc/calamares/modules/unpackfs/unpackfs.schema.yaml
Normal file
21
etc/calamares/modules/unpackfs/unpackfs.schema.yaml
Normal file
@ -0,0 +1,21 @@
|
||||
# SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
---
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/unpackfs
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
unpack:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
properties:
|
||||
source: { type: string }
|
||||
sourcefs: { type: string }
|
||||
destination: { type: string }
|
||||
excludeFile: { type: string }
|
||||
exclude: { type: array, items: { type: string } }
|
||||
weight: { type: integer, exclusiveMinimum: 0 }
|
||||
required: [ source , sourcefs, destination ]
|
236
etc/calamares/settings.conf
Normal file
236
etc/calamares/settings.conf
Normal file
@ -0,0 +1,236 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# Configuration file for Calamares
|
||||
#
|
||||
# This is the top-level configuration file for Calamares.
|
||||
# It specifies what modules will be used, as well as some
|
||||
# overall characteristics -- is this a setup program, or
|
||||
# an installer. More specific configuration is devolved
|
||||
# to the branding file (for the UI) and the individual
|
||||
# module configuration files (for functionality).
|
||||
---
|
||||
# Modules can be job modules (with different interfaces) and QtWidgets view
|
||||
# modules. They could all be placed in a number of different paths.
|
||||
# "modules-search" is a list of strings, each of these can either be a full
|
||||
# path to a directory or the keyword "local".
|
||||
#
|
||||
# "local" means:
|
||||
# - modules in $LIBDIR/calamares/modules, with
|
||||
# - settings in SHARE/calamares/modules or /etc/calamares/modules.
|
||||
# In debug-mode (e.g. calamares -d) "local" also adds some paths
|
||||
# that make sense from inside the build-directory, so that you
|
||||
# can build-and-run with the latest modules immediately.
|
||||
#
|
||||
# Strings other than "local" are taken as paths and interpreted
|
||||
# relative to wherever Calamares is started. It is therefore **strongly**
|
||||
# recommended to use only absolute paths here. This is mostly useful
|
||||
# if your distro has forks of standard Calamares modules, but also
|
||||
# uses some form of upstream packaging which might overwrite those
|
||||
# forked modules -- then you can keep modules somewhere outside of
|
||||
# the "regular" module tree.
|
||||
#
|
||||
#
|
||||
# YAML: list of strings.
|
||||
modules-search: [ local ]
|
||||
|
||||
# Instances section. This section is optional, and it defines custom instances
|
||||
# for modules of any kind. An instance entry has these keys:
|
||||
# - *module* name, which matches the module name from the module descriptor
|
||||
# (usually the name of the directory under `src/modules/`, but third-
|
||||
# party modules may diverge.
|
||||
# - *id* (optional) an identifier to distinguish this instance from
|
||||
# all the others. If none is given, the name of the module is used.
|
||||
# Together, the module and id form an instance key (see below).
|
||||
# - *config* (optional) a filename for the configuration. If none is
|
||||
# given, *module*`.conf` is used (e.g. `welcome.conf` for the welcome
|
||||
# module)
|
||||
# - *weight* (optional) In the *exec* phase of the sequence, progress
|
||||
# is reported as jobs are completed. The jobs from a single module
|
||||
# together contribute the full weight of that module. The overall
|
||||
# progress (0 .. 100%) is divided up according to the weight of each
|
||||
# module. Give modules that take a lot of time to complete, a larger
|
||||
# weight to keep the overall progress moving along steadily. This
|
||||
# weight overrides a weight given in the module descriptor. If no weight
|
||||
# is given, uses the value from the module descriptor, or 1 if there
|
||||
# isn't one there either.
|
||||
#
|
||||
# The primary goal of this mechanism is to allow loading multiple instances
|
||||
# of the same module, with different configuration. If you don't need this,
|
||||
# the instances section can safely be left empty.
|
||||
#
|
||||
# Module name plus instance name makes an instance key, e.g.
|
||||
# "packagechooserq@licenseq", where "packagechooserq" is the module name (for the packagechooserq
|
||||
# viewmodule) and "licenseq" is the instance name. In the *sequence*
|
||||
# section below, use instance-keys to name instances (instead of just
|
||||
# a module name, for modules which have only a single instance).
|
||||
#
|
||||
# Every module implicitly has an instance with the instance name equal
|
||||
# to its module name, e.g. "welcome@welcome". In the *sequence* section,
|
||||
# mentioning a module without a full instance key (e.g. "welcome")
|
||||
# means that implicit module.
|
||||
#
|
||||
# An instance may specify its configuration file (e.g. `webview-home.conf`).
|
||||
# The implicit instances all have configuration files named `<module>.conf`.
|
||||
# This (implict) way matches the source examples, where the welcome
|
||||
# module contains an example `welcome.conf`. Specify a *config* for
|
||||
# any module (also implicit instances) to change which file is used.
|
||||
#
|
||||
# For more information on running module instances, run Calamares in debug
|
||||
# mode and check the Modules page in the Debug information interface.
|
||||
#
|
||||
# A module that is often used with instances is shellprocess, which will
|
||||
# run shell commands specified in the configuration file. By configuring
|
||||
# more than one instance of the module, multiple shell sessions can be run
|
||||
# during install.
|
||||
#
|
||||
# YAML: list of maps of string:string key-value pairs.
|
||||
#instances:
|
||||
#- id: licenseq
|
||||
# module: packagechooserq
|
||||
# config: licenseq.conf
|
||||
|
||||
# Sequence section. This section describes the sequence of modules, both
|
||||
# viewmodules and jobmodules, as they should appear and/or run.
|
||||
#
|
||||
# A jobmodule instance key (or name) can only appear in an exec phase, whereas
|
||||
# a viewmodule instance key (or name) can appear in both exec and show phases.
|
||||
# There is no limit to the number of show or exec phases. However, the same
|
||||
# module instance key should not appear more than once per phase, and
|
||||
# deployers should take notice that the global storage structure is persistent
|
||||
# throughout the application lifetime, possibly influencing behavior across
|
||||
# phases. A show phase defines a sequence of viewmodules (and therefore
|
||||
# pages). These viewmodules can offer up jobs for the execution queue.
|
||||
#
|
||||
# An exec phase displays a progress page (with brandable slideshow). This
|
||||
# progress page iterates over the modules listed in the *immediately
|
||||
# preceding* show phase, and enqueues their jobs, as well as any other jobs
|
||||
# from jobmodules, in the order defined in the current exec phase.
|
||||
#
|
||||
# It then executes the job queue and clears it. If a viewmodule offers up a
|
||||
# job for execution, but the module name (or instance key) isn't listed in the
|
||||
# immediately following exec phase, this job will not be executed.
|
||||
#
|
||||
# YAML: list of lists of strings.
|
||||
sequence:
|
||||
- show:
|
||||
- welcome
|
||||
# - notesqml
|
||||
# - packagechooserq@licenseq
|
||||
- locale
|
||||
- keyboard
|
||||
- partition
|
||||
- users
|
||||
# - tracking
|
||||
- summary
|
||||
- exec:
|
||||
# - dummycpp
|
||||
# - dummyprocess
|
||||
# - dummypython
|
||||
- partition
|
||||
# - zfs
|
||||
- mount
|
||||
- unpackfs
|
||||
- machineid
|
||||
- locale
|
||||
- keyboard
|
||||
- localecfg
|
||||
# - luksbootkeyfile
|
||||
# - luksopenswaphookcfg
|
||||
# - dracutlukscfg
|
||||
- fstab
|
||||
# - plymouthcfg
|
||||
# - zfshostid
|
||||
- initcpiocfg
|
||||
- initcpio
|
||||
- users
|
||||
- displaymanager
|
||||
- networkcfg
|
||||
- hwclock
|
||||
- services-systemd
|
||||
# - dracut
|
||||
- initramfs
|
||||
# - grubcfg
|
||||
- bootloader
|
||||
- umount
|
||||
- show:
|
||||
- finished
|
||||
|
||||
# A branding component is a directory, either in SHARE/calamares/branding or
|
||||
# in /etc/calamares/branding (the latter takes precedence). The directory must
|
||||
# contain a YAML file branding.desc which may reference additional resources
|
||||
# (such as images) as paths relative to the current directory.
|
||||
#
|
||||
# A branding component can also ship a QML slideshow for execution pages,
|
||||
# along with translation files.
|
||||
#
|
||||
# Only the name of the branding component (directory) should be specified
|
||||
# here, Calamares then takes care of finding it and loading the contents.
|
||||
#
|
||||
# YAML: string.
|
||||
branding: default
|
||||
|
||||
# If this is set to true, Calamares will show an "Are you sure?" prompt right
|
||||
# before each execution phase, i.e. at points of no return. If this is set to
|
||||
# false, no prompt is shown. Default is false, but Calamares will complain if
|
||||
# this is not explicitly set.
|
||||
#
|
||||
# YAML: boolean.
|
||||
prompt-install: false
|
||||
|
||||
# If this is set to true, Calamares will execute all target environment
|
||||
# commands in the current environment, without chroot. This setting should
|
||||
# only be used when setting up Calamares as a post-install configuration tool,
|
||||
# as opposed to a full operating system installer.
|
||||
#
|
||||
# Some official Calamares modules are not expected to function with this
|
||||
# setting. (e.g. partitioning seems like a bad idea, since that is expected to
|
||||
# have been done already)
|
||||
#
|
||||
# Default is false (for a normal installer), but Calamares will complain if
|
||||
# this is not explicitly set.
|
||||
#
|
||||
# YAML: boolean.
|
||||
dont-chroot: false
|
||||
|
||||
# If this is set to true, Calamares refers to itself as a "setup program"
|
||||
# rather than an "installer". Defaults to the value of dont-chroot, but
|
||||
# Calamares will complain if this is not explicitly set.
|
||||
oem-setup: false
|
||||
|
||||
# If this is set to true, the "Cancel" button will be disabled entirely.
|
||||
# The button is also hidden from view.
|
||||
#
|
||||
# This can be useful if when e.g. Calamares is used as a post-install
|
||||
# configuration tool and you require the user to go through all the
|
||||
# configuration steps.
|
||||
#
|
||||
# Default is false, but Calamares will complain if this is not explicitly set.
|
||||
#
|
||||
# YAML: boolean.
|
||||
disable-cancel: false
|
||||
|
||||
# If this is set to true, the "Cancel" button will be disabled once
|
||||
# you start the 'Installation', meaning there won't be a way to cancel
|
||||
# the Installation until it has finished or installation has failed.
|
||||
#
|
||||
# Default is false, but Calamares will complain if this is not explicitly set.
|
||||
#
|
||||
# YAML: boolean.
|
||||
disable-cancel-during-exec: false
|
||||
|
||||
# If this is set to true, the "Next" and "Back" button will be hidden once
|
||||
# you start the 'Installation'.
|
||||
#
|
||||
# Default is false, but Calamares will complain if this is not explicitly set.
|
||||
#
|
||||
# YAML: boolean.
|
||||
hide-back-and-next-during-exec: false
|
||||
|
||||
# If this is set to true, then once the end of the sequence has
|
||||
# been reached, the quit (done) button is clicked automatically
|
||||
# and Calamares will close. Default is false: the user will see
|
||||
# that the end of installation has been reached, and that things are ok.
|
||||
#
|
||||
#
|
||||
quit-at-end: false
|
Loading…
Reference in New Issue
Block a user