Compare commits
140 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51e89e58dd | ||
|
|
d8d5a1fb26 | ||
|
|
85f05e8121 | ||
|
|
c28c9b8114 | ||
|
|
935f21ace5 | ||
|
|
6bd75570de | ||
|
|
acdcdea668 | ||
|
|
edb405a4d1 | ||
|
|
3ad9c221d4 | ||
|
|
dc3550eccd | ||
|
|
fac16ac6a7 | ||
|
|
a442ed8c12 | ||
|
|
e08d687061 | ||
|
|
15f6369537 | ||
|
|
f01b4ed2f8 | ||
|
|
ea762b0945 | ||
|
|
cae8acb4a4 | ||
|
|
ae204d0108 | ||
|
|
a2fae600c4 | ||
|
|
349acad491 | ||
|
|
9b4c4876bc | ||
|
|
cc02baed9a | ||
|
|
dfab089938 | ||
|
|
2dd9a7ba8a | ||
|
|
82f31f3cd9 | ||
|
|
c5b01a574d | ||
|
|
bc4789d57f | ||
|
|
0962b98494 | ||
|
|
108476c025 | ||
|
|
04a1bc9e2c | ||
|
|
bff5e485f4 | ||
|
|
3c838436c2 | ||
|
|
644c9cf4f3 | ||
|
|
dcaa378ddd | ||
|
|
14fd23dcef | ||
|
|
f4bc7052e0 | ||
|
|
4f0f48d99d | ||
|
|
1344880f2e | ||
|
|
5704e146a0 | ||
|
|
85eb434b57 | ||
|
|
4b2ea61aa3 | ||
|
|
39d25eef1c | ||
|
|
e82d32fe66 | ||
|
|
a50ab49c22 | ||
|
|
a66ab99ce8 | ||
|
|
c3170a9dfb | ||
|
|
88437d3612 | ||
|
|
6db52a904e | ||
|
|
8f0403a3f8 | ||
|
|
caf231b0d1 | ||
|
|
9ad86f81bb | ||
|
|
4d601f2e6a | ||
|
|
69f68d82e6 | ||
|
|
572a94e493 | ||
|
|
90454be1b9 | ||
|
|
6144404bd0 | ||
|
|
8f4d8d119c | ||
|
|
e8c870205d | ||
|
|
081d7d47d1 | ||
|
|
e92ecea3f5 | ||
|
|
e158402478 | ||
|
|
d242d077db | ||
|
|
5f9b46a820 | ||
|
|
9151d0fcee | ||
|
|
282f5bfade | ||
|
|
eeb264f32e | ||
|
|
83606aaf9d | ||
|
|
322a7a212f | ||
|
|
40c7496f85 | ||
|
|
f1fd52e790 | ||
|
|
12f6068622 | ||
|
|
16a3e2edb2 | ||
|
|
8fc9b907af | ||
|
|
ecaf2c3076 | ||
|
|
ea97927997 | ||
|
|
6795190216 | ||
|
|
51149e34d7 | ||
|
|
a2674c652d | ||
|
|
d4d6d17efe | ||
|
|
b74d77a9c5 | ||
|
|
5074bebd32 | ||
|
|
76be9988fe | ||
|
|
c85daf8f7b | ||
|
|
13e8b1e9b5 | ||
|
|
e6ddf30512 | ||
|
|
9938d11ad1 | ||
|
|
def4ee5c7e | ||
|
|
718f73c9c8 | ||
|
|
720415d8b7 | ||
|
|
0f0b9aa776 | ||
|
|
19d508ca2e | ||
|
|
7af1aeb132 | ||
|
|
3f7cabe832 | ||
|
|
341c9f4a7f | ||
|
|
03260efb3a | ||
|
|
18060db82d | ||
|
|
b978f03618 | ||
|
|
a4a6194a5d | ||
|
|
93cf06da82 | ||
|
|
901211c12d | ||
|
|
e89a58a34b | ||
|
|
fb36765982 | ||
|
|
f1d2bfacce | ||
|
|
9703bd9058 | ||
|
|
0e2a178436 | ||
|
|
fb70e29e29 | ||
|
|
fbfa9d8038 | ||
|
|
59ab728502 | ||
|
|
476224d34e | ||
|
|
2aaf440fec | ||
|
|
b416caa462 | ||
|
|
0c11b864e5 | ||
|
|
0f9ffb9e35 | ||
|
|
813d26ec4e | ||
|
|
5d44118b4b | ||
|
|
833e33f011 | ||
|
|
ea3a03a8cc | ||
|
|
05bbeae2c3 | ||
|
|
b9b923e69c | ||
|
|
ff3391f67b | ||
|
|
b60b21b680 | ||
|
|
8a533d22be | ||
|
|
6f32c18ef9 | ||
|
|
f36f21c55c | ||
|
|
bcacab531f | ||
|
|
85586293c8 | ||
|
|
e71eb01feb | ||
|
|
3eb3e9c98d | ||
|
|
2bf5706f73 | ||
|
|
809491c969 | ||
|
|
febeb3281e | ||
|
|
76885c7fe1 | ||
|
|
fad0575e4d | ||
|
|
550f7d40ef | ||
|
|
6c07d39374 | ||
|
|
4285ccebd7 | ||
|
|
320d67a5ba | ||
|
|
6a80ce6dab | ||
|
|
33678a6a16 | ||
|
|
2c91dc4664 |
@@ -8,6 +8,7 @@ AlignEscapedNewlines: DontAlign
|
||||
AllowAllParametersOfDeclarationOnNextLine: "false"
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: "false"
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: "false"
|
||||
AlwaysBreakAfterReturnType: TopLevelDefinitions
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
@@ -28,7 +29,6 @@ ReflowComments: "false"
|
||||
SortIncludes: "true"
|
||||
SpaceAfterCStyleCast: "false"
|
||||
SpacesBeforeTrailingComments: "2"
|
||||
# SpaceInEmptyBlock: "true"
|
||||
SpacesInAngles: "true"
|
||||
SpacesInParentheses: "true"
|
||||
SpacesInSquareBrackets: "true"
|
||||
|
||||
35
.clang-format.base
Normal file
35
.clang-format.base
Normal file
@@ -0,0 +1,35 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
BasedOnStyle: WebKit
|
||||
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignEscapedNewlines: DontAlign
|
||||
AllowAllParametersOfDeclarationOnNextLine: "false"
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: "false"
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: "false"
|
||||
AlwaysBreakAfterReturnType: TopLevelDefinitions
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: "false"
|
||||
BinPackParameters: "false"
|
||||
BreakBeforeBraces: Allman
|
||||
BreakBeforeTernaryOperators: "true"
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
ColumnLimit: 120
|
||||
Cpp11BracedListStyle: "false"
|
||||
FixNamespaceComments: "true"
|
||||
IncludeBlocks: Preserve
|
||||
IndentWidth: "4"
|
||||
MaxEmptyLinesToKeep: "2"
|
||||
NamespaceIndentation: None
|
||||
PointerAlignment: Left
|
||||
ReflowComments: "false"
|
||||
SortIncludes: "true"
|
||||
SpaceAfterCStyleCast: "false"
|
||||
SpacesBeforeTrailingComments: "2"
|
||||
SpacesInAngles: "true"
|
||||
SpacesInParentheses: "true"
|
||||
SpacesInSquareBrackets: "true"
|
||||
Standard: Cpp11
|
||||
74
.github/workflows/nightly-neon.yml
vendored
74
.github/workflows/nightly-neon.yml
vendored
@@ -31,70 +31,30 @@ jobs:
|
||||
path: ${{ env.BUILDDIR }}
|
||||
repo: calamares/calamares
|
||||
- name: "prepare env"
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install git-core
|
||||
sudo apt-get -y install \
|
||||
build-essential \
|
||||
cmake \
|
||||
extra-cmake-modules \
|
||||
gettext \
|
||||
kio-dev \
|
||||
libatasmart-dev \
|
||||
libboost-python-dev \
|
||||
libkf5config-dev \
|
||||
libkf5coreaddons-dev \
|
||||
libkf5i18n-dev \
|
||||
libkf5iconthemes-dev \
|
||||
libkf5parts-dev \
|
||||
libkf5service-dev \
|
||||
libkf5solid-dev \
|
||||
libkpmcore-dev \
|
||||
libparted-dev \
|
||||
libpolkit-qt5-1-dev \
|
||||
libqt5svg5-dev \
|
||||
libqt5webkit5-dev \
|
||||
libyaml-cpp-dev \
|
||||
os-prober \
|
||||
pkg-config \
|
||||
python3-dev \
|
||||
qtbase5-dev \
|
||||
qtdeclarative5-dev \
|
||||
qttools5-dev \
|
||||
qttools5-dev-tools
|
||||
uses: calamares/actions/prepare-neon@v2
|
||||
- name: "prepare source"
|
||||
uses: actions/checkout@v2
|
||||
- name: "prepare artifacts"
|
||||
run: tar xvzf "$BUILDDIR/calamares.tar.gz" -C / --strip-components 1
|
||||
- name: "prepare build"
|
||||
id: pre_build
|
||||
run: |
|
||||
test -n "$BUILDDIR" || { echo "! \$BUILDDIR not set" ; exit 1 ; }
|
||||
mkdir -p $BUILDDIR
|
||||
test -f $SRCDIR/CMakeLists.txt || { echo "! Missing $SRCDIR/CMakeLists.txt" ; exit 1 ; }
|
||||
echo "::set-output name=message::"`git log -1 --abbrev-commit --pretty=oneline --no-decorate ${{ github.event.head_commit.id }}`
|
||||
- name: "Calamares-Extensions: cmake"
|
||||
working-directory: ${{ env.BUILDDIR }}
|
||||
run: cmake $CMAKE_ARGS $SRCDIR
|
||||
- name: "Calamares-Extensions: make"
|
||||
working-directory: ${{ env.BUILDDIR }}
|
||||
run: make -j2 VERBOSE=1
|
||||
- name: "Calamares-Extensions: install"
|
||||
working-directory: ${{ env.BUILDDIR }}
|
||||
run: make install VERBOSE=1
|
||||
- name: "build"
|
||||
id: build
|
||||
uses: calamares/actions/generic-build@v2
|
||||
- name: "notify: ok"
|
||||
uses: rectalogic/notify-irc@v1
|
||||
if: ${{ success() && github.repository == 'calamares/calamares-extensions' }}
|
||||
uses: calamares/actions/matrix-notify@v2
|
||||
with:
|
||||
server: chat.freenode.net
|
||||
nickname: cala-ci
|
||||
channel: "#calamares"
|
||||
message: "OK ${{ github.workflow }} in ${{ github.repository }} ${{ steps.pre_build.outputs.message }}"
|
||||
token: ${{ secrets.MATRIX_TOKEN }}
|
||||
room: ${{ secrets.MATRIX_ROOM }}
|
||||
message: "OK ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git_summary }}"
|
||||
- name: "notify: fail"
|
||||
uses: rectalogic/notify-irc@v1
|
||||
if: ${{ failure() && github.repository == 'calamares/calamares' }}
|
||||
uses: calamares/actions/matrix-notify@v2
|
||||
with:
|
||||
server: chat.freenode.net
|
||||
nickname: cala-ci
|
||||
channel: "#calamares"
|
||||
message: "FAIL ${{ github.workflow }} in ${{ github.repository }} ${{ steps.pre_build.outputs.message }}"
|
||||
token: ${{ secrets.MATRIX_TOKEN }}
|
||||
room: ${{ secrets.MATRIX_ROOM }}
|
||||
message: "FAIL ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git_summary}}"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
76
.github/workflows/push.yml
vendored
76
.github/workflows/push.yml
vendored
@@ -37,70 +37,30 @@ jobs:
|
||||
path: ${{ env.BUILDDIR }}
|
||||
repo: calamares/calamares
|
||||
- name: "prepare env"
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install git-core
|
||||
sudo apt-get -y install \
|
||||
build-essential \
|
||||
cmake \
|
||||
extra-cmake-modules \
|
||||
gettext \
|
||||
kio-dev \
|
||||
libatasmart-dev \
|
||||
libboost-python-dev \
|
||||
libkf5config-dev \
|
||||
libkf5coreaddons-dev \
|
||||
libkf5i18n-dev \
|
||||
libkf5iconthemes-dev \
|
||||
libkf5parts-dev \
|
||||
libkf5service-dev \
|
||||
libkf5solid-dev \
|
||||
libkpmcore-dev \
|
||||
libparted-dev \
|
||||
libpolkit-qt5-1-dev \
|
||||
libqt5svg5-dev \
|
||||
libqt5webkit5-dev \
|
||||
libyaml-cpp-dev \
|
||||
os-prober \
|
||||
pkg-config \
|
||||
python3-dev \
|
||||
qtbase5-dev \
|
||||
qtdeclarative5-dev \
|
||||
qttools5-dev \
|
||||
qttools5-dev-tools
|
||||
uses: calamares/actions/prepare-neon@v2
|
||||
- name: "prepare source"
|
||||
uses: actions/checkout@v2
|
||||
- name: "prepare artifacts"
|
||||
run: tar xvzf "$BUILDDIR/calamares.tar.gz" -C / --strip-components 1
|
||||
- name: "prepare build"
|
||||
id: pre_build
|
||||
run: |
|
||||
test -n "$BUILDDIR" || { echo "! \$BUILDDIR not set" ; exit 1 ; }
|
||||
mkdir -p $BUILDDIR
|
||||
test -f $SRCDIR/CMakeLists.txt || { echo "! Missing $SRCDIR/CMakeLists.txt" ; exit 1 ; }
|
||||
echo "::set-output name=message::"`git log -1 --abbrev-commit --pretty=oneline --no-decorate ${{ github.event.head_commit.id }}`
|
||||
- name: "Calamares-Extensions: cmake"
|
||||
working-directory: ${{ env.BUILDDIR }}
|
||||
run: cmake $CMAKE_ARGS $SRCDIR
|
||||
- name: "Calamares-Extensions: make"
|
||||
working-directory: ${{ env.BUILDDIR }}
|
||||
run: make -j2 VERBOSE=1
|
||||
- name: "Calamares-Extensions: install"
|
||||
working-directory: ${{ env.BUILDDIR }}
|
||||
run: make install VERBOSE=1
|
||||
- name: "build"
|
||||
id: build
|
||||
uses: calamares/actions/generic-build@v2
|
||||
- name: "notify: ok"
|
||||
uses: rectalogic/notify-irc@v1
|
||||
if: ${{ success() && github.repository == 'calamares/calamares-extensions' }}
|
||||
uses: calamares/actions/matrix-notify@v2
|
||||
with:
|
||||
server: chat.freenode.net
|
||||
nickname: cala-ci
|
||||
channel: "#calamares"
|
||||
message: "OK ${{ github.workflow }} in ${{ github.repository }} ${{ github.actor }} on ${{ github.event.ref }}\n.. ${{ steps.pre_build.outputs.message }}"
|
||||
token: ${{ secrets.MATRIX_TOKEN }}
|
||||
room: ${{ secrets.MATRIX_ROOM }}
|
||||
message: |
|
||||
OK ${{ github.workflow }} in ${{ github.repository }} by ${{ github.actor }} on ${{ github.event.ref }}
|
||||
.. ${{ steps.build.outputs.git-summary }}
|
||||
- name: "notify: fail"
|
||||
uses: rectalogic/notify-irc@v1
|
||||
if: ${{ failure() && github.repository == 'calamares/calamares' }}
|
||||
if: ${{ failure() && github.repository == 'calamares/calamares-extensions' }}
|
||||
uses: calamares/actions/matrix-notify@v2
|
||||
with:
|
||||
server: chat.freenode.net
|
||||
nickname: cala-ci
|
||||
channel: "#calamares"
|
||||
message: "FAIL ${{ github.workflow }} in ${{ github.repository }} ${{ github.actor }} on ${{ github.event.ref }}\n.. ${{ steps.pre_build.outputs.message }}\n.. DIFF ${{ github.event.compare }}"
|
||||
token: ${{ secrets.MATRIX_TOKEN }}
|
||||
room: ${{ secrets.MATRIX_ROOM }}
|
||||
message: |
|
||||
FAIL ${{ github.workflow }} in ${{ github.repository }} by ${{ github.actor }} on ${{ github.event.ref }}
|
||||
.. ${{ steps.build.outputs.git-summary }}
|
||||
.. ${{ github.event.compare }}
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,3 +1,6 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
.kdev4/
|
||||
build/
|
||||
*.kdev4
|
||||
|
||||
23
.reuse/dep5
Normal file
23
.reuse/dep5
Normal file
@@ -0,0 +1,23 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: Calamares-Extensions
|
||||
Source: https://github.com/calamares/calamares-extensions.git
|
||||
|
||||
### BUILD ARTIFACTS / NOT SOURCE
|
||||
#
|
||||
# QRC Files are basically build artifacts
|
||||
#
|
||||
FILES: modules/*/*.qrc
|
||||
License: CC0-1.0
|
||||
Copyright: no
|
||||
|
||||
# GitHub issue templates are not part of the source
|
||||
#
|
||||
Files: .github/ISSUE_TEMPLATE/*
|
||||
License: CC0-1.0
|
||||
Copyright: no
|
||||
|
||||
# GitHub actions are not part of the source
|
||||
Files: .github/workflows/*.yml
|
||||
License: CC0-1.0
|
||||
Copyright: no
|
||||
|
||||
60
CHANGES
60
CHANGES
@@ -6,8 +6,62 @@ This is the changelog for Calamares-Extensions. For each release, the major
|
||||
changes and contributors are listed. Note that Calamares-Extensions does not
|
||||
have a historical changelog -- this log starts with version 1.0.0.
|
||||
|
||||
# 1.3.2 (2023-08-28)
|
||||
|
||||
# 1.1.1 (2021-02-23) #
|
||||
We skipped a couple of releases in the release-notes, then tagged
|
||||
1.3.1 without a version bump or release-notes. So 1.3.2 brings us
|
||||
back to "regular releases".
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
- Anke Boersma
|
||||
- Nathan Schulte
|
||||
- Oliver Smith
|
||||
- stravanpannala
|
||||
- undef
|
||||
|
||||
Changes and new modules in this release:
|
||||
- *mobile* Has new configuration options. (Thanks Nathan, Oliver)
|
||||
- *unpackfsc* Uses a more portable invocation of tar. (Thanks sravanpannala)
|
||||
|
||||
|
||||
# 1.2.1 (2021-11-16)
|
||||
|
||||
The 1.2.0 release had no release-notes for that version, and failed to
|
||||
credit Anke and Otus.
|
||||
|
||||
Changes and new modules in this release:
|
||||
- *unpackfsc* can use `fsarchiver` and unpack that, instead of squashfs;
|
||||
a distro might choose one tool or the other. Currently, only *savedir* /
|
||||
*restdir* mode (i.e. directories, not block-devices) are supported.
|
||||
|
||||
# 1.2.0 (2021-11-16)
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
- Anke Boersma
|
||||
- Otus9051
|
||||
|
||||
Changes and new modules in this release:
|
||||
- *refind* is a new module that installs the rEFInd bootloader. It can
|
||||
be used instead of the *bootloader* module from core Calamares. (Thanks Anke)
|
||||
- *unpackfsc* is a new module that uses `unsquashfs` directly. This may
|
||||
be faster or more convenient than the *unpackfs* module from core Calamares.
|
||||
The configuration file supports only one entry, but is otherwise easy to
|
||||
adapt from an existing `unpackfs.conf`.
|
||||
|
||||
|
||||
# 1.1.2 (2021-05-14)
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
- Oliver Smith
|
||||
|
||||
Changes and new modules in this release:
|
||||
- New *os-* modules are intended for OS-specific work. They don't
|
||||
do anything concrete yet, though.
|
||||
- The *mobile* module has new features thanks to Oliver, with
|
||||
keyboard selection (numeric / alpha) for PIN / password entry among them.
|
||||
|
||||
|
||||
# 1.1.1 (2021-02-23)
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
- Oliver Smith
|
||||
@@ -22,7 +76,7 @@ Changes and new modules in this release:
|
||||
- *mobile* wait screen has been re-worded.
|
||||
|
||||
|
||||
# 1.1.0 (2021-01-04) #
|
||||
# 1.1.0 (2021-01-04)
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
- Oliver Smith
|
||||
@@ -32,7 +86,7 @@ Changes and new modules in this release:
|
||||
- *mobile* module SSH daemon can be disabled
|
||||
|
||||
|
||||
# 1.0.0 (2020-12-05) #
|
||||
# 1.0.0 (2020-12-05)
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
- Oliver Smith
|
||||
|
||||
130
CMakeLists.txt
130
CMakeLists.txt
@@ -1,20 +1,15 @@
|
||||
# === 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.
|
||||
# SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#
|
||||
# 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/>.
|
||||
# Calamares-Examples is Free Software: see the License-Identifier above.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0+
|
||||
# License-Filename: LICENSE
|
||||
# Individual files may have different licenses (like the CMake
|
||||
# infrastructure, which is BSD-2-Clause licensed). Check the SPDX
|
||||
# identifiers in each file.
|
||||
#
|
||||
###
|
||||
#
|
||||
@@ -24,15 +19,85 @@
|
||||
# distro can use an unmodified (upstream) Calamares package and a local
|
||||
# customisation package in tandem.
|
||||
#
|
||||
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
|
||||
# Besides being an example repository, it is also a collection of modules
|
||||
# and branding that is usable in its own right.
|
||||
#
|
||||
### CONFIGURING
|
||||
#
|
||||
# By default, all the branding examples and all the modules are built.
|
||||
# This can be influenced through:
|
||||
# SKIP_MODULES : a space or semicolon-separated list of directory names
|
||||
# under src/modules that should not be built.
|
||||
# USE_* : fills in SKIP_MODULES for modules called *-<something>
|
||||
# In this repository, there is just one "group" to which USE_* applies:
|
||||
# USE_os : operating-system-specific modules.
|
||||
#
|
||||
# There is a knob WITH_QT6 which can be used to build against Qt6 rather
|
||||
# than Qt5. This must match what Calamares itself is built with.
|
||||
#
|
||||
### NOTES
|
||||
#
|
||||
# Call this CMake file in script mode, e.g. `cmake -P CMakeLists.txt`
|
||||
# to print out version information. Use `cmake -DVERSION_STYLE=short`
|
||||
# to get just the short versioning.
|
||||
#
|
||||
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
|
||||
|
||||
set( CALAMARES_EXTENSIONS_VERSION 3.3.1 )
|
||||
|
||||
include( ${CMAKE_CURRENT_LIST_DIR}/CMakeModules/ExtendedVersion.cmake )
|
||||
if ( CMAKE_SCRIPT_MODE_FILE )
|
||||
report_version( ${CALAMARES_EXTENSIONS_VERSION} ${CMAKE_CURRENT_LIST_DIR} )
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(calamares-extensions
|
||||
VERSION 1.1.1
|
||||
VERSION ${CALAMARES_EXTENSIONS_VERSION}
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
find_package(Calamares 3.2.26 REQUIRED)
|
||||
set( CMAKE_CXX_STANDARD 17 )
|
||||
set( CMAKE_CXX_STANDARD_REQUIRED ON )
|
||||
|
||||
# On developer's machine, the user package registry breaks
|
||||
# consumers by loading the developer's config from a build
|
||||
# directory (which doesn't have the rest of the config
|
||||
# installed inside it).
|
||||
set( CALAMARES_VERSION_REQUIRED 3.3.1 )
|
||||
find_package(Calamares ${CALAMARES_VERSION_REQUIRED} NO_CMAKE_PACKAGE_REGISTRY)
|
||||
if (NOT TARGET Calamares::calamares OR NOT TARGET Calamares::calamaresui)
|
||||
find_package(Calamares ${CALAMARES_VERSION_REQUIRED} REQUIRED)
|
||||
endif()
|
||||
|
||||
message(STATUS "Found Calamares version ${Calamares_VERSION}")
|
||||
message(STATUS " libraries ${Calamares_LIB_DIRS}")
|
||||
message(STATUS "")
|
||||
|
||||
### EXTRACTING DEPENDENCIES AND CONFIGURATION FROM CALAMARES
|
||||
#
|
||||
#
|
||||
if(WITH_QT6)
|
||||
set(kfname "KF6")
|
||||
set(KF_VERSION 5.240) # KDE Neon weirdness
|
||||
else()
|
||||
message(STATUS "Building Calamares with Qt5")
|
||||
set(kfname "KF5")
|
||||
set(KF_VERSION 5.78)
|
||||
# API that was deprecated before Qt 5.15 causes a compile error
|
||||
add_compile_definitions(QT_DISABLE_DEPRECATED_BEFORE=0x050f00)
|
||||
endif()
|
||||
|
||||
include( FeatureSummary )
|
||||
find_package(${kfname}CoreAddons ${KF_VERSION} QUIET)
|
||||
set_package_properties(
|
||||
${kfname}CoreAddons
|
||||
PROPERTIES
|
||||
TYPE REQUIRED
|
||||
DESCRIPTION "KDE Framework CoreAddons"
|
||||
URL "https://api.kde.org/frameworks/"
|
||||
PURPOSE "Essential Framework for AboutData and Macros"
|
||||
)
|
||||
|
||||
find_package(YAMLCPP REQUIRED) # Needed to untangle some dependencies before Calamares 3.2.36
|
||||
|
||||
### CMAKE SETUP
|
||||
#
|
||||
@@ -52,6 +117,7 @@ if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.10.0")
|
||||
"K_EXPORT_PLASMA_RUNNER"
|
||||
)
|
||||
endif()
|
||||
include( CTest )
|
||||
|
||||
|
||||
### BRANDING
|
||||
@@ -76,28 +142,18 @@ calamares_add_branding_subdirectory( branding/kaos_branding NAME kaos )
|
||||
#
|
||||
# Add one of more modules, either C++ or Python.
|
||||
#
|
||||
set(SKIPPED_MODULES "")
|
||||
set(LIST_SKIPPED_MODULES "")
|
||||
|
||||
calamares_add_module_subdirectory( modules/filekeeper ) # C++ job
|
||||
calamares_add_module_subdirectory( modules/freebsddisk ) # C++ viewmodule
|
||||
calamares_add_module_subdirectory( modules/mobile )
|
||||
calamares_add_module_subdirectory( modules/slowpython ) # Python job
|
||||
calamares_add_module_subdirectory( modules/freebsddisk LIST_SKIPPED_MODULES ) # C++ viewmodule
|
||||
calamares_add_module_subdirectory( modules/mobile LIST_SKIPPED_MODULES )
|
||||
calamares_add_module_subdirectory( modules/os-freebsd LIST_SKIPPED_MODULES )
|
||||
calamares_add_module_subdirectory( modules/os-nixos LIST_SKIPPED_MODULES )
|
||||
calamares_add_module_subdirectory( modules/refind LIST_SKIPPED_MODULES )
|
||||
calamares_add_module_subdirectory( modules/slowpython LIST_SKIPPED_MODULES ) # Python job
|
||||
calamares_add_module_subdirectory( modules/unpackfsc LIST_SKIPPED_MODULES )
|
||||
|
||||
message(STATUS "Calamares extensions ${CALAMARES_EXTENSIONS_VERSION} for Calamares version ${Calamares_VERSION}")
|
||||
|
||||
# If modules cannot be built, they usually call a macro
|
||||
# which builds a list of explanations; show that list.
|
||||
calamares_explain_skipped_modules( ${SKIPPED_MODULES} )
|
||||
|
||||
### RELEASE SUPPORT
|
||||
#
|
||||
#
|
||||
set( CALAMARES_VERSION ${calamares-extensions_VERSION_MAJOR}.${calamares-extensions_VERSION_MINOR}.${calamares-extensions_VERSION_PATCH} )
|
||||
# In rare cases we have hotfix-releases with a tweak
|
||||
if( calamares-extensions_VERSION_TWEAK )
|
||||
set( CALAMARES_VERSION "${calamares-extensions_VERSION}.${calamares-extensions_VERSION_TWEAK}" )
|
||||
endif()
|
||||
set( CALAMARES_VERSION_SHORT "${CALAMARES_VERSION}" )
|
||||
|
||||
add_custom_target(show-version
|
||||
${CMAKE_COMMAND} -E echo CALAMARES_VERSION=${CALAMARES_VERSION_SHORT}
|
||||
USES_TERMINAL
|
||||
)
|
||||
calamares_explain_skipped_modules( ${LIST_SKIPPED_MODULES} )
|
||||
|
||||
90
CMakeModules/ExtendedVersion.cmake
Normal file
90
CMakeModules/ExtendedVersion.cmake
Normal file
@@ -0,0 +1,90 @@
|
||||
# === This file is part of Calamares - <https://calamares.io> ===
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2014 Teo Mrnjavac <teo@kde.org>
|
||||
# SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
###
|
||||
#
|
||||
# This file defines one function for extending a VERSION-like value
|
||||
# with date and git information (if desired).
|
||||
#
|
||||
# - extend_version( version-string short_var long_var )
|
||||
# Calling this function will copy *version-string* (which would typically
|
||||
# be a semver-style string, like "3.2.40") into the variable *short_var*.
|
||||
# The *version-string* plus date and git information (if git is available),
|
||||
# is copied into the varialbe *long_var*, in the format {version}-{date}-{hash}
|
||||
#
|
||||
# A helper function that may be used independently:
|
||||
#
|
||||
# - get_git_version_info( out_var )
|
||||
# If relevant and possible (e.g. it is a git checkout and git is availablle
|
||||
# in the environment), put git versioning information in *out_var*.
|
||||
#
|
||||
# A convenience function for use from script-mode for version reporting:
|
||||
#
|
||||
# - report_version( version top_dir )
|
||||
# Call this with an intended version string (e.g. "1.1") and
|
||||
# the top-level source directory (e.g. `${CMAKE_CURRENT_LIST_DIR}`
|
||||
# or `${CMAKE_SOURCE_DIR}` .. in script mode, the latter is not defined).
|
||||
#
|
||||
|
||||
function( get_git_version_info out_var )
|
||||
set(CMAKE_VERSION_SOURCE "")
|
||||
if(EXISTS ${CMAKE_SOURCE_DIR}/.git/HEAD)
|
||||
find_program(GIT_EXECUTABLE NAMES git git.cmd)
|
||||
mark_as_advanced(GIT_EXECUTABLE)
|
||||
if(GIT_EXECUTABLE)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} rev-parse --verify -q --short=8 HEAD
|
||||
OUTPUT_VARIABLE head
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
if(head)
|
||||
set(CMAKE_VERSION_SOURCE "${head}")
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} update-index -q --refresh
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD --
|
||||
OUTPUT_VARIABLE dirty
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
if(dirty)
|
||||
set(CMAKE_VERSION_SOURCE "${CMAKE_VERSION_SOURCE}-dirty")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
set( ${out_var} "${CMAKE_VERSION_SOURCE}" PARENT_SCOPE )
|
||||
endfunction()
|
||||
|
||||
function( extend_version version short_var long_var )
|
||||
set( ${short_var} "${version}" PARENT_SCOPE )
|
||||
|
||||
# Additional info for non-release builds which want "long" version info
|
||||
# with date and git information (commit, dirty status).
|
||||
set( _v "${version}" )
|
||||
string( TIMESTAMP CALAMARES_VERSION_DATE "%Y%m%d" )
|
||||
if( CALAMARES_VERSION_DATE GREATER 0 )
|
||||
set( _v ${_v}.${CALAMARES_VERSION_DATE} )
|
||||
endif()
|
||||
get_git_version_info( _gitv )
|
||||
if( _gitv )
|
||||
set( _v "${_v}-${_gitv}" )
|
||||
endif()
|
||||
set( ${long_var} "${_v}" PARENT_SCOPE )
|
||||
endfunction()
|
||||
|
||||
function( report_version version top_dir )
|
||||
set( CMAKE_SOURCE_DIR ${top_dir} )
|
||||
extend_version( ${version} _vshort _vlong )
|
||||
if ( "x${VERSION_STYLE}" STREQUAL "xshort" )
|
||||
message( "${_vshort}" )
|
||||
else()
|
||||
message( "${_vlong}" )
|
||||
endif()
|
||||
endfunction()
|
||||
40
CONTRIBUTING.md
Normal file
40
CONTRIBUTING.md
Normal file
@@ -0,0 +1,40 @@
|
||||
<!-- SPDX-FileCopyrightText: no
|
||||
SPDX-License-Identifier: CC0-1.0
|
||||
-->
|
||||
|
||||
# Contributing to Calamares Extensions
|
||||
|
||||
Welcome to Calamares! We're happy that you would like to add
|
||||
something to Calamares -- by extending it!
|
||||
This contribution guide is minimal:
|
||||
all the **technical** parts of contributing to
|
||||
Calamares Extensions are the same as [contributing to Calamares](https://github.com/calamares/calamares/CONTRIBUTING.md).
|
||||
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
The Calamares community -- of developers, translators, and downstream (distro) users --
|
||||
aims to be courteous, professional, and inclusive. Harrassment, discriminatory
|
||||
statements and abuse are not tolerated. In general, we apply the
|
||||
[KDE Code of Conduct](https://www.kde.org/code-of-conduct/) and the
|
||||
[GNOME Code of Conduct](https://wiki.gnome.org/Foundation/CodeOfConduct) (the
|
||||
rules of decent behavior in both communities are pretty much the same).
|
||||
|
||||
> See the [CoC section on the wiki](https://github.com/calamares/calamares/wiki#code-of-conduct)
|
||||
> for a longer text. To report a problem, please contact the maintainer,
|
||||
> Adriaan de Groot, or the KDE Community Working Group.
|
||||
|
||||
|
||||
## Join the Conversation
|
||||
|
||||
GitHub Issues are **one** place for discussing Calamares and its extensions if there are concrete
|
||||
problems or a new feature to discuss.
|
||||
Issues are not a help channel.
|
||||
Visit Matrix for help with configuration or compilation.
|
||||
|
||||
Regular Calamares development chit-chat happens in a [Matrix](https://matrix.org/)
|
||||
room, `#calamares:kde.org`. Responsiveness is best during the day
|
||||
in Europe, but feel free to idle.
|
||||
Matrix is persistent, and we'll see your message eventually.
|
||||
|
||||
* [](https://webchat.kde.org/#/room/%23calamares:kde.org)
|
||||
24
LICENSES/BSD-2-Clause.txt
Normal file
24
LICENSES/BSD-2-Clause.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
Copyright 2019 Adriaan de Groot <groot@kde.org>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
119
LICENSES/CC0-1.0.txt
Normal file
119
LICENSES/CC0-1.0.txt
Normal file
@@ -0,0 +1,119 @@
|
||||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES
|
||||
NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE
|
||||
AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION
|
||||
ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE
|
||||
OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS
|
||||
LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION
|
||||
OR WORKS PROVIDED HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer exclusive
|
||||
Copyright and Related Rights (defined below) upon the creator and subsequent
|
||||
owner(s) (each and all, an "owner") of an original work of authorship and/or
|
||||
a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for the
|
||||
purpose of contributing to a commons of creative, cultural and scientific
|
||||
works ("Commons") that the public can reliably and without fear of later claims
|
||||
of infringement build upon, modify, incorporate in other works, reuse and
|
||||
redistribute as freely as possible in any form whatsoever and for any purposes,
|
||||
including without limitation commercial purposes. These owners may contribute
|
||||
to the Commons to promote the ideal of a free culture and the further production
|
||||
of creative, cultural and scientific works, or to gain reputation or greater
|
||||
distribution for their Work in part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any expectation
|
||||
of additional consideration or compensation, the person associating CC0 with
|
||||
a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
|
||||
and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
|
||||
and publicly distribute the Work under its terms, with knowledge of his or
|
||||
her Copyright and Related Rights in the Work and the meaning and intended
|
||||
legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be protected
|
||||
by copyright and related or neighboring rights ("Copyright and Related Rights").
|
||||
Copyright and Related Rights include, but are not limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display, communicate,
|
||||
and translate a Work;
|
||||
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
|
||||
iii. publicity and privacy rights pertaining to a person's image or likeness
|
||||
depicted in a Work;
|
||||
|
||||
iv. rights protecting against unfair competition in regards to a Work, subject
|
||||
to the limitations in paragraph 4(a), below;
|
||||
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal protection
|
||||
of databases, and under any national implementation thereof, including any
|
||||
amended or successor version of such directive); and
|
||||
|
||||
vii. other similar, equivalent or corresponding rights throughout the world
|
||||
based on applicable law or treaty, and any national implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention of,
|
||||
applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
|
||||
unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
|
||||
and Related Rights and associated claims and causes of action, whether now
|
||||
known or unknown (including existing as well as future claims and causes of
|
||||
action), in the Work (i) in all territories worldwide, (ii) for the maximum
|
||||
duration provided by applicable law or treaty (including future time extensions),
|
||||
(iii) in any current or future medium and for any number of copies, and (iv)
|
||||
for any purpose whatsoever, including without limitation commercial, advertising
|
||||
or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the
|
||||
benefit of each member of the public at large and to the detriment of Affirmer's
|
||||
heirs and successors, fully intending that such Waiver shall not be subject
|
||||
to revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason be
|
||||
judged legally invalid or ineffective under applicable law, then the Waiver
|
||||
shall be preserved to the maximum extent permitted taking into account Affirmer's
|
||||
express Statement of Purpose. In addition, to the extent the Waiver is so
|
||||
judged Affirmer hereby grants to each affected person a royalty-free, non
|
||||
transferable, non sublicensable, non exclusive, irrevocable and unconditional
|
||||
license to exercise Affirmer's Copyright and Related Rights in the Work (i)
|
||||
in all territories worldwide, (ii) for the maximum duration provided by applicable
|
||||
law or treaty (including future time extensions), (iii) in any current or
|
||||
future medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional purposes
|
||||
(the "License"). The License shall be deemed effective as of the date CC0
|
||||
was applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder of
|
||||
the License, and in such case Affirmer hereby affirms that he or she will
|
||||
not (i) exercise any of his or her remaining Copyright and Related Rights
|
||||
in the Work or (ii) assert any associated claims and causes of action with
|
||||
respect to the Work, in either case contrary to Affirmer's express Statement
|
||||
of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered,
|
||||
licensed or otherwise affected by this document.
|
||||
|
||||
b. Affirmer offers the Work as-is and makes no representations or warranties
|
||||
of any kind concerning the Work, express, implied, statutory or otherwise,
|
||||
including without limitation warranties of title, merchantability, fitness
|
||||
for a particular purpose, non infringement, or the absence of latent or other
|
||||
defects, accuracy, or the present or absence of errors, whether or not discoverable,
|
||||
all to the greatest extent permissible under applicable law.
|
||||
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without limitation
|
||||
any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims
|
||||
responsibility for obtaining any necessary consents, permissions or other
|
||||
rights required for any use of the Work.
|
||||
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a party
|
||||
to this document and has no duty or obligation with respect to this CC0 or
|
||||
use of the Work.
|
||||
34
README.md
34
README.md
@@ -1,3 +1,7 @@
|
||||
<!-- SPDX-FileCopyrightText: no
|
||||
SPDX-License-Identifier: CC0-1.0
|
||||
-->
|
||||
|
||||
# Calamares Branding and Module Examples
|
||||
|
||||
> A *branding component* in Calamares is a description of the
|
||||
@@ -36,7 +40,10 @@ and documentation for the framework that Calamares ships with.
|
||||
(probably moreso than the default slideshow).
|
||||
- [`kaos_branding/`](branding/kaos_branding/branding.desc)
|
||||
is a copy of the KaOS branding component, which
|
||||
has translations and a bunch of fancy graphics.
|
||||
has translations and a bunch of fancy graphics for the
|
||||
slideshow. Plus it includes examples of using different
|
||||
QML options for a vertical navigation bar and horizontal
|
||||
sidebar.
|
||||
- [`samegame/` ](branding/default/branding.desc)
|
||||
is a copy of the Qt Company "Same Game" QML demo. It
|
||||
shows that **any** QML can be used for branding purposes.
|
||||
@@ -172,9 +179,13 @@ phase).
|
||||
|
||||
- [mobile](modules/mobile/CMakeLists.txt) is a QML **view** that
|
||||
takes over a number of other view steps. It is specific to
|
||||
mobile phone use, possibly specific to PostmarketOS. It does
|
||||
a number of "welcome to your new phone" things, e.g.
|
||||
with PostmarketOS installed on a PinePhone.
|
||||
mobile phone use, and as of writing used by
|
||||
[postmarketOS](https://postmarketos.org) and
|
||||
[Mobian](https://mobian-project.org/). Among other things, it
|
||||
allows to set up full disk encryption and to configure the
|
||||
default user's password. Read the
|
||||
[on-device installer](https://wiki.postmarketos.org/wiki/On-device_installer)
|
||||
article for more information.
|
||||
|
||||
### CMake Preparation
|
||||
|
||||
@@ -203,3 +214,18 @@ usually called `main.py` which defines a `run()` function.
|
||||
|
||||
The API is loosely documented in the
|
||||
[developer guide](https://github.com/calamares/calamares/wiki/Develop-Guide).
|
||||
|
||||
# Join the Conversation
|
||||
|
||||
GitHub Issues are **one** place for discussing Calamares (and Calamares Extensions)
|
||||
if there are concrete
|
||||
problems or a new feature to discuss.
|
||||
Issues are not a help channel.
|
||||
Visit Matrix for help with configuration or compilation.
|
||||
|
||||
Regular Calamares development chit-chat happens in a [Matrix](https://matrix.org/)
|
||||
room, `#calamares:kde.org`. Responsiveness is best during the day
|
||||
in Europe, but feel free to idle.
|
||||
Matrix is persistent, and we'll see your message eventually.
|
||||
|
||||
* [](https://webchat.kde.org/#/room/%23calamares:kde.org)
|
||||
|
||||
101
branding/kaos_branding/about.qml
Normal file
101
branding/kaos_branding/about.qml
Normal file
@@ -0,0 +1,101 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2020 2022 Anke Boersma <demm@kaosx.us>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
import io.calamares.core 1.0
|
||||
import io.calamares.ui 1.0
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Window 2.3
|
||||
|
||||
ApplicationWindow {
|
||||
id: about
|
||||
visible: true
|
||||
width: 760
|
||||
height: 400
|
||||
title: qsTr("About Calamares")
|
||||
|
||||
property var appName: "Calamares"
|
||||
property var appVersion: "3.3 RC"
|
||||
|
||||
Rectangle {
|
||||
id: textArea
|
||||
anchors.fill: parent
|
||||
color: "#f2f2f2"
|
||||
|
||||
Column {
|
||||
id: column
|
||||
anchors.centerIn: parent
|
||||
|
||||
|
||||
Rectangle {
|
||||
width: 560
|
||||
height: 250
|
||||
radius: 10
|
||||
border.width: 0
|
||||
|
||||
Text {
|
||||
width: 400
|
||||
height: 250
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("<h1>%1</h1><br/>
|
||||
<strong>%2<br/>
|
||||
for %3</strong><br/><br/>
|
||||
Copyright 2014-2017 Teo Mrnjavac <teo@kde.org><br/>
|
||||
Copyright 2017-2022 Adriaan de Groot <groot@kde.org><br/>
|
||||
Thanks to <a href='https://calamares.io/team/'>the Calamares team</a>
|
||||
and the <a href=\"https://www.transifex.com/kaos/kaos/\">KaOS
|
||||
translators team</a>.<br/><br/>
|
||||
<a href='https://calamares.io/'>Calamares</a>
|
||||
development is sponsored by <br/>
|
||||
<a href='http://www.blue-systems.com/'>Blue Systems</a> -
|
||||
Liberating Software." )
|
||||
.arg(appName)
|
||||
.arg(appVersion)
|
||||
.arg(Branding.string(Branding.VersionedName))
|
||||
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
|
||||
font.pointSize: 10
|
||||
anchors.verticalCenterOffset: 10
|
||||
anchors.horizontalCenterOffset: 40
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Image {
|
||||
id: image
|
||||
x: 8
|
||||
y: 12
|
||||
height: 100
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "squid.png"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
icon.name: "window-close"
|
||||
text: qsTr("Close")
|
||||
hoverEnabled: true
|
||||
onClicked: about.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,22 +1,32 @@
|
||||
---
|
||||
componentName: kaos
|
||||
|
||||
welcomeStyleCalamares: false
|
||||
|
||||
# Should the welcome image (productWelcome, below) be scaled
|
||||
# up beyond its natural size?
|
||||
welcomeExpandingLogo: true
|
||||
|
||||
windowExpanding: normal
|
||||
windowSize: 920px,630px
|
||||
windowPlacement: center
|
||||
|
||||
sidebar: qml,bottom
|
||||
navigation: qml,right
|
||||
|
||||
strings:
|
||||
productName: KaOS
|
||||
shortProductName: KaOS
|
||||
version: 2018.03
|
||||
version: 2022.08
|
||||
shortVersion: KaOS
|
||||
versionedName: KaOS 2018.03
|
||||
versionedName: KaOS 2022.08
|
||||
shortVersionedName: KaOS 2018.03
|
||||
bootloaderEntryName: KaOS
|
||||
productUrl: https://kaosx.us/
|
||||
supportUrl: https://kaosx.us/docs/
|
||||
knownIssuesUrl: https://kaosx.us/pages/download/#known-issues
|
||||
releaseNotesUrl: https://kaosx.us/pages/release_notes
|
||||
donateUrl: https://kaosx.us/about/donors
|
||||
|
||||
images:
|
||||
productLogo: "kaos.png"
|
||||
@@ -27,6 +37,7 @@ slideshow: "show.qml"
|
||||
slideshowAPI: 1
|
||||
|
||||
style:
|
||||
sidebarBackground: "#bdc3c7"
|
||||
sidebarText: "#1F1F1F"
|
||||
sidebarTextSelect: "#3498DB"
|
||||
SidebarBackground: "#bdc3c7"
|
||||
SidebarText: "#1F1F1F"
|
||||
SidebarTextCurrent: "#3498DB"
|
||||
SidebarBackgroundCurrent: "#eff0f1"
|
||||
|
||||
224
branding/kaos_branding/calamares-navigation.qml
Normal file
224
branding/kaos_branding/calamares-navigation.qml
Normal file
@@ -0,0 +1,224 @@
|
||||
/* Sample of QML navigation.
|
||||
|
||||
SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
|
||||
SPDX-FileCopyrightText: 2021 - 2022 Anke Boersma <demm@kaosx.us>
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
|
||||
This navigation panel is for a "vertical" layout, with
|
||||
mouse areas for next and previous and it includes the logo
|
||||
plus About & Debug buttons.
|
||||
*/
|
||||
import io.calamares.ui 1.0
|
||||
import io.calamares.core 1.0
|
||||
|
||||
import QtQuick 2.3
|
||||
import QtQuick.Controls 2.10
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
Rectangle {
|
||||
id: navigationBar;
|
||||
color: Branding.styleString( Branding.SidebarBackground );
|
||||
height: parent.height;
|
||||
width:64;
|
||||
|
||||
ColumnLayout {
|
||||
id: buttonBar
|
||||
anchors.fill: parent;
|
||||
spacing: 1
|
||||
|
||||
Image {
|
||||
Layout.topMargin: 1;
|
||||
Layout.bottomMargin:parent.height / 7;
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
id: logo;
|
||||
width: 62;
|
||||
height: width; // square
|
||||
source: "file:/" + Branding.imagePath(Branding.ProductLogo);
|
||||
sourceSize.width: width;
|
||||
sourceSize.height: height;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: backArea
|
||||
Layout.fillWidth: true;
|
||||
Layout.preferredHeight: parent.height / 7;
|
||||
color: mouseBack.containsMouse ? "#e6e9ea" : "#d9dcde";
|
||||
enabled: ViewManager.backEnabled;
|
||||
visible: ViewManager.backAndNextVisible;
|
||||
|
||||
MouseArea {
|
||||
id: mouseBack
|
||||
anchors.fill: parent;
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("Back")
|
||||
color: Branding.styleString( !backArea.enabled ? Branding.SidebarBackground : (mouseBack.containsMouse ? Branding.SidebarTextCurrent : Branding.SidebarText ));
|
||||
font.pointSize : 8
|
||||
}
|
||||
Image {
|
||||
source: "pan-start-symbolic.svg"
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset : 18
|
||||
fillMode: Image.PreserveAspectFit
|
||||
height: 32
|
||||
opacity: backArea.enabled ? 1 : 0.2
|
||||
}
|
||||
|
||||
onClicked: { ViewManager.back(); }
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: nextArea
|
||||
Layout.preferredHeight: parent.height / 7;
|
||||
Layout.fillWidth: true
|
||||
color: mouseNext.containsMouse ? "#f4f5f6" : "#e6e9ea";
|
||||
enabled: ViewManager.nextEnabled;
|
||||
visible: ViewManager.backAndNextVisible;
|
||||
|
||||
MouseArea {
|
||||
id: mouseNext
|
||||
anchors.fill: parent;
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("Next")
|
||||
color: Branding.styleString( !nextArea.enabled ? Branding.SidebarBackground : (mouseNext.containsMouse ? Branding.SidebarTextCurrent : Branding.SidebarText ));
|
||||
font.pointSize : 8
|
||||
}
|
||||
Image {
|
||||
source: "pan-end-symbolic.svg"
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset : 18
|
||||
fillMode: Image.PreserveAspectFit
|
||||
height: 32
|
||||
opacity: nextArea.enabled ? 1 : 0.2
|
||||
}
|
||||
|
||||
onClicked: { ViewManager.next(); }
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: cancelArea
|
||||
height: parent.height / 7;
|
||||
Layout.fillWidth: true
|
||||
color: mouseCancel.containsMouse ? "#e6e9ea" : "#d9dcde";
|
||||
|
||||
/*
|
||||
* The ViewManager has settings -- user-controlled via the
|
||||
* branding component, and party based on program state --
|
||||
* whether the quit button should be enabled and visible.
|
||||
*
|
||||
* QML navigation *should* follow this pattern, but can also
|
||||
* add other qualifications. For instance, you may have a
|
||||
* "finished" module that handles quit in its own way, and
|
||||
* want to hide the quit button then. The ViewManager has a
|
||||
* current step and a total count, so compare them:
|
||||
*
|
||||
* visible: ViewManager.quitVisible && ( ViewManager.currentStepIndex < ViewManager.rowCount()-1);
|
||||
*/
|
||||
|
||||
enabled: ViewManager.quitEnabled;
|
||||
visible: ViewManager.quitVisible && ( ViewManager.currentStepIndex < ViewManager.rowCount()-1);
|
||||
|
||||
ToolTip {
|
||||
width: 59
|
||||
visible: mouseCancel.containsMouse
|
||||
timeout: 5000
|
||||
delay: 1000
|
||||
text: ViewManager.quitTooltip;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseCancel
|
||||
anchors.fill: parent;
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("Cancel")
|
||||
color: Branding.styleString( !cancelArea.enabled ? Branding.SidebarBackground : (mouseCancel.containsMouse ? Branding.SidebarTextCurrent : Branding.SidebarText ));
|
||||
font.pointSize : 8
|
||||
}
|
||||
Image {
|
||||
source: "draw-rectangle.svg"
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset : 18
|
||||
fillMode: Image.PreserveAspectFit
|
||||
height: 9
|
||||
opacity: cancelArea.enabled ? 1 : 0.2
|
||||
}
|
||||
|
||||
onClicked: { ViewManager.quit(); }
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: debugArea
|
||||
Layout.fillWidth: true;
|
||||
height: 35
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||
color: Branding.styleString( mouseAreaDebug.containsMouse ? Branding.SidebarBackgroundCurrent : Branding.SidebarBackground);
|
||||
visible: debug.enabled
|
||||
|
||||
MouseArea {
|
||||
id: mouseAreaDebug
|
||||
anchors.fill: parent;
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("Debug")
|
||||
color: Branding.styleString( mouseAreaDebug.containsMouse ? Branding.SidebarTextCurrent : Branding.SidebarBackground );
|
||||
font.pointSize : 8
|
||||
}
|
||||
|
||||
onClicked: debug.toggle()
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: aboutArea
|
||||
Layout.fillWidth: true;
|
||||
height: 35
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||
color: Branding.styleString( mouseAreaAbout.containsMouse ? Branding.SidebarBackgroundCurrent : Branding.SidebarBackground);
|
||||
visible: true
|
||||
|
||||
MouseArea {
|
||||
id: mouseAreaAbout
|
||||
anchors.fill: parent;
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("About")
|
||||
ToolTip {
|
||||
visible: mouseAreaAbout.containsMouse
|
||||
delay: 1000
|
||||
text: qsTr("Info about Calamares")
|
||||
}
|
||||
color: Branding.styleString( mouseAreaAbout.containsMouse ? Branding.SidebarTextCurrent : Branding.SidebarBackgroundCurrent );
|
||||
font.pointSize : 8
|
||||
}
|
||||
|
||||
property variant window;
|
||||
onClicked: {
|
||||
var component = Qt.createComponent("about.qml");
|
||||
window = component.createObject();
|
||||
window.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
72
branding/kaos_branding/calamares-sidebar.qml
Normal file
72
branding/kaos_branding/calamares-sidebar.qml
Normal file
@@ -0,0 +1,72 @@
|
||||
/* Sample of QML progress tree.
|
||||
|
||||
SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
|
||||
SPDX-FileCopyrightText: 2021 - 2022 Anke Boersma <demm@kaosx.us>
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
|
||||
The progress tree (actually a list) is "horizontal" in this example,
|
||||
with the steps going to the right.
|
||||
*/
|
||||
import io.calamares.ui 1.0
|
||||
import io.calamares.core 1.0
|
||||
|
||||
import QtQuick 2.3
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
Rectangle {
|
||||
id: sideBar;
|
||||
color: Branding.styleString( Branding.SidebarBackground );
|
||||
height: 48;
|
||||
width: parent.width
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent;
|
||||
spacing: 2;
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true;
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: ViewManager
|
||||
Rectangle {
|
||||
Layout.leftMargin: 0;
|
||||
Layout.fillWidth: true;
|
||||
Layout.alignment: Qt.AlignTop;
|
||||
height: 42;
|
||||
radius: 0;
|
||||
color: Branding.styleString( index == ViewManager.currentStepIndex ? Branding.SidebarBackgroundCurrent : Branding.SidebarBackground );
|
||||
|
||||
Text {
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
x: parent.x + 12;
|
||||
color: Branding.styleString( index == ViewManager.currentStepIndex ? Branding.SidebarTextCurrent : Branding.SidebarText );
|
||||
text: display;
|
||||
font.pointSize : index == ViewManager.currentStepIndex ? 10 : 9
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
height: 2
|
||||
width: 800
|
||||
anchors.bottom: parent.bottom;
|
||||
border.color: Branding.styleString(ViewManager.currentStepIndex === index ? Branding.SidebarTextCurrent : (ViewManager.currentStepIndex >= index ? Branding.SidebarTextCurrent : Branding.SidebarBackgroundCurrent))
|
||||
border.width: 3
|
||||
|
||||
Image {
|
||||
source: "pan-up-symbolic.svg"
|
||||
id: image
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
anchors.verticalCenterOffset : -3
|
||||
x: parent.x + 35;
|
||||
fillMode: Image.PreserveAspectFit
|
||||
height: 32
|
||||
visible: index == ViewManager.currentStepIndex ? true : false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
branding/kaos_branding/draw-rectangle.svg
Normal file
1
branding/kaos_branding/draw-rectangle.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22"><path d="m2 1034.36v16h16v-16z" fill="#566060" transform="translate(1-1031.36)"/></svg>
|
||||
|
After Width: | Height: | Size: 147 B |
@@ -1,3 +1,6 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
foreach( lang ast ca cs de en es es_AR fr hu id_ID nl_NL pl pt_BR pt_PT ro_RO ru sr_RS tr_TR zh_CN )
|
||||
list( APPEND TS_FILES "${CMAKE_CURRENT_SOURCE_DIR}/calamares-${COMPONENT_NAME}_${lang}.ts" )
|
||||
endforeach()
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 292 KiB After Width: | Height: | Size: 106 KiB |
15
branding/kaos_branding/pan-end-symbolic.svg
Normal file
15
branding/kaos_branding/pan-end-symbolic.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<svg height="16" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" version="1.1" width="16" xmlns="http://www.w3.org/2000/svg" enable-background="new">
|
||||
<metadata id="metadata90"/>
|
||||
<defs id="defs7386">
|
||||
<linearGradient id="linearGradient5606" osb:paint="solid">
|
||||
<stop id="stop5608"/>
|
||||
</linearGradient>
|
||||
<filter inkscape:collect="always" color-interpolation-filters="sRGB" id="filter7554">
|
||||
<feBlend inkscape:collect="always" id="feBlend7556" in2="BackgroundImage" mode="darken"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<g inkscape:groupmode="layer" id="layer12" inkscape:label="actions" transform="translate(-445.0002,-129)">
|
||||
<path inkscape:connector-curvature="0" d="m 451.0002,142 5,-5 -5,-5 z" id="path6412" sodipodi:nodetypes="cccc" fill="#555555"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 896 B |
15
branding/kaos_branding/pan-start-symbolic.svg
Normal file
15
branding/kaos_branding/pan-start-symbolic.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<svg height="16" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" version="1.1" width="16" xmlns="http://www.w3.org/2000/svg" enable-background="new">
|
||||
<metadata id="metadata90"/>
|
||||
<defs id="defs7386">
|
||||
<linearGradient id="linearGradient5606" osb:paint="solid">
|
||||
<stop id="stop5608"/>
|
||||
</linearGradient>
|
||||
<filter inkscape:collect="always" color-interpolation-filters="sRGB" id="filter7554">
|
||||
<feBlend inkscape:collect="always" id="feBlend7556" in2="BackgroundImage" mode="darken"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<g inkscape:groupmode="layer" id="layer12" inkscape:label="actions" transform="translate(-425.0002,-129)">
|
||||
<path inkscape:connector-curvature="0" d="m 435.0002,142 -5,-5 5,-5 z" id="path6400-8" sodipodi:nodetypes="cccc" fill="#555555"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 898 B |
15
branding/kaos_branding/pan-up-symbolic.svg
Normal file
15
branding/kaos_branding/pan-up-symbolic.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<svg height="16" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" version="1.1" width="16" xmlns="http://www.w3.org/2000/svg" enable-background="new">
|
||||
<metadata id="metadata90"/>
|
||||
<defs id="defs7386">
|
||||
<linearGradient id="linearGradient5606" osb:paint="solid">
|
||||
<stop id="stop5608"/>
|
||||
</linearGradient>
|
||||
<filter inkscape:collect="always" color-interpolation-filters="sRGB" id="filter7554">
|
||||
<feBlend inkscape:collect="always" id="feBlend7556" in2="BackgroundImage" mode="darken"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<g inkscape:groupmode="layer" id="layer12" inkscape:label="actions" transform="translate(-465.0002,-129.00001)">
|
||||
<path inkscape:connector-curvature="0" d="m 478.0002,139 -5,-5 -5,5 z" id="path6418" sodipodi:nodetypes="cccc" fill="#3498DB"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 902 B |
@@ -1,6 +1,7 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2015, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright 2015-2018, Anke Boersma <demm@kaosx.us>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -24,13 +25,12 @@ Presentation
|
||||
id: presentation
|
||||
|
||||
Timer {
|
||||
id: advanceTimer
|
||||
interval: 5000
|
||||
running: false
|
||||
repeat: true
|
||||
onTriggered: presentation.goToNextSlide()
|
||||
}
|
||||
|
||||
|
||||
Slide {
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -38,7 +38,7 @@ Presentation
|
||||
id: background
|
||||
source: "1.svg"
|
||||
anchors.fill: parent
|
||||
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: 0
|
||||
@@ -96,15 +96,15 @@ Presentation
|
||||
anchors.horizontalCenterOffset: -100
|
||||
font.pixelSize: parent.width *.015
|
||||
color: 'white'
|
||||
text: qsTr("The default Office Suite is Calligra.<br/>"+
|
||||
"LibreOffice is available in the repositories. <br/>")
|
||||
text: qsTr("The default Office Suite is LibreOffice.<br/>"+
|
||||
"Calligra is available in the repositories. <br/>")
|
||||
wrapMode: Text.WordWrap
|
||||
width: 450
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Slide {
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -120,7 +120,7 @@ Presentation
|
||||
font.pixelSize: parent.width *.015
|
||||
color: 'white'
|
||||
text: qsTr("Qt/KDE specific internet applications include the <br/>"+
|
||||
"Qupzilla web-browser and kde-telepathy for <br/>"+
|
||||
"Falkon web-browser and kde-telepathy for <br/>"+
|
||||
"chat and Instant Messaging. <br/>")
|
||||
wrapMode: Text.WordWrap
|
||||
width: 450
|
||||
@@ -128,7 +128,7 @@ Presentation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Slide {
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -150,7 +150,7 @@ Presentation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Slide {
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -172,6 +172,4 @@ Presentation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: advanceTimer.running = true
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
# NOTE: this is largely a copy of the release script for Calamares,
|
||||
# with not-applicable parts (such as translation-freeze) either
|
||||
# commented-out, or skipped with if(false).
|
||||
# NOTE: this script contains Linuxisms (in particular, expects GNU mktemp(1))
|
||||
# NOTE: this script may contain Linuxisms
|
||||
#
|
||||
# This attempts to perform the different steps of the RELEASE.md
|
||||
# document automatically. It's not tested on other machines or
|
||||
@@ -93,7 +93,7 @@ fi
|
||||
### Setup
|
||||
#
|
||||
#
|
||||
BUILDDIR=$(mktemp -d --suffix=-build --tmpdir=.)
|
||||
BUILDDIR=$(mktemp -d -p . -t build.XXXXX)
|
||||
|
||||
### Build with default compiler
|
||||
#
|
||||
@@ -140,30 +140,34 @@ fi
|
||||
### Get version number for this release
|
||||
#
|
||||
#
|
||||
V=$( cd "$BUILDDIR" && make show-version | grep ^CALAMARES_VERSION | sed s/^[A-Z_]*=// )
|
||||
V=$( cmake -DVERSION_STYLE=short -P CMakeLists.txt 2>&1 )
|
||||
test -n "$V" || { echo "Could not obtain version in $BUILDDIR ." ; exit 1 ; }
|
||||
|
||||
### Create signed tag
|
||||
#
|
||||
# This is the signing key ID associated with the GitHub account adriaandegroot,
|
||||
# which is used to create all "verified" tags in the Calamares repo.
|
||||
KEY_ID="CFDDC96F12B1915C"
|
||||
#
|
||||
KEY_ID="328D742D8807A435"
|
||||
git tag -u "$KEY_ID" -m "Release v$V" "v$V" || { echo "Could not sign tag v$V." ; exit 1 ; }
|
||||
|
||||
### Create the tarball
|
||||
#
|
||||
# Create the tarball, compute SHA256 for later reporting, and
|
||||
# sign the tarball so the signature can be uploaded separately.
|
||||
#
|
||||
TAR_V="$TARBALL_PREFIX-$V"
|
||||
TAR_FILE="$TAR_V.tar.gz"
|
||||
git archive -o "$TAR_FILE" --prefix "$TAR_V/" "v$V" || { echo "Could not create tarball." ; exit 1 ; }
|
||||
test -f "$TAR_FILE" || { echo "Tarball was not created." ; exit 1 ; }
|
||||
SHA256=$(sha256sum "$TAR_FILE" | cut -d" " -f1)
|
||||
gpg -s -u $KEY_ID --detach --armor $TAR_FILE # Sign the tarball
|
||||
|
||||
### Build the tarball
|
||||
#
|
||||
#
|
||||
D=$(date +%Y%m%d-%H%M%S)
|
||||
TMPDIR=$(mktemp -d --suffix="-calamares-$D")
|
||||
TMPDIR=$(mktemp -d -p . -t calamares.XXXXX)
|
||||
test -d "$TMPDIR" || { echo "Could not create tarball-build directory." ; exit 1 ; }
|
||||
tar xzf "$TAR_FILE" -C "$TMPDIR" || { echo "Could not unpack tarball." ; exit 1 ; }
|
||||
test -d "$TMPDIR/$TAR_V" || { echo "Tarball did not contain source directory." ; exit 1 ; }
|
||||
@@ -183,7 +187,6 @@ rm -rf "$TMPDIR" # From tarball
|
||||
cat <<EOF
|
||||
# Next steps for this release:
|
||||
git push origin v$V
|
||||
gpg -s -u $KEY_ID --detach --armor $TAR_FILE # Sign the tarball
|
||||
# Upload tarball $TAR_FILE and the signature $TAR_FILE.asc
|
||||
# Announce via https://github.com/calamares/$PROJECT_NAME/releases/new
|
||||
# SHA256: $SHA256
|
||||
|
||||
@@ -5,12 +5,7 @@
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
# Calls astyle with settings matching Calamares coding style
|
||||
# Requires astyle >= 2.04 and clang-format-7 -8 or -9
|
||||
#
|
||||
# Clang-format-10 is **not** supported, since it changes a default
|
||||
# that re-introduces a space into empty function bodies; this
|
||||
# can be turned off with a style setting, but that breaks
|
||||
# older format versions which don't recognize the setting.
|
||||
# Requires astyle >= 2.04 and clang-format-8 or later
|
||||
#
|
||||
# You can pass in directory names, in which case the files
|
||||
# in that directory (NOT below it) are processed.
|
||||
@@ -20,9 +15,16 @@ LC_ALL=C
|
||||
LC_NUMERIC=C
|
||||
export LANG LC_ALL LC_NUMERIC
|
||||
|
||||
BASEDIR=$(dirname $0)
|
||||
TOPDIR=$( cd $BASEDIR/.. && pwd -P )
|
||||
test -d "$BASEDIR" || { echo "! Could not determine base for $0" ; exit 1 ; }
|
||||
test -d "$TOPDIR" || { echo "! Cound not determine top-level source dir" ; exit 1 ; }
|
||||
test -f "$TOPDIR/.clang-format.base" || { echo "! No .clang-format support files in $TOPDIR" ; exit 1 ; }
|
||||
|
||||
AS=$( which astyle )
|
||||
|
||||
CF_VERSIONS="clang-format-7 clang-format-8 clang-format70 clang-format80 clang-format90 clang-format-9.0.1 clang-format"
|
||||
# Allow specifying CF_VERSIONS outside already
|
||||
CF_VERSIONS="$CF_VERSIONS clang-format-8 clang-format80 clang-format90 clang-format-9.0.1 clang-format"
|
||||
for _cf in $CF_VERSIONS
|
||||
do
|
||||
# Not an error if this particular clang-format isn't found
|
||||
@@ -35,14 +37,39 @@ test -n "$CF" || { echo "! No clang-format ($CF_VERSIONS) found in PATH"; exit 1
|
||||
test -x "$AS" || { echo "! $AS is not executable."; exit 1 ; }
|
||||
test -x "$CF" || { echo "! $CF is not executable."; exit 1 ; }
|
||||
|
||||
unmangle_clang_format=""
|
||||
if expr `"$CF" --version | tr -dc '[^.0-9]' | cut -d . -f 1` '<' 10 > /dev/null ; then
|
||||
:
|
||||
else
|
||||
unmangle_clang_format=$( dirname $0 )/../.clang-format
|
||||
echo "SpaceInEmptyBlock: false" >> "$unmangle_clang_format"
|
||||
fi
|
||||
### CLANG-FORMAT-WRANGLING
|
||||
#
|
||||
# Version 7 and earlier doesn't understand all the options we would like
|
||||
# Version 8 is ok
|
||||
# Version 9 is ok
|
||||
# Later versions change some defaults so need extra wrangling.
|
||||
# .. there are extra files that are appended to the settings, per
|
||||
# .. clang-format version.
|
||||
|
||||
format_version=`"$CF" --version | tr -dc '[^.0-9]' | cut -d . -f 1`
|
||||
case "$format_version" in
|
||||
[0-7] )
|
||||
echo "! Clang-format version 8+ required"
|
||||
exit 1
|
||||
;;
|
||||
[89] )
|
||||
:
|
||||
;;
|
||||
* )
|
||||
echo "! Clang-format version '$format_version' unsupported."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
_fmt="$TOPDIR/.clang-format"
|
||||
cp "$_fmt.base" "$_fmt"
|
||||
for f in "$extra_settings" ; do
|
||||
test -f "$_fmt.$f" && cat "$_fmt.$f" >> "$_fmt"
|
||||
done
|
||||
|
||||
|
||||
### FILE PROCESSING
|
||||
#
|
||||
#
|
||||
set -e
|
||||
|
||||
any_dirs=no
|
||||
@@ -54,7 +81,7 @@ done
|
||||
style_some()
|
||||
{
|
||||
if test -n "$*" ; then
|
||||
$AS --options=$(dirname $0)/astylerc --quiet "$@"
|
||||
$AS --options=$BASEDIR/astylerc --quiet "$@"
|
||||
$CF -i -style=file "$@"
|
||||
fi
|
||||
}
|
||||
@@ -72,6 +99,7 @@ else
|
||||
style_some "$@"
|
||||
fi
|
||||
|
||||
if test -n "$unmangle_clang_format" ; then
|
||||
sed -i.bak '/^SpaceInEmptyBlock/d' "$unmangle_clang_format"
|
||||
fi
|
||||
### CLANG-FORMAT-WRANGLING
|
||||
#
|
||||
# Restore the original .clang-format
|
||||
cp "$_fmt.base" "$_fmt"
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# The FileKeeper plugin preserves files from the live system
|
||||
# to the target system. It is particularly suited for copying
|
||||
# the log file(s) for post-installation or post-mortem examination.
|
||||
|
||||
calamares_add_plugin( filekeeper
|
||||
TYPE job
|
||||
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||
SOURCES
|
||||
FileKeeper.cpp
|
||||
SHARED_LIB
|
||||
)
|
||||
@@ -1,58 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2018, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "FileKeeper.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QProcess>
|
||||
#include <QThread>
|
||||
|
||||
#include <GlobalStorage.h>
|
||||
#include <JobQueue.h>
|
||||
|
||||
#include <utils/Logger.h>
|
||||
|
||||
FileKeeperJob::FileKeeperJob( QObject* parent )
|
||||
: Calamares::CppJob( parent )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FileKeeperJob::~FileKeeperJob() {}
|
||||
|
||||
|
||||
QString
|
||||
FileKeeperJob::prettyName() const
|
||||
{
|
||||
return tr( "File keeper Job" );
|
||||
}
|
||||
|
||||
Calamares::JobResult
|
||||
FileKeeperJob::exec()
|
||||
{
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FileKeeperJob::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
{
|
||||
Q_UNUSED( configurationMap );
|
||||
}
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( FileKeeperJobFactory, registerPlugin< FileKeeperJob >(); )
|
||||
@@ -1,46 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2018, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef FILEKEEPER_H
|
||||
#define FILEKEEPER_H
|
||||
|
||||
#include <CppJob.h>
|
||||
#include <DllMacro.h>
|
||||
#include <utils/PluginFactory.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariantMap>
|
||||
|
||||
class PLUGINDLLEXPORT FileKeeperJob : public Calamares::CppJob
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FileKeeperJob( QObject* parent = nullptr );
|
||||
virtual ~FileKeeperJob() override;
|
||||
|
||||
QString prettyName() const override;
|
||||
|
||||
Calamares::JobResult exec() override;
|
||||
|
||||
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
||||
};
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( FileKeeperJobFactory )
|
||||
|
||||
#endif
|
||||
@@ -1,3 +1,6 @@
|
||||
# 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()
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# 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.
|
||||
|
||||
@@ -6,13 +6,9 @@ calamares_add_plugin( mobile
|
||||
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||
SOURCES
|
||||
Config.cpp
|
||||
Config.h
|
||||
MobileQmlViewStep.cpp
|
||||
MobileQmlViewStep.h
|
||||
PartitionJob.cpp
|
||||
PartitionJob.h
|
||||
UsersJob.cpp
|
||||
UsersJob.h
|
||||
RESOURCES
|
||||
mobile.qrc
|
||||
SHARED_LIB
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "UsersJob.h"
|
||||
|
||||
#include "ViewManager.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Variant.h"
|
||||
|
||||
#include <QVariant>
|
||||
@@ -17,14 +18,29 @@ Config::Config( QObject* parent )
|
||||
void
|
||||
Config::setConfigurationMap( const QVariantMap& cfgMap )
|
||||
{
|
||||
using namespace CalamaresUtils;
|
||||
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 );
|
||||
@@ -45,6 +61,8 @@ Config::setConfigurationMap( const QVariantMap& cfgMap )
|
||||
|
||||
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" );
|
||||
@@ -59,6 +77,7 @@ Config::createJobs()
|
||||
/* 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,
|
||||
@@ -123,6 +142,13 @@ Config::runPartitionJobThenLeave( bool b )
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Config::setUsername( const QString& username )
|
||||
{
|
||||
m_username = username;
|
||||
emit usernameChanged( m_username );
|
||||
}
|
||||
|
||||
void
|
||||
Config::setUserPassword( const QString& userPassword )
|
||||
{
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
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 )
|
||||
@@ -17,9 +20,13 @@ class Config : public QObject
|
||||
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 CONSTANT FINAL )
|
||||
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 )
|
||||
@@ -58,6 +65,9 @@ public:
|
||||
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; }
|
||||
@@ -65,12 +75,17 @@ public:
|
||||
QString userInterface() const { return m_userInterface; }
|
||||
QString version() const { return m_version; }
|
||||
|
||||
/* default user */
|
||||
/* 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 + credetials */
|
||||
/* ssh server + credentials */
|
||||
bool featureSshd() { return m_featureSshd; }
|
||||
QString sshdUsername() const { return m_sshdUsername; }
|
||||
QString sshdPassword() const { return m_sshdPassword; }
|
||||
@@ -112,11 +127,15 @@ public:
|
||||
|
||||
/* 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;
|
||||
@@ -124,26 +143,30 @@ private:
|
||||
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 + credetials */
|
||||
bool m_featureSshd;
|
||||
/* ssh server + credentials */
|
||||
bool m_featureSshd = false;
|
||||
QString m_sshdUsername;
|
||||
QString m_sshdPassword;
|
||||
bool m_isSshEnabled;
|
||||
bool m_isSshEnabled = false;
|
||||
|
||||
/* full disk encryption */
|
||||
QString m_fdePassword = "";
|
||||
QString m_fdePassword;
|
||||
bool m_isFdeEnabled = false;
|
||||
|
||||
/* filesystem selection */
|
||||
bool m_featureFsType;
|
||||
bool m_featureFsType = false;
|
||||
QString m_defaultFs;
|
||||
QString m_fsType;
|
||||
// Index of the currently selected filesystem in UI.
|
||||
int m_fsIndex;
|
||||
int m_fsIndex = -1;
|
||||
QStringList m_fsList;
|
||||
|
||||
/* partition job */
|
||||
@@ -160,6 +183,7 @@ private:
|
||||
|
||||
/* users job */
|
||||
QString m_cmdPasswd;
|
||||
QString m_cmdUsermod;
|
||||
QString m_cmdSshdEnable;
|
||||
QString m_cmdSshdDisable;
|
||||
QString m_cmdSshdUseradd;
|
||||
@@ -169,6 +193,7 @@ signals:
|
||||
|
||||
/* default user */
|
||||
void userPasswordChanged( QString userPassword );
|
||||
void usernameChanged( QString username );
|
||||
|
||||
/* ssh server + credentials */
|
||||
void sshdUsernameChanged( QString sshdUsername );
|
||||
|
||||
@@ -2,16 +2,14 @@
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
#include "MobileQmlViewStep.h"
|
||||
|
||||
#include "Branding.h"
|
||||
#include "GlobalStorage.h"
|
||||
|
||||
#include "locale/LabelModel.h"
|
||||
#include "locale/TranslationsModel.h"
|
||||
#include "modulesystem/ModuleManager.h"
|
||||
#include "utils/Dirs.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Variant.h"
|
||||
|
||||
#include "Branding.h"
|
||||
#include "modulesystem/ModuleManager.h"
|
||||
|
||||
#include <QProcess>
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( MobileQmlViewStepFactory, registerPlugin< MobileQmlViewStep >(); )
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
#include "Settings.h"
|
||||
#include "utils/CalamaresUtilsSystem.h"
|
||||
#include "utils/System.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QDir>
|
||||
@@ -75,7 +75,7 @@ Calamares::JobResult
|
||||
PartitionJob::exec()
|
||||
{
|
||||
using namespace Calamares;
|
||||
using namespace CalamaresUtils;
|
||||
using namespace Calamares;
|
||||
using namespace std;
|
||||
|
||||
const QString pathMount = "/mnt/install";
|
||||
@@ -118,7 +118,7 @@ PartitionJob::exec()
|
||||
const QString pathRoot = "/";
|
||||
|
||||
ProcessResult res
|
||||
= System::runCommand( System::RunLocation::RunInHost, args, pathRoot, stdInput, chrono::seconds( 120 ) );
|
||||
= System::runCommand( System::RunLocation::RunInHost, args, pathRoot, stdInput, chrono::seconds( 600 ) );
|
||||
if ( res.getExitCode() )
|
||||
{
|
||||
return JobResult::error( "Command failed:<br><br>"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
#include "Settings.h"
|
||||
#include "utils/CalamaresUtilsSystem.h"
|
||||
#include "utils/System.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QDir>
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
UsersJob::UsersJob( bool featureSshd,
|
||||
const QString& cmdPasswd,
|
||||
const QString& cmdUsermod,
|
||||
const QString& cmdSshd,
|
||||
const QString& cmdSshdUseradd,
|
||||
bool isSshEnabled,
|
||||
@@ -24,6 +25,7 @@ UsersJob::UsersJob( bool featureSshd,
|
||||
: Calamares::Job()
|
||||
, m_featureSshd( featureSshd )
|
||||
, m_cmdPasswd( cmdPasswd )
|
||||
, m_cmdUsermod( cmdUsermod )
|
||||
, m_cmdSshd( cmdSshd )
|
||||
, m_cmdSshdUseradd( cmdSshdUseradd )
|
||||
, m_isSshEnabled( isSshEnabled )
|
||||
@@ -45,13 +47,15 @@ Calamares::JobResult
|
||||
UsersJob::exec()
|
||||
{
|
||||
using namespace Calamares;
|
||||
using namespace CalamaresUtils;
|
||||
using namespace Calamares;
|
||||
using namespace std;
|
||||
|
||||
QList< QPair< QStringList, QString > > commands = {
|
||||
{ { "sh", "-c", m_cmdPasswd + " " + m_username }, m_password + "\n" + m_password + "\n" },
|
||||
{ { "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() } );
|
||||
|
||||
@@ -10,6 +10,7 @@ class UsersJob : public Calamares::Job
|
||||
public:
|
||||
UsersJob( bool featureSshd,
|
||||
const QString& cmdPasswd,
|
||||
const QString& cmdUsermod,
|
||||
const QString& cmdSshd,
|
||||
const QString& cmdSshdUseradd,
|
||||
bool isSshEnabled,
|
||||
@@ -26,6 +27,7 @@ public:
|
||||
private:
|
||||
bool m_featureSshd;
|
||||
QString m_cmdPasswd;
|
||||
QString m_cmdUsermod;
|
||||
QString m_cmdSshd;
|
||||
QString m_cmdSshdUseradd;
|
||||
bool m_isSshEnabled;
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
/* 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: description
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 30
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
text: "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."
|
||||
|
||||
width: 500
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: userPin
|
||||
anchors.top: description.bottom
|
||||
placeholderText: qsTr("PIN")
|
||||
echoMode: TextInput.Password
|
||||
onTextChanged: validatePin(userPin, userPinRepeat, errorText)
|
||||
text: config.userPassword
|
||||
|
||||
/* Let the virtual keyboard change to digits only */
|
||||
inputMethodHints: Qt.ImhDigitsOnly
|
||||
onActiveFocusChanged: {
|
||||
if(activeFocus) {
|
||||
Qt.inputMethod.update(Qt.ImQueryInput)
|
||||
}
|
||||
}
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: 50
|
||||
width: 500
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: userPinRepeat
|
||||
anchors.top: userPin.bottom
|
||||
placeholderText: qsTr("PIN (repeat)")
|
||||
inputMethodHints: Qt.ImhDigitsOnly
|
||||
echoMode: TextInput.Password
|
||||
onTextChanged: validatePin(userPin, userPinRepeat, errorText)
|
||||
text: config.userPassword
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: 50
|
||||
width: 500
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.top: userPinRepeat.bottom
|
||||
id: errorText
|
||||
visible: false
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: 50
|
||||
width: 500
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: errorText.bottom
|
||||
anchors.topMargin: 40
|
||||
width: 500
|
||||
|
||||
text: qsTr("Continue")
|
||||
onClicked: {
|
||||
if (validatePin(userPin, userPinRepeat, errorText)) {
|
||||
config.userPassword = userPin.text;
|
||||
navNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ Item {
|
||||
id: mainText
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 30
|
||||
anchors.topMargin: 10
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
text: "To protect your data in case your device gets stolen," +
|
||||
@@ -33,15 +33,15 @@ Item {
|
||||
" boot your device or access any data on it. Make sure that" +
|
||||
" you don't lose this password!"
|
||||
|
||||
width: 500
|
||||
width: 200
|
||||
}
|
||||
|
||||
Button {
|
||||
id: firstButton
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: mainText.bottom
|
||||
anchors.topMargin: 40
|
||||
width: 500
|
||||
anchors.topMargin: 10
|
||||
width: 200
|
||||
|
||||
text: qsTr("Enable")
|
||||
onClicked: {
|
||||
@@ -53,8 +53,8 @@ Item {
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: firstButton.bottom
|
||||
anchors.topMargin: 40
|
||||
width: 500
|
||||
anchors.topMargin: 10
|
||||
width: 200
|
||||
|
||||
text: qsTr("Disable")
|
||||
onClicked: {
|
||||
|
||||
@@ -36,7 +36,7 @@ Item {
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: 50
|
||||
width: 500
|
||||
width: 200
|
||||
}
|
||||
|
||||
TextField {
|
||||
@@ -49,8 +49,8 @@ Item {
|
||||
text: config.fdePassword
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: 50
|
||||
width: 500
|
||||
anchors.topMargin: 10
|
||||
width: 200
|
||||
}
|
||||
|
||||
Text {
|
||||
@@ -59,15 +59,15 @@ Item {
|
||||
visible: false
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: 50
|
||||
width: 500
|
||||
anchors.topMargin: 10
|
||||
width: 200
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: errorText.bottom
|
||||
anchors.topMargin: 40
|
||||
width: 500
|
||||
anchors.topMargin: 10
|
||||
width: 200
|
||||
|
||||
text: qsTr("Continue")
|
||||
onClicked: {
|
||||
|
||||
@@ -22,21 +22,21 @@ Item {
|
||||
id: mainText
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 30
|
||||
anchors.topMargin: 10
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
text: "Select the filesystem for root partition. If unsure, leave the default."
|
||||
|
||||
width: 500
|
||||
width: 200
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: fsTypeCB
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: mainText.bottom
|
||||
anchors.topMargin: 40
|
||||
width: 500
|
||||
height: 60
|
||||
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 */
|
||||
@@ -47,8 +47,8 @@ Item {
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: fsTypeCB.bottom
|
||||
anchors.topMargin: 40
|
||||
width: 500
|
||||
anchors.topMargin: 10
|
||||
width: 200
|
||||
|
||||
text: qsTr("Continue")
|
||||
onClicked: {
|
||||
|
||||
@@ -22,13 +22,13 @@ Item {
|
||||
id: mainText
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 30
|
||||
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><br>";
|
||||
" device until it is done.<br>";
|
||||
|
||||
if (config.installFromExternalToInternal) {
|
||||
ret += "<b>After the installation, your device will shutdown" +
|
||||
@@ -44,15 +44,15 @@ Item {
|
||||
return ret;
|
||||
}())
|
||||
|
||||
width: 500
|
||||
width: 200
|
||||
}
|
||||
|
||||
Button {
|
||||
id: firstButton
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: mainText.bottom
|
||||
anchors.topMargin: 40
|
||||
width: 500
|
||||
anchors.topMargin: 10
|
||||
width: 200
|
||||
|
||||
text: qsTr("Install")
|
||||
onClicked: navFinish()
|
||||
|
||||
@@ -22,7 +22,7 @@ Item {
|
||||
id: mainText
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 30
|
||||
anchors.topMargin: 10
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
text: "The installation was started from an external storage medium." +
|
||||
@@ -32,15 +32,15 @@ Item {
|
||||
"<br>" +
|
||||
"Where would you like to install " + config.osName + "?"
|
||||
|
||||
width: 500
|
||||
width: 200
|
||||
}
|
||||
|
||||
Button {
|
||||
id: firstButton
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: mainText.bottom
|
||||
anchors.topMargin: 40
|
||||
width: 500
|
||||
anchors.topMargin: 10
|
||||
width: 200
|
||||
|
||||
text: qsTr("Internal (eMMC)")
|
||||
onClicked: {
|
||||
@@ -52,8 +52,8 @@ Item {
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: firstButton.bottom
|
||||
anchors.topMargin: 40
|
||||
width: 500
|
||||
anchors.topMargin: 10
|
||||
width: 200
|
||||
|
||||
text: qsTr("External (SD card)")
|
||||
onClicked: {
|
||||
|
||||
@@ -22,21 +22,21 @@ Item {
|
||||
id: mainText
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 30
|
||||
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: 500
|
||||
width: 200
|
||||
}
|
||||
|
||||
Button {
|
||||
id: firstButton
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: mainText.bottom
|
||||
anchors.topMargin: 40
|
||||
width: 500
|
||||
anchors.topMargin: 10
|
||||
width: 200
|
||||
|
||||
text: qsTr("Yes")
|
||||
onClicked: {
|
||||
@@ -47,8 +47,8 @@ Item {
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: firstButton.bottom
|
||||
anchors.topMargin: 40
|
||||
width: 500
|
||||
anchors.topMargin: 10
|
||||
width: 200
|
||||
|
||||
text: qsTr("No")
|
||||
onClicked: {
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
# 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
|
||||
#######
|
||||
@@ -11,12 +18,53 @@
|
||||
## 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
|
||||
#######
|
||||
@@ -64,6 +112,10 @@
|
||||
## 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
|
||||
#######
|
||||
@@ -103,6 +155,10 @@
|
||||
### 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
|
||||
|
||||
@@ -19,7 +19,7 @@ Page
|
||||
"welcome": null, /* titlebar disabled */
|
||||
"install_target": "Installation target",
|
||||
"install_target_confirm": "Warning",
|
||||
"default_pin": "Lockscreen PIN",
|
||||
"user_pass": "User password",
|
||||
"ssh_confirm": "SSH server",
|
||||
"ssh_credentials": "SSH credentials",
|
||||
"fs_selection": "Root filesystem",
|
||||
@@ -33,8 +33,8 @@ Page
|
||||
"screens": ["welcome"]},
|
||||
{"name": "installTarget",
|
||||
"screens": ["install_target", "install_target_confirm"]},
|
||||
{"name": "userPin",
|
||||
"screens": ["default_pin"]},
|
||||
{"name": "userPassword",
|
||||
"screens": ["user_pass"]},
|
||||
{"name": "sshd",
|
||||
"screens": ["ssh_confirm", "ssh_credentials"]},
|
||||
{"name": "fsType",
|
||||
@@ -46,7 +46,7 @@ Page
|
||||
]
|
||||
property var featureIdByScreen: (function() {
|
||||
/* Put "features" above into an index of screen name -> feature id:
|
||||
* featureIdByScreen = {"welcome": 0, "default_pin": 1, ...} */
|
||||
* 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++) {
|
||||
@@ -55,8 +55,8 @@ Page
|
||||
}
|
||||
return ret;
|
||||
}())
|
||||
/* Only allow characters, that can be typed in with the initramfs on-screen keyboard
|
||||
* (osk-sdl: see src/keyboard.cpp). FIXME: make configurable, but keep this as default? */
|
||||
/* 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" +
|
||||
@@ -77,7 +77,7 @@ Page
|
||||
Rectangle {
|
||||
id: mobileNavigation
|
||||
width: parent.width
|
||||
height: 60
|
||||
height: 30
|
||||
color: "#e6e4e1"
|
||||
Layout.fillWidth: true
|
||||
|
||||
@@ -98,8 +98,8 @@ Page
|
||||
text: "<"
|
||||
|
||||
background: Rectangle {
|
||||
implicitWidth: 32
|
||||
implicitHeight: 30
|
||||
implicitWidth: 10
|
||||
implicitHeight: 7
|
||||
border.color: "#c1bab5"
|
||||
border.width: 1
|
||||
radius: 4
|
||||
@@ -109,7 +109,7 @@ Page
|
||||
onClicked: navBack()
|
||||
}
|
||||
Rectangle {
|
||||
implicitHeight: 30
|
||||
implicitHeight: 10
|
||||
Layout.fillWidth: true
|
||||
color: "#e6e4e1"
|
||||
|
||||
@@ -142,6 +142,7 @@ Page
|
||||
InputPanel {
|
||||
id: inputPanel
|
||||
y: Qt.inputMethod.visible ? parent.height - inputPanel.height : parent.height
|
||||
visible: config.builtinVirtualKeyboard
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
}
|
||||
@@ -183,10 +184,10 @@ Page
|
||||
timer.start();
|
||||
}
|
||||
function navNextFeature() {
|
||||
var id = featureIdByScreen[screen] + 1;
|
||||
var id;
|
||||
|
||||
/* Skip disabled features */
|
||||
do {
|
||||
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);
|
||||
@@ -195,7 +196,6 @@ Page
|
||||
var configOption = "feature" + nameUp;
|
||||
if (config[configOption] === false) {
|
||||
console.log("Skipping feature (disabled in config): " + name);
|
||||
id += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -204,10 +204,11 @@ Page
|
||||
if (eval("typeof " + funcName) === "function"
|
||||
&& eval(funcName + "()")) {
|
||||
console.log("Skipping feature (skip function): " + name);
|
||||
id += 1;
|
||||
continue;
|
||||
}
|
||||
} while(false);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
console.log("Navigating to feature: " + features[id]["name"]);
|
||||
return navTo(features[id]["screens"][0]);
|
||||
@@ -252,7 +253,7 @@ Page
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Input validation: user-screens (default_pin, ssh_credentials) */
|
||||
/* Input validation: user-screens (fde_pass, user_pass, ssh_credentials) */
|
||||
function validatePin(userPin, userPinRepeat, errorText) {
|
||||
var pin = userPin.text;
|
||||
var repeat = userPinRepeat.text;
|
||||
@@ -277,47 +278,12 @@ Page
|
||||
|
||||
return validationFailureClear(errorText);
|
||||
}
|
||||
function validateSshdUsername(username, errorText) {
|
||||
function validateUsername(username, errorText, extraReservedUsernames = []) {
|
||||
var name = username.text;
|
||||
var reserved = [ /* FIXME: make configurable */
|
||||
config.username,
|
||||
"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",
|
||||
]
|
||||
var reserved = config.reservedUsernames.concat(extraReservedUsernames);
|
||||
|
||||
/* Validate characters */
|
||||
for (var i=0; i<name.length; i++) {
|
||||
for (var i = 0; i < name.length; i++) {
|
||||
if (i) {
|
||||
if (!name[i].match(/^[a-z0-9_-]$/))
|
||||
return validationFailure(errorText,
|
||||
@@ -334,16 +300,20 @@ Page
|
||||
}
|
||||
|
||||
/* Validate against reserved usernames */
|
||||
for (var i=0;i<reserved.length;i++) {
|
||||
for (var i = 0; i < reserved.length; i++) {
|
||||
if (name == reserved[i])
|
||||
return validationFailure(errorText, "Username '" +
|
||||
reserved[i] +
|
||||
"' is reserved.")
|
||||
"' 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;
|
||||
@@ -351,10 +321,10 @@ Page
|
||||
if (pass == "")
|
||||
return validationFailure(errorText);
|
||||
|
||||
if (pass.length < 8)
|
||||
if (pass.length < 6)
|
||||
return validationFailure(errorText,
|
||||
"Too short: needs at least 8" +
|
||||
" characters.");
|
||||
"Too short: needs at least 6" +
|
||||
" digits/characters.");
|
||||
|
||||
if (repeat == "")
|
||||
return validationFailure(errorText);
|
||||
@@ -364,8 +334,6 @@ Page
|
||||
|
||||
return validationFailureClear(errorText);
|
||||
}
|
||||
|
||||
/* Input validation: fde_pass */
|
||||
function check_chars(input) {
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
if (allowed_chars.indexOf(input[i]) == -1)
|
||||
@@ -388,18 +356,28 @@ Page
|
||||
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 cannot be" +
|
||||
" typed in at boot time:\n" +
|
||||
" these characters, others can possibly" +
|
||||
" not be typed in after installation:\n" +
|
||||
"\n" +
|
||||
allowed_chars_multiline());
|
||||
|
||||
if (pass.length < 8)
|
||||
if (pass.length < 6)
|
||||
return validationFailure(errorText,
|
||||
"Too short: needs at least 8" +
|
||||
" characters.");
|
||||
"Too short: needs at least 6" +
|
||||
" digits/characters.");
|
||||
|
||||
if (repeat == "")
|
||||
return validationFailure(errorText);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<file>install_target.qml</file> <!-- install from external to internal? -->
|
||||
<file>install_target_confirm.qml</file> <!-- overwrite internal storage? -->
|
||||
|
||||
<file>default_pin.qml</file> <!-- default user: pin -->
|
||||
<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 -->
|
||||
|
||||
@@ -36,7 +36,7 @@ Item {
|
||||
"More information:<br>" +
|
||||
"https://postmarketos.org/ssh"
|
||||
|
||||
width: 500
|
||||
width: 200
|
||||
}
|
||||
|
||||
Button {
|
||||
@@ -44,7 +44,7 @@ Item {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: mainText.bottom
|
||||
anchors.topMargin: 40
|
||||
width: 500
|
||||
width: 200
|
||||
|
||||
text: qsTr("Enable")
|
||||
onClicked: {
|
||||
@@ -57,7 +57,7 @@ Item {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: firstButton.bottom
|
||||
anchors.topMargin: 40
|
||||
width: 500
|
||||
width: 200
|
||||
|
||||
text: qsTr("Disable")
|
||||
onClicked: {
|
||||
|
||||
@@ -34,7 +34,7 @@ Item {
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: 50
|
||||
width: 500
|
||||
width: 200
|
||||
}
|
||||
|
||||
Text {
|
||||
@@ -45,7 +45,7 @@ Item {
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: 50
|
||||
width: 500
|
||||
width: 200
|
||||
}
|
||||
|
||||
TextField {
|
||||
@@ -59,7 +59,7 @@ Item {
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: 50
|
||||
width: 500
|
||||
width: 200
|
||||
}
|
||||
|
||||
TextField {
|
||||
@@ -73,7 +73,7 @@ Item {
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: 50
|
||||
width: 500
|
||||
width: 200
|
||||
}
|
||||
|
||||
Text {
|
||||
@@ -84,13 +84,13 @@ Item {
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: 50
|
||||
width: 500
|
||||
width: 200
|
||||
}
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: errorTextPassword.bottom
|
||||
anchors.topMargin: 40
|
||||
width: 500
|
||||
width: 200
|
||||
|
||||
text: qsTr("Continue")
|
||||
onClicked: {
|
||||
|
||||
143
modules/mobile/user_pass.qml
Normal file
143
modules/mobile/user_pass.qml
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,8 +26,8 @@ Page
|
||||
id: logo
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 50
|
||||
height: 250
|
||||
anchors.topMargin: 10
|
||||
height: 50
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "file:///usr/share/calamares/branding/default-mobile/logo.png"
|
||||
}
|
||||
@@ -35,11 +35,11 @@ Page
|
||||
id: waitText
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: logo.bottom
|
||||
anchors.topMargin: 150
|
||||
anchors.topMargin: 50
|
||||
wrapMode: Text.WordWrap
|
||||
text: "Formatting and mounting target partition. This may" +
|
||||
" take up to two minutes, please be patient."
|
||||
width: 500
|
||||
" take up to ten minutes, please be patient."
|
||||
width: 200
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ Page
|
||||
id: logo
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 50
|
||||
height: 250
|
||||
anchors.topMargin: 10
|
||||
height: 50
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "file:///usr/share/calamares/branding/default-mobile/logo.png"
|
||||
}
|
||||
@@ -37,7 +37,7 @@ Page
|
||||
id: mainText
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: logo.bottom
|
||||
anchors.topMargin: 50
|
||||
anchors.topMargin: 10
|
||||
horizontalAlignment: Text.AlignRight
|
||||
text: "You are about to install<br>" +
|
||||
"<b>" + config.osName +
|
||||
@@ -46,16 +46,16 @@ Page
|
||||
"<b>" + config.userInterface + "</b><br>" +
|
||||
"architecture " +
|
||||
"<b>" + config.arch + "</b><br>" +
|
||||
"on your " +
|
||||
"on your <br>" +
|
||||
"<b>" + config.device + "</b><br>"
|
||||
width: 500
|
||||
width: 200
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: mainText.bottom
|
||||
anchors.topMargin: 50
|
||||
width: 500
|
||||
anchors.topMargin: 10
|
||||
width: 200
|
||||
|
||||
text: qsTr("Continue")
|
||||
onClicked: navNext()
|
||||
|
||||
20
modules/os-freebsd/CMakeLists.txt
Normal file
20
modules/os-freebsd/CMakeLists.txt
Normal 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
|
||||
)
|
||||
58
modules/os-freebsd/FreeBSDJob.cpp
Normal file
58
modules/os-freebsd/FreeBSDJob.cpp
Normal 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 >(); )
|
||||
39
modules/os-freebsd/FreeBSDJob.h
Normal file
39
modules/os-freebsd/FreeBSDJob.h
Normal 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
|
||||
276
modules/os-nixos/main.py
Normal file
276
modules/os-nixos/main.py
Normal 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. It‘s 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
|
||||
11
modules/os-nixos/module.desc
Normal file
11
modules/os-nixos/module.desc
Normal 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"
|
||||
6
modules/os-nixos/tests/1.global
Normal file
6
modules/os-nixos/tests/1.global
Normal file
@@ -0,0 +1,6 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
hostname: my-nix-host
|
||||
locationRegion: Asia
|
||||
locationZone: Kolkata
|
||||
130
modules/refind/main.py
Normal file
130
modules/refind/main.py
Normal 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()
|
||||
11
modules/refind/module.desc
Normal file
11
modules/refind/module.desc
Normal 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" ]
|
||||
12
modules/refind/refind.conf.in
Normal file
12
modules/refind/refind.conf.in
Normal 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"
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# 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.
|
||||
---
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# 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
|
||||
|
||||
15
modules/unpackfsc/CMakeLists.txt
Normal file
15
modules/unpackfsc/CMakeLists.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
# SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
calamares_add_plugin( unpackfsc
|
||||
TYPE job
|
||||
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||
SOURCES
|
||||
UnpackFSCJob.cpp
|
||||
# The workers for differently-packed filesystems
|
||||
Runners.cpp
|
||||
FSArchiverRunner.cpp
|
||||
TarballRunner.cpp
|
||||
UnsquashRunner.cpp
|
||||
SHARED_LIB
|
||||
)
|
||||
117
modules/unpackfsc/FSArchiverRunner.cpp
Normal file
117
modules/unpackfsc/FSArchiverRunner.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FSArchiverRunner.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Runner.h>
|
||||
|
||||
#include <QProcess>
|
||||
|
||||
static constexpr const int chunk_size = 137;
|
||||
static const QString&
|
||||
toolName()
|
||||
{
|
||||
static const QString name = QStringLiteral( "fsarchiver" );
|
||||
return name;
|
||||
}
|
||||
|
||||
void
|
||||
FSArchiverRunner::fsarchiverProgress( QString line )
|
||||
{
|
||||
m_since++;
|
||||
// Typical line of output is this:
|
||||
// -[00][ 99%][REGFILEM] /boot/thing
|
||||
// 5 9 ^21
|
||||
if ( m_since >= chunk_size && line.length() > 21 && line[ 5 ] == '[' && line[ 9 ] == '%' )
|
||||
{
|
||||
m_since = 0;
|
||||
double p = double( line.mid( 6, 3 ).toInt() ) / 100.0;
|
||||
const QString filename = line.mid( 22 );
|
||||
Q_EMIT progress( p, filename );
|
||||
}
|
||||
}
|
||||
|
||||
Calamares::JobResult
|
||||
FSArchiverRunner::checkPrerequisites( QString& fsarchiverExecutable ) const
|
||||
{
|
||||
if ( !checkToolExists( toolName(), fsarchiverExecutable ) )
|
||||
{
|
||||
return Calamares::JobResult::internalError(
|
||||
tr( "Missing tools" ),
|
||||
tr( "The <i>%1</i> tool is not installed on the system." ).arg( toolName() ),
|
||||
Calamares::JobResult::MissingRequirements );
|
||||
}
|
||||
|
||||
if ( !checkSourceExists() )
|
||||
{
|
||||
return Calamares::JobResult::internalError(
|
||||
tr( "Invalid fsarchiver configuration" ),
|
||||
tr( "The source archive <i>%1</i> does not exist." ).arg( m_source ),
|
||||
Calamares::JobResult::InvalidConfiguration );
|
||||
}
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
Calamares::JobResult
|
||||
FSArchiverRunner::checkDestination( QString& destinationPath ) const
|
||||
{
|
||||
destinationPath = Calamares::System::instance()->targetPath( m_destination );
|
||||
if ( destinationPath.isEmpty() )
|
||||
{
|
||||
return Calamares::JobResult::internalError(
|
||||
tr( "Invalid fsarchiver configuration" ),
|
||||
tr( "No destination could be found for <i>%1</i>." ).arg( m_destination ),
|
||||
Calamares::JobResult::InvalidConfiguration );
|
||||
}
|
||||
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
Calamares::JobResult
|
||||
FSArchiverDirRunner::run()
|
||||
{
|
||||
QString fsarchiverExecutable;
|
||||
if ( auto res = checkPrerequisites( fsarchiverExecutable ); !res )
|
||||
{
|
||||
return res;
|
||||
}
|
||||
QString destinationPath;
|
||||
if ( auto res = checkDestination( destinationPath ); !res )
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
Calamares::Utils::Runner r(
|
||||
{ fsarchiverExecutable, QStringLiteral( "-v" ), QStringLiteral( "restdir" ), m_source, destinationPath } );
|
||||
r.setLocation( Calamares::Utils::RunLocation::RunInHost ).enableOutputProcessing();
|
||||
connect( &r, &decltype( r )::output, this, &FSArchiverDirRunner::fsarchiverProgress );
|
||||
return r.run().explainProcess( toolName(), std::chrono::seconds( 0 ) );
|
||||
}
|
||||
|
||||
Calamares::JobResult
|
||||
FSArchiverFSRunner::run()
|
||||
{
|
||||
QString fsarchiverExecutable;
|
||||
if ( auto res = checkPrerequisites( fsarchiverExecutable ); !res )
|
||||
{
|
||||
return res;
|
||||
}
|
||||
QString destinationPath;
|
||||
if ( auto res = checkDestination( destinationPath ); !res )
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
Calamares::Utils::Runner r(
|
||||
{ fsarchiverExecutable, QStringLiteral( "-v" ), QStringLiteral( "restfs" ), m_source, destinationPath } );
|
||||
r.setLocation( Calamares::Utils::RunLocation::RunInHost ).enableOutputProcessing();
|
||||
connect( &r, &decltype( r )::output, this, &FSArchiverFSRunner::fsarchiverProgress );
|
||||
return r.run().explainProcess( toolName(), std::chrono::seconds( 0 ) );
|
||||
}
|
||||
59
modules/unpackfsc/FSArchiverRunner.h
Normal file
59
modules/unpackfsc/FSArchiverRunner.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UNPACKFSC_FSARCHIVERRUNNER_H
|
||||
#define UNPACKFSC_FSARCHIVERRUNNER_H
|
||||
|
||||
#include "Runners.h"
|
||||
|
||||
/** @brief Base class for runners of FSArchiver
|
||||
*
|
||||
*/
|
||||
class FSArchiverRunner : public Runner
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using Runner::Runner;
|
||||
|
||||
protected Q_SLOTS:
|
||||
void fsarchiverProgress( QString line );
|
||||
|
||||
protected:
|
||||
/** @brief Checks prerequisites, sets full path of fsarchiver in @p executable
|
||||
*/
|
||||
Calamares::JobResult checkPrerequisites( QString& executable ) const;
|
||||
Calamares::JobResult checkDestination( QString& destinationPath ) const;
|
||||
|
||||
int m_since = 0;
|
||||
};
|
||||
|
||||
/** @brief Running FSArchiver in **dir** mode
|
||||
*
|
||||
*/
|
||||
class FSArchiverDirRunner : public FSArchiverRunner
|
||||
{
|
||||
public:
|
||||
using FSArchiverRunner::FSArchiverRunner;
|
||||
|
||||
Calamares::JobResult run() override;
|
||||
};
|
||||
|
||||
/** @brief Running FSArchiver in **dir** mode
|
||||
*
|
||||
*/
|
||||
class FSArchiverFSRunner : public FSArchiverRunner
|
||||
{
|
||||
public:
|
||||
using FSArchiverRunner::FSArchiverRunner;
|
||||
|
||||
Calamares::JobResult run() override;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
38
modules/unpackfsc/Runners.cpp
Normal file
38
modules/unpackfsc/Runners.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Runners.h"
|
||||
|
||||
#include <utils/System.h>
|
||||
#include <utils/Logger.h>
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QStandardPaths>
|
||||
|
||||
Runner::Runner( const QString& source, const QString& destination )
|
||||
: m_source( source )
|
||||
, m_destination( destination )
|
||||
{
|
||||
}
|
||||
|
||||
Runner::~Runner() { }
|
||||
|
||||
bool
|
||||
Runner::checkSourceExists() const
|
||||
{
|
||||
QFileInfo fi( m_source );
|
||||
return fi.exists() && fi.isReadable();
|
||||
}
|
||||
|
||||
bool
|
||||
Runner::checkToolExists( const QString& toolName, QString& fullPath )
|
||||
{
|
||||
fullPath = QStandardPaths::findExecutable( toolName );
|
||||
return !fullPath.isEmpty();
|
||||
}
|
||||
48
modules/unpackfsc/Runners.h
Normal file
48
modules/unpackfsc/Runners.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UNPACKFSC_RUNNERS_H
|
||||
#define UNPACKFSC_RUNNERS_H
|
||||
|
||||
#include <Job.h>
|
||||
|
||||
class Runner : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Runner( const QString& source, const QString& destination );
|
||||
~Runner() override;
|
||||
|
||||
virtual Calamares::JobResult run() = 0;
|
||||
|
||||
/** @brief Check that the (configured) source file exists.
|
||||
*
|
||||
* Returns @c true if it's a file and readable.
|
||||
*/
|
||||
bool checkSourceExists() const;
|
||||
|
||||
/** @brief Check that a named tool (executable) exists in the search path.
|
||||
*
|
||||
* Returns @c true if the tool is found and sets @p fullPath
|
||||
* to the full path of that tool; returns @c false and clears
|
||||
* @p fullPath otherwise.
|
||||
*/
|
||||
static bool checkToolExists( const QString& toolName, QString& fullPath );
|
||||
|
||||
Q_SIGNALS:
|
||||
// See Calamares Job::progress
|
||||
void progress( qreal percent, const QString& message );
|
||||
|
||||
protected:
|
||||
QString m_source;
|
||||
QString m_destination;
|
||||
};
|
||||
|
||||
#endif
|
||||
86
modules/unpackfsc/TarballRunner.cpp
Normal file
86
modules/unpackfsc/TarballRunner.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "TarballRunner.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Runner.h>
|
||||
#include <utils/String.h>
|
||||
|
||||
#include <QString>
|
||||
|
||||
static constexpr const int chunk_size = 107;
|
||||
|
||||
Calamares::JobResult
|
||||
TarballRunner::run()
|
||||
{
|
||||
if ( !checkSourceExists() )
|
||||
{
|
||||
return Calamares::JobResult::internalError(
|
||||
tr( "Invalid tarball configuration" ),
|
||||
tr( "The source archive <i>%1</i> does not exist." ).arg( m_source ),
|
||||
Calamares::JobResult::InvalidConfiguration );
|
||||
}
|
||||
|
||||
const QString toolName = QStringLiteral( "tar" );
|
||||
QString tarExecutable;
|
||||
if ( !checkToolExists( toolName, tarExecutable ) )
|
||||
{
|
||||
return Calamares::JobResult::internalError(
|
||||
tr( "Missing tools" ),
|
||||
tr( "The <i>%1</i> tool is not installed on the system." ).arg( toolName ),
|
||||
Calamares::JobResult::MissingRequirements );
|
||||
}
|
||||
|
||||
const QString destinationPath = Calamares::System::instance()->targetPath( m_destination );
|
||||
if ( destinationPath.isEmpty() )
|
||||
{
|
||||
return Calamares::JobResult::internalError(
|
||||
tr( "Invalid tarball configuration" ),
|
||||
tr( "No destination could be found for <i>%1</i>." ).arg( m_destination ),
|
||||
Calamares::JobResult::InvalidConfiguration );
|
||||
}
|
||||
|
||||
// Get the stats (number of inodes) from the FS
|
||||
{
|
||||
m_total = 0;
|
||||
Calamares::Utils::Runner r( { tarExecutable, QStringLiteral( "-tf" ), m_source } );
|
||||
r.setLocation( Calamares::Utils::RunLocation::RunInHost ).enableOutputProcessing();
|
||||
QObject::connect( &r, &decltype( r )::output, [ & ]( QString line ) { m_total++; } );
|
||||
/* ignored */ r.run();
|
||||
}
|
||||
if ( m_total <= 0 )
|
||||
{
|
||||
cWarning() << "No stats could be obtained from" << tarExecutable << "-tf" << m_source;
|
||||
}
|
||||
|
||||
// Now do the actual unpack
|
||||
{
|
||||
m_processed = 0;
|
||||
m_since = 0;
|
||||
Calamares::Utils::Runner r(
|
||||
{ tarExecutable, QStringLiteral( "-xpvf" ), m_source, QStringLiteral( "-C" ), destinationPath } );
|
||||
r.setLocation( Calamares::Utils::RunLocation::RunInHost ).enableOutputProcessing();
|
||||
connect( &r, &decltype( r )::output, this, &TarballRunner::tarballProgress );
|
||||
return r.run().explainProcess( toolName, std::chrono::seconds( 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TarballRunner::tarballProgress( QString line )
|
||||
{
|
||||
m_processed++;
|
||||
m_since++;
|
||||
if ( m_since > chunk_size )
|
||||
{
|
||||
m_since = 0;
|
||||
double p = m_total > 0 ? ( double( m_processed ) / double( m_total ) ) : 0.5;
|
||||
Q_EMIT progress( p, tr( "Tarball extract file %1" ).arg( line ) );
|
||||
}
|
||||
}
|
||||
35
modules/unpackfsc/TarballRunner.h
Normal file
35
modules/unpackfsc/TarballRunner.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UNPACKFSC_TARBALLRUNNER_H
|
||||
#define UNPACKFSC_TARBALLRUNNER_H
|
||||
|
||||
#include "Runners.h"
|
||||
|
||||
/** @brief Use (GNU) tar for extracting a filesystem
|
||||
*
|
||||
*/
|
||||
class TarballRunner : public Runner
|
||||
{
|
||||
public:
|
||||
using Runner::Runner;
|
||||
|
||||
Calamares::JobResult run() override;
|
||||
|
||||
protected Q_SLOTS:
|
||||
void tarballProgress( QString line );
|
||||
|
||||
private:
|
||||
// Progress reporting
|
||||
int m_total = 0;
|
||||
int m_processed = 0;
|
||||
int m_since = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
130
modules/unpackfsc/UnpackFSCJob.cpp
Normal file
130
modules/unpackfsc/UnpackFSCJob.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "UnpackFSCJob.h"
|
||||
|
||||
#include "FSArchiverRunner.h"
|
||||
#include "TarballRunner.h"
|
||||
#include "UnsquashRunner.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/NamedEnum.h>
|
||||
#include <utils/RAII.h>
|
||||
#include <utils/Variant.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
static const NamedEnumTable< UnpackFSCJob::Type >
|
||||
typeNames()
|
||||
{
|
||||
using T = UnpackFSCJob::Type;
|
||||
// clang-format off
|
||||
static const NamedEnumTable< T > names
|
||||
{
|
||||
{ "none", T::None },
|
||||
{ "fsarchiver", T::FSArchive },
|
||||
{ "fsarchive", T::FSArchive },
|
||||
{ "fsa", T::FSArchive },
|
||||
{ "fsa-dir", T::FSArchive },
|
||||
{ "fsa-block", T::FSArchiveFS },
|
||||
{ "fsa-fs", T::FSArchiveFS },
|
||||
{ "squashfs", T::Squashfs },
|
||||
{ "squash", T::Squashfs },
|
||||
{ "unsquash", T::Squashfs },
|
||||
{ "tar", T::Tarball },
|
||||
{ "tarball", T::Tarball },
|
||||
{ "tgz", T::Tarball },
|
||||
};
|
||||
// clang-format on
|
||||
return names;
|
||||
}
|
||||
|
||||
UnpackFSCJob::UnpackFSCJob( QObject* parent )
|
||||
: Calamares::CppJob( parent )
|
||||
{
|
||||
}
|
||||
|
||||
UnpackFSCJob::~UnpackFSCJob() { }
|
||||
|
||||
QString
|
||||
UnpackFSCJob::prettyName() const
|
||||
{
|
||||
return tr( "Unpack filesystems" );
|
||||
}
|
||||
|
||||
QString
|
||||
UnpackFSCJob::prettyStatusMessage() const
|
||||
{
|
||||
return m_progressMessage;
|
||||
}
|
||||
Calamares::JobResult
|
||||
UnpackFSCJob::exec()
|
||||
{
|
||||
cScopedAssignment messageClearer( &m_progressMessage, QString() );
|
||||
std::unique_ptr< Runner > r;
|
||||
switch ( m_type )
|
||||
{
|
||||
case Type::FSArchive:
|
||||
r = std::make_unique< FSArchiverDirRunner >( m_source, m_destination );
|
||||
break;
|
||||
case Type::FSArchiveFS:
|
||||
r = std::make_unique< FSArchiverFSRunner >( m_source, m_destination );
|
||||
break;
|
||||
case Type::Squashfs:
|
||||
r = std::make_unique< UnsquashRunner >( m_source, m_destination );
|
||||
break;
|
||||
case Type::Tarball:
|
||||
r = std::make_unique< TarballRunner >( m_source, m_destination );
|
||||
break;
|
||||
case Type::None:
|
||||
default:
|
||||
cDebug() << "Nothing to do.";
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
connect( r.get(),
|
||||
&Runner::progress,
|
||||
[ = ]( qreal percent, const QString& message )
|
||||
{
|
||||
m_progressMessage = message;
|
||||
Q_EMIT progress( percent );
|
||||
} );
|
||||
return r->run();
|
||||
}
|
||||
|
||||
void
|
||||
UnpackFSCJob::setConfigurationMap( const QVariantMap& map )
|
||||
{
|
||||
QString source = Calamares::getString( map, "source" );
|
||||
QString sourceTypeName = Calamares::getString( map, "sourcefs" );
|
||||
if ( source.isEmpty() || sourceTypeName.isEmpty() )
|
||||
{
|
||||
cWarning() << "Skipping item with bad source data:" << map;
|
||||
return;
|
||||
}
|
||||
bool bogus = false;
|
||||
Type sourceType = typeNames().find( sourceTypeName, bogus );
|
||||
if ( sourceType == Type::None )
|
||||
{
|
||||
cWarning() << "Skipping item with source type None";
|
||||
return;
|
||||
}
|
||||
QString destination = Calamares::getString( map, "destination" );
|
||||
if ( destination.isEmpty() )
|
||||
{
|
||||
cWarning() << "Skipping item with empty destination";
|
||||
return;
|
||||
}
|
||||
|
||||
m_source = source;
|
||||
m_destination = destination;
|
||||
m_type = sourceType;
|
||||
}
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( UnpackFSCFactory, registerPlugin< UnpackFSCJob >(); )
|
||||
50
modules/unpackfsc/UnpackFSCJob.h
Normal file
50
modules/unpackfsc/UnpackFSCJob.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UNPACKFSC_UNPACKFSCJOB_H
|
||||
#define UNPACKFSC_UNPACKFSCJOB_H
|
||||
|
||||
#include <CppJob.h>
|
||||
#include <DllMacro.h>
|
||||
#include <utils/PluginFactory.h>
|
||||
|
||||
class PLUGINDLLEXPORT UnpackFSCJob : public Calamares::CppJob
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class Type
|
||||
{
|
||||
None, /// << Invalid
|
||||
FSArchive,
|
||||
FSArchiveFS,
|
||||
Squashfs,
|
||||
Tarball,
|
||||
};
|
||||
|
||||
explicit UnpackFSCJob( QObject* parent = nullptr );
|
||||
~UnpackFSCJob() override;
|
||||
|
||||
QString prettyName() const override;
|
||||
QString prettyStatusMessage() const override;
|
||||
|
||||
Calamares::JobResult exec() override;
|
||||
|
||||
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
||||
|
||||
private:
|
||||
QString m_source;
|
||||
QString m_destination;
|
||||
Type m_type = Type::None;
|
||||
QString m_progressMessage;
|
||||
};
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( UnpackFSCFactory )
|
||||
|
||||
#endif
|
||||
101
modules/unpackfsc/UnsquashRunner.cpp
Normal file
101
modules/unpackfsc/UnsquashRunner.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "UnsquashRunner.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Runner.h>
|
||||
#include <utils/String.h>
|
||||
|
||||
#include <QString>
|
||||
|
||||
static constexpr const int chunk_size = 107;
|
||||
|
||||
Calamares::JobResult
|
||||
UnsquashRunner::run()
|
||||
{
|
||||
if ( !checkSourceExists() )
|
||||
{
|
||||
return Calamares::JobResult::internalError(
|
||||
tr( "Invalid unsquash configuration" ),
|
||||
tr( "The source archive <i>%1</i> does not exist." ).arg( m_source ),
|
||||
Calamares::JobResult::InvalidConfiguration );
|
||||
}
|
||||
|
||||
const QString toolName = QStringLiteral( "unsquashfs" );
|
||||
QString unsquashExecutable;
|
||||
if ( !checkToolExists( toolName, unsquashExecutable ) )
|
||||
{
|
||||
return Calamares::JobResult::internalError(
|
||||
tr( "Missing tools" ),
|
||||
tr( "The <i>%1</i> tool is not installed on the system." ).arg( toolName ),
|
||||
Calamares::JobResult::MissingRequirements );
|
||||
}
|
||||
|
||||
const QString destinationPath = Calamares::System::instance()->targetPath( m_destination );
|
||||
if ( destinationPath.isEmpty() )
|
||||
{
|
||||
return Calamares::JobResult::internalError(
|
||||
tr( "Invalid unsquash configuration" ),
|
||||
tr( "No destination could be found for <i>%1</i>." ).arg( m_destination ),
|
||||
Calamares::JobResult::InvalidConfiguration );
|
||||
}
|
||||
|
||||
// Get the stats (number of inodes) from the FS
|
||||
{
|
||||
m_inodes = -1;
|
||||
Calamares::Utils::Runner r( { unsquashExecutable, QStringLiteral( "-s" ), m_source } );
|
||||
r.setLocation( Calamares::Utils::RunLocation::RunInHost ).enableOutputProcessing();
|
||||
QObject::connect( &r,
|
||||
&decltype( r )::output,
|
||||
[ & ]( QString line )
|
||||
{
|
||||
if ( line.startsWith( "Number of inodes " ) )
|
||||
{
|
||||
m_inodes = line.split( ' ', SplitSkipEmptyParts ).last().toInt();
|
||||
}
|
||||
} );
|
||||
/* ignored */ r.run();
|
||||
}
|
||||
if ( m_inodes <= 0 )
|
||||
{
|
||||
cWarning() << "No stats could be obtained from" << unsquashExecutable << "-s";
|
||||
}
|
||||
|
||||
// Now do the actual unpack
|
||||
{
|
||||
m_processed = 0;
|
||||
Calamares::Utils::Runner r( { unsquashExecutable,
|
||||
QStringLiteral( "-i" ), // List files
|
||||
QStringLiteral( "-f" ), // Force-overwrite
|
||||
QStringLiteral( "-d" ),
|
||||
destinationPath,
|
||||
m_source } );
|
||||
r.setLocation( Calamares::Utils::RunLocation::RunInHost ).enableOutputProcessing();
|
||||
connect( &r, &decltype( r )::output, this, &UnsquashRunner::unsquashProgress );
|
||||
return r.run().explainProcess( toolName, std::chrono::seconds( 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UnsquashRunner::unsquashProgress( QString line )
|
||||
{
|
||||
m_processed++;
|
||||
m_since++;
|
||||
if ( m_since > chunk_size && line.contains( '/' ) )
|
||||
{
|
||||
const QString filename = line.split( '/', SplitSkipEmptyParts ).last().trimmed();
|
||||
if ( !filename.isEmpty() )
|
||||
{
|
||||
m_since = 0;
|
||||
double p = m_inodes > 0 ? ( double( m_processed ) / double( m_inodes ) ) : 0.5;
|
||||
Q_EMIT progress( p, tr( "Unsquash file %1" ).arg( filename ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
36
modules/unpackfsc/UnsquashRunner.h
Normal file
36
modules/unpackfsc/UnsquashRunner.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UNPACKFSC_UNSQUASHRUNNER_H
|
||||
#define UNPACKFSC_UNSQUASHRUNNER_H
|
||||
|
||||
#include "Runners.h"
|
||||
|
||||
/** @brief Use Unsquash for extracting a filesystem
|
||||
*
|
||||
*/
|
||||
class UnsquashRunner : public Runner
|
||||
{
|
||||
public:
|
||||
using Runner::Runner;
|
||||
|
||||
Calamares::JobResult run() override;
|
||||
|
||||
protected Q_SLOTS:
|
||||
void unsquashProgress( QString line );
|
||||
|
||||
private:
|
||||
int m_inodes = 0; // Total in the FS
|
||||
|
||||
// Progress reporting
|
||||
int m_processed = 0;
|
||||
int m_since = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
2
modules/unpackfsc/tests/1.global
Normal file
2
modules/unpackfsc/tests/1.global
Normal file
@@ -0,0 +1,2 @@
|
||||
---
|
||||
rootMountPoint: /tmp/fstest
|
||||
4
modules/unpackfsc/tests/1.job
Normal file
4
modules/unpackfsc/tests/1.job
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
source: /tmp/src.fsa
|
||||
sourcefs: fsarchive
|
||||
destination: "/calasrc"
|
||||
39
modules/unpackfsc/unpackfsc.conf
Normal file
39
modules/unpackfsc/unpackfsc.conf
Normal file
@@ -0,0 +1,39 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# Unpack a filesystem. Supported ways to "pack" the filesystem are:
|
||||
# - fsarchiver in *savedir/restdir* mode (directories, not block devices)
|
||||
# - squashfs
|
||||
#
|
||||
# Configuration:
|
||||
#
|
||||
# from globalstorage: rootMountPoint
|
||||
# from job configuration: the item to unpack
|
||||
#
|
||||
|
||||
---
|
||||
# This module is configured a lot like the items in the *unpackfs*
|
||||
# module, but with only **one** item. Use multiple instances for
|
||||
# unpacking more than one filesystem.
|
||||
#
|
||||
# There are the following **mandatory** keys:
|
||||
# - *source* path relative to the live / intstalling system to the image
|
||||
# - *sourcefs* the type of the source files; valid entries are
|
||||
# - `none` (this entry is ignored; kind of useless)
|
||||
# - `fsarchiver`
|
||||
# Aliases of this are `fsarchive`, `fsa` and `fsa-dir`. Uses
|
||||
# fsarchiver in "restdir" mode.
|
||||
# - `fsarchiver-block`
|
||||
# Aliases of this are `fsa-block` and `fsa-fs`. Uses fsarchiver
|
||||
# in "restfs" mode.
|
||||
# - `squashfs`
|
||||
# Aliases of this are `squash` and `unsquash`.
|
||||
# - `tar`
|
||||
# - *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.
|
||||
#
|
||||
source: /data/rootfs.fsa
|
||||
sourcefs: fsarchiver
|
||||
destination: "/"
|
||||
19
modules/unpackfsc/unpackfsc.schema.yaml
Normal file
19
modules/unpackfsc/unpackfsc.schema.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
# 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/unpackfsc
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
unpack:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
properties:
|
||||
source: { type: string }
|
||||
sourcefs: { type: string }
|
||||
destination: { type: string }
|
||||
weight: { type: integer, exclusiveMinimum: 0 }
|
||||
required: [ source , sourcefs, destination ]
|
||||
Reference in New Issue
Block a user