Compare commits
	
		
			137 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 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 | ||
|   | b3cda8d7cb | ||
|   | 4611f2f9ea | ||
|   | 7acd4bb3d6 | ||
|   | 41b4b59a5e | ||
|   | 077320dc19 | ||
|   | c5eeeb7a50 | ||
|   | 52882df5ee | ||
|   | 616e51b3ee | ||
|   | f2e59e611f | ||
|   | a532b309b7 | ||
|   | 45ae6084d8 | ||
|   | e0cd044e5b | ||
|   | 2c1cbb7f85 | ||
|   | bf5e3d857a | ||
|   | e78bd936a3 | ||
|   | a53f9359f4 | ||
|   | 3a525359a5 | ||
|   | 7716052fbb | ||
|   | 5e7c6ef005 | ||
|   | 83da9b2485 | ||
|   | ceea4db418 | ||
|   | 86823162c6 | ||
|   | 19ffdc47bb | ||
|   | 0bd415f83e | ||
|   | 028042afe7 | ||
|   | 59556074cc | ||
|   | a6a9dc6890 | ||
|   | ed7d63d913 | ||
|   | 9b1da6ff8c | ||
|   | 7d3c483b35 | ||
|   | 0d057478b0 | ||
|   | 7f750cb145 | ||
|   | 86e77b975f | ||
|   | 70fa9fa766 | ||
|   | c43bd06860 | 
| @@ -8,6 +8,7 @@ AlignEscapedNewlines: DontAlign | |||||||
| AllowAllParametersOfDeclarationOnNextLine: "false" | AllowAllParametersOfDeclarationOnNextLine: "false" | ||||||
| AllowShortFunctionsOnASingleLine: Inline | AllowShortFunctionsOnASingleLine: Inline | ||||||
| AllowShortIfStatementsOnASingleLine: "false" | AllowShortIfStatementsOnASingleLine: "false" | ||||||
|  | AllowShortLambdasOnASingleLine: All | ||||||
| AllowShortLoopsOnASingleLine: "false" | AllowShortLoopsOnASingleLine: "false" | ||||||
| AlwaysBreakAfterReturnType: TopLevelDefinitions | AlwaysBreakAfterReturnType: TopLevelDefinitions | ||||||
| AlwaysBreakTemplateDeclarations: Yes | AlwaysBreakTemplateDeclarations: Yes | ||||||
| @@ -28,7 +29,6 @@ ReflowComments: "false" | |||||||
| SortIncludes: "true" | SortIncludes: "true" | ||||||
| SpaceAfterCStyleCast: "false" | SpaceAfterCStyleCast: "false" | ||||||
| SpacesBeforeTrailingComments: "2" | SpacesBeforeTrailingComments: "2" | ||||||
| # SpaceInEmptyBlock: "true" |  | ||||||
| SpacesInAngles: "true" | SpacesInAngles: "true" | ||||||
| SpacesInParentheses: "true" | SpacesInParentheses: "true" | ||||||
| SpacesInSquareBrackets: "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 | ||||||
							
								
								
									
										60
									
								
								.github/workflows/nightly-neon.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								.github/workflows/nightly-neon.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | |||||||
|  | name: nightly-neon-xtn | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   schedule: | ||||||
|  |     - cron: "52 1 * * *" | ||||||
|  |   workflow_dispatch: | ||||||
|  |  | ||||||
|  | env: | ||||||
|  |   BUILDDIR: /build | ||||||
|  |   SRCDIR: ${{ github.workspace }} | ||||||
|  |   CMAKE_ARGS: | | ||||||
|  |     -DWEBVIEW_FORCE_WEBKIT=1 | ||||||
|  |     -DKDE_INSTALL_USE_QT_SYS_PATHS=ON | ||||||
|  |     -DWITH_PYTHONQT=OFF" | ||||||
|  |     -DCMAKE_BUILD_TYPE=Debug | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     container: | ||||||
|  |       image: docker://kdeneon/plasma:user | ||||||
|  |       options: --tmpfs /build:rw --user 0:0 | ||||||
|  |     steps: | ||||||
|  |       - name: "fetch artifacts" | ||||||
|  |         uses: dawidd6/action-download-artifact@v2 | ||||||
|  |         with: | ||||||
|  |           workflow: nightly-neon.yml | ||||||
|  |           workflow_conclusion: success | ||||||
|  |           branch: calamares | ||||||
|  |           name: calamares-tarball | ||||||
|  |           path: ${{ env.BUILDDIR }} | ||||||
|  |           repo: calamares/calamares | ||||||
|  |       - name: "prepare env" | ||||||
|  |         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: "build" | ||||||
|  |         id: build | ||||||
|  |         uses: calamares/actions/generic-build@v2 | ||||||
|  |       - name: "notify: ok" | ||||||
|  |         if: ${{ success() && github.repository == 'calamares/calamares-extensions' }} | ||||||
|  |         uses: calamares/actions/matrix-notify@v2 | ||||||
|  |         with: | ||||||
|  |           token: ${{ secrets.MATRIX_TOKEN }} | ||||||
|  |           room: ${{ secrets.MATRIX_ROOM }} | ||||||
|  |           message: "OK ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git_summary }}" | ||||||
|  |       - name: "notify: fail" | ||||||
|  |         if: ${{ failure() && github.repository == 'calamares/calamares' }} | ||||||
|  |         uses: calamares/actions/matrix-notify@v2 | ||||||
|  |         with: | ||||||
|  |           token: ${{ secrets.MATRIX_TOKEN }} | ||||||
|  |           room: ${{ secrets.MATRIX_ROOM }} | ||||||
|  |           message: "FAIL ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git_summary}}" | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										66
									
								
								.github/workflows/push.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								.github/workflows/push.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | name: ci-push-xtn | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     branches: | ||||||
|  |       - calamares | ||||||
|  |   pull_request: | ||||||
|  |     types: | ||||||
|  |       - opened | ||||||
|  |       - reopened | ||||||
|  |       - synchronize | ||||||
|  |   workflow_dispatch: | ||||||
|  |  | ||||||
|  | env: | ||||||
|  |   BUILDDIR: /build | ||||||
|  |   SRCDIR: ${{ github.workspace }} | ||||||
|  |   CMAKE_ARGS: | | ||||||
|  |     -DWEBVIEW_FORCE_WEBKIT=1 | ||||||
|  |     -DKDE_INSTALL_USE_QT_SYS_PATHS=ON | ||||||
|  |     -DWITH_PYTHONQT=OFF" | ||||||
|  |     -DCMAKE_BUILD_TYPE=Debug | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     container: | ||||||
|  |       image: docker://kdeneon/plasma:user | ||||||
|  |       options: --tmpfs /build:rw --user 0:0 | ||||||
|  |     steps: | ||||||
|  |       - name: "fetch artifacts" | ||||||
|  |         uses: dawidd6/action-download-artifact@v2 | ||||||
|  |         with: | ||||||
|  |           workflow: nightly-neon.yml | ||||||
|  |           workflow_conclusion: success | ||||||
|  |           branch: calamares | ||||||
|  |           name: calamares-tarball | ||||||
|  |           path: ${{ env.BUILDDIR }} | ||||||
|  |           repo: calamares/calamares | ||||||
|  |       - name: "prepare env" | ||||||
|  |         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: "build" | ||||||
|  |         id: build | ||||||
|  |         uses: calamares/actions/generic-build@v2 | ||||||
|  |       - name: "notify: ok" | ||||||
|  |         if: ${{ success() && github.repository == 'calamares/calamares-extensions' }} | ||||||
|  |         uses: calamares/actions/matrix-notify@v2 | ||||||
|  |         with: | ||||||
|  |           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" | ||||||
|  |         if: ${{ failure() && github.repository == 'calamares/calamares-extensions' }} | ||||||
|  |         uses: calamares/actions/matrix-notify@v2 | ||||||
|  |         with: | ||||||
|  |           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/ | .kdev4/ | ||||||
| build/ | build/ | ||||||
| *.kdev4 | *.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 | ||||||
|  |  | ||||||
							
								
								
									
										79
									
								
								CHANGES
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								CHANGES
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | |||||||
|  | <!-- SPDX-FileCopyrightText: no | ||||||
|  |      SPDX-License-Identifier: CC0-1.0 | ||||||
|  | --> | ||||||
|  |  | ||||||
|  | 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.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 | ||||||
|  |  - Undef | ||||||
|  |  | ||||||
|  | Changes and new modules in this release: | ||||||
|  |  - Branding has a new example, *image-slideshow*, for a QML-based | ||||||
|  |    slideshow with only images. | ||||||
|  |  - CI now builds the extensions against a recent Calamares build. | ||||||
|  |  - *mobile* add ability to select target filesystem. | ||||||
|  |  - *mobile* rename `cmdMkfsRoot` to `cmdMkfsRootExt4`. | ||||||
|  |  - *mobile* wait screen has been re-worded. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # 1.1.0 (2021-01-04) | ||||||
|  |  | ||||||
|  | This release contains contributions from (alphabetically by first name): | ||||||
|  |  - Oliver Smith | ||||||
|  |  | ||||||
|  | Changes and new modules in this release: | ||||||
|  |  - *mobile* module bugfixes | ||||||
|  |  - *mobile* module SSH daemon can be disabled | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # 1.0.0 (2020-12-05) | ||||||
|  |  | ||||||
|  | This release contains contributions from (alphabetically by first name): | ||||||
|  |  - Oliver Smith | ||||||
|  |  - ShalokShalom | ||||||
|  |  | ||||||
|  | Initial release of Calamares-Extensions as such, with one new module | ||||||
|  |  - *mobile*, for PostmarketOS initial configuration | ||||||
|  |  | ||||||
							
								
								
									
										110
									
								
								CMakeLists.txt
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								CMakeLists.txt
									
									
									
									
									
								
							| @@ -1,20 +1,15 @@ | |||||||
| # === This file is part of Calamares - <https://github.com/calamares> === | # === This file is part of Calamares - <https://github.com/calamares> === | ||||||
| # | # | ||||||
| #   Calamares is free software: you can redistribute it and/or modify | #   SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org> | ||||||
| #   it under the terms of the GNU General Public License as published by | #   SPDX-License-Identifier: GPL-3.0-or-later | ||||||
| #   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 | #   Calamares-Examples is Free Software: see the License-Identifier above. | ||||||
| #   along with Calamares. If not, see <http://www.gnu.org/licenses/>. |  | ||||||
| # | # | ||||||
| #   SPDX-License-Identifier: GPL-3.0+ | #   Individual files may have different licenses (like the CMake | ||||||
| #   License-Filename: LICENSE | #   infrastructure, which is BSD-2-Clause licensed). Check the SPDX | ||||||
|  | #   identifiers in each file. | ||||||
| # | # | ||||||
| ### | ### | ||||||
| # | # | ||||||
| @@ -24,15 +19,73 @@ | |||||||
| # distro can use an unmodified (upstream) Calamares package and a local | # distro can use an unmodified (upstream) Calamares package and a local | ||||||
| # customisation package in tandem. | # customisation package in tandem. | ||||||
| # | # | ||||||
|  | # 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. | ||||||
|  | # | ||||||
|  | ### 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.3 FATAL_ERROR) | cmake_minimum_required(VERSION 3.3 FATAL_ERROR) | ||||||
|  |  | ||||||
|  | set( CALAMARES_EXTENSIONS_VERSION 1.2.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 | project(calamares-extensions | ||||||
|     VERSION 1.0.0 |     VERSION ${CALAMARES_EXTENSIONS_VERSION} | ||||||
|     LANGUAGES CXX |     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.2.46 ) | ||||||
|  | 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() | ||||||
|  |  | ||||||
|  | ### CMAKE SETUP | ||||||
|  | # | ||||||
|  | # Enable IN_LIST | ||||||
|  | if( POLICY CMP0057 ) | ||||||
|  |     cmake_policy( SET CMP0057 NEW ) | ||||||
|  | endif() | ||||||
|  | # Let ``AUTOMOC`` and ``AUTOUIC`` process ``GENERATED`` files. | ||||||
|  | if( POLICY CMP0071 ) | ||||||
|  |     cmake_policy( SET CMP0071 NEW ) | ||||||
|  | endif() | ||||||
|  | # Recognize more macros to trigger automoc | ||||||
|  | if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.10.0") | ||||||
|  |     list(APPEND CMAKE_AUTOMOC_MACRO_NAMES | ||||||
|  |         "K_PLUGIN_FACTORY_WITH_JSON" | ||||||
|  |         "K_EXPORT_PLASMA_DATAENGINE_WITH_JSON" | ||||||
|  |         "K_EXPORT_PLASMA_RUNNER" | ||||||
|  |     ) | ||||||
|  | endif() | ||||||
|  | include( CTest ) | ||||||
|  |  | ||||||
| find_package(YAMLCPP REQUIRED) |  | ||||||
|  |  | ||||||
| ### BRANDING | ### BRANDING | ||||||
| # | # | ||||||
| @@ -56,25 +109,16 @@ calamares_add_branding_subdirectory( branding/kaos_branding NAME kaos ) | |||||||
| # | # | ||||||
| # Add one of more modules, either C++ or Python. | # 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 LIST_SKIPPED_MODULES )  # C++ viewmodule | ||||||
| calamares_add_module_subdirectory( modules/freebsddisk )  # C++ viewmodule | calamares_add_module_subdirectory( modules/mobile LIST_SKIPPED_MODULES ) | ||||||
| calamares_add_module_subdirectory( modules/mobile ) | calamares_add_module_subdirectory( modules/os-freebsd LIST_SKIPPED_MODULES ) | ||||||
| calamares_add_module_subdirectory( modules/slowpython )  # Python job | 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 ) | ||||||
|  |  | ||||||
| # If modules cannot be built, they usually call a macro | # If modules cannot be built, they usually call a macro | ||||||
| # which builds a list of explanations; show that list. | # which builds a list of explanations; show that list. | ||||||
| calamares_explain_skipped_modules( ${SKIPPED_MODULES} ) | calamares_explain_skipped_modules( ${LIST_SKIPPED_MODULES} ) | ||||||
|  |  | ||||||
| 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 |  | ||||||
| ) |  | ||||||
|   | |||||||
							
								
								
									
										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() | ||||||
							
								
								
									
										43
									
								
								CONTRIBUTING.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								CONTRIBUTING.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | <!-- 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. | ||||||
|  |  | ||||||
|  | Regular Calamares development chit-chat happens in a [Matrix](https://matrix.org/) | ||||||
|  | room, `#calamares:kde.org`. The conversation is bridged with IRC | ||||||
|  | on [Libera.Chat](https://libera.chat/). | ||||||
|  | Responsiveness is best during the day | ||||||
|  | in Europe, but feel free to idle. If you use IRC, **DO NOT** ask-and-leave. Keep | ||||||
|  | that chat window open because it can easily take a few hours for | ||||||
|  | someone to notice a message. | ||||||
|  | Matrix is persistent, and we'll see your message eventually. | ||||||
|  |  | ||||||
|  | * [](https://webchat.kde.org/#/room/%23calamares:kde.org) | ||||||
|  | * [](https://kiwiirc.com/client/irc.libera.chat/#calamares) | ||||||
							
								
								
									
										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. | ||||||
							
								
								
									
										98
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										98
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,10 +1,15 @@ | |||||||
|  | <!-- SPDX-FileCopyrightText: no | ||||||
|  |      SPDX-License-Identifier: CC0-1.0 | ||||||
|  | --> | ||||||
|  |  | ||||||
| # Calamares Branding and Module Examples | # Calamares Branding and Module Examples | ||||||
|  |  | ||||||
| > A *branding component* in Calamares is a description of the | > A *branding component* in Calamares is a description of the | ||||||
| > produce (i.e. distribution) being installed along with a "slideshow"  | > product (i.e. distribution) being installed along with a "slideshow" | ||||||
| > that is displayed during the installation phase of Calamares. | > that is displayed during the installation phase of Calamares. | ||||||
|  | > This shapes the **look** of your installation. | ||||||
| > | > | ||||||
| > A *module* adds functionality to Calamares; modules may be written | > A *module* adds **functionality** to Calamares; modules may be written | ||||||
| > in C++ or Python, using Qt Widgets or QML for the UI (with C++) | > in C++ or Python, using Qt Widgets or QML for the UI (with C++) | ||||||
| > if there is one. Both C++ and Python allow a full control over the | > if there is one. Both C++ and Python allow a full control over the | ||||||
| > target system during the installation. | > target system during the installation. | ||||||
| @@ -13,13 +18,9 @@ This repository contains complete examples of branding and some | |||||||
| modules for Calamares. | modules for Calamares. | ||||||
|  |  | ||||||
| - [Branding](#branding) documentation | - [Branding](#branding) documentation | ||||||
|   - [default](branding/default/branding.desc) branding example | - [Module](#modules) documentation | ||||||
|   - [fancy](branding/fancy/branding.desc) branding example |  | ||||||
|   - [KaOS](branding/kaos_branding/branding.desc) branding example | ## Branding | ||||||
|   - [SameGame](branding/samegame/branding.desc) branding example |  | ||||||
| - [Module](#module) documentation |  | ||||||
|    |  | ||||||
| ## Branding  |  | ||||||
|  |  | ||||||
| > Branding shapes the **look** of Calamares to your distro | > Branding shapes the **look** of Calamares to your distro | ||||||
|  |  | ||||||
| @@ -28,11 +29,20 @@ can be used for testing. The examples here show what can be done | |||||||
| with QML in the context of Calamares branding, and provide examples | with QML in the context of Calamares branding, and provide examples | ||||||
| and documentation for the framework that Calamares ships with. | and documentation for the framework that Calamares ships with. | ||||||
|  |  | ||||||
|  - `default/` is a copy of the default branding included with Calamares. |  - [`default/`](branding/default/branding.desc) | ||||||
|  - `fancy/` has navigation buttons and a slide counter. |    is a copy of the default branding included with Calamares. | ||||||
|  - `kaos_branding/` is a copy of the KaOS branding component, which |  - [`fancy/`](branding/fancy/branding.desc) | ||||||
|  |    has navigation buttons and a slide counter. | ||||||
|  |  - [`image-slideshow/`](branding/image-slideshow/branding.desc) | ||||||
|  |    is a variant of the *default* branding that implements its | ||||||
|  |    own slide element for QML that supports a single image. | ||||||
|  |    This is useful for straightforward images-only slideshows | ||||||
|  |    (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. | ||||||
|  - `samegame/` is a copy of the Qt Company "Same Game" QML demo. It |  - [`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. |    shows that **any** QML can be used for branding purposes. | ||||||
|  |  | ||||||
| ### Writing your own Branding | ### Writing your own Branding | ||||||
| @@ -62,7 +72,7 @@ and documentation for the framework that Calamares ships with. | |||||||
|   parts of Calamares. |   parts of Calamares. | ||||||
|  |  | ||||||
|   See the [styling paragraph](https://github.com/calamares/calamares/wiki/Deploy-Guide#styling-calamares) of the deployment guide for more details. |   See the [styling paragraph](https://github.com/calamares/calamares/wiki/Deploy-Guide#styling-calamares) of the deployment guide for more details. | ||||||
|     |  | ||||||
| ### Testing a Branding Component | ### Testing a Branding Component | ||||||
|  |  | ||||||
| If Calamares is installed, then the Calamares QML support files | If Calamares is installed, then the Calamares QML support files | ||||||
| @@ -72,7 +82,7 @@ branding component is free to do whatever is interesting in QML. | |||||||
|  |  | ||||||
| The tool for quickly viewing QML files is `qmlscene`, which is | The tool for quickly viewing QML files is `qmlscene`, which is | ||||||
| included with the Qt development tools. It can be used to | included with the Qt development tools. It can be used to | ||||||
| preview a Calamares branding component (slideshow) without starting  | preview a Calamares branding component (slideshow) without starting | ||||||
| Calamares.  If the component uses translations, you will need to | Calamares.  If the component uses translations, you will need to | ||||||
| build the translations first (using Qt Linguist `lrelease`, or by | build the translations first (using Qt Linguist `lrelease`, or by | ||||||
| using the normal build system for branding components). | using the normal build system for branding components). | ||||||
| @@ -87,7 +97,7 @@ qmlscene \ | |||||||
|     -translation build/calamares-fancy_nl.qm \ |     -translation build/calamares-fancy_nl.qm \ | ||||||
|     -I /usr/local/share/calamares/qml \ |     -I /usr/local/share/calamares/qml \ | ||||||
|     -geometry 600x400 \ |     -geometry 600x400 \ | ||||||
|     fancy/show.qml  |     fancy/show.qml | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| This starts the viewer with the Dutch (nl) translation, using the | This starts the viewer with the Dutch (nl) translation, using the | ||||||
| @@ -104,25 +114,39 @@ every time. | |||||||
| ### Calamares Branding API | ### Calamares Branding API | ||||||
|  |  | ||||||
| The slideshow which is configured in the branding files can have | The slideshow which is configured in the branding files can have | ||||||
| one of two "API styles".  | one of two "API styles". | ||||||
|  |  | ||||||
| - Version 1 is loaded when the slideshow starts. If the slideshow is | - Version 1 is loaded when the slideshow starts. If the slideshow is | ||||||
|   large, or contains remote content, then this may be slow. |   large, or contains remote content, then this may be slow. | ||||||
|  |   The loading time may be visible as a "white flash" as the | ||||||
|  |   QML component is displayed with no background until the | ||||||
|  |   slideshow is loaded. | ||||||
| - Version 2 is loaded asynchronously from the moment Calamares is | - Version 2 is loaded asynchronously from the moment Calamares is | ||||||
|   started. This may delay startup a little, but may appear more |   started. This may delay startup a little, but appears more | ||||||
|   responsive overall. |   responsive overall. | ||||||
|  |  | ||||||
| If the slideshow QML defines functions | If the slideshow QML defines functions | ||||||
| `onActivate()` and `onLeave()` then those functions | `onActivate()` and `onLeave()` then those functions | ||||||
| are called when the slideshow becomes visible and when the installation is finished. | are called when the slideshow becomes visible and when the installation is finished. | ||||||
| These can be used to start and stop timers or sound effects or | These can be used to start and stop timers or sound effects or | ||||||
| whatever.  | whatever. | ||||||
|  |  | ||||||
| In addition, if the slideshow QML defines a property | In addition, if the slideshow QML defines a property | ||||||
| `activatedInCalamares` then it is set to `true` | `activatedInCalamares` then it is set to `true` | ||||||
| when the slideshow becomes visible, and to `false` when  | when the slideshow becomes visible, and to `false` when | ||||||
| the installation is finished. This can also be used to | the installation is finished. This can also be used to | ||||||
| start timers, etc. | start timers, etc. The standard `Presentation.qml` included with | ||||||
|  | Calamares has such a property. | ||||||
|  |  | ||||||
|  | A slideshow (`show.qml`) can be entirely independent, with bespoke code, | ||||||
|  | or it can make use of files shipped as part of Calamares: a *Presentation* and | ||||||
|  | a *Slide* element (and some others). There are also Calamares internals which | ||||||
|  | can be used from QML: | ||||||
|  | - `import calamares.slideshow 1.0` for the standard QML slideshow (e.g. *Presentation* element; | ||||||
|  |   use *Slide* with this or write an API-equivalent element such as the one in `image-slideshow/`). | ||||||
|  | - `import io.calamares.ui 1.0` for a *Branding* object which has an API to | ||||||
|  |   get colors and strings that are used elsewhere in Calamares (e.g. to make the | ||||||
|  |   slide background the same as the background defined in `branding.desc`). | ||||||
|  |  | ||||||
|  |  | ||||||
| ## Modules | ## Modules | ||||||
| @@ -135,6 +159,8 @@ listed in the *show* phase, and may run jobs if listed in the | |||||||
| *exec*  phase) and a Python job module (no UI, runs in the *exec* | *exec*  phase) and a Python job module (no UI, runs in the *exec* | ||||||
| phase). | phase). | ||||||
|  |  | ||||||
|  | ### Example Modules | ||||||
|  |  | ||||||
| - [filekeeper](modules/filekeeper/CMakeLists.txt) is a C++ **job** module | - [filekeeper](modules/filekeeper/CMakeLists.txt) is a C++ **job** module | ||||||
|   to copy files from the host (live) system to the target system at |   to copy files from the host (live) system to the target system at | ||||||
|   the end of installation, like logfiles. (This module is made obsolete |   the end of installation, like logfiles. (This module is made obsolete | ||||||
| @@ -146,6 +172,18 @@ phase). | |||||||
|   module that just serves to slow down an installation by delaying |   module that just serves to slow down an installation by delaying | ||||||
|   a configurable (default 30 seconds) amount of time. |   a configurable (default 30 seconds) amount of time. | ||||||
|  |  | ||||||
|  | ### Functional Modules | ||||||
|  |  | ||||||
|  | - [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, 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 | ### CMake Preparation | ||||||
|  |  | ||||||
| The single macro `calamares_add_module_subdirectory()` | The single macro `calamares_add_module_subdirectory()` | ||||||
| @@ -173,3 +211,21 @@ usually called `main.py` which defines a `run()` function. | |||||||
|  |  | ||||||
| The API is loosely documented in the | The API is loosely documented in the | ||||||
| [developer guide](https://github.com/calamares/calamares/wiki/Develop-Guide). | [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. | ||||||
|  |  | ||||||
|  | Regular Calamares development chit-chat happens in a [Matrix](https://matrix.org/) | ||||||
|  | room, `#calamares:kde.org`. The conversation is bridged with IRC | ||||||
|  | on [Libera.Chat](https://libera.chat/). | ||||||
|  | Responsiveness is best during the day | ||||||
|  | in Europe, but feel free to idle. If you use IRC, **DO NOT** ask-and-leave. Keep | ||||||
|  | that chat window open because it can easily take a few hours for | ||||||
|  | someone to notice a message. | ||||||
|  | Matrix is persistent, and we'll see your message eventually. | ||||||
|  |  | ||||||
|  | * [](https://webchat.kde.org/#/room/%23calamares:kde.org) | ||||||
|  | * [](https://kiwiirc.com/client/irc.libera.chat/#calamares) | ||||||
|   | |||||||
							
								
								
									
										64
									
								
								branding/image-slideshow/ImageSlide.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								branding/image-slideshow/ImageSlide.qml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | /* === This file is part of Calamares Extensions - <http://github.com/calamares-extensions> === | ||||||
|  |  * | ||||||
|  |  * SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org> | ||||||
|  |  * SPDX-License-Identifier: BSD-2-Clause | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /* An *ImageSlide* is a *Slide* (it offers the API that *Presentation* | ||||||
|  |  * expects) while displaying only a single image. This is useful | ||||||
|  |  * for presentations that are all images, with no interaction or text. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | import QtQuick 2.5 | ||||||
|  |  | ||||||
|  | /* To use an *ImageSlide*, instantiate it inside your *Presentation* | ||||||
|  |  * and set the *src* property to a path to an image file in a supported | ||||||
|  |  * format. Relative paths are ok. | ||||||
|  |  */ | ||||||
|  | Item { | ||||||
|  |     id: imageslide | ||||||
|  |  | ||||||
|  |     /* Slides should be non-visible at the start; the *Presentation* | ||||||
|  |      * handles visibility (so that one slide at a time is visible). | ||||||
|  |      */ | ||||||
|  |     visible: false | ||||||
|  |     /* Make this item fill up the parent, so that alignment of the | ||||||
|  |      * image (below) works out to "middle of the parent". | ||||||
|  |      */ | ||||||
|  |     anchors.fill: parent | ||||||
|  |  | ||||||
|  |     /* The *Presentation* manages visibility of children that have | ||||||
|  |      * attribute *isSlide* and *isSlide* is set to *true*. Other | ||||||
|  |      * children are ignored, so we need to set this so that the | ||||||
|  |      * *ImageSlide* elements are treated like slides. | ||||||
|  |      */ | ||||||
|  |     property bool isSlide: true; | ||||||
|  |     /* The *Presentation* allows slides to have notes, so just leave | ||||||
|  |      * an empty string here. | ||||||
|  |      */ | ||||||
|  |     property string notes; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /* This is the important property for *ImageSlide*: the path to the | ||||||
|  |      * image to display. When instantiating *ImageSlide*, set this for | ||||||
|  |      * each instance. Relative paths are ok. | ||||||
|  |      */ | ||||||
|  |     property string src; | ||||||
|  |  | ||||||
|  |     /* The image itself. It has fixed sizes (300x150px). You could set | ||||||
|  |      * an aspect ratio here (e.g. `height: width / 2`) as well. | ||||||
|  |      * | ||||||
|  |      * This binds the image source (filename) to the string *src* | ||||||
|  |      * in the *ImageSlide* element, for convenience in setting things | ||||||
|  |      * up in the overall slideshow. If you want to make width and | ||||||
|  |      * height configurable, add a property above and then bind to | ||||||
|  |      * them from the Image element. | ||||||
|  |      */ | ||||||
|  |     Image { | ||||||
|  |         id: image | ||||||
|  |         source: src | ||||||
|  |         width: 300 | ||||||
|  |         height: 150 | ||||||
|  |         anchors.centerIn: parent | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										40
									
								
								branding/image-slideshow/branding.desc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								branding/image-slideshow/branding.desc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | # SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org> | ||||||
|  | # SPDX-License-Identifier: BSD-2-Clause | ||||||
|  | --- | ||||||
|  | componentName:  default | ||||||
|  | # image-slideshow | ||||||
|  |  | ||||||
|  | # Branding must define some strings for the welcome page, | ||||||
|  | # even though this example is about the slideshow, not the rest. | ||||||
|  | strings: | ||||||
|  |     productName:         Mirror Linux | ||||||
|  |     shortProductName:    Mirror | ||||||
|  |     version: | ||||||
|  |     shortVersion: | ||||||
|  |     versionedName:       Mirror Linux 1.0 | ||||||
|  |     shortVersionedName:  Mirror 1.0 | ||||||
|  |     bootloaderEntryName: Mirror | ||||||
|  |  | ||||||
|  | # These images do not exist in this branding example. | ||||||
|  | images: | ||||||
|  |     productLogo:         "logo.png" | ||||||
|  |     productIcon:         "logo.png" | ||||||
|  |     productWelcome:      "languages.png" | ||||||
|  |  | ||||||
|  | # Dark-mode for Calamares. The slideshow can access these color values | ||||||
|  | # through the Branding object which is always available to QML inside Calamares. | ||||||
|  | style: | ||||||
|  |    sidebarBackground:    "#36393e" | ||||||
|  |    sidebarText:          "#efefef" | ||||||
|  |    sidebarTextSelect:    "#2eb69b" | ||||||
|  |    sidebarTextHighlight: "#313338" | ||||||
|  |  | ||||||
|  | # The actual slideshow. API version 2 means that the QML is loaded at | ||||||
|  | # startup. This is **slightly** slower at startup, but means that by | ||||||
|  | # the time we reach the slideshow, it is loaded and ready-to-go. | ||||||
|  | # | ||||||
|  | # A v2 slideshow **may** have an onActivate() and onLeave() function, | ||||||
|  | # although Calamares will complain if it does not. | ||||||
|  | slideshow:               "show.qml" | ||||||
|  | slideshowAPI:            2 | ||||||
|  |  | ||||||
							
								
								
									
										103
									
								
								branding/image-slideshow/show.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								branding/image-slideshow/show.qml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | |||||||
|  | /* === This file is part of Calamares Extensions - <http://github.com/calamares-extensions> === | ||||||
|  |  * | ||||||
|  |  * SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org> | ||||||
|  |  * SPDX-License-Identifier: BSD-2-Clause | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /* This is a simple slideshow for use during the *exec* phase of | ||||||
|  |  * installation, that displays a handful of slides. It uses | ||||||
|  |  * the *Presentation* QML components -- this allows, for instance, | ||||||
|  |  * notes to be added to slides, and for arrow navigation to be | ||||||
|  |  * used. But at its core it's just a bunch of images, repeating. | ||||||
|  |  * | ||||||
|  |  * For this kind of limited functionality, it may be better to | ||||||
|  |  * use the "plain images" slideshow format in Calamares, although | ||||||
|  |  * then you don't have any say in how things are animated. | ||||||
|  |  * | ||||||
|  |  * This slideshow is written for *slideshowAPI* version 1, so in | ||||||
|  |  * `branding.desc` set that appropriately. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | import QtQuick 2.0  // Basic QML | ||||||
|  | import calamares.slideshow 1.0  // Calamares slideshow: Presentation | ||||||
|  | import io.calamares.ui 1.0  // Calamares internals: Branding | ||||||
|  |  | ||||||
|  | /* *Presentation* comes from the pre-installed calamares.slideshow | ||||||
|  |  * that comes with Calamares itself. See `Presentation.qml` in the | ||||||
|  |  * Calamares repository for details and documentation. | ||||||
|  |  * | ||||||
|  |  * The important parts of presentation are: | ||||||
|  |  *  - it has a property *activatedInCalamares* which is set to *true* | ||||||
|  |  *    when the slideshow becomes visible, *false* afterwards. | ||||||
|  |  *  - it expects one or more children with a property *isSlide* | ||||||
|  |  *    set to *true*. | ||||||
|  |  *  - it has a function *goToNextSlide()* to do just that (where | ||||||
|  |  *    "slides" is the sequence of children that have property | ||||||
|  |  *    *isSlide* set to *true*. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | Presentation | ||||||
|  | { | ||||||
|  |     id: presentation | ||||||
|  |  | ||||||
|  |     /* This timer ticks once per second (1000ms, set in *interval*) | ||||||
|  |      * and calls *goToNextSlide()* each time. Note that it needs | ||||||
|  |      * to know the *id* of the presentation, so keep *id* (above) | ||||||
|  |      * matched with the function call. | ||||||
|  |      * | ||||||
|  |      * The timer starts when the presentation is activated; you could | ||||||
|  |      * also set *running* to true, but that might cost extra resources. | ||||||
|  |      */ | ||||||
|  |     Timer { | ||||||
|  |         interval: 1000 | ||||||
|  |         running: presentation.activatedInCalamares | ||||||
|  |         repeat: true | ||||||
|  |         onTriggered: presentation.goToNextSlide() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* These functions are called when the presentation starts and | ||||||
|  |      * ends, respectively. They could be used to start the timer, | ||||||
|  |      * but that is done automatically through *activatedInCalamares*, | ||||||
|  |      * so there's nothing **to** do. | ||||||
|  |      * | ||||||
|  |      * Leaving these functions out is fine, although Calamares will | ||||||
|  |      * complain that they are missing, then. | ||||||
|  |      */ | ||||||
|  |     function onActivate() { } | ||||||
|  |     function onLeave() { } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /* A presentation is an Item: it has no visual appearance at all. | ||||||
|  |      * Give it a background, which fills the whole area of the presentation. | ||||||
|  |      * Setting *z* to a low value places this rectangle **behind** other | ||||||
|  |      * things in the presentation -- which is correct for a background. | ||||||
|  |      * | ||||||
|  |      * This uses the background set in the styles section of `branding.desc`. | ||||||
|  |      */ | ||||||
|  |     Rectangle { | ||||||
|  |         id: mybackground | ||||||
|  |         anchors.fill: parent | ||||||
|  |         color: Branding.styleString(Branding.SidebarBackground) | ||||||
|  |         z: -1 | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* The *ImageSlide* is a component unique to this branding directory. | ||||||
|  |      * The QML file `ImageSlide.qml` can be stored alongside `show.qml` | ||||||
|  |      * and it will be loaded on-demand. See the documentation in that | ||||||
|  |      * file for details, but it comes down to this: for each *ImageSlide*, | ||||||
|  |      * set *src* to a suitable value (an image path in this directory) | ||||||
|  |      * and that will be displayed. | ||||||
|  |      */ | ||||||
|  |     ImageSlide { | ||||||
|  |         src: "slide1.png" | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ImageSlide { | ||||||
|  |         src: "slide2.png" | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ImageSlide { | ||||||
|  |         src: "slide3.png" | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										
											BIN
										
									
								
								branding/image-slideshow/slide1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								branding/image-slideshow/slide1.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 7.0 KiB | 
							
								
								
									
										
											BIN
										
									
								
								branding/image-slideshow/slide2.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								branding/image-slideshow/slide2.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 31 KiB | 
							
								
								
									
										
											BIN
										
									
								
								branding/image-slideshow/slide3.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								branding/image-slideshow/slide3.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 31 KiB | 
| @@ -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 ) | 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" ) |    list( APPEND TS_FILES "${CMAKE_CURRENT_SOURCE_DIR}/calamares-${COMPONENT_NAME}_${lang}.ts" ) | ||||||
| endforeach() | endforeach() | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
| # NOTE: this is largely a copy of the release script for Calamares, | # NOTE: this is largely a copy of the release script for Calamares, | ||||||
| #       with not-applicable parts (such as translation-freeze) either | #       with not-applicable parts (such as translation-freeze) either | ||||||
| #       commented-out, or skipped with if(false). | #       commented-out, or skipped with if(false). | ||||||
|  | # NOTE: this script contains Linuxisms (in particular, expects GNU mktemp(1)) | ||||||
| # | # | ||||||
| # This attempts to perform the different steps of the RELEASE.md | # This attempts to perform the different steps of the RELEASE.md | ||||||
| # document automatically. It's not tested on other machines or | # document automatically. It's not tested on other machines or | ||||||
| @@ -31,6 +32,7 @@ | |||||||
| #   * `-B` do not build (before tagging) | #   * `-B` do not build (before tagging) | ||||||
| #   * `-P` do not package (tag, sign, tarball) | #   * `-P` do not package (tag, sign, tarball) | ||||||
| #   * `-T` do not respect string freeze | #   * `-T` do not respect string freeze | ||||||
|  | #   * `-C <args>` set extra arguments to pass to CMake | ||||||
| # | # | ||||||
| # The build / package settings can be influenced via environment variables: | # The build / package settings can be influenced via environment variables: | ||||||
| #   * BUILD_DEFAULT set to `false` to avoid first build with gcc | #   * BUILD_DEFAULT set to `false` to avoid first build with gcc | ||||||
| @@ -138,24 +140,28 @@ fi | |||||||
| ### Get version number for this release | ### 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 ; } | test -n "$V" || { echo "Could not obtain version in $BUILDDIR ." ; exit 1 ; } | ||||||
|  |  | ||||||
| ### Create signed tag | ### Create signed tag | ||||||
| # | # | ||||||
| # This is the signing key ID associated with the GitHub account adriaandegroot, | # This is the signing key ID associated with the GitHub account adriaandegroot, | ||||||
| # which is used to create all "verified" tags in the Calamares repo. | # which is used to create all "verified" tags in the Calamares repo. | ||||||
|  | # | ||||||
| KEY_ID="CFDDC96F12B1915C" | KEY_ID="CFDDC96F12B1915C" | ||||||
| git tag -u "$KEY_ID" -m "Release v$V" "v$V" || { echo "Could not sign tag v$V." ; exit 1 ; } | 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 | ||||||
| # | # | ||||||
|  | # 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_V="$TARBALL_PREFIX-$V" | ||||||
| TAR_FILE="$TAR_V.tar.gz" | TAR_FILE="$TAR_V.tar.gz" | ||||||
| git archive -o "$TAR_FILE" --prefix "$TAR_V/" "v$V" || { echo "Could not create tarball." ; exit 1 ; } | 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 ; } | test -f "$TAR_FILE" || { echo "Tarball was not created." ; exit 1 ; } | ||||||
| SHA256=$(sha256sum "$TAR_FILE" | cut -d" " -f1) | SHA256=$(sha256sum "$TAR_FILE" | cut -d" " -f1) | ||||||
|  | gpg -s -u $KEY_ID --detach --armor $TAR_FILE  # Sign the tarball | ||||||
|  |  | ||||||
| ### Build the tarball | ### Build the tarball | ||||||
| # | # | ||||||
| @@ -181,7 +187,6 @@ rm -rf "$TMPDIR"  # From tarball | |||||||
| cat <<EOF | cat <<EOF | ||||||
| # Next steps for this release: | # Next steps for this release: | ||||||
|   git push origin v$V |   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 |   # Upload tarball $TAR_FILE and the signature $TAR_FILE.asc | ||||||
|   # Announce via https://github.com/calamares/$PROJECT_NAME/releases/new |   # Announce via https://github.com/calamares/$PROJECT_NAME/releases/new | ||||||
|   # SHA256: $SHA256 |   # SHA256: $SHA256 | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								ci/astylerc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								ci/astylerc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | #   SPDX-FileCopyrightText: 2014 Aurélien Gâteau <agateau@kde.org> | ||||||
|  | #   SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org> | ||||||
|  | #   SPDX-License-Identifier: BSD-2-Clause | ||||||
|  |  | ||||||
|  | # Do not create a backup file | ||||||
|  | suffix=none | ||||||
|  |  | ||||||
|  | indent=spaces=4 | ||||||
|  |  | ||||||
|  | # Brackets | ||||||
|  | style=break | ||||||
|  | add-brackets | ||||||
|  |  | ||||||
|  | # Spaces | ||||||
|  | pad-paren-in | ||||||
|  | pad-header | ||||||
|  | align-pointer=type | ||||||
							
								
								
									
										105
									
								
								ci/calamaresstyle
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										105
									
								
								ci/calamaresstyle
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,105 @@ | |||||||
|  | #!/bin/sh | ||||||
|  | # | ||||||
|  | #   SPDX-FileCopyrightText: 2014 Aurélien Gâteau <agateau@kde.org> | ||||||
|  | #   SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org> | ||||||
|  | #   SPDX-License-Identifier: BSD-2-Clause | ||||||
|  | # | ||||||
|  | # Calls astyle with settings matching Calamares coding style | ||||||
|  | # 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. | ||||||
|  | # | ||||||
|  | LANG=C | ||||||
|  | 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 ) | ||||||
|  |  | ||||||
|  | # 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 | ||||||
|  | 	CF=$( which $_cf 2> /dev/null || true ) | ||||||
|  | 	test -n "$CF" && break | ||||||
|  | done | ||||||
|  |  | ||||||
|  | test -n "$AS" || { echo "! No astyle found in PATH"; exit 1 ; } | ||||||
|  | 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 ; } | ||||||
|  |  | ||||||
|  | ### 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 | ||||||
|  | for d in "$@" | ||||||
|  | do | ||||||
|  | 	test -d "$d" && any_dirs=yes | ||||||
|  | done | ||||||
|  |  | ||||||
|  | style_some() | ||||||
|  | { | ||||||
|  | 	if test -n "$*" ; then | ||||||
|  | 		$AS --options=$BASEDIR/astylerc --quiet "$@" | ||||||
|  | 		$CF -i -style=file "$@" | ||||||
|  | 	fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if test "x$any_dirs" = "xyes" ; then | ||||||
|  | 	for d in "$@" | ||||||
|  | 	do | ||||||
|  | 		if test -d "$d"  ; then | ||||||
|  | 			style_some $( find "$d" -maxdepth 1 -type f -name '*.cpp' -o -name '*.h' ) | ||||||
|  | 		else | ||||||
|  | 			style_some "$d" | ||||||
|  | 		fi | ||||||
|  | 	done | ||||||
|  | else | ||||||
|  | 	style_some "$@" | ||||||
|  | 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 ) | if( NOT Calamares_WITH_QML ) | ||||||
|     calamares_skip_module( "freebsddisk (QML is not supported in this build)" ) |     calamares_skip_module( "freebsddisk (QML is not supported in this build)" ) | ||||||
|     return() |     return() | ||||||
|   | |||||||
| @@ -1,3 +1,6 @@ | |||||||
|  | # SPDX-FileCopyrightText: no | ||||||
|  | # SPDX-License-Identifier: CC0-1.0 | ||||||
|  | # | ||||||
| # The *freebsddisk* module can be used to pick a disk | # The *freebsddisk* module can be used to pick a disk | ||||||
| # as an installer step. This module supports ZFSroot | # as an installer step. This module supports ZFSroot | ||||||
| # on one whole disk, and UFSroot on one whole disk. | # on one whole disk, and UFSroot on one whole disk. | ||||||
|   | |||||||
| @@ -6,13 +6,9 @@ calamares_add_plugin( mobile | |||||||
|     EXPORT_MACRO PLUGINDLLEXPORT_PRO |     EXPORT_MACRO PLUGINDLLEXPORT_PRO | ||||||
|     SOURCES |     SOURCES | ||||||
|         Config.cpp |         Config.cpp | ||||||
|         Config.h |  | ||||||
|         MobileQmlViewStep.cpp |         MobileQmlViewStep.cpp | ||||||
|         MobileQmlViewStep.h |  | ||||||
|         PartitionJob.cpp |         PartitionJob.cpp | ||||||
|         PartitionJob.h |  | ||||||
|         UsersJob.cpp |         UsersJob.cpp | ||||||
|         UsersJob.h |  | ||||||
|     RESOURCES |     RESOURCES | ||||||
|         mobile.qrc |         mobile.qrc | ||||||
|     SHARED_LIB |     SHARED_LIB | ||||||
|   | |||||||
| @@ -1,6 +1,13 @@ | |||||||
| /* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org> | /* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org> | ||||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ |  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||||
| #include "Config.h" | #include "Config.h" | ||||||
|  | #include "PartitionJob.h" | ||||||
|  | #include "UsersJob.h" | ||||||
|  |  | ||||||
|  | #include "ViewManager.h" | ||||||
|  | #include "utils/Logger.h" | ||||||
|  | #include "utils/Variant.h" | ||||||
|  |  | ||||||
| #include <QVariant> | #include <QVariant> | ||||||
|  |  | ||||||
| Config::Config( QObject* parent ) | Config::Config( QObject* parent ) | ||||||
| @@ -8,37 +15,121 @@ Config::Config( QObject* parent ) | |||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
| QString |  | ||||||
| cfgStr( const QVariantMap& cfgMap, QString key, QString defaultStr ) |  | ||||||
| { |  | ||||||
|     QString ret = cfgMap.value( key ).toString(); |  | ||||||
|     if ( ret.isEmpty() ) |  | ||||||
|     { |  | ||||||
|         return defaultStr; |  | ||||||
|     } |  | ||||||
|     return ret; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void | void | ||||||
| Config::setConfigurationMap( const QVariantMap& cfgMap ) | Config::setConfigurationMap( const QVariantMap& cfgMap ) | ||||||
| { | { | ||||||
|     m_osName = cfgStr( cfgMap, "osName", "(unknown)" ); |     using namespace CalamaresUtils; | ||||||
|     m_arch = cfgStr( cfgMap, "arch", "(unknown)" ); |  | ||||||
|     m_device = cfgStr( cfgMap, "device", "(unknown)" ); |  | ||||||
|     m_userInterface = cfgStr( cfgMap, "userInterface", "(unknown)" ); |  | ||||||
|     m_version = cfgStr( cfgMap, "version", "(unknown)" ); |  | ||||||
|     m_username = cfgStr( cfgMap, "username", "user" ); |  | ||||||
|  |  | ||||||
|     m_cmdLuksFormat = cfgStr( cfgMap, "cmdLuksFormat", "cryptsetup luksFormat --use-random" ); |     if ( getBool( cfgMap, "bogus", false ) ) | ||||||
|     m_cmdLuksOpen = cfgStr( cfgMap, "cmdLuksOpen", "cryptsetup luksOpen" ); |     { | ||||||
|     m_cmdMkfsRoot = cfgStr( cfgMap, "cmdMkfsRoot", "mkfs.ext4 -L 'unknownOS_root'" ); |         cWarning() << "Configuration key \"bogus\" is still set for *mobile*"; | ||||||
|     m_cmdMount = cfgStr( cfgMap, "cmdMount", "mount" ); |     } | ||||||
|     m_targetDeviceRoot = cfgStr( cfgMap, "targetDeviceRoot", "/dev/unknown" ); |  | ||||||
|  |  | ||||||
|     m_cmdPasswd = cfgStr( cfgMap, "cmdPasswd", "passwd" ); |     m_osName = getString( cfgMap, "osName", "(unknown)" ); | ||||||
|     m_cmdSshdEnable = cfgStr( cfgMap, "cmdSshdEnable", "systemctl enable sshd.service" ); |     m_arch = getString( cfgMap, "arch", "(unknown)" ); | ||||||
|     m_cmdSshdDisable = cfgStr( cfgMap, "cmdSshdDisable", "systemctl disable sshd.service" ); |     m_device = getString( cfgMap, "device", "(unknown)" ); | ||||||
|     m_cmdSshdUseradd = cfgStr( cfgMap, "cmdSshdUseradd", "useradd -G wheel -m" ); |     m_userInterface = getString( cfgMap, "userInterface", "(unknown)" ); | ||||||
|  |     m_version = getString( cfgMap, "version", "(unknown)" ); | ||||||
|  |     m_username = getString( cfgMap, "username", "user" ); | ||||||
|  |     m_userPasswordNumeric = getBool( cfgMap, "userPasswordNumeric", true ); | ||||||
|  |  | ||||||
|  |     m_builtinVirtualKeyboard = getBool( cfgMap, "builtinVirtualKeyboard", true ); | ||||||
|  |  | ||||||
|  |     m_featureSshd = getBool( cfgMap, "featureSshd", true ); | ||||||
|  |     m_featureFsType = getBool( cfgMap, "featureFsType", false ); | ||||||
|  |  | ||||||
|  |     m_cmdLuksFormat = getString( cfgMap, "cmdLuksFormat", "cryptsetup luksFormat --use-random" ); | ||||||
|  |     m_cmdLuksOpen = getString( cfgMap, "cmdLuksOpen", "cryptsetup luksOpen" ); | ||||||
|  |     m_cmdMount = getString( cfgMap, "cmdMount", "mount" ); | ||||||
|  |     m_targetDeviceRoot = getString( cfgMap, "targetDeviceRoot", "/dev/unknown" ); | ||||||
|  |     m_targetDeviceRootInternal = getString( cfgMap, "targetDeviceRootInternal", "" ); | ||||||
|  |  | ||||||
|  |     m_cmdMkfsRootBtrfs = getString( cfgMap, "cmdMkfsRootBtrfs", "mkfs.btrfs -L 'unknownOS_root'" ); | ||||||
|  |     m_cmdMkfsRootExt4 = getString( cfgMap, "cmdMkfsRootExt4", "mkfs.ext4 -L 'unknownOS_root'" ); | ||||||
|  |     m_cmdMkfsRootF2fs = getString( cfgMap, "cmdMkfsRootF2fs", "mkfs.f2fs -l 'unknownOS_root'" ); | ||||||
|  |     m_fsList = getStringList( cfgMap, "fsModel", QStringList { "ext4", "f2fs", "btrfs" } ); | ||||||
|  |     m_defaultFs = getString( cfgMap, "defaultFs", "ext4" ); | ||||||
|  |     m_fsIndex = m_fsList.indexOf( m_defaultFs ); | ||||||
|  |     m_fsType = m_defaultFs; | ||||||
|  |  | ||||||
|  |     m_cmdInternalStoragePrepare = getString( cfgMap, "cmdInternalStoragePrepare", "ondev-internal-storage-prepare" ); | ||||||
|  |     m_cmdPasswd = getString( cfgMap, "cmdPasswd", "passwd" ); | ||||||
|  |     m_cmdSshdEnable = getString( cfgMap, "cmdSshdEnable", "systemctl enable sshd.service" ); | ||||||
|  |     m_cmdSshdDisable = getString( cfgMap, "cmdSshdDisable", "systemctl disable sshd.service" ); | ||||||
|  |     m_cmdSshdUseradd = getString( cfgMap, "cmdSshdUseradd", "useradd -G wheel -m" ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Calamares::JobList | ||||||
|  | Config::createJobs() | ||||||
|  | { | ||||||
|  |     QList< Calamares::job_ptr > list; | ||||||
|  |     QString cmdSshd = m_isSshEnabled ? m_cmdSshdEnable : m_cmdSshdDisable; | ||||||
|  |  | ||||||
|  |     /* Put users job in queue (should run after unpackfs) */ | ||||||
|  |     Calamares::Job* j = new UsersJob( m_featureSshd, | ||||||
|  |                                       m_cmdPasswd, | ||||||
|  |                                       cmdSshd, | ||||||
|  |                                       m_cmdSshdUseradd, | ||||||
|  |                                       m_isSshEnabled, | ||||||
|  |                                       m_username, | ||||||
|  |                                       m_userPassword, | ||||||
|  |                                       m_sshdUsername, | ||||||
|  |                                       m_sshdPassword ); | ||||||
|  |     list.append( Calamares::job_ptr( j ) ); | ||||||
|  |  | ||||||
|  |     return list; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | Config::runPartitionJobThenLeave( bool b ) | ||||||
|  | { | ||||||
|  |     Calamares::ViewManager* v = Calamares::ViewManager::instance(); | ||||||
|  |     QString cmdMkfsRoot; | ||||||
|  |     if ( m_fsType == QStringLiteral( "btrfs" ) ) | ||||||
|  |     { | ||||||
|  |         cmdMkfsRoot = m_cmdMkfsRootBtrfs; | ||||||
|  |     } | ||||||
|  |     else if ( m_fsType == QStringLiteral( "f2fs" ) ) | ||||||
|  |     { | ||||||
|  |         cmdMkfsRoot = m_cmdMkfsRootF2fs; | ||||||
|  |     } | ||||||
|  |     else if ( m_fsType == QStringLiteral( "ext4" ) ) | ||||||
|  |     { | ||||||
|  |         cmdMkfsRoot = m_cmdMkfsRootExt4; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         v->onInstallationFailed( "Unknown filesystem: '" + m_fsType + "'", "" ); | ||||||
|  |     } | ||||||
|  |     /* HACK: run partition job | ||||||
|  |      * The "mobile" module has two jobs, the partition job and the users job. | ||||||
|  |      * If we added both of them in Config::createJobs(), Calamares would run | ||||||
|  |      * them right after each other. But we need the "unpackfs" module to run | ||||||
|  |      * inbetween, that's why as workaround, the partition job is started here. | ||||||
|  |      * To solve this properly, we would need to place the partition job in an | ||||||
|  |      * own module and pass everything via globalstorage. But then we might as | ||||||
|  |      * well refactor everything so we can unify the mobile's partition job with | ||||||
|  |      * the proper partition job from Calamares. */ | ||||||
|  |     Calamares::Job* j = new PartitionJob( m_cmdInternalStoragePrepare, | ||||||
|  |                                           m_cmdLuksFormat, | ||||||
|  |                                           m_cmdLuksOpen, | ||||||
|  |                                           cmdMkfsRoot, | ||||||
|  |                                           m_cmdMount, | ||||||
|  |                                           m_targetDeviceRoot, | ||||||
|  |                                           m_targetDeviceRootInternal, | ||||||
|  |                                           m_installFromExternalToInternal, | ||||||
|  |                                           m_isFdeEnabled, | ||||||
|  |                                           m_fdePassword ); | ||||||
|  |     Calamares::JobResult res = j->exec(); | ||||||
|  |  | ||||||
|  |     if ( res ) | ||||||
|  |     { | ||||||
|  |         v->next(); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         v->onInstallationFailed( res.message(), res.details() ); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| @@ -80,3 +171,34 @@ Config::setIsFdeEnabled( const bool isFdeEnabled ) | |||||||
| { | { | ||||||
|     m_isFdeEnabled = isFdeEnabled; |     m_isFdeEnabled = isFdeEnabled; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | Config::setInstallFromExternalToInternal( const bool val ) | ||||||
|  | { | ||||||
|  |     m_installFromExternalToInternal = val; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | Config::setFsType( int idx ) | ||||||
|  | { | ||||||
|  |     if ( idx >= 0 && idx < m_fsList.length() ) | ||||||
|  |     { | ||||||
|  |         setFsType( m_fsList[ idx ] ); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | void | ||||||
|  | Config::setFsType( const QString& fsType ) | ||||||
|  | { | ||||||
|  |     if ( fsType != m_fsType ) | ||||||
|  |     { | ||||||
|  |         m_fsType = fsType; | ||||||
|  |         emit fsTypeChanged( m_fsType ); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | Config::setFsIndex( const int fsIndex ) | ||||||
|  | { | ||||||
|  |     m_fsIndex = fsIndex; | ||||||
|  |     emit fsIndexChanged( m_fsIndex ); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,12 +1,18 @@ | |||||||
| /* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org> | /* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org> | ||||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ |  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
|  | #include "Job.h" | ||||||
|  |  | ||||||
| #include <QObject> | #include <QObject> | ||||||
| #include <memory> | #include <memory> | ||||||
|  |  | ||||||
| class Config : public QObject | class Config : public QObject | ||||||
| { | { | ||||||
|     Q_OBJECT |     Q_OBJECT | ||||||
|  |     /* installer UI */ | ||||||
|  |     Q_PROPERTY( bool builtinVirtualKeyboard READ builtinVirtualKeyboard CONSTANT FINAL ) | ||||||
|  |  | ||||||
|     /* welcome */ |     /* welcome */ | ||||||
|     Q_PROPERTY( QString osName READ osName CONSTANT FINAL ) |     Q_PROPERTY( QString osName READ osName CONSTANT FINAL ) | ||||||
|     Q_PROPERTY( QString arch READ arch CONSTANT FINAL ) |     Q_PROPERTY( QString arch READ arch CONSTANT FINAL ) | ||||||
| @@ -17,8 +23,10 @@ class Config : public QObject | |||||||
|     /* default user */ |     /* default user */ | ||||||
|     Q_PROPERTY( QString username READ username CONSTANT FINAL ) |     Q_PROPERTY( QString username READ username CONSTANT FINAL ) | ||||||
|     Q_PROPERTY( QString userPassword READ userPassword WRITE setUserPassword NOTIFY userPasswordChanged ) |     Q_PROPERTY( QString userPassword READ userPassword WRITE setUserPassword NOTIFY userPasswordChanged ) | ||||||
|  |     Q_PROPERTY( bool userPasswordNumeric READ userPasswordNumeric CONSTANT FINAL ) | ||||||
|  |  | ||||||
|     /* ssh server + credentials */ |     /* ssh server + credentials */ | ||||||
|  |     Q_PROPERTY( bool featureSshd READ featureSshd CONSTANT FINAL ) | ||||||
|     Q_PROPERTY( QString sshdUsername READ sshdUsername WRITE setSshdUsername NOTIFY sshdUsernameChanged ) |     Q_PROPERTY( QString sshdUsername READ sshdUsername WRITE setSshdUsername NOTIFY sshdUsernameChanged ) | ||||||
|     Q_PROPERTY( QString sshdPassword READ sshdPassword WRITE setSshdPassword NOTIFY sshdPasswordChanged ) |     Q_PROPERTY( QString sshdPassword READ sshdPassword WRITE setSshdPassword NOTIFY sshdPasswordChanged ) | ||||||
|     Q_PROPERTY( bool isSshEnabled READ isSshEnabled WRITE setIsSshEnabled ) |     Q_PROPERTY( bool isSshEnabled READ isSshEnabled WRITE setIsSshEnabled ) | ||||||
| @@ -27,12 +35,23 @@ class Config : public QObject | |||||||
|     Q_PROPERTY( QString fdePassword READ fdePassword WRITE setFdePassword NOTIFY fdePasswordChanged ) |     Q_PROPERTY( QString fdePassword READ fdePassword WRITE setFdePassword NOTIFY fdePasswordChanged ) | ||||||
|     Q_PROPERTY( bool isFdeEnabled READ isFdeEnabled WRITE setIsFdeEnabled ) |     Q_PROPERTY( bool isFdeEnabled READ isFdeEnabled WRITE setIsFdeEnabled ) | ||||||
|  |  | ||||||
|  |     /* filesystem selection */ | ||||||
|  |     Q_PROPERTY( QString fsType READ fsType WRITE setFsType NOTIFY fsTypeChanged ) | ||||||
|  |     Q_PROPERTY( bool featureFsType READ featureFsType CONSTANT FINAL ) | ||||||
|  |     Q_PROPERTY( QStringList fsList READ fsList CONSTANT FINAL ) | ||||||
|  |     Q_PROPERTY( QString defaultFs READ defaultFs CONSTANT FINAL ) | ||||||
|  |     Q_PROPERTY( int fsIndex READ fsIndex WRITE setFsIndex NOTIFY fsIndexChanged ) | ||||||
|  |  | ||||||
|     /* partition job */ |     /* partition job */ | ||||||
|  |     Q_PROPERTY( bool runPartitionJobThenLeave READ runPartitionJobThenLeaveDummy WRITE runPartitionJobThenLeave ) | ||||||
|  |     Q_PROPERTY( QString cmdInternalStoragePrepare READ cmdInternalStoragePrepare CONSTANT FINAL ) | ||||||
|     Q_PROPERTY( QString cmdLuksFormat READ cmdLuksFormat CONSTANT FINAL ) |     Q_PROPERTY( QString cmdLuksFormat READ cmdLuksFormat CONSTANT FINAL ) | ||||||
|     Q_PROPERTY( QString cmdLuksOpen READ cmdLuksOpen CONSTANT FINAL ) |     Q_PROPERTY( QString cmdLuksOpen READ cmdLuksOpen CONSTANT FINAL ) | ||||||
|     Q_PROPERTY( QString cmdMkfsRoot READ cmdMkfsRoot CONSTANT FINAL ) |  | ||||||
|     Q_PROPERTY( QString cmdMount READ cmdMount CONSTANT FINAL ) |     Q_PROPERTY( QString cmdMount READ cmdMount CONSTANT FINAL ) | ||||||
|     Q_PROPERTY( QString targetDeviceRoot READ targetDeviceRoot CONSTANT FINAL ) |     Q_PROPERTY( QString targetDeviceRoot READ targetDeviceRoot CONSTANT FINAL ) | ||||||
|  |     Q_PROPERTY( QString targetDeviceRootInternal READ targetDeviceRootInternal CONSTANT FINAL ) | ||||||
|  |     Q_PROPERTY( | ||||||
|  |         bool installFromExternalToInternal READ installFromExternalToInternal WRITE setInstallFromExternalToInternal ) | ||||||
|  |  | ||||||
|     /* users job */ |     /* users job */ | ||||||
|     Q_PROPERTY( QString cmdSshdEnable READ cmdSshdEnable CONSTANT FINAL ) |     Q_PROPERTY( QString cmdSshdEnable READ cmdSshdEnable CONSTANT FINAL ) | ||||||
| @@ -41,6 +60,10 @@ class Config : public QObject | |||||||
| public: | public: | ||||||
|     Config( QObject* parent = nullptr ); |     Config( QObject* parent = nullptr ); | ||||||
|     void setConfigurationMap( const QVariantMap& ); |     void setConfigurationMap( const QVariantMap& ); | ||||||
|  |     Calamares::JobList createJobs(); | ||||||
|  |  | ||||||
|  |     /* installer UI */ | ||||||
|  |     bool builtinVirtualKeyboard() { return m_builtinVirtualKeyboard; } | ||||||
|  |  | ||||||
|     /* welcome */ |     /* welcome */ | ||||||
|     QString osName() const { return m_osName; } |     QString osName() const { return m_osName; } | ||||||
| @@ -53,8 +76,10 @@ public: | |||||||
|     QString username() const { return m_username; } |     QString username() const { return m_username; } | ||||||
|     QString userPassword() const { return m_userPassword; } |     QString userPassword() const { return m_userPassword; } | ||||||
|     void setUserPassword( const QString& userPassword ); |     void setUserPassword( const QString& userPassword ); | ||||||
|  |     bool userPasswordNumeric() const { return m_userPasswordNumeric; } | ||||||
|  |  | ||||||
|     /* ssh server + credetials */ |     /* ssh server + credetials */ | ||||||
|  |     bool featureSshd() { return m_featureSshd; } | ||||||
|     QString sshdUsername() const { return m_sshdUsername; } |     QString sshdUsername() const { return m_sshdUsername; } | ||||||
|     QString sshdPassword() const { return m_sshdPassword; } |     QString sshdPassword() const { return m_sshdPassword; } | ||||||
|     bool isSshEnabled() { return m_isSshEnabled; } |     bool isSshEnabled() { return m_isSshEnabled; } | ||||||
| @@ -68,12 +93,30 @@ public: | |||||||
|     void setFdePassword( const QString& fdePassword ); |     void setFdePassword( const QString& fdePassword ); | ||||||
|     void setIsFdeEnabled( bool isFdeEnabled ); |     void setIsFdeEnabled( bool isFdeEnabled ); | ||||||
|  |  | ||||||
|  |     /* filesystem selection */ | ||||||
|  |     bool featureFsType() { return m_featureFsType; }; | ||||||
|  |     QString fsType() const { return m_fsType; }; | ||||||
|  |     void setFsType( int idx ); | ||||||
|  |     void setFsType( const QString& fsType ); | ||||||
|  |     QStringList fsList() const { return m_fsList; }; | ||||||
|  |     int fsIndex() const { return m_fsIndex; }; | ||||||
|  |     void setFsIndex( const int fsIndex ); | ||||||
|  |     QString defaultFs() const { return m_defaultFs; }; | ||||||
|  |  | ||||||
|     /* partition job */ |     /* partition job */ | ||||||
|  |     bool runPartitionJobThenLeaveDummy() { return 0; } | ||||||
|  |     void runPartitionJobThenLeave( bool b ); | ||||||
|  |     QString cmdInternalStoragePrepare() const { return m_cmdInternalStoragePrepare; } | ||||||
|     QString cmdLuksFormat() const { return m_cmdLuksFormat; } |     QString cmdLuksFormat() const { return m_cmdLuksFormat; } | ||||||
|     QString cmdLuksOpen() const { return m_cmdLuksOpen; } |     QString cmdLuksOpen() const { return m_cmdLuksOpen; } | ||||||
|     QString cmdMkfsRoot() const { return m_cmdMkfsRoot; } |     QString cmdMkfsRootBtrfs() const { return m_cmdMkfsRootBtrfs; } | ||||||
|  |     QString cmdMkfsRootExt4() const { return m_cmdMkfsRootExt4; } | ||||||
|  |     QString cmdMkfsRootF2fs() const { return m_cmdMkfsRootF2fs; } | ||||||
|     QString cmdMount() const { return m_cmdMount; } |     QString cmdMount() const { return m_cmdMount; } | ||||||
|     QString targetDeviceRoot() const { return m_targetDeviceRoot; } |     QString targetDeviceRoot() const { return m_targetDeviceRoot; } | ||||||
|  |     QString targetDeviceRootInternal() const { return m_targetDeviceRootInternal; } | ||||||
|  |     bool installFromExternalToInternal() { return m_installFromExternalToInternal; } | ||||||
|  |     void setInstallFromExternalToInternal( const bool val ); | ||||||
|  |  | ||||||
|     /* users job */ |     /* users job */ | ||||||
|     QString cmdPasswd() const { return m_cmdPasswd; } |     QString cmdPasswd() const { return m_cmdPasswd; } | ||||||
| @@ -82,6 +125,9 @@ public: | |||||||
|     QString cmdSshdUseradd() const { return m_cmdSshdUseradd; } |     QString cmdSshdUseradd() const { return m_cmdSshdUseradd; } | ||||||
|  |  | ||||||
| private: | private: | ||||||
|  |     /* installer UI */ | ||||||
|  |     bool m_builtinVirtualKeyboard; | ||||||
|  |  | ||||||
|     /* welcome */ |     /* welcome */ | ||||||
|     QString m_osName; |     QString m_osName; | ||||||
|     QString m_arch; |     QString m_arch; | ||||||
| @@ -92,22 +138,37 @@ private: | |||||||
|     /* default user */ |     /* default user */ | ||||||
|     QString m_username; |     QString m_username; | ||||||
|     QString m_userPassword; |     QString m_userPassword; | ||||||
|  |     bool m_userPasswordNumeric; | ||||||
|  |  | ||||||
|     /* ssh server + credetials */ |     /* ssh server + credentials */ | ||||||
|  |     bool m_featureSshd = false; | ||||||
|     QString m_sshdUsername; |     QString m_sshdUsername; | ||||||
|     QString m_sshdPassword; |     QString m_sshdPassword; | ||||||
|     bool m_isSshEnabled; |     bool m_isSshEnabled = false; | ||||||
|  |  | ||||||
|     /* full disk encryption */ |     /* full disk encryption */ | ||||||
|     QString m_fdePassword = ""; |     QString m_fdePassword; | ||||||
|     bool m_isFdeEnabled = false; |     bool m_isFdeEnabled = false; | ||||||
|  |  | ||||||
|  |     /* filesystem selection */ | ||||||
|  |     bool m_featureFsType = false; | ||||||
|  |     QString m_defaultFs; | ||||||
|  |     QString m_fsType; | ||||||
|  |     // Index of the currently selected filesystem in UI. | ||||||
|  |     int m_fsIndex = -1; | ||||||
|  |     QStringList m_fsList; | ||||||
|  |  | ||||||
|     /* partition job */ |     /* partition job */ | ||||||
|  |     QString m_cmdInternalStoragePrepare; | ||||||
|     QString m_cmdLuksFormat; |     QString m_cmdLuksFormat; | ||||||
|     QString m_cmdLuksOpen; |     QString m_cmdLuksOpen; | ||||||
|     QString m_cmdMkfsRoot; |     QString m_cmdMkfsRootBtrfs; | ||||||
|  |     QString m_cmdMkfsRootExt4; | ||||||
|  |     QString m_cmdMkfsRootF2fs; | ||||||
|     QString m_cmdMount; |     QString m_cmdMount; | ||||||
|     QString m_targetDeviceRoot; |     QString m_targetDeviceRoot; | ||||||
|  |     QString m_targetDeviceRootInternal; | ||||||
|  |     bool m_installFromExternalToInternal = false; | ||||||
|  |  | ||||||
|     /* users job */ |     /* users job */ | ||||||
|     QString m_cmdPasswd; |     QString m_cmdPasswd; | ||||||
| @@ -116,14 +177,18 @@ private: | |||||||
|     QString m_cmdSshdUseradd; |     QString m_cmdSshdUseradd; | ||||||
|  |  | ||||||
| signals: | signals: | ||||||
|  |     /* booleans we don't read from QML (like isSshEnabled) don't need a signal */ | ||||||
|  |  | ||||||
|     /* default user */ |     /* default user */ | ||||||
|     void userPasswordChanged( QString userPassword ); |     void userPasswordChanged( QString userPassword ); | ||||||
|  |  | ||||||
|     /* ssh server + credetials */ |     /* ssh server + credentials */ | ||||||
|     void sshdUsernameChanged( QString sshdUsername ); |     void sshdUsernameChanged( QString sshdUsername ); | ||||||
|     void sshdPasswordChanged( QString sshdPassword ); |     void sshdPasswordChanged( QString sshdPassword ); | ||||||
|     /* isSshEnabled doesn't need a signal, we don't read it from QML */ |  | ||||||
|  |  | ||||||
|     /* full disk encryption */ |     /* full disk encryption */ | ||||||
|     void fdePasswordChanged( QString fdePassword ); |     void fdePasswordChanged( QString fdePassword ); | ||||||
|  |  | ||||||
|  |     void fsTypeChanged( QString fsType ); | ||||||
|  |     void fsIndexChanged( int fsIndex ); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -1,20 +1,15 @@ | |||||||
| /* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org> | /* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org> | ||||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ |  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||||
| #include "MobileQmlViewStep.h" | #include "MobileQmlViewStep.h" | ||||||
| #include "PartitionJob.h" |  | ||||||
| #include "UsersJob.h" |  | ||||||
|  |  | ||||||
|  | #include "Branding.h" | ||||||
| #include "GlobalStorage.h" | #include "GlobalStorage.h" | ||||||
| #include "JobQueue.h" | #include "locale/TranslationsModel.h" | ||||||
|  | #include "modulesystem/ModuleManager.h" | ||||||
| #include "locale/LabelModel.h" |  | ||||||
| #include "utils/Dirs.h" | #include "utils/Dirs.h" | ||||||
| #include "utils/Logger.h" | #include "utils/Logger.h" | ||||||
| #include "utils/Variant.h" | #include "utils/Variant.h" | ||||||
|  |  | ||||||
| #include "Branding.h" |  | ||||||
| #include "modulesystem/ModuleManager.h" |  | ||||||
|  |  | ||||||
| #include <QProcess> | #include <QProcess> | ||||||
|  |  | ||||||
| CALAMARES_PLUGIN_FACTORY_DEFINITION( MobileQmlViewStepFactory, registerPlugin< MobileQmlViewStep >(); ) | CALAMARES_PLUGIN_FACTORY_DEFINITION( MobileQmlViewStepFactory, registerPlugin< MobileQmlViewStep >(); ) | ||||||
| @@ -35,34 +30,7 @@ MobileQmlViewStep::MobileQmlViewStep( QObject* parent ) | |||||||
| void | void | ||||||
| MobileQmlViewStep::onLeave() | MobileQmlViewStep::onLeave() | ||||||
| { | { | ||||||
|     Calamares::Job *partition, *users; |     return; | ||||||
|  |  | ||||||
|     /* HACK: run partition job now */ |  | ||||||
|     partition = new PartitionJob( m_config->cmdLuksFormat(), |  | ||||||
|                                   m_config->cmdLuksOpen(), |  | ||||||
|                                   m_config->cmdMkfsRoot(), |  | ||||||
|                                   m_config->cmdMount(), |  | ||||||
|                                   m_config->targetDeviceRoot(), |  | ||||||
|                                   m_config->isFdeEnabled(), |  | ||||||
|                                   m_config->fdePassword() ); |  | ||||||
|     Calamares::JobResult res = partition->exec(); |  | ||||||
|     if ( !res ) |  | ||||||
|     { |  | ||||||
|         cError() << "PARTITION JOB FAILED: " << res.message(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /* Put users job in queue (should run after unpackfs) */ |  | ||||||
|     m_jobs.clear(); |  | ||||||
|     QString cmdSshd = m_config->isSshEnabled() ? m_config->cmdSshdEnable() : m_config->cmdSshdDisable(); |  | ||||||
|     users = new UsersJob( m_config->cmdPasswd(), |  | ||||||
|                           cmdSshd, |  | ||||||
|                           m_config->cmdSshdUseradd(), |  | ||||||
|                           m_config->isSshEnabled(), |  | ||||||
|                           m_config->username(), |  | ||||||
|                           m_config->userPassword(), |  | ||||||
|                           m_config->sshdUsername(), |  | ||||||
|                           m_config->sshdPassword() ); |  | ||||||
|     m_jobs.append( Calamares::job_ptr( users ) ); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| bool | bool | ||||||
| @@ -95,7 +63,7 @@ MobileQmlViewStep::isAtEnd() const | |||||||
| Calamares::JobList | Calamares::JobList | ||||||
| MobileQmlViewStep::jobs() const | MobileQmlViewStep::jobs() const | ||||||
| { | { | ||||||
|     return m_jobs; |     return m_config->createJobs(); | ||||||
| } | } | ||||||
|  |  | ||||||
| QObject* | QObject* | ||||||
|   | |||||||
| @@ -32,7 +32,6 @@ public: | |||||||
|  |  | ||||||
| private: | private: | ||||||
|     Config* m_config; |     Config* m_config; | ||||||
|     QList< Calamares::job_ptr > m_jobs; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| CALAMARES_PLUGIN_FACTORY_DECLARATION( MobileQmlViewStepFactory ) | CALAMARES_PLUGIN_FACTORY_DECLARATION( MobileQmlViewStepFactory ) | ||||||
|   | |||||||
| @@ -12,19 +12,25 @@ | |||||||
| #include <QFileInfo> | #include <QFileInfo> | ||||||
|  |  | ||||||
|  |  | ||||||
| PartitionJob::PartitionJob( QString cmdLuksFormat, | PartitionJob::PartitionJob( const QString& cmdInternalStoragePrepare, | ||||||
|                             QString cmdLuksOpen, |                             const QString& cmdLuksFormat, | ||||||
|                             QString cmdMkfsRoot, |                             const QString& cmdLuksOpen, | ||||||
|                             QString cmdMount, |                             const QString& cmdMkfsRoot, | ||||||
|                             QString targetDeviceRoot, |                             const QString& cmdMount, | ||||||
|  |                             const QString& targetDeviceRoot, | ||||||
|  |                             const QString& targetDeviceRootInternal, | ||||||
|  |                             bool installFromExternalToInternal, | ||||||
|                             bool isFdeEnabled, |                             bool isFdeEnabled, | ||||||
|                             const QString& password ) |                             const QString& password ) | ||||||
|     : Calamares::Job() |     : Calamares::Job() | ||||||
|  |     , m_cmdInternalStoragePrepare( cmdInternalStoragePrepare ) | ||||||
|     , m_cmdLuksFormat( cmdLuksFormat ) |     , m_cmdLuksFormat( cmdLuksFormat ) | ||||||
|     , m_cmdLuksOpen( cmdLuksOpen ) |     , m_cmdLuksOpen( cmdLuksOpen ) | ||||||
|     , m_cmdMkfsRoot( cmdMkfsRoot ) |     , m_cmdMkfsRoot( cmdMkfsRoot ) | ||||||
|     , m_cmdMount( cmdMount ) |     , m_cmdMount( cmdMount ) | ||||||
|     , m_targetDeviceRoot( targetDeviceRoot ) |     , m_targetDeviceRoot( targetDeviceRoot ) | ||||||
|  |     , m_targetDeviceRootInternal( targetDeviceRootInternal ) | ||||||
|  |     , m_installFromExternalToInternal( installFromExternalToInternal ) | ||||||
|     , m_isFdeEnabled( isFdeEnabled ) |     , m_isFdeEnabled( isFdeEnabled ) | ||||||
|     , m_password( password ) |     , m_password( password ) | ||||||
| { | { | ||||||
| @@ -77,10 +83,18 @@ PartitionJob::exec() | |||||||
|     QString cryptDev = "/dev/mapper/" + cryptName; |     QString cryptDev = "/dev/mapper/" + cryptName; | ||||||
|     QString passwordStdin = m_password + "\n"; |     QString passwordStdin = m_password + "\n"; | ||||||
|     QString dev = m_targetDeviceRoot; |     QString dev = m_targetDeviceRoot; | ||||||
|  |     QList< QPair< QStringList, QString > > commands = {}; | ||||||
|  |  | ||||||
|     QList< QPair< QStringList, QString > > commands = { |     if ( m_installFromExternalToInternal ) | ||||||
|         { { "mkdir", "-p", pathMount }, QString() }, |     { | ||||||
|     }; |         dev = m_targetDeviceRootInternal; | ||||||
|  |  | ||||||
|  |         commands.append( { | ||||||
|  |             { { "sh", "-c", m_cmdInternalStoragePrepare }, QString() }, | ||||||
|  |         } ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     commands.append( { { { "mkdir", "-p", pathMount }, QString() } } ); | ||||||
|  |  | ||||||
|     if ( m_isFdeEnabled ) |     if ( m_isFdeEnabled ) | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -8,11 +8,14 @@ class PartitionJob : public Calamares::Job | |||||||
| { | { | ||||||
|     Q_OBJECT |     Q_OBJECT | ||||||
| public: | public: | ||||||
|     PartitionJob( QString cmdLuksFormat, |     PartitionJob( const QString& cmdInternalStoragePrepare, | ||||||
|                   QString cmdLuksOpen, |                   const QString& cmdLuksFormat, | ||||||
|                   QString cmdMkfsRoot, |                   const QString& cmdLuksOpen, | ||||||
|                   QString cmdMount, |                   const QString& cmdMkfsRoot, | ||||||
|                   QString targetDeviceRoot, |                   const QString& cmdMount, | ||||||
|  |                   const QString& targetDeviceRoot, | ||||||
|  |                   const QString& targetDeviceRootInternal, | ||||||
|  |                   bool installFromExternalToInternal, | ||||||
|                   bool isFdeEnabled, |                   bool isFdeEnabled, | ||||||
|                   const QString& password ); |                   const QString& password ); | ||||||
|  |  | ||||||
| @@ -22,11 +25,14 @@ public: | |||||||
|     Calamares::JobList createJobs(); |     Calamares::JobList createJobs(); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|  |     QString m_cmdInternalStoragePrepare; | ||||||
|     QString m_cmdLuksFormat; |     QString m_cmdLuksFormat; | ||||||
|     QString m_cmdLuksOpen; |     QString m_cmdLuksOpen; | ||||||
|     QString m_cmdMkfsRoot; |     QString m_cmdMkfsRoot; | ||||||
|     QString m_cmdMount; |     QString m_cmdMount; | ||||||
|     QString m_targetDeviceRoot; |     QString m_targetDeviceRoot; | ||||||
|  |     QString m_targetDeviceRootInternal; | ||||||
|  |     bool m_installFromExternalToInternal; | ||||||
|     bool m_isFdeEnabled; |     bool m_isFdeEnabled; | ||||||
|     QString m_password; |     QString m_password; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -12,15 +12,17 @@ | |||||||
| #include <QFileInfo> | #include <QFileInfo> | ||||||
|  |  | ||||||
|  |  | ||||||
| UsersJob::UsersJob( QString cmdPasswd, | UsersJob::UsersJob( bool featureSshd, | ||||||
|                     QString cmdSshd, |                     const QString& cmdPasswd, | ||||||
|                     QString cmdSshdUseradd, |                     const QString& cmdSshd, | ||||||
|  |                     const QString& cmdSshdUseradd, | ||||||
|                     bool isSshEnabled, |                     bool isSshEnabled, | ||||||
|                     QString username, |                     const QString& username, | ||||||
|                     QString password, |                     const QString& password, | ||||||
|                     QString sshdUsername, |                     const QString& sshdUsername, | ||||||
|                     QString sshdPassword ) |                     const QString& sshdPassword ) | ||||||
|     : Calamares::Job() |     : Calamares::Job() | ||||||
|  |     , m_featureSshd( featureSshd ) | ||||||
|     , m_cmdPasswd( cmdPasswd ) |     , m_cmdPasswd( cmdPasswd ) | ||||||
|     , m_cmdSshd( cmdSshd ) |     , m_cmdSshd( cmdSshd ) | ||||||
|     , m_cmdSshdUseradd( cmdSshdUseradd ) |     , m_cmdSshdUseradd( cmdSshdUseradd ) | ||||||
| @@ -48,14 +50,18 @@ UsersJob::exec() | |||||||
|  |  | ||||||
|     QList< QPair< QStringList, QString > > commands = { |     QList< QPair< QStringList, QString > > commands = { | ||||||
|         { { "sh", "-c", m_cmdPasswd + " " + m_username }, m_password + "\n" + m_password + "\n" }, |         { { "sh", "-c", m_cmdPasswd + " " + m_username }, m_password + "\n" + m_password + "\n" }, | ||||||
|         { { "sh", "-c", m_cmdSshd }, QString() }, |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     if ( m_isSshEnabled ) |     if ( m_featureSshd ) | ||||||
|     { |     { | ||||||
|         commands.append( { { "sh", "-c", m_cmdSshdUseradd + " " + m_sshdUsername }, QString() } ); |         commands.append( { { "sh", "-c", m_cmdSshd }, QString() } ); | ||||||
|         commands.append( |  | ||||||
|             { { "sh", "-c", m_cmdPasswd + " " + m_sshdUsername }, m_sshdPassword + "\n" + m_sshdPassword + "\n" } ); |         if ( m_isSshEnabled ) | ||||||
|  |         { | ||||||
|  |             commands.append( { { "sh", "-c", m_cmdSshdUseradd + " " + m_sshdUsername }, QString() } ); | ||||||
|  |             commands.append( | ||||||
|  |                 { { "sh", "-c", m_cmdPasswd + " " + m_sshdUsername }, m_sshdPassword + "\n" + m_sshdPassword + "\n" } ); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     foreach ( auto command, commands ) |     foreach ( auto command, commands ) | ||||||
|   | |||||||
| @@ -8,14 +8,15 @@ class UsersJob : public Calamares::Job | |||||||
| { | { | ||||||
|     Q_OBJECT |     Q_OBJECT | ||||||
| public: | public: | ||||||
|     UsersJob( QString cmdPasswd, |     UsersJob( bool featureSshd, | ||||||
|               QString cmdSshd, |               const QString& cmdPasswd, | ||||||
|               QString cmdSshdUseradd, |               const QString& cmdSshd, | ||||||
|  |               const QString& cmdSshdUseradd, | ||||||
|               bool isSshEnabled, |               bool isSshEnabled, | ||||||
|               QString username, |               const QString& username, | ||||||
|               QString password, |               const QString& password, | ||||||
|               QString sshdUsername, |               const QString& sshdUsername, | ||||||
|               QString sshdPassword ); |               const QString& sshdPassword ); | ||||||
|  |  | ||||||
|     QString prettyName() const override; |     QString prettyName() const override; | ||||||
|     Calamares::JobResult exec() override; |     Calamares::JobResult exec() override; | ||||||
| @@ -23,6 +24,7 @@ public: | |||||||
|     Calamares::JobList createJobs(); |     Calamares::JobList createJobs(); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|  |     bool m_featureSshd; | ||||||
|     QString m_cmdPasswd; |     QString m_cmdPasswd; | ||||||
|     QString m_cmdSshd; |     QString m_cmdSshd; | ||||||
|     QString m_cmdSshdUseradd; |     QString m_cmdSshdUseradd; | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ Item { | |||||||
|     height: parent.height |     height: parent.height | ||||||
|  |  | ||||||
|     Text { |     Text { | ||||||
|         id: welcomeText |         id: mainText | ||||||
|         anchors.horizontalCenter: parent.horizontalCenter |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|         anchors.top: parent.top |         anchors.top: parent.top | ||||||
|         anchors.topMargin: 30 |         anchors.topMargin: 30 | ||||||
| @@ -37,29 +37,29 @@ Item { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     Button { |     Button { | ||||||
|         id: enableButton |         id: firstButton | ||||||
|         anchors.horizontalCenter: parent.horizontalCenter |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|         anchors.top: welcomeText.bottom |         anchors.top: mainText.bottom | ||||||
|         anchors.topMargin: 40 |         anchors.topMargin: 40 | ||||||
|         width: 500 |         width: 500 | ||||||
|  |  | ||||||
|         text: qsTr("Enable") |         text: qsTr("Enable") | ||||||
|         onClicked: { |         onClicked: { | ||||||
|             config.isFdeEnabled = true; |             config.isFdeEnabled = true; | ||||||
|             navTo("fde_pass"); |             navNext(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     Button { |     Button { | ||||||
|         anchors.horizontalCenter: parent.horizontalCenter |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|         anchors.top: enableButton.bottom |         anchors.top: firstButton.bottom | ||||||
|         anchors.topMargin: 40 |         anchors.topMargin: 40 | ||||||
|         width: 500 |         width: 500 | ||||||
|  |  | ||||||
|         text: qsTr("Disable") |         text: qsTr("Disable") | ||||||
|         onClicked: { |         onClicked: { | ||||||
|             config.isFdeEnabled = false; |             config.isFdeEnabled = false; | ||||||
|             navTo("install_confirm"); |             navNextFeature(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -73,7 +73,7 @@ Item { | |||||||
|         onClicked: { |         onClicked: { | ||||||
|             if (validatePassword(password, passwordRepeat, errorText)) { |             if (validatePassword(password, passwordRepeat, errorText)) { | ||||||
|                 config.fdePassword = password.text; |                 config.fdePassword = password.text; | ||||||
|                 navTo("install_confirm"); |                 navNext(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
							
								
								
									
										59
									
								
								modules/mobile/fs_selection.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								modules/mobile/fs_selection.qml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | |||||||
|  | /* SPDX-FileCopyrightText: 2020 Undef <calamares@undef.tools> | ||||||
|  |  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||||
|  | import io.calamares.core 1.0 | ||||||
|  | import io.calamares.ui 1.0 | ||||||
|  |  | ||||||
|  | import QtQuick 2.10 | ||||||
|  | import QtQuick.Controls 2.10 | ||||||
|  | import QtQuick.Layouts 1.3 | ||||||
|  | import org.kde.kirigami 2.7 as Kirigami | ||||||
|  | import QtGraphicalEffects 1.0 | ||||||
|  | import QtQuick.Window 2.3 | ||||||
|  | import QtQuick.VirtualKeyboard 2.1 | ||||||
|  |  | ||||||
|  | Item { | ||||||
|  |     anchors.left: parent.left | ||||||
|  |     anchors.top: parent.top | ||||||
|  |     anchors.right: parent.right | ||||||
|  |     width: parent.width | ||||||
|  |     height: parent.height | ||||||
|  |  | ||||||
|  |     Text { | ||||||
|  |         id: mainText | ||||||
|  |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|  |         anchors.top: parent.top | ||||||
|  |         anchors.topMargin: 30 | ||||||
|  |         wrapMode: Text.WordWrap | ||||||
|  |  | ||||||
|  |         text: "Select the filesystem for root partition. If unsure, leave the default." | ||||||
|  |  | ||||||
|  |         width: 500 | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ComboBox { | ||||||
|  |         id: fsTypeCB | ||||||
|  |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|  |         anchors.top: mainText.bottom | ||||||
|  |         anchors.topMargin: 40 | ||||||
|  |         width: 500 | ||||||
|  |         height: 60 | ||||||
|  |         editable: false | ||||||
|  |         model: config.fsList | ||||||
|  |         /* Save the current state on selection so it is there when the back button is pressed */ | ||||||
|  |         onActivated: config.fsType = fsTypeCB.currentText; | ||||||
|  |         Component.onCompleted: fsTypeCB.currentIndex = find( config.fsType, Qt.MatchContains ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Button { | ||||||
|  |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|  |         anchors.top: fsTypeCB.bottom | ||||||
|  |         anchors.topMargin: 40 | ||||||
|  |         width: 500 | ||||||
|  |  | ||||||
|  |         text: qsTr("Continue") | ||||||
|  |         onClicked: { | ||||||
|  |             config.fsType = fsTypeCB.currentText; | ||||||
|  |             navNextFeature(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -19,24 +19,38 @@ Item { | |||||||
|     height: parent.height |     height: parent.height | ||||||
|  |  | ||||||
|     Text { |     Text { | ||||||
|         id: welcomeText |         id: mainText | ||||||
|         anchors.horizontalCenter: parent.horizontalCenter |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|         anchors.top: parent.top |         anchors.top: parent.top | ||||||
|         anchors.topMargin: 30 |         anchors.topMargin: 30 | ||||||
|         wrapMode: Text.WordWrap |         wrapMode: Text.WordWrap | ||||||
|  |  | ||||||
|         text: "Once you hit 'install', the installation will begin. It will" + |         text: (function() { | ||||||
|               " typically take a few minutes. Do not power off the device" + |             var ret = "Once you hit 'install', the installation will begin." + | ||||||
|               " until it is done. Afterwards, it will reboot into the" + |                 " It will typically take a few minutes. Do not power off the" + | ||||||
|               " installed system." |                 " device until it is done.<br><br>"; | ||||||
|  |  | ||||||
|  |             if (config.installFromExternalToInternal) { | ||||||
|  |                 ret += "<b>After the installation, your device will shutdown" + | ||||||
|  |                        " automatically. You must remove the external storage" + | ||||||
|  |                        " (SD card) before booting again.</b>" + | ||||||
|  |                        "<br><br>" + | ||||||
|  |                        "Otherwise, your device will boot into the installer" + | ||||||
|  |                        " again, and not into the installed system." | ||||||
|  |             } else { | ||||||
|  |                 ret += "Afterwards, it will reboot into the installed system."; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return ret; | ||||||
|  |         }()) | ||||||
|  |  | ||||||
|         width: 500 |         width: 500 | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     Button { |     Button { | ||||||
|         id: enableButton |         id: firstButton | ||||||
|         anchors.horizontalCenter: parent.horizontalCenter |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|         anchors.top: welcomeText.bottom |         anchors.top: mainText.bottom | ||||||
|         anchors.topMargin: 40 |         anchors.topMargin: 40 | ||||||
|         width: 500 |         width: 500 | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										64
									
								
								modules/mobile/install_target.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								modules/mobile/install_target.qml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | /* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org> | ||||||
|  |  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||||
|  | import io.calamares.core 1.0 | ||||||
|  | import io.calamares.ui 1.0 | ||||||
|  |  | ||||||
|  | import QtQuick 2.10 | ||||||
|  | import QtQuick.Controls 2.10 | ||||||
|  | import QtQuick.Layouts 1.3 | ||||||
|  | import org.kde.kirigami 2.7 as Kirigami | ||||||
|  | import QtGraphicalEffects 1.0 | ||||||
|  | import QtQuick.Window 2.3 | ||||||
|  | import QtQuick.VirtualKeyboard 2.1 | ||||||
|  |  | ||||||
|  | Item { | ||||||
|  |     anchors.left: parent.left | ||||||
|  |     anchors.top: parent.top | ||||||
|  |     anchors.right: parent.right | ||||||
|  |     width: parent.width | ||||||
|  |     height: parent.height | ||||||
|  |  | ||||||
|  |     Text { | ||||||
|  |         id: mainText | ||||||
|  |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|  |         anchors.top: parent.top | ||||||
|  |         anchors.topMargin: 30 | ||||||
|  |         wrapMode: Text.WordWrap | ||||||
|  |  | ||||||
|  |         text: "The installation was started from an external storage medium." + | ||||||
|  |               "<br>" + | ||||||
|  |               "You can either install to the same medium and overwrite the" + | ||||||
|  |               " installer, or install to the internal storage.<br>" + | ||||||
|  |               "<br>" + | ||||||
|  |               "Where would you like to install " + config.osName + "?" | ||||||
|  |  | ||||||
|  |         width: 500 | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Button { | ||||||
|  |         id: firstButton | ||||||
|  |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|  |         anchors.top: mainText.bottom | ||||||
|  |         anchors.topMargin: 40 | ||||||
|  |         width: 500 | ||||||
|  |  | ||||||
|  |         text: qsTr("Internal (eMMC)") | ||||||
|  |         onClicked: { | ||||||
|  |             config.installFromExternalToInternal = true; | ||||||
|  |             navNext(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Button { | ||||||
|  |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|  |         anchors.top: firstButton.bottom | ||||||
|  |         anchors.topMargin: 40 | ||||||
|  |         width: 500 | ||||||
|  |  | ||||||
|  |         text: qsTr("External (SD card)") | ||||||
|  |         onClicked: { | ||||||
|  |             config.installFromExternalToInternal = false; | ||||||
|  |             navNextFeature(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										58
									
								
								modules/mobile/install_target_confirm.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								modules/mobile/install_target_confirm.qml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | |||||||
|  | /* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org> | ||||||
|  |  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||||
|  | import io.calamares.core 1.0 | ||||||
|  | import io.calamares.ui 1.0 | ||||||
|  |  | ||||||
|  | import QtQuick 2.10 | ||||||
|  | import QtQuick.Controls 2.10 | ||||||
|  | import QtQuick.Layouts 1.3 | ||||||
|  | import org.kde.kirigami 2.7 as Kirigami | ||||||
|  | import QtGraphicalEffects 1.0 | ||||||
|  | import QtQuick.Window 2.3 | ||||||
|  | import QtQuick.VirtualKeyboard 2.1 | ||||||
|  |  | ||||||
|  | Item { | ||||||
|  |     anchors.left: parent.left | ||||||
|  |     anchors.top: parent.top | ||||||
|  |     anchors.right: parent.right | ||||||
|  |     width: parent.width | ||||||
|  |     height: parent.height | ||||||
|  |  | ||||||
|  |     Text { | ||||||
|  |         id: mainText | ||||||
|  |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|  |         anchors.top: parent.top | ||||||
|  |         anchors.topMargin: 30 | ||||||
|  |         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 | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Button { | ||||||
|  |         id: firstButton | ||||||
|  |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|  |         anchors.top: mainText.bottom | ||||||
|  |         anchors.topMargin: 40 | ||||||
|  |         width: 500 | ||||||
|  |  | ||||||
|  |         text: qsTr("Yes") | ||||||
|  |         onClicked: { | ||||||
|  |             navNext(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     Button { | ||||||
|  |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|  |         anchors.top: firstButton.bottom | ||||||
|  |         anchors.topMargin: 40 | ||||||
|  |         width: 500 | ||||||
|  |  | ||||||
|  |         text: qsTr("No") | ||||||
|  |         onClicked: { | ||||||
|  |             navBack(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,6 +1,13 @@ | |||||||
|  | # SPDX-FileCopyrightText: no | ||||||
|  | # SPDX-License-Identifier: CC0-1.0 | ||||||
|  | # | ||||||
| # Commented out values are defaults. | # Commented out values are defaults. | ||||||
| # All commands are running with 'sh -c'. | # 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 | ### Target OS information | ||||||
| ####### | ####### | ||||||
| @@ -11,6 +18,10 @@ | |||||||
| ## User Interface name (e.g. Plasma Mobile) | ## User Interface name (e.g. Plasma Mobile) | ||||||
| # userInterface: "(unknown)" | # 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 | ## OS version | ||||||
| # version: "(unknown)" | # version: "(unknown)" | ||||||
|  |  | ||||||
| @@ -27,9 +38,47 @@ | |||||||
| ## Name of the device (e.g. PinePhone) | ## Name of the device (e.g. PinePhone) | ||||||
| # device: "(unknown)" | # device: "(unknown)" | ||||||
|  |  | ||||||
| ## Partition that will be formatted and mounted (optionally with FDE) for the rootfs | ## Partition that will be formatted and mounted (optionally with FDE) for the | ||||||
|  | ## rootfs | ||||||
| # targetDeviceRoot: "/dev/unknown" | # targetDeviceRoot: "/dev/unknown" | ||||||
|  |  | ||||||
|  | ## Partition that will be formatted and mounted (optionally with FDE) for the | ||||||
|  | ## rootfs, on internal storage. The installer OS must not set this, if it was | ||||||
|  | ## booted from the internal storage (this is not checked in the mobile | ||||||
|  | ## module!). | ||||||
|  | ## If this is set, the user gets asked whether they want to install on internal | ||||||
|  | ## or external storage. If the user chose internal storage, | ||||||
|  | ## cmdInternalStoragePrepare (see below) runs before this partition gets | ||||||
|  | ## formatted (see below). A note is displayed, that the device is powered off | ||||||
|  | ## after installation and that the user should remove the external storage | ||||||
|  | ## medium. So you need to adjust the installer OS to poweroff in that case, and | ||||||
|  | ## not reboot. See postmarketos-ondev.git for reference. | ||||||
|  | # targetDeviceRootInternal: "" | ||||||
|  |  | ||||||
|  | ###### | ||||||
|  | ### Installer Features | ||||||
|  | ###### | ||||||
|  |  | ||||||
|  | ## Ask whether sshd should be enabled or not. If enabled, add a dedicated ssh | ||||||
|  | ## user with proper username and password and suggest to change to key-based | ||||||
|  | ## authentication after installation. | ||||||
|  | # featureSshd: true | ||||||
|  |  | ||||||
|  | ## Ask the user, which filesystem to use. | ||||||
|  | # featureFsType: false | ||||||
|  | ## Filesystems that the user can choose from. | ||||||
|  | #fsModel: | ||||||
|  | #        - ext4 | ||||||
|  | #        - f2fs | ||||||
|  | #        - btrfs | ||||||
|  | ## Default filesystem to display in the dialog. If featureFsType is disabled, | ||||||
|  | ## this gets used without asking the user. | ||||||
|  | # defaultFs: ext4 | ||||||
|  |  | ||||||
|  | ## Start Qt's virtual keyboard within the mobile module. Disable if you bring | ||||||
|  | ## your own virtual keyboard (e.g. svkbd). | ||||||
|  | # builtinVirtualKeyboard: true | ||||||
|  |  | ||||||
| ####### | ####### | ||||||
| ### Commands running in the installer OS | ### Commands running in the installer OS | ||||||
| ####### | ####### | ||||||
| @@ -46,12 +95,25 @@ | |||||||
|  |  | ||||||
| ## Format the rootfs with a file system | ## Format the rootfs with a file system | ||||||
| ## Arguments: <device> | ## Arguments: <device> | ||||||
| # cmdMkfsRoot: "mkfs.ext4 -L 'unknownOS_root'" | ## Btrfs: to allow snapshots to work on the root subvolume, it is recommended that this | ||||||
|  | ## command be a script which will create a subvolume and make it default | ||||||
|  | ## An example can be found at: | ||||||
|  | ## https://gitlab.com/mobian1/calamares-settings-mobian/-/merge_requests/2/diffs#diff-content-dde34f5f1c89e3dea63608c553bbc452dedf428f | ||||||
|  | # cmdMkfsRootBtrfs: "mkfs.btrfs -L 'unknownOS_root'" | ||||||
|  | # cmdMkfsRootExt4: "mkfs.ext4 -L 'unknownOS_root'" | ||||||
|  | # cmdMkfsRootF2fs: "mkfs.f2fs -l 'unknownOS_root'" | ||||||
|  |  | ||||||
| ## Mount the partition after formatting with file system | ## Mount the partition after formatting with file system | ||||||
| ## Arguments: <device> <mountpoint> | ## Arguments: <device> <mountpoint> | ||||||
| # cmdMount: "mount" | # cmdMount: "mount" | ||||||
|  |  | ||||||
|  | ## When user selects installation from external storage to internal storage | ||||||
|  | ## (see targetDeviceRootInternal above), use this command to prepare the | ||||||
|  | ## internal storage medium. The command must create a partition table with | ||||||
|  | ## two partitions (boot, root) and fill the boot partition. See the | ||||||
|  | ## ondev-internal-storage-prepare.sh in postmarketos-ondev as example. | ||||||
|  | # cmdInternalStoragePrepare: "ondev-internal-storage-prepare" | ||||||
|  |  | ||||||
| ####### | ####### | ||||||
| ### Commands running in the target OS (chroot) | ### Commands running in the target OS (chroot) | ||||||
| ####### | ####### | ||||||
|   | |||||||
| @@ -17,16 +17,46 @@ Page | |||||||
|     property var screenPrevious: [] |     property var screenPrevious: [] | ||||||
|     property var titles: { |     property var titles: { | ||||||
|         "welcome": null, /* titlebar disabled */ |         "welcome": null, /* titlebar disabled */ | ||||||
|         "default_pin": "Lockscreen PIN", |         "install_target": "Installation target", | ||||||
|  |         "install_target_confirm": "Warning", | ||||||
|  |         "user_pass": "User password", | ||||||
|         "ssh_confirm": "SSH server", |         "ssh_confirm": "SSH server", | ||||||
|         "ssh_credentials": "SSH credentials", |         "ssh_credentials": "SSH credentials", | ||||||
|  |         "fs_selection": "Root filesystem", | ||||||
|         "fde_confirm": "Full disk encryption", |         "fde_confirm": "Full disk encryption", | ||||||
|         "fde_pass": "Full disk encryption", |         "fde_pass": "Full disk encryption", | ||||||
|         "install_confirm": "Ready to install", |         "install_confirm": "Ready to install", | ||||||
|         "wait": null |         "wait": null | ||||||
|     } |     } | ||||||
|     /* Only allow characters, that can be typed in with the initramfs on-screen keyboard |     property var features: [ | ||||||
|      * (osk-sdl: see src/keyboard.cpp). FIXME: make configurable, but keep this as default? */ |         {"name": "welcome", | ||||||
|  |          "screens": ["welcome"]}, | ||||||
|  |         {"name": "installTarget", | ||||||
|  |          "screens": ["install_target", "install_target_confirm"]}, | ||||||
|  |         {"name": "userPassword", | ||||||
|  |          "screens": ["user_pass"]}, | ||||||
|  |         {"name": "sshd", | ||||||
|  |          "screens": ["ssh_confirm", "ssh_credentials"]}, | ||||||
|  |         {"name": "fsType", | ||||||
|  |          "screens": ["fs_selection"]}, | ||||||
|  |         {"name": "fde", | ||||||
|  |          "screens": ["fde_confirm", "fde_pass"]}, | ||||||
|  |         {"name": "installConfirm", | ||||||
|  |          "screens": ["install_confirm", "wait"]} | ||||||
|  |     ] | ||||||
|  |     property var featureIdByScreen: (function() { | ||||||
|  |         /* Put "features" above into an index of screen name -> feature id: | ||||||
|  |          * featureIdByScreen = {"welcome": 0, "user_pass": 1, ...} */ | ||||||
|  |         var ret = {}; | ||||||
|  |         for (var i=0; i<features.length; i++) { | ||||||
|  |             for (var j=0; j<features[i]["screens"].length; j++) { | ||||||
|  |                 ret[ features[i]["screens"][j] ] = i; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return ret; | ||||||
|  |     }()) | ||||||
|  |     /* Only allow characters, that can be typed in with osk-sdl | ||||||
|  |      * (src/keyboard.cpp). Details in big comment in validatePassword(). */ | ||||||
|      property var allowed_chars: |      property var allowed_chars: | ||||||
|         /* layer 0 */ "abcdefghijklmnopqrstuvwxyz" + |         /* layer 0 */ "abcdefghijklmnopqrstuvwxyz" + | ||||||
|         /* layer 1 */ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + |         /* layer 1 */ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + | ||||||
| @@ -112,6 +142,7 @@ Page | |||||||
|     InputPanel { |     InputPanel { | ||||||
|         id: inputPanel |         id: inputPanel | ||||||
|         y: Qt.inputMethod.visible ? parent.height - inputPanel.height : parent.height |         y: Qt.inputMethod.visible ? parent.height - inputPanel.height : parent.height | ||||||
|  |         visible: config.builtinVirtualKeyboard | ||||||
|         anchors.left: parent.left |         anchors.left: parent.left | ||||||
|         anchors.right: parent.right |         anchors.right: parent.right | ||||||
|     } |     } | ||||||
| @@ -120,8 +151,13 @@ Page | |||||||
|         id: timer |         id: timer | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     function skipFeatureInstallTarget() { | ||||||
|  |         return config.targetDeviceRootInternal == ""; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /* Navigation related */ |     /* Navigation related */ | ||||||
|     function navTo(name, historyPush=true) { |     function navTo(name, historyPush=true) { | ||||||
|  |         console.log("Navigating to screen: " + name); | ||||||
|         if (historyPush) |         if (historyPush) | ||||||
|             screenPrevious.push(screen); |             screenPrevious.push(screen); | ||||||
|         screen = name; |         screen = name; | ||||||
| @@ -131,15 +167,71 @@ Page | |||||||
|         Qt.inputMethod.hide(); |         Qt.inputMethod.hide(); | ||||||
|     } |     } | ||||||
|     function navFinish() { |     function navFinish() { | ||||||
|         /* Show a waiting screen and wait a second (so it can render), then let |         /* Show a waiting screen and wait a second (so it can render). The big | ||||||
|          * MobileQmlViewStep.cpp::onLeave() create the (encrypted) partition |          * comment in Config.cpp::runPartitionJobThenLeave() explains why this | ||||||
|          * and mount it. We can't have this as proper job due to ondev#18. */ |          * is necessary. */ | ||||||
|         navTo("wait"); |         navTo("wait"); | ||||||
|         timer.interval = 1000; |         timer.interval = 1000; | ||||||
|         timer.repeat = false; |         timer.repeat = false; | ||||||
|         timer.triggered.connect(ViewManager.next); |         timer.triggered.connect(function() { | ||||||
|  |             /* Trigger Config.cpp::runPartitionJobThenLeave(). (We could expose | ||||||
|  |              * the function directly with qmlRegisterSingletonType somehow, but | ||||||
|  |              * I haven't seen existing Calamares code do that with the Config | ||||||
|  |              * object, so just use the side effect of setting the variable, as | ||||||
|  |              * done in existing code of Calamares modules.) */ | ||||||
|  |             config.runPartitionJobThenLeave = 1 | ||||||
|  |         }); | ||||||
|         timer.start(); |         timer.start(); | ||||||
|     } |     } | ||||||
|  |     function navNextFeature() { | ||||||
|  |         var id; | ||||||
|  |  | ||||||
|  |         /* Skip disabled features */ | ||||||
|  |         for (id = featureIdByScreen[screen] + 1; id < features.length; id++) { | ||||||
|  |             /* First letter uppercase */ | ||||||
|  |             var name = features[id]["name"]; | ||||||
|  |             var nameUp = name.charAt(0).toUpperCase() + name.slice(1); | ||||||
|  |  | ||||||
|  |             /* Check config.Feature<Name> */ | ||||||
|  |             var configOption = "feature" + nameUp; | ||||||
|  |             if (config[configOption] === false) { | ||||||
|  |                 console.log("Skipping feature (disabled in config): " + name); | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             /* Check skipFeature<Name>() */ | ||||||
|  |             var funcName = "skipFeature" + nameUp; | ||||||
|  |             if (eval("typeof " + funcName) === "function" | ||||||
|  |                 && eval(funcName + "()")) { | ||||||
|  |                 console.log("Skipping feature (skip function): " + name); | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         console.log("Navigating to feature: " + features[id]["name"]); | ||||||
|  |         return navTo(features[id]["screens"][0]); | ||||||
|  |     } | ||||||
|  |     function navNext() { | ||||||
|  |         var featureId = featureIdByScreen[screen]; | ||||||
|  |         var featureScreens = features[featureId]["screens"]; | ||||||
|  |         for (var i = 0; i<featureScreens.length; i++) { | ||||||
|  |             /* Seek ahead until i is current screen */ | ||||||
|  |             if (featureScreens[i] != screen) | ||||||
|  |                 continue; | ||||||
|  |  | ||||||
|  |             /* Navigate to next screen in same feature */ | ||||||
|  |             if (i + 1 < featureScreens.length) { | ||||||
|  |                 var screenNext = featureScreens[i + 1]; | ||||||
|  |                 return navTo(screenNext); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             /* Screen is last in feature */ | ||||||
|  |             return navNextFeature(); | ||||||
|  |         } | ||||||
|  |         console.log("ERROR: navNext() failed for screen: " + screen); | ||||||
|  |     } | ||||||
|     function navBack() { |     function navBack() { | ||||||
|         if (screenPrevious.length) |         if (screenPrevious.length) | ||||||
|             return navTo(screenPrevious.pop(), false); |             return navTo(screenPrevious.pop(), false); | ||||||
| @@ -161,7 +253,7 @@ Page | |||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /* Input validation: user-screens (default_pin, ssh_credentials) */ |     /* Input validation: user-screens (user_pass, ssh_credentials) */ | ||||||
|     function validatePin(userPin, userPinRepeat, errorText) { |     function validatePin(userPin, userPinRepeat, errorText) { | ||||||
|         var pin = userPin.text; |         var pin = userPin.text; | ||||||
|         var repeat = userPinRepeat.text; |         var repeat = userPinRepeat.text; | ||||||
| @@ -183,7 +275,7 @@ Page | |||||||
|         if (repeat != pin) |         if (repeat != pin) | ||||||
|             return validationFailure(errorText, |             return validationFailure(errorText, | ||||||
|                                      "The PINs don't match."); |                                      "The PINs don't match."); | ||||||
|                               |  | ||||||
|         return validationFailureClear(errorText); |         return validationFailureClear(errorText); | ||||||
|     } |     } | ||||||
|     function validateSshdUsername(username, errorText) { |     function validateSshdUsername(username, errorText) { | ||||||
| @@ -297,11 +389,21 @@ Page | |||||||
|         if (pass == "") |         if (pass == "") | ||||||
|             return validationFailure(errorText); |             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)) |         if (!check_chars(pass)) | ||||||
|             return validationFailure(errorText, |             return validationFailure(errorText, | ||||||
|                                      "The password must only contain" + |                                      "The password must only contain" + | ||||||
|                                      " these characters, others cannot be" + |                                      " these characters, others can possibly" + | ||||||
|                                      " typed in at boot time:\n" + |                                      " not be typed in after installation:\n" + | ||||||
|                                      "\n" + |                                      "\n" + | ||||||
|                                      allowed_chars_multiline()); |                                      allowed_chars_multiline()); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,9 +4,13 @@ | |||||||
|  |  | ||||||
|   <file>welcome.qml</file> |   <file>welcome.qml</file> | ||||||
|  |  | ||||||
|   <file>default_pin.qml</file> <!-- default user: pin --> |   <file>install_target.qml</file> <!-- install from external to internal? --> | ||||||
|  |   <file>install_target_confirm.qml</file> <!-- overwrite internal storage? --> | ||||||
|  |  | ||||||
|  |   <file>user_pass.qml</file> <!-- default user: password --> | ||||||
|   <file>ssh_confirm.qml</file> <!-- sshd: enable or not? --> |   <file>ssh_confirm.qml</file> <!-- sshd: enable or not? --> | ||||||
|   <file>ssh_credentials.qml</file> <!-- sshd user: username, password --> |   <file>ssh_credentials.qml</file> <!-- sshd user: username, password --> | ||||||
|  |   <file>fs_selection.qml</file> <!-- filesystem selection --> | ||||||
|  |  | ||||||
|   <file>fde_confirm.qml</file> <!-- enable FDE or not? --> |   <file>fde_confirm.qml</file> <!-- enable FDE or not? --> | ||||||
|   <file>fde_pass.qml</file> <!-- FDE password (optional) --> |   <file>fde_pass.qml</file> <!-- FDE password (optional) --> | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ Item { | |||||||
|     height: parent.height |     height: parent.height | ||||||
|  |  | ||||||
|     Text { |     Text { | ||||||
|         id: welcomeText |         id: mainText | ||||||
|         anchors.horizontalCenter: parent.horizontalCenter |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|         anchors.top: parent.top |         anchors.top: parent.top | ||||||
|         anchors.topMargin: 30 |         anchors.topMargin: 30 | ||||||
| @@ -40,29 +40,29 @@ Item { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     Button { |     Button { | ||||||
|         id: enableButton |         id: firstButton | ||||||
|         anchors.horizontalCenter: parent.horizontalCenter |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|         anchors.top: welcomeText.bottom |         anchors.top: mainText.bottom | ||||||
|         anchors.topMargin: 40 |         anchors.topMargin: 40 | ||||||
|         width: 500 |         width: 500 | ||||||
|  |  | ||||||
|         text: qsTr("Enable") |         text: qsTr("Enable") | ||||||
|         onClicked: { |         onClicked: { | ||||||
|             config.isSshEnabled = true; |             config.isSshEnabled = true; | ||||||
|             navTo("ssh_credentials"); |             navNext(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     Button { |     Button { | ||||||
|         anchors.horizontalCenter: parent.horizontalCenter |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
|         anchors.top: enableButton.bottom |         anchors.top: firstButton.bottom | ||||||
|         anchors.topMargin: 40 |         anchors.topMargin: 40 | ||||||
|         width: 500 |         width: 500 | ||||||
|  |  | ||||||
|         text: qsTr("Disable") |         text: qsTr("Disable") | ||||||
|         onClicked: { |         onClicked: { | ||||||
|             config.isSshEnabled = false; |             config.isSshEnabled = false; | ||||||
|             navTo("fde_confirm"); |             navNextFeature(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -100,7 +100,7 @@ Item { | |||||||
|                 config.sshdUsername = username.text; |                 config.sshdUsername = username.text; | ||||||
|                 config.sshdPassword = password.text; |                 config.sshdPassword = password.text; | ||||||
|  |  | ||||||
|                 navTo("fde_confirm"); |                 navNext(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -12,6 +12,17 @@ import QtQuick.Window 2.3 | |||||||
| import QtQuick.VirtualKeyboard 2.1 | import QtQuick.VirtualKeyboard 2.1 | ||||||
| 
 | 
 | ||||||
| Item { | Item { | ||||||
|  |     property var placeholder: (config.userPasswordNumeric | ||||||
|  |                                ? "PIN" | ||||||
|  |                                : "Password") | ||||||
|  |     property var hints: (config.userPasswordNumeric | ||||||
|  |                          ? Qt.ImhDigitsOnly | ||||||
|  |                          : Qt.ImhPreferLowercase) | ||||||
|  |     property var validateFunc: (config.userPasswordNumeric | ||||||
|  |                                 ? validatePin | ||||||
|  |                                 : validatePassword); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     anchors.left: parent.left |     anchors.left: parent.left | ||||||
|     anchors.top: parent.top |     anchors.top: parent.top | ||||||
|     anchors.right: parent.right |     anchors.right: parent.right | ||||||
| @@ -25,23 +36,31 @@ Item { | |||||||
|         anchors.topMargin: 30 |         anchors.topMargin: 30 | ||||||
|         wrapMode: Text.WordWrap |         wrapMode: Text.WordWrap | ||||||
| 
 | 
 | ||||||
|         text: "Set the numeric password of your user. The lockscreen will" + |         text: (function() { | ||||||
|               " ask for this PIN. This is <i>not</i> the PIN of your SIM" + |             if (config.userPasswordNumeric) { | ||||||
|               " card. Make sure to remember it." |                 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: 500 |         width: 500 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     TextField { |     TextField { | ||||||
|         id: userPin |         id: userPass | ||||||
|         anchors.top: description.bottom |         anchors.top: description.bottom | ||||||
|         placeholderText: qsTr("PIN") |         placeholderText: qsTr(placeholder) | ||||||
|         echoMode: TextInput.Password |         echoMode: TextInput.Password | ||||||
|         onTextChanged: validatePin(userPin, userPinRepeat, errorText) |         onTextChanged: validateFunc(userPass, userPassRepeat, errorText) | ||||||
|         text: config.userPassword |         text: config.userPassword | ||||||
| 
 | 
 | ||||||
|         /* Let the virtual keyboard change to digits only */ |         /* Let the virtual keyboard change to digits only */ | ||||||
|         inputMethodHints: Qt.ImhDigitsOnly |         inputMethodHints: hints | ||||||
|         onActiveFocusChanged: { |         onActiveFocusChanged: { | ||||||
|             if(activeFocus) { |             if(activeFocus) { | ||||||
|                 Qt.inputMethod.update(Qt.ImQueryInput) |                 Qt.inputMethod.update(Qt.ImQueryInput) | ||||||
| @@ -54,12 +73,12 @@ Item { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     TextField { |     TextField { | ||||||
|         id: userPinRepeat |         id: userPassRepeat | ||||||
|         anchors.top: userPin.bottom |         anchors.top: userPass.bottom | ||||||
|         placeholderText: qsTr("PIN (repeat)") |         placeholderText: qsTr(placeholder + " (repeat)") | ||||||
|         inputMethodHints: Qt.ImhDigitsOnly |         inputMethodHints: hints | ||||||
|         echoMode: TextInput.Password |         echoMode: TextInput.Password | ||||||
|         onTextChanged: validatePin(userPin, userPinRepeat, errorText) |         onTextChanged: validateFunc(userPass, userPassRepeat, errorText) | ||||||
|         text: config.userPassword |         text: config.userPassword | ||||||
| 
 | 
 | ||||||
|         anchors.horizontalCenter: parent.horizontalCenter |         anchors.horizontalCenter: parent.horizontalCenter | ||||||
| @@ -68,7 +87,7 @@ Item { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     Text { |     Text { | ||||||
|         anchors.top: userPinRepeat.bottom |         anchors.top: userPassRepeat.bottom | ||||||
|         id: errorText |         id: errorText | ||||||
|         visible: false |         visible: false | ||||||
|         wrapMode: Text.WordWrap |         wrapMode: Text.WordWrap | ||||||
| @@ -86,9 +105,9 @@ Item { | |||||||
| 
 | 
 | ||||||
|         text: qsTr("Continue") |         text: qsTr("Continue") | ||||||
|         onClicked: { |         onClicked: { | ||||||
|             if (validatePin(userPin, userPinRepeat, errorText)) { |             if (validateFunc(userPass, userPassRepeat, errorText)) { | ||||||
|                 config.userPassword = userPin.text; |                 config.userPassword = userPass.text; | ||||||
|                 navTo("ssh_confirm"); |                 navNext(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -38,7 +38,7 @@ Page | |||||||
|             anchors.topMargin: 150 |             anchors.topMargin: 150 | ||||||
|             wrapMode: Text.WordWrap |             wrapMode: Text.WordWrap | ||||||
|             text: "Formatting and mounting target partition. This may" + |             text: "Formatting and mounting target partition. This may" + | ||||||
|                   " take up to 20 seconds, please be patient." |                   " take up to two minutes, please be patient." | ||||||
|             width: 500 |             width: 500 | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ Page | |||||||
|                 source: "file:///usr/share/calamares/branding/default-mobile/logo.png" |                 source: "file:///usr/share/calamares/branding/default-mobile/logo.png" | ||||||
|             } |             } | ||||||
|             Text { |             Text { | ||||||
|                 id: welcomeText |                 id: mainText | ||||||
|                 anchors.horizontalCenter: parent.horizontalCenter |                 anchors.horizontalCenter: parent.horizontalCenter | ||||||
|                 anchors.top: logo.bottom |                 anchors.top: logo.bottom | ||||||
|                 anchors.topMargin: 50 |                 anchors.topMargin: 50 | ||||||
| @@ -53,12 +53,12 @@ Page | |||||||
|  |  | ||||||
|             Button { |             Button { | ||||||
|                 anchors.horizontalCenter: parent.horizontalCenter |                 anchors.horizontalCenter: parent.horizontalCenter | ||||||
|                 anchors.top: welcomeText.bottom |                 anchors.top: mainText.bottom | ||||||
|                 anchors.topMargin: 50 |                 anchors.topMargin: 50 | ||||||
|                 width: 500 |                 width: 500 | ||||||
|  |  | ||||||
|                 text: qsTr("Continue") |                 text: qsTr("Continue") | ||||||
|                 onClicked: navTo("default_pin") |                 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 | # The slowpython module is .. just slow. It can be used | ||||||
| # in testing to allow the slideshow time to run. | # 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. | # This is an example module for Python Job Modules. | ||||||
| # | # | ||||||
| # The slowpython module is just slow. It does produce | # The slowpython module is just slow. It does produce | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								modules/unpackfsc/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								modules/unpackfsc/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | # 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 | ||||||
|  |         UnsquashRunner.cpp | ||||||
|  |     SHARED_LIB | ||||||
|  | ) | ||||||
							
								
								
									
										74
									
								
								modules/unpackfsc/FSArchiverRunner.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								modules/unpackfsc/FSArchiverRunner.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | |||||||
|  | /* === 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; | ||||||
|  |  | ||||||
|  | Calamares::JobResult | ||||||
|  | FSArchiverRunner::run() | ||||||
|  | { | ||||||
|  |     const QString toolName = QStringLiteral( "fsarchiver" ); | ||||||
|  |  | ||||||
|  |     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 ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     QString fsarchiverExecutable; | ||||||
|  |     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 ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const QString destinationPath = CalamaresUtils::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 ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     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, &FSArchiverRunner::fsarchiverProgress ); | ||||||
|  |     return r.run().explainProcess( toolName, std::chrono::seconds( 0 ) ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										30
									
								
								modules/unpackfsc/FSArchiverRunner.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								modules/unpackfsc/FSArchiverRunner.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | /* === 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" | ||||||
|  |  | ||||||
|  | class FSArchiverRunner : public Runner | ||||||
|  | { | ||||||
|  |     Q_OBJECT | ||||||
|  | public: | ||||||
|  |     using Runner::Runner; | ||||||
|  |  | ||||||
|  |     Calamares::JobResult run() override; | ||||||
|  |  | ||||||
|  | protected Q_SLOTS: | ||||||
|  |     void fsarchiverProgress( QString line ); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     int m_since = 0; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #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/CalamaresUtilsSystem.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 | ||||||
							
								
								
									
										116
									
								
								modules/unpackfsc/UnpackFSCJob.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								modules/unpackfsc/UnpackFSCJob.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | |||||||
|  | /* === 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 "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 }, | ||||||
|  |         // TODO: support fsa-block, savefs/restfs format | ||||||
|  |         { "squashfs", T::Squashfs }, | ||||||
|  |         { "squash", T::Squashfs }, | ||||||
|  |         { "unsquash", T::Squashfs }, | ||||||
|  |     }; | ||||||
|  |     // 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< FSArchiverRunner >( m_source, m_destination ); | ||||||
|  |         break; | ||||||
|  |     case Type::Squashfs: | ||||||
|  |         r = std::make_unique< UnsquashRunner >( 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 = CalamaresUtils::getString( map, "source" ); | ||||||
|  |     QString sourceTypeName = CalamaresUtils::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 = CalamaresUtils::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 >(); ) | ||||||
							
								
								
									
										48
									
								
								modules/unpackfsc/UnpackFSCJob.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								modules/unpackfsc/UnpackFSCJob.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_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, | ||||||
|  |         Squashfs, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     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 | ||||||
							
								
								
									
										98
									
								
								modules/unpackfsc/UnsquashRunner.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								modules/unpackfsc/UnsquashRunner.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | |||||||
|  | /* === 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 = CalamaresUtils::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 ) ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										37
									
								
								modules/unpackfsc/UnsquashRunner.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								modules/unpackfsc/UnsquashRunner.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | /* === 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 | ||||||
|  |  * | ||||||
|  |  * NOTE: not implemented | ||||||
|  |  */ | ||||||
|  | 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" | ||||||
							
								
								
									
										35
									
								
								modules/unpackfsc/unpackfsc.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								modules/unpackfsc/unpackfsc.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | # 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`. | ||||||
|  | #       - `squashfs` | ||||||
|  | #         Aliases of this are `squash` and `unsquash`. | ||||||
|  | #   - *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. | ||||||
|  | # | ||||||
|  | # TODO: add `fsa-block` and support for *savefs/restfs* mode. | ||||||
|  | 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